Compare commits
835 Commits
v0.5.0-alp
...
aarch-wind
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6688bcb488 | ||
|
|
73097075d4 | ||
|
|
5e1cab2e75 | ||
|
|
30f439caec | ||
|
|
4b5db4e5a9 | ||
|
|
3fa1d6b09c | ||
|
|
6051a5f1f1 | ||
|
|
5f7dd45361 | ||
|
|
3ca975d81d | ||
|
|
7e2bab921a | ||
|
|
a7b45ee859 | ||
|
|
62f4a1f3c2 | ||
|
|
3d4e387d35 | ||
|
|
2c46640105 | ||
|
|
41443d3989 | ||
|
|
4b3470d30b | ||
|
|
ce71a3df4d | ||
|
|
7232721b87 | ||
|
|
b2f133e6f1 | ||
|
|
87920964d7 | ||
|
|
c7a4f892e3 | ||
|
|
8f9e307930 | ||
|
|
856d43ce69 | ||
|
|
26181a5a1f | ||
|
|
edf87bf9a3 | ||
|
|
5f51538e0b | ||
|
|
48bb760739 | ||
|
|
42121a9fc9 | ||
|
|
02d79a4749 | ||
|
|
ddb26c73bd | ||
|
|
8ff064fe28 | ||
|
|
cf25eb0833 | ||
|
|
5c4260f3ac | ||
|
|
7abf19804c | ||
|
|
df707d5bef | ||
|
|
f3b0b0027e | ||
|
|
106a01223e | ||
|
|
506a60d0be | ||
|
|
4018607b77 | ||
|
|
1cc720ad34 | ||
|
|
73828af715 | ||
|
|
c0a96e3811 | ||
|
|
9d0d76f0a5 | ||
|
|
c7173ac832 | ||
|
|
b12ce47e7e | ||
|
|
269272983b | ||
|
|
6adc5eb9fb | ||
|
|
fd8bc8ae3f | ||
|
|
3369b0d429 | ||
|
|
097d39e8ce | ||
|
|
11fa08e6d6 | ||
|
|
96987af71d | ||
|
|
23327cb3ef | ||
|
|
b43b45be8f | ||
|
|
41994ec82e | ||
|
|
cd14ea7c62 | ||
|
|
9f13bca6b8 | ||
|
|
f4252c3e97 | ||
|
|
6598867d3d | ||
|
|
f39e040a0d | ||
|
|
a3d140269b | ||
|
|
feac29ea40 | ||
|
|
834c8cdbca | ||
|
|
d441fbdf91 | ||
|
|
e897f524dc | ||
|
|
1caf9446d8 | ||
|
|
bfd2c885db | ||
|
|
f467fa4e59 | ||
|
|
41fca4a2bb | ||
|
|
d38f955144 | ||
|
|
010e50a25d | ||
|
|
eab7c607cd | ||
|
|
3cafbf7f1a | ||
|
|
d7277b5a5b | ||
|
|
bb8dd1402d | ||
|
|
539cd0d418 | ||
|
|
0f8e1625d5 | ||
|
|
840e9bedb2 | ||
|
|
e11ad476fc | ||
|
|
c43726bc75 | ||
|
|
c9ab933a23 | ||
|
|
066a0b1668 | ||
|
|
aa68fe412e | ||
|
|
d748ea7e40 | ||
|
|
a7a282078f | ||
|
|
2fad3b588a | ||
|
|
4cb5d4a9c5 | ||
|
|
5b22ef192e | ||
|
|
34024d8524 | ||
|
|
ecc31dea15 | ||
|
|
d0e48d9bdc | ||
|
|
f6fc5599c0 | ||
|
|
89b6666436 | ||
|
|
94d45a2262 | ||
|
|
dc17a185ca | ||
|
|
4915477823 | ||
|
|
8662d2227c | ||
|
|
dd01a9bef3 | ||
|
|
6e320b1fd5 | ||
|
|
6e40993199 | ||
|
|
9d48af2b50 | ||
|
|
28d48a76e3 | ||
|
|
80eb14f9da | ||
|
|
623fa06d52 | ||
|
|
7154113c13 | ||
|
|
0a932ff880 | ||
|
|
7ef4a1ff12 | ||
|
|
ccc52b69d2 | ||
|
|
8139fdc738 | ||
|
|
a4fd53d516 | ||
|
|
27357110b5 | ||
|
|
fde78738b6 | ||
|
|
ce530e795a | ||
|
|
658d211779 | ||
|
|
66c1cd0d93 | ||
|
|
55ac231cec | ||
|
|
67674d53a2 | ||
|
|
8646b2dfce | ||
|
|
a2f68c2e3c | ||
|
|
5b1a090c5e | ||
|
|
e9efa238b0 | ||
|
|
0dabd8a1f6 | ||
|
|
b7a1f82f56 | ||
|
|
2507e096b7 | ||
|
|
b303b0a99c | ||
|
|
342fb57d14 | ||
|
|
a9ca77e27f | ||
|
|
6542304340 | ||
|
|
6b0f7f94b6 | ||
|
|
d87c76a23e | ||
|
|
305423b856 | ||
|
|
4b62190aff | ||
|
|
e17771a6a5 | ||
|
|
bac30ae78b | ||
|
|
c0219922b2 | ||
|
|
b5ed952d5c | ||
|
|
7994bc4909 | ||
|
|
b88d34c639 | ||
|
|
96cb1ee3fd | ||
|
|
003abe86bb | ||
|
|
6ec411a618 | ||
|
|
c7c0903804 | ||
|
|
cdc972a5ce | ||
|
|
17de912608 | ||
|
|
9876508887 | ||
|
|
72d62220e8 | ||
|
|
46ad337fa5 | ||
|
|
7a3ba7721f | ||
|
|
e0198e626b | ||
|
|
142705f386 | ||
|
|
4cb49c7825 | ||
|
|
05adb82dda | ||
|
|
faf7671799 | ||
|
|
d64db329dd | ||
|
|
e34d2339ad | ||
|
|
d196c5091c | ||
|
|
3e83f92532 | ||
|
|
41d7aaf323 | ||
|
|
e110f3726a | ||
|
|
eb5c897ac0 | ||
|
|
e864cf0c7d | ||
|
|
565c12405e | ||
|
|
2a6a8b42a6 | ||
|
|
5cb4cc0d1d | ||
|
|
62eb4f026f | ||
|
|
411d1a89c1 | ||
|
|
6ae0bf366a | ||
|
|
178cdc9dfa | ||
|
|
5bf1f86886 | ||
|
|
e482aba030 | ||
|
|
535e4d42bb | ||
|
|
54398d4c4b | ||
|
|
0987b44e23 | ||
|
|
58098e96d4 | ||
|
|
f649c180cf | ||
|
|
966478b131 | ||
|
|
ca0759a011 | ||
|
|
f1cdf2fe79 | ||
|
|
04fa5e2719 | ||
|
|
eccb95690c | ||
|
|
acf7456371 | ||
|
|
8ea41480b7 | ||
|
|
0d1bc0d7fe | ||
|
|
f9b7774286 | ||
|
|
2e672badf2 | ||
|
|
cd5d6fd15c | ||
|
|
cf76982cfa | ||
|
|
2624ea7d2a | ||
|
|
2e7c4b6dff | ||
|
|
e5dbee1073 | ||
|
|
c06463b61d | ||
|
|
10341e3776 | ||
|
|
824cdc5dcd | ||
|
|
7aa7a35aa5 | ||
|
|
79b57b3359 | ||
|
|
c7aeffe586 | ||
|
|
79c02f2457 | ||
|
|
b9ed68fa9e | ||
|
|
6c6d6c9c8d | ||
|
|
e169d7be68 | ||
|
|
192fd7d4dd | ||
|
|
1f1193e857 | ||
|
|
0a412ade88 | ||
|
|
3cef2fe9aa | ||
|
|
18e53f06fe | ||
|
|
eaac539087 | ||
|
|
57005c4fd5 | ||
|
|
ea58999a2a | ||
|
|
a5a69fd9fc | ||
|
|
f1d0f1c1c9 | ||
|
|
83492d7495 | ||
|
|
10abc2254a | ||
|
|
5d5536a95e | ||
|
|
fe81e55925 | ||
|
|
654690d73e | ||
|
|
256aba4bc1 | ||
|
|
49f8845105 | ||
|
|
12370846b4 | ||
|
|
07637dfe96 | ||
|
|
f389a4a1db | ||
|
|
af077c796c | ||
|
|
1c319f2fa8 | ||
|
|
e8afa03f7b | ||
|
|
9b22545842 | ||
|
|
adc733d25c | ||
|
|
6896257647 | ||
|
|
1d9845a6cb | ||
|
|
8461339e9a | ||
|
|
9904d94e4c | ||
|
|
da25c80d0b | ||
|
|
5fa63733fd | ||
|
|
8b54bf0ba1 | ||
|
|
173dc12cb3 | ||
|
|
e136529ff0 | ||
|
|
75542dacb3 | ||
|
|
07abfbde43 | ||
|
|
96112fe118 | ||
|
|
9d0b313261 | ||
|
|
277ddfa9be | ||
|
|
5d88bdb256 | ||
|
|
8d29b43155 | ||
|
|
cc071a6415 | ||
|
|
8954def25c | ||
|
|
d484098781 | ||
|
|
9f06cbf3a0 | ||
|
|
af4a3ca0af | ||
|
|
43715143e4 | ||
|
|
16aa354d36 | ||
|
|
c739025453 | ||
|
|
f0526d17de | ||
|
|
6cc2e919c0 | ||
|
|
e1f9eaefa9 | ||
|
|
5d62bf9b60 | ||
|
|
4aa5814a0a | ||
|
|
5bca244062 | ||
|
|
7cf57714a4 | ||
|
|
92e6f862ad | ||
|
|
2377f41036 | ||
|
|
26a08f4d9f | ||
|
|
672d207961 | ||
|
|
a3d8e50f26 | ||
|
|
d3abca46a8 | ||
|
|
17fdd18c55 | ||
|
|
e482d038c6 | ||
|
|
d0482a004e | ||
|
|
561a3e3256 | ||
|
|
158dac5e1c | ||
|
|
1413f8c0b6 | ||
|
|
ffb2aa332a | ||
|
|
45e8208e9c | ||
|
|
7f230a8bf4 | ||
|
|
afe26b8c16 | ||
|
|
d153f62b8a | ||
|
|
5c80cd6e50 | ||
|
|
df1aced95d | ||
|
|
5a0a8f5077 | ||
|
|
1c281539e0 | ||
|
|
ef41d14f50 | ||
|
|
aa29397732 | ||
|
|
ca8865a3ce | ||
|
|
7599ef6626 | ||
|
|
43e71f9242 | ||
|
|
aac9b25efe | ||
|
|
532d170585 | ||
|
|
3dcb14013b | ||
|
|
a4c782cd35 | ||
|
|
0779baa0ac | ||
|
|
0849fab644 | ||
|
|
d85bca2e7e | ||
|
|
c7ab6c435c | ||
|
|
98db3b4f08 | ||
|
|
0e7ba839ed | ||
|
|
2c27691e57 | ||
|
|
934506bdfd | ||
|
|
f313fa4ae1 | ||
|
|
78755b6130 | ||
|
|
8bf59e5cbb | ||
|
|
8f71d13714 | ||
|
|
f4a790eb50 | ||
|
|
0d951c8ad1 | ||
|
|
59ef5f05ea | ||
|
|
b84aab0960 | ||
|
|
0e89b91c38 | ||
|
|
7888a704e1 | ||
|
|
804fd3de8e | ||
|
|
4992c36f08 | ||
|
|
27af0c841b | ||
|
|
cc4f4df4f9 | ||
|
|
5989ab3b85 | ||
|
|
040b9c1452 | ||
|
|
bb7bd2e27e | ||
|
|
02dbd4ba75 | ||
|
|
3b149cc875 | ||
|
|
f3745c68d2 | ||
|
|
eddbe7d0cf | ||
|
|
faf86d006a | ||
|
|
71e4dfeb14 | ||
|
|
da8ed6ddf9 | ||
|
|
503e687c55 | ||
|
|
dd667cce0b | ||
|
|
f911009752 | ||
|
|
cae4c46669 | ||
|
|
a937fc38db | ||
|
|
ff43ffce07 | ||
|
|
5bb3dc258a | ||
|
|
98238e4516 | ||
|
|
23b8308282 | ||
|
|
a1f7cdc2b6 | ||
|
|
dcb30351c5 | ||
|
|
1c0dc60071 | ||
|
|
0401c3ac0e | ||
|
|
3b800d1cd7 | ||
|
|
35efb464e5 | ||
|
|
19a955a327 | ||
|
|
836b18e68a | ||
|
|
046dc0d598 | ||
|
|
039d92ce78 | ||
|
|
2136da15d6 | ||
|
|
e5041d80ef | ||
|
|
f66860bdfe | ||
|
|
50f0a2bd2e | ||
|
|
7cd9bd383e | ||
|
|
45a20a1633 | ||
|
|
ec5b3f80ef | ||
|
|
3b257ea87a | ||
|
|
6b82cead9c | ||
|
|
79ae4c52cd | ||
|
|
a4616cda7d | ||
|
|
95648361be | ||
|
|
0c41e9c10b | ||
|
|
61c7ef3cb0 | ||
|
|
65898125d0 | ||
|
|
da05078ff3 | ||
|
|
badb5c3636 | ||
|
|
9453588ab1 | ||
|
|
4cbb3874a4 | ||
|
|
940aff7ef4 | ||
|
|
a3edb93273 | ||
|
|
782b054b1a | ||
|
|
fc27b2911e | ||
|
|
486b067567 | ||
|
|
bdd1afea57 | ||
|
|
5ccd02939b | ||
|
|
ca5b8ab309 | ||
|
|
9481fdd38d | ||
|
|
56bf6d282b | ||
|
|
5364c9c1bc | ||
|
|
a4d4beeb97 | ||
|
|
30a01381be | ||
|
|
def99a9e4d | ||
|
|
1214fc8b0d | ||
|
|
5a5b1268d3 | ||
|
|
6a1fffd1ce | ||
|
|
571ef3060a | ||
|
|
3cf82e112f | ||
|
|
9b459c20d6 | ||
|
|
5c85cd27c3 | ||
|
|
4bf73c7a8a | ||
|
|
62e51b7535 | ||
|
|
729a7f0053 | ||
|
|
03c297190d | ||
|
|
9c790eddd7 | ||
|
|
8ebe7e332b | ||
|
|
f43777e37e | ||
|
|
691a8fcdeb | ||
|
|
69c0e8d70e | ||
|
|
330c92c9a8 | ||
|
|
cf0ff60d31 | ||
|
|
9e9cf5dd1f | ||
|
|
5768d8e4a4 | ||
|
|
3b433e53be | ||
|
|
28ddf40344 | ||
|
|
c1286db9c1 | ||
|
|
f13940262e | ||
|
|
9f0a6101b8 | ||
|
|
0b0fe01a7c | ||
|
|
85e098d5c8 | ||
|
|
e8d1faf4e2 | ||
|
|
2a46df1110 | ||
|
|
1601e6d26e | ||
|
|
0e4f6dea2b | ||
|
|
a2356773dc | ||
|
|
4a4da4737d | ||
|
|
2cefd1bf2e | ||
|
|
c5ce15fe34 | ||
|
|
76dea568c9 | ||
|
|
8e81140eff | ||
|
|
d58e1f0792 | ||
|
|
830c242751 | ||
|
|
91d45afd0f | ||
|
|
102c77b23e | ||
|
|
aa4039a2e7 | ||
|
|
c065ded440 | ||
|
|
f69096dadb | ||
|
|
363f95ba14 | ||
|
|
dcc15e8911 | ||
|
|
bd13047b58 | ||
|
|
1a83789c01 | ||
|
|
1cbe272e19 | ||
|
|
6de74b41b3 | ||
|
|
b0fc9ee507 | ||
|
|
a95ffe1d31 | ||
|
|
4119a510f5 | ||
|
|
cfa7f03815 | ||
|
|
9b4c89820d | ||
|
|
fe874720aa | ||
|
|
f7c0f33eb5 | ||
|
|
c1bf9d9dfc | ||
|
|
255bf439d3 | ||
|
|
2a31937b81 | ||
|
|
eb8964e1d1 | ||
|
|
fe0ca280a1 | ||
|
|
e8e3b7b985 | ||
|
|
c437507442 | ||
|
|
ca151b434e | ||
|
|
10ba74c21e | ||
|
|
6191b6371d | ||
|
|
5be4175ac3 | ||
|
|
f61f3671a6 | ||
|
|
477e0ada32 | ||
|
|
a884f693ae | ||
|
|
3107b1b21b | ||
|
|
04529de7b3 | ||
|
|
199a39208c | ||
|
|
0187da5f24 | ||
|
|
2e1c37ffff | ||
|
|
4b0189dd55 | ||
|
|
d4a39674de | ||
|
|
07c6fd3711 | ||
|
|
cf5b72aa9a | ||
|
|
cdfbebd637 | ||
|
|
e86e3316a9 | ||
|
|
bb2dcbaea0 | ||
|
|
fefc7a69cd | ||
|
|
1b24cd36e0 | ||
|
|
6322c1f46d | ||
|
|
00a29bb6be | ||
|
|
3a029caf2b | ||
|
|
57263905e7 | ||
|
|
4f46012c11 | ||
|
|
7ea9a1e3e8 | ||
|
|
c7510e12c4 | ||
|
|
89b5d9294c | ||
|
|
339e1060b7 | ||
|
|
52e1dbd846 | ||
|
|
b4963f4ff7 | ||
|
|
838e8f6bde | ||
|
|
8f21514855 | ||
|
|
44041f33e3 | ||
|
|
5d9bc4473c | ||
|
|
a3e0d42e86 | ||
|
|
4a9c1d0d1b | ||
|
|
ff47f79c62 | ||
|
|
f46a391873 | ||
|
|
99b8ada42b | ||
|
|
f2227aa7cb | ||
|
|
a9f6c20113 | ||
|
|
e261e7a2c7 | ||
|
|
ae811aafd0 | ||
|
|
cc593b465d | ||
|
|
f81e8339e3 | ||
|
|
cdc5513726 | ||
|
|
a398338c02 | ||
|
|
26e2e81188 | ||
|
|
46d7bba87d | ||
|
|
57d5610a58 | ||
|
|
1968e1fdb7 | ||
|
|
f2584cf807 | ||
|
|
dd592d1d6d | ||
|
|
cfff08cdfd | ||
|
|
e83437c193 | ||
|
|
1d900a6a3c | ||
|
|
859c7bea8a | ||
|
|
1b9e90e786 | ||
|
|
41396367ac | ||
|
|
16c9a23d55 | ||
|
|
ce338a2a72 | ||
|
|
1f7f2b22e7 | ||
|
|
47c7f63d75 | ||
|
|
8b1e85fbb4 | ||
|
|
ff4e9fb027 | ||
|
|
d15ef40988 | ||
|
|
eadfb18f74 | ||
|
|
4b89bb087a | ||
|
|
f0a602b48b | ||
|
|
fe10da9a6c | ||
|
|
948303aac8 | ||
|
|
12df80da56 | ||
|
|
a48c238ed7 | ||
|
|
da6c7b4d7a | ||
|
|
15cbbacc2f | ||
|
|
c3f6a17bae | ||
|
|
0fbeb70865 | ||
|
|
02f98a4053 | ||
|
|
d2e2a13479 | ||
|
|
f32cb592e2 | ||
|
|
72342f3118 | ||
|
|
246fd5f6c4 | ||
|
|
715022def5 | ||
|
|
78b2bafde1 | ||
|
|
2d7ebac8e6 | ||
|
|
bcffd2eb99 | ||
|
|
459bf62fab | ||
|
|
bdaa671823 | ||
|
|
463bf9b116 | ||
|
|
0c7a94c062 | ||
|
|
af866f0665 | ||
|
|
2493c70241 | ||
|
|
3c3359999c | ||
|
|
2467004dc2 | ||
|
|
3a9f438390 | ||
|
|
3126de2c37 | ||
|
|
b7d026b98e | ||
|
|
3f8b178f88 | ||
|
|
6184f4ce4f | ||
|
|
fa736697a9 | ||
|
|
2c88c700ca | ||
|
|
0b2e9ce1ad | ||
|
|
ccafdf250e | ||
|
|
57b28faa74 | ||
|
|
d0d7c58af1 | ||
|
|
339fc979f5 | ||
|
|
47614c3102 | ||
|
|
94e1501329 | ||
|
|
dfb015acc2 | ||
|
|
f1daafbf9e | ||
|
|
432e10c205 | ||
|
|
62b626a931 | ||
|
|
9a2893c6bc | ||
|
|
3a538f98ed | ||
|
|
7c71708de7 | ||
|
|
b64d97e808 | ||
|
|
428a19789d | ||
|
|
7cc4055d94 | ||
|
|
114c93fa46 | ||
|
|
07801a0283 | ||
|
|
30c8ea583b | ||
|
|
d54a5f647e | ||
|
|
457ed05174 | ||
|
|
44c94da2d8 | ||
|
|
ec614e1912 | ||
|
|
559b509a03 | ||
|
|
e2e9209655 | ||
|
|
e55b72f73f | ||
|
|
85e30cc968 | ||
|
|
51dcfbab75 | ||
|
|
7c0aa45057 | ||
|
|
a5fdc2a9cc | ||
|
|
64fd2f9cf8 | ||
|
|
a77495c562 | ||
|
|
3880708e1d | ||
|
|
cc68d57f11 | ||
|
|
56f5a61362 | ||
|
|
40540c3637 | ||
|
|
82678235ab | ||
|
|
5123d21290 | ||
|
|
b0dcf515f0 | ||
|
|
9aafccc946 | ||
|
|
ccf98d7283 | ||
|
|
1b35c98be5 | ||
|
|
db23c3d35a | ||
|
|
1c6c1298d5 | ||
|
|
b9ebed14a5 | ||
|
|
7077f0f1f3 | ||
|
|
d1887c6cd3 | ||
|
|
9278c81611 | ||
|
|
dec9ec32df | ||
|
|
1967f738a8 | ||
|
|
1031600c63 | ||
|
|
24c697bea7 | ||
|
|
83665018d4 | ||
|
|
b093626a21 | ||
|
|
f3dc78b7cd | ||
|
|
f0cd4333c3 | ||
|
|
6d38a785ed | ||
|
|
e46f9fd94f | ||
|
|
6b620ddcef | ||
|
|
e5684ad947 | ||
|
|
dfabc07044 | ||
|
|
dca88e8272 | ||
|
|
9f947ae2c5 | ||
|
|
28156bcaf2 | ||
|
|
a14aacbcf9 | ||
|
|
321e026e43 | ||
|
|
30351f7b9d | ||
|
|
2393a1a114 | ||
|
|
479476561e | ||
|
|
a02f485040 | ||
|
|
2957e8ad73 | ||
|
|
f83abe15cb | ||
|
|
709cba45ce | ||
|
|
8a9a72fd50 | ||
|
|
13cb0a27a0 | ||
|
|
fa817e3cdd | ||
|
|
3bd8549f41 | ||
|
|
4e47655b17 | ||
|
|
18533d5944 | ||
|
|
c5839c94ca | ||
|
|
ffc146ff9b | ||
|
|
7b82e3d641 | ||
|
|
ab6cedb659 | ||
|
|
e60be94be0 | ||
|
|
f830b024d5 | ||
|
|
98519da7d9 | ||
|
|
cb3211cf46 | ||
|
|
c051153a1f | ||
|
|
956d7e0918 | ||
|
|
530a7aa834 | ||
|
|
052ca52cc3 | ||
|
|
2025b8a494 | ||
|
|
238233ca81 | ||
|
|
938c8259c3 | ||
|
|
35df5f25c7 | ||
|
|
cd84fb9fc1 | ||
|
|
8bcf12e317 | ||
|
|
10ed353e0a | ||
|
|
72d88200e4 | ||
|
|
6ef832b3a9 | ||
|
|
17d91563d5 | ||
|
|
fb65693627 | ||
|
|
079fc738ad | ||
|
|
ae0f3b0b02 | ||
|
|
b2c515f2e6 | ||
|
|
6f1469a551 | ||
|
|
1d441b86d2 | ||
|
|
b72e6e54e6 | ||
|
|
1ee679395d | ||
|
|
cf62ee5ccb | ||
|
|
995685adfe | ||
|
|
f0eb955628 | ||
|
|
923f661428 | ||
|
|
b562d11994 | ||
|
|
3554112f31 | ||
|
|
7cada2608f | ||
|
|
21d4acebc3 | ||
|
|
73bbaaf0af | ||
|
|
40105515d2 | ||
|
|
79f09deecb | ||
|
|
c4a7f8675f | ||
|
|
f9a5fee364 | ||
|
|
bdd9c58cae | ||
|
|
09368e87cf | ||
|
|
46858c45b8 | ||
|
|
fe1a96f850 | ||
|
|
581449d992 | ||
|
|
15e848d4bf | ||
|
|
0dbbf44ab2 | ||
|
|
c62a5d15ad | ||
|
|
53bd02a890 | ||
|
|
099aa26ef8 | ||
|
|
2598ea3577 | ||
|
|
7be5b36494 | ||
|
|
3dff4d1061 | ||
|
|
5b7037550d | ||
|
|
b94f21402c | ||
|
|
9f5875d4bb | ||
|
|
694b6101ca | ||
|
|
1737da9c1f | ||
|
|
bcf4fea598 | ||
|
|
90e41f3ce9 | ||
|
|
5f5fb51eae | ||
|
|
95f06d56d8 | ||
|
|
1c6788ea45 | ||
|
|
457a8a5cf8 | ||
|
|
282caf10a5 | ||
|
|
b2fc6c165b | ||
|
|
0a1fa9588f | ||
|
|
5f5bfadf2b | ||
|
|
b512e707a5 | ||
|
|
3678ddfa36 | ||
|
|
ab8aa89f2a | ||
|
|
fd22482f06 | ||
|
|
e741f7b557 | ||
|
|
a70b7ee150 | ||
|
|
87227c96ed | ||
|
|
91d12aeb4f | ||
|
|
b3f132201b | ||
|
|
24b9f552eb | ||
|
|
b4a8dec68c | ||
|
|
c140823bea | ||
|
|
f166cc93cd | ||
|
|
125c9767f1 | ||
|
|
7b7c978db6 | ||
|
|
26fc097672 | ||
|
|
0f2e2406e8 | ||
|
|
061a096600 | ||
|
|
07fe963bed | ||
|
|
7a1eda98ca | ||
|
|
e8a5e44319 | ||
|
|
486319407a | ||
|
|
4f3d917c9b | ||
|
|
e2761965d5 | ||
|
|
171ab196c8 | ||
|
|
5630cea9a0 | ||
|
|
5a4189a770 | ||
|
|
2440d9fc48 | ||
|
|
bd33aebc3d | ||
|
|
a46d467b75 | ||
|
|
8c6981da0d | ||
|
|
500a9f647f | ||
|
|
71968fca0d | ||
|
|
fc6f84897f | ||
|
|
b31ad4b1f8 | ||
|
|
aababf37a8 | ||
|
|
44a42a177a | ||
|
|
e773a92e53 | ||
|
|
196d27b959 | ||
|
|
ec8861e983 | ||
|
|
9b601eb9fe | ||
|
|
c80d9cbf01 | ||
|
|
717c15256f | ||
|
|
13dafc2091 | ||
|
|
cfc3bcfa41 | ||
|
|
2e052e97c5 | ||
|
|
5d48d05287 | ||
|
|
e34ba844c5 | ||
|
|
1d84d3e440 | ||
|
|
7a7e9087e6 | ||
|
|
8481caa67c | ||
|
|
651e63a0fb | ||
|
|
88e462c4e5 | ||
|
|
8ef797d1a4 | ||
|
|
877fd1af35 | ||
|
|
fc01eecdcb | ||
|
|
e6ba6203bb | ||
|
|
6a786f18e6 | ||
|
|
57d46287d7 | ||
|
|
bb6ab74c19 | ||
|
|
3e759b3e8e | ||
|
|
47ee8d54a8 | ||
|
|
824b984a64 | ||
|
|
618185a52d | ||
|
|
8dbc6ab7d3 | ||
|
|
5eb6754b7c | ||
|
|
a914a92cea | ||
|
|
439a1a758e | ||
|
|
9383240627 | ||
|
|
ea765eb929 | ||
|
|
d5c816f24d | ||
|
|
cf5f20bbb5 | ||
|
|
27839dfd21 | ||
|
|
27517e1aee | ||
|
|
a31bfbefa7 | ||
|
|
f1729163cf | ||
|
|
6747d97d60 | ||
|
|
2fb2342fd4 | ||
|
|
0f530b7e80 | ||
|
|
78e3cf4ffb | ||
|
|
4e512b7023 | ||
|
|
ee3fed97e0 | ||
|
|
b45d4f6401 | ||
|
|
d4c28de2c4 | ||
|
|
b7d613ace6 | ||
|
|
68dbb31272 | ||
|
|
8fe1fa48b8 | ||
|
|
e5575b782c | ||
|
|
ea112dd93d | ||
|
|
056fc5e087 | ||
|
|
cacb02b7c8 | ||
|
|
c0b6ec8ccb | ||
|
|
f4c8f0a3d8 | ||
|
|
81407ffe3c | ||
|
|
6f7dbe99fe | ||
|
|
ec9afba029 | ||
|
|
6164c5d78d | ||
|
|
94dbcd5c06 | ||
|
|
4d0dee7ee8 | ||
|
|
49e10698b1 | ||
|
|
8e1536b59b | ||
|
|
aed160994a | ||
|
|
b2b3173420 | ||
|
|
f465af964a | ||
|
|
5a7d6a673a | ||
|
|
7fb9aa2115 | ||
|
|
fea303ac8b | ||
|
|
8e8291a0bd | ||
|
|
4dc175fcd2 | ||
|
|
009a99a8eb | ||
|
|
91caa67e04 | ||
|
|
53793f7dd2 | ||
|
|
32af8783ba | ||
|
|
d6f51f8eba | ||
|
|
f40b7361e8 | ||
|
|
0231e114d5 | ||
|
|
ca61a3e83f | ||
|
|
6979f5c82d | ||
|
|
7d45b45667 | ||
|
|
7575504b80 | ||
|
|
36bcb611f1 | ||
|
|
cc34c36794 | ||
|
|
b84cb93d2c | ||
|
|
08211a7740 | ||
|
|
97985dd458 | ||
|
|
edf157215c | ||
|
|
89671c71fa | ||
|
|
eeedcc50ab | ||
|
|
de0bb069aa | ||
|
|
5d53f8bfb3 | ||
|
|
d4a7de8070 | ||
|
|
3fe15641c7 | ||
|
|
08df71a7e4 | ||
|
|
77db25b4d9 | ||
|
|
62bb5a28aa | ||
|
|
f768b200d2 | ||
|
|
a5b6db74e5 | ||
|
|
cbe4467a22 | ||
|
|
8417d18eec | ||
|
|
93ae8187cd | ||
|
|
972338d86a | ||
|
|
a4a6e3b8f6 | ||
|
|
d788dd3042 | ||
|
|
974760f020 | ||
|
|
65569c4a60 | ||
|
|
39da45f0bd | ||
|
|
dc7c27e619 |
@@ -3,16 +3,27 @@ root = true
|
|||||||
[*]
|
[*]
|
||||||
end_of_line = lf
|
end_of_line = lf
|
||||||
charset = utf-8
|
charset = utf-8
|
||||||
insert_final_newline = false
|
|
||||||
trim_trailing_whitespace = true
|
trim_trailing_whitespace = true
|
||||||
|
insert_final_newline = false
|
||||||
|
|
||||||
[*.{json,js,css}]
|
[*.{json,js,css}]
|
||||||
indent_style = space
|
indent_style = space
|
||||||
indent_size = 2
|
indent_size = 2
|
||||||
|
|
||||||
[*.{md,rs}]
|
[*.md]
|
||||||
indent_style = space
|
indent_style = space
|
||||||
indent_size = 4
|
indent_size = 4
|
||||||
|
|
||||||
|
[*.{rs,toml}]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 4
|
||||||
|
insert_final_newline = true
|
||||||
|
|
||||||
|
[*.snap]
|
||||||
|
insert_final_newline = true
|
||||||
|
|
||||||
[*.lua]
|
[*.lua]
|
||||||
|
indent_style = tab
|
||||||
|
|
||||||
|
[*.luau]
|
||||||
indent_style = tab
|
indent_style = tab
|
||||||
2
.git-blame-ignore-revs
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
# stylua formatting
|
||||||
|
0f8e1625d572a5fe0f7b5c08653ff92cc837d346
|
||||||
1
.gitattributes
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
*.lua linguist-language=Luau
|
||||||
23
.github/workflows/changelog.yml
vendored
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
name: Changelog Check
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
types: [assigned, opened, synchronize, reopened, labeled, unlabeled]
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
name: Check Actions
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Changelog check
|
||||||
|
uses: Zomzog/changelog-checker@v1.3.0
|
||||||
|
with:
|
||||||
|
fileName: CHANGELOG.md
|
||||||
|
noChangelogLabel: skip changelog
|
||||||
|
checkNotification: Simple
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
99
.github/workflows/ci.yml
vendored
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
name: CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
name: Build and Test
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
os: [ubuntu-latest, windows-latest, macos-latest]
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: true
|
||||||
|
|
||||||
|
- name: Install Rust
|
||||||
|
uses: dtolnay/rust-toolchain@stable
|
||||||
|
|
||||||
|
- name: Rust cache
|
||||||
|
uses: Swatinem/rust-cache@v2
|
||||||
|
|
||||||
|
- name: Setup Aftman
|
||||||
|
uses: ok-nick/setup-aftman@v0.3.0
|
||||||
|
with:
|
||||||
|
version: 'v0.2.7'
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: cargo build --locked --verbose
|
||||||
|
|
||||||
|
- name: Test
|
||||||
|
run: cargo test --locked --verbose
|
||||||
|
|
||||||
|
msrv:
|
||||||
|
name: Check MSRV
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: true
|
||||||
|
|
||||||
|
- name: Install Rust
|
||||||
|
uses: dtolnay/rust-toolchain@1.70.0
|
||||||
|
|
||||||
|
- name: Rust cache
|
||||||
|
uses: Swatinem/rust-cache@v2
|
||||||
|
|
||||||
|
- name: Setup Aftman
|
||||||
|
uses: ok-nick/setup-aftman@v0.3.0
|
||||||
|
with:
|
||||||
|
version: 'v0.2.7'
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: cargo build --locked --verbose
|
||||||
|
|
||||||
|
lint:
|
||||||
|
name: Rustfmt, Clippy, Stylua, & Selene
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: true
|
||||||
|
|
||||||
|
- name: Install Rust
|
||||||
|
uses: dtolnay/rust-toolchain@stable
|
||||||
|
with:
|
||||||
|
components: rustfmt, clippy
|
||||||
|
|
||||||
|
- name: Rust cache
|
||||||
|
uses: Swatinem/rust-cache@v2
|
||||||
|
|
||||||
|
- name: Setup Aftman
|
||||||
|
uses: ok-nick/setup-aftman@v0.3.0
|
||||||
|
with:
|
||||||
|
version: 'v0.2.7'
|
||||||
|
|
||||||
|
- name: Stylua
|
||||||
|
run: stylua --check plugin/src
|
||||||
|
|
||||||
|
- name: Selene
|
||||||
|
run: selene plugin/src
|
||||||
|
|
||||||
|
- name: Rustfmt
|
||||||
|
run: cargo fmt -- --check
|
||||||
|
|
||||||
|
- name: Clippy
|
||||||
|
run: cargo clippy
|
||||||
|
|
||||||
145
.github/workflows/release.yml
vendored
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
name: Release
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags: ["v*"]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
create-release:
|
||||||
|
name: Create Release
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Create Release
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
run: |
|
||||||
|
gh release create ${{ github.ref_name }} --draft --verify-tag --title ${{ github.ref_name }}
|
||||||
|
|
||||||
|
build-plugin:
|
||||||
|
needs: ["create-release"]
|
||||||
|
name: Build Roblox Studio Plugin
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: true
|
||||||
|
|
||||||
|
- name: Setup Aftman
|
||||||
|
uses: ok-nick/setup-aftman@v0.1.0
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
trust-check: false
|
||||||
|
version: 'v0.2.6'
|
||||||
|
|
||||||
|
- name: Build Plugin
|
||||||
|
run: rojo build plugin --output Rojo.rbxm
|
||||||
|
|
||||||
|
- name: Upload Plugin to Release
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
run: |
|
||||||
|
gh release upload ${{ github.ref_name }} Rojo.rbxm
|
||||||
|
|
||||||
|
- name: Upload Plugin to Artifacts
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: Rojo.rbxm
|
||||||
|
path: Rojo.rbxm
|
||||||
|
|
||||||
|
build:
|
||||||
|
needs: ["create-release"]
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
# https://doc.rust-lang.org/rustc/platform-support.html
|
||||||
|
include:
|
||||||
|
- host: linux
|
||||||
|
os: ubuntu-20.04
|
||||||
|
target: x86_64-unknown-linux-gnu
|
||||||
|
label: linux-x86_64
|
||||||
|
|
||||||
|
- host: linux
|
||||||
|
os: ubuntu-20.04
|
||||||
|
target: aarch64-unknown-linux-gnu
|
||||||
|
label: linux-aarch64
|
||||||
|
|
||||||
|
- host: windows
|
||||||
|
os: windows-latest
|
||||||
|
target: x86_64-pc-windows-msvc
|
||||||
|
label: windows-x86_64
|
||||||
|
|
||||||
|
- host: windows
|
||||||
|
os: windows-latest
|
||||||
|
target: aarch64-pc-windows-msvc
|
||||||
|
label: windows-aarch64
|
||||||
|
|
||||||
|
- host: macos
|
||||||
|
os: macos-latest
|
||||||
|
target: x86_64-apple-darwin
|
||||||
|
label: macos-x86_64
|
||||||
|
|
||||||
|
- host: macos
|
||||||
|
os: macos-latest
|
||||||
|
target: aarch64-apple-darwin
|
||||||
|
label: macos-aarch64
|
||||||
|
|
||||||
|
name: Build (${{ matrix.target }})
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
env:
|
||||||
|
BIN: rojo
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: true
|
||||||
|
|
||||||
|
- name: Install Rust
|
||||||
|
uses: dtolnay/rust-toolchain@stable
|
||||||
|
with:
|
||||||
|
targets: ${{ matrix.target }}
|
||||||
|
|
||||||
|
- name: Setup Aftman
|
||||||
|
uses: ok-nick/setup-aftman@v0.1.0
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
trust-check: false
|
||||||
|
version: 'v0.2.6'
|
||||||
|
|
||||||
|
- name: Build Release
|
||||||
|
run: cargo build --release --locked --verbose --target ${{ matrix.target }}
|
||||||
|
env:
|
||||||
|
# Build into a known directory so we can find our build artifact more
|
||||||
|
# easily.
|
||||||
|
CARGO_TARGET_DIR: output
|
||||||
|
|
||||||
|
- name: Generate Artifact Name
|
||||||
|
shell: bash
|
||||||
|
env:
|
||||||
|
TAG_NAME: ${{ github.ref_name }}
|
||||||
|
run: |
|
||||||
|
echo "ARTIFACT_NAME=$BIN-${TAG_NAME#v}-${{ matrix.label }}.zip" >> "$GITHUB_ENV"
|
||||||
|
|
||||||
|
- name: Create Archive and Upload to Release
|
||||||
|
shell: bash
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
run: |
|
||||||
|
mkdir staging
|
||||||
|
|
||||||
|
if [ "${{ matrix.host }}" = "windows" ]; then
|
||||||
|
cp "output/${{ matrix.target }}/release/$BIN.exe" staging/
|
||||||
|
cd staging
|
||||||
|
7z a ../$ARTIFACT_NAME *
|
||||||
|
else
|
||||||
|
cp "output/${{ matrix.target }}/release/$BIN" staging/
|
||||||
|
cd staging
|
||||||
|
zip ../$ARTIFACT_NAME *
|
||||||
|
fi
|
||||||
|
|
||||||
|
gh release upload ${{ github.ref_name }} ../$ARTIFACT_NAME
|
||||||
|
|
||||||
|
- name: Upload Archive to Artifacts
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
path: ${{ env.ARTIFACT_NAME }}
|
||||||
|
name: ${{ env.ARTIFACT_NAME }}
|
||||||
22
.gitignore
vendored
@@ -1,9 +1,21 @@
|
|||||||
/site
|
# Rust output directory
|
||||||
/target
|
/target
|
||||||
/scratch-project
|
|
||||||
**/*.rs.bk
|
# Headers for clibrojo
|
||||||
/server/failed-snapshots/
|
/include
|
||||||
|
|
||||||
|
# Roblox model and place files in the root, used for debugging
|
||||||
/*.rbxm
|
/*.rbxm
|
||||||
/*.rbxmx
|
/*.rbxmx
|
||||||
/*.rbxl
|
/*.rbxl
|
||||||
/*.rbxlx
|
/*.rbxlx
|
||||||
|
|
||||||
|
# Test places for the Roblox Studio Plugin
|
||||||
|
/plugin/*.rbxlx
|
||||||
|
|
||||||
|
# Roblox Studio holds 'lock' files on places
|
||||||
|
*.rbxl.lock
|
||||||
|
*.rbxlx.lock
|
||||||
|
|
||||||
|
# Snapshot files from the 'insta' Rust crate
|
||||||
|
**/*.snap.new
|
||||||
|
|||||||
34
.gitmodules
vendored
@@ -1,18 +1,18 @@
|
|||||||
[submodule "plugin/modules/roact"]
|
[submodule "plugin/Packages/Roact"]
|
||||||
path = plugin/modules/roact
|
path = plugin/Packages/Roact
|
||||||
url = https://github.com/Roblox/roact.git
|
url = https://github.com/roblox/roact.git
|
||||||
[submodule "plugin/modules/testez"]
|
[submodule "plugin/Packages/Flipper"]
|
||||||
path = plugin/modules/testez
|
path = plugin/Packages/Flipper
|
||||||
url = https://github.com/Roblox/testez.git
|
url = https://github.com/reselim/flipper.git
|
||||||
[submodule "plugin/modules/lemur"]
|
[submodule "plugin/Packages/Promise"]
|
||||||
path = plugin/modules/lemur
|
path = plugin/Packages/Promise
|
||||||
url = https://github.com/LPGhatguy/lemur.git
|
url = https://github.com/evaera/roblox-lua-promise.git
|
||||||
[submodule "plugin/modules/promise"]
|
[submodule "plugin/Packages/t"]
|
||||||
path = plugin/modules/promise
|
path = plugin/Packages/t
|
||||||
url = https://github.com/LPGhatguy/roblox-lua-promise.git
|
|
||||||
[submodule "plugin/modules/t"]
|
|
||||||
path = plugin/modules/t
|
|
||||||
url = https://github.com/osyrisrblx/t.git
|
url = https://github.com/osyrisrblx/t.git
|
||||||
[submodule "plugin/modules/rbx-dom"]
|
[submodule "plugin/Packages/TestEZ"]
|
||||||
path = plugin/modules/rbx-dom
|
path = plugin/Packages/TestEZ
|
||||||
url = http://github.com/LPGhatguy/rbx-dom
|
url = https://github.com/roblox/testez.git
|
||||||
|
[submodule "plugin/Packages/Highlighter"]
|
||||||
|
path = plugin/Packages/Highlighter
|
||||||
|
url = https://github.com/boatbomber/highlighter.git
|
||||||
|
|||||||
54
.travis.yml
@@ -1,54 +0,0 @@
|
|||||||
matrix:
|
|
||||||
include:
|
|
||||||
# Lua tests are currently disabled because of holes in Lemur that are pretty
|
|
||||||
# tedious to fix. It should be fixed by either adding missing features to
|
|
||||||
# Lemur or by migrating to a CI system based on real Roblox instead.
|
|
||||||
|
|
||||||
# - language: python
|
|
||||||
# env:
|
|
||||||
# - LUA="lua=5.1"
|
|
||||||
|
|
||||||
# before_install:
|
|
||||||
# - pip install hererocks
|
|
||||||
# - hererocks lua_install -r^ --$LUA
|
|
||||||
# - export PATH=$PATH:$PWD/lua_install/bin
|
|
||||||
|
|
||||||
# install:
|
|
||||||
# - luarocks install luafilesystem
|
|
||||||
# - luarocks install busted
|
|
||||||
# - luarocks install luacov
|
|
||||||
# - luarocks install luacov-coveralls
|
|
||||||
# - luarocks install luacheck
|
|
||||||
|
|
||||||
# script:
|
|
||||||
# - cd plugin
|
|
||||||
# - luacheck src
|
|
||||||
# - lua -lluacov spec.lua
|
|
||||||
|
|
||||||
# after_success:
|
|
||||||
# - cd plugin
|
|
||||||
# - luacov-coveralls -e $TRAVIS_BUILD_DIR/lua_install
|
|
||||||
|
|
||||||
- language: rust
|
|
||||||
rust: 1.32.0
|
|
||||||
cache: cargo
|
|
||||||
|
|
||||||
script:
|
|
||||||
- cargo test --verbose
|
|
||||||
- cargo test --verbose --all-features
|
|
||||||
|
|
||||||
- language: rust
|
|
||||||
rust: stable
|
|
||||||
cache: cargo
|
|
||||||
|
|
||||||
script:
|
|
||||||
- cargo test --verbose
|
|
||||||
- cargo test --verbose --all-features
|
|
||||||
|
|
||||||
- language: rust
|
|
||||||
rust: beta
|
|
||||||
cache: cargo
|
|
||||||
|
|
||||||
script:
|
|
||||||
- cargo test --verbose
|
|
||||||
- cargo test --verbose --all-features
|
|
||||||
645
CHANGELOG.md
@@ -1,5 +1,646 @@
|
|||||||
# Rojo Changelog
|
# Rojo Changelog
|
||||||
|
|
||||||
|
## Unreleased Changes
|
||||||
|
* Projects may now manually link `Ref` properties together using `Attributes`. ([#843])
|
||||||
|
This has two parts: using `id` or `$id` in JSON files or a `Rojo_Target` attribute, an Instance
|
||||||
|
is given an ID. Then, that ID may be used elsewhere in the project to point to an Instance
|
||||||
|
using an attribute named `Rojo_Target_PROP_NAME`, where `PROP_NAME` is the name of a property.
|
||||||
|
|
||||||
|
As an example, here is a `model.json` for an ObjectValue that refers to itself:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "arbitrary string",
|
||||||
|
"attributes": {
|
||||||
|
"Rojo_Target_Value": "arbitrary string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
This is a very rough implementation and the usage will become more ergonomic
|
||||||
|
over time.
|
||||||
|
|
||||||
|
* Updated Undo/Redo history to be more robust ([#915])
|
||||||
|
* Added popout diff visualizer for table properties like Attributes and Tags ([#834])
|
||||||
|
* Updated Theme to use Studio colors ([#838])
|
||||||
|
* Improved patch visualizer UX ([#883])
|
||||||
|
* Added update notifications for newer compatible versions in the Studio plugin. ([#832])
|
||||||
|
* Added experimental setting for Auto Connect in playtests ([#840])
|
||||||
|
* Improved settings UI ([#886])
|
||||||
|
* `Open Scripts Externally` option can now be changed while syncing ([#911])
|
||||||
|
* Projects may now specify rules for syncing files as if they had a different file extension. ([#813])
|
||||||
|
This is specified via a new field on project files, `syncRules`:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"syncRules": [
|
||||||
|
{
|
||||||
|
"pattern": "*.foo",
|
||||||
|
"use": "text",
|
||||||
|
"exclude": "*.exclude.foo",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pattern": "*.bar.baz",
|
||||||
|
"use": "json",
|
||||||
|
"suffix": ".bar.baz",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"name": "SyncRulesAreCool",
|
||||||
|
"tree": {
|
||||||
|
"$path": "src"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The `pattern` field is a glob used to match the sync rule to files. If present, the `suffix` field allows you to specify parts of a file's name get cut off by Rojo to name the Instance, including the file extension. If it isn't specified, Rojo will only cut off the first part of the file extension, up to the first dot.
|
||||||
|
|
||||||
|
Additionally, the `exclude` field allows files to be excluded from the sync rule if they match a pattern specified by it. If it's not present, all files that match `pattern` will be modified using the sync rule.
|
||||||
|
|
||||||
|
The `use` field corresponds to one of the potential file type that Rojo will currently include in a project. Files that match the provided pattern will be treated as if they had the file extension for that file type. A full list is below:
|
||||||
|
|
||||||
|
| `use` value | file extension |
|
||||||
|
|:---------------|:----------------|
|
||||||
|
| `serverScript` | `.server.lua` |
|
||||||
|
| `clientScript` | `.client.lua` |
|
||||||
|
| `moduleScript` | `.lua` |
|
||||||
|
| `json` | `.json` |
|
||||||
|
| `toml` | `.toml` |
|
||||||
|
| `csv` | `.csv` |
|
||||||
|
| `text` | `.txt` |
|
||||||
|
| `jsonModel` | `.model.json` |
|
||||||
|
| `rbxm` | `.rbxm` |
|
||||||
|
| `rbxmx` | `.rbxmx` |
|
||||||
|
| `project` | `.project.json` |
|
||||||
|
| `ignore` | None! |
|
||||||
|
|
||||||
|
**All** sync rules are reset between project files, so they must be specified in each one when nesting them. This is to ensure that nothing can break other projects by changing how files are synced!
|
||||||
|
|
||||||
|
[#813]: https://github.com/rojo-rbx/rojo/pull/813
|
||||||
|
[#832]: https://github.com/rojo-rbx/rojo/pull/832
|
||||||
|
[#834]: https://github.com/rojo-rbx/rojo/pull/834
|
||||||
|
[#838]: https://github.com/rojo-rbx/rojo/pull/838
|
||||||
|
[#840]: https://github.com/rojo-rbx/rojo/pull/840
|
||||||
|
[#843]: https://github.com/rojo-rbx/rojo/pull/843
|
||||||
|
[#883]: https://github.com/rojo-rbx/rojo/pull/883
|
||||||
|
[#886]: https://github.com/rojo-rbx/rojo/pull/886
|
||||||
|
[#911]: https://github.com/rojo-rbx/rojo/pull/911
|
||||||
|
[#915]: https://github.com/rojo-rbx/rojo/pull/915
|
||||||
|
|
||||||
|
## [7.4.3] - August 6th, 2024
|
||||||
|
* Fixed issue with building binary files introduced in 7.4.2
|
||||||
|
* Fixed `value of type nil cannot be converted to number` warning spam in output. [#955]
|
||||||
|
|
||||||
|
[#955]: https://github.com/rojo-rbx/rojo/pull/955
|
||||||
|
|
||||||
|
## [7.4.2] - July 23, 2024
|
||||||
|
* Added Never option to Confirmation ([#893])
|
||||||
|
* Fixed removing trailing newlines ([#903])
|
||||||
|
* Updated the internal property database, correcting an issue with `SurfaceAppearance.Color` that was reported [here][Surface_Appearance_Color_1] and [here][Surface_Appearance_Color_2] ([#948])
|
||||||
|
|
||||||
|
[#893]: https://github.com/rojo-rbx/rojo/pull/893
|
||||||
|
[#903]: https://github.com/rojo-rbx/rojo/pull/903
|
||||||
|
[#948]: https://github.com/rojo-rbx/rojo/pull/948
|
||||||
|
[Surface_Appearance_Color_1]: https://devforum.roblox.com/t/jailbreak-custom-character-turned-shiny-black-no-texture/3075563
|
||||||
|
[Surface_Appearance_Color_2]: https://devforum.roblox.com/t/surfaceappearance-not-displaying-correctly/3075588
|
||||||
|
|
||||||
|
## [7.4.1] - February 20, 2024
|
||||||
|
* Made the `name` field optional on project files ([#870])
|
||||||
|
|
||||||
|
Files named `default.project.json` inherit the name of the folder they're in and all other projects
|
||||||
|
are named as expect (e.g. `foo.project.json` becomes an Instance named `foo`)
|
||||||
|
|
||||||
|
There is no change in behavior if `name` is set.
|
||||||
|
* Fixed incorrect results when building model pivots ([#865])
|
||||||
|
* Fixed incorrect results when serving model pivots ([#868])
|
||||||
|
* Rojo now converts any line endings to LF, preventing spurious diffs when syncing Lua files on Windows ([#854])
|
||||||
|
* Fixed Rojo plugin failing to connect when project contains certain unreadable properties ([#848])
|
||||||
|
* Fixed various cases where patch visualizer would not display sync failures ([#845], [#844])
|
||||||
|
* Fixed http error handling so Rojo can be used in Github Codespaces ([#847])
|
||||||
|
|
||||||
|
[#848]: https://github.com/rojo-rbx/rojo/pull/848
|
||||||
|
[#845]: https://github.com/rojo-rbx/rojo/pull/845
|
||||||
|
[#844]: https://github.com/rojo-rbx/rojo/pull/844
|
||||||
|
[#847]: https://github.com/rojo-rbx/rojo/pull/847
|
||||||
|
[#854]: https://github.com/rojo-rbx/rojo/pull/854
|
||||||
|
[#865]: https://github.com/rojo-rbx/rojo/pull/865
|
||||||
|
[#868]: https://github.com/rojo-rbx/rojo/pull/868
|
||||||
|
[#870]: https://github.com/rojo-rbx/rojo/pull/870
|
||||||
|
|
||||||
|
## [7.4.0] - January 16, 2024
|
||||||
|
* Improved the visualization for array properties like Tags ([#829])
|
||||||
|
* Significantly improved performance of `rojo serve`, `rojo build --watch`, and `rojo sourcemap --watch` on macOS. ([#830])
|
||||||
|
* Changed *.lua files that init command generates to *.luau ([#831])
|
||||||
|
* Does not remind users to sync if the sync lock is claimed already ([#833])
|
||||||
|
|
||||||
|
[#829]: https://github.com/rojo-rbx/rojo/pull/829
|
||||||
|
[#830]: https://github.com/rojo-rbx/rojo/pull/830
|
||||||
|
[#831]: https://github.com/rojo-rbx/rojo/pull/831
|
||||||
|
[#833]: https://github.com/rojo-rbx/rojo/pull/833
|
||||||
|
|
||||||
|
## [7.4.0-rc3] - October 25, 2023
|
||||||
|
* Changed `sourcemap --watch` to only generate the sourcemap when it's necessary ([#800])
|
||||||
|
* Switched script source property getter and setter to `ScriptEditorService` methods ([#801])
|
||||||
|
|
||||||
|
This ensures that the script editor reflects any changes Rojo makes to a script while it is open in the script editor.
|
||||||
|
|
||||||
|
* Fixed issues when handling `SecurityCapabilities` values ([#803], [#807])
|
||||||
|
* Fixed Rojo plugin erroring out when attempting to sync attributes with invalid names ([#809])
|
||||||
|
|
||||||
|
[#800]: https://github.com/rojo-rbx/rojo/pull/800
|
||||||
|
[#801]: https://github.com/rojo-rbx/rojo/pull/801
|
||||||
|
[#803]: https://github.com/rojo-rbx/rojo/pull/803
|
||||||
|
[#807]: https://github.com/rojo-rbx/rojo/pull/807
|
||||||
|
[#809]: https://github.com/rojo-rbx/rojo/pull/809
|
||||||
|
|
||||||
|
## [7.4.0-rc2] - October 3, 2023
|
||||||
|
* Fixed bug with parsing version for plugin validation ([#797])
|
||||||
|
|
||||||
|
[#797]: https://github.com/rojo-rbx/rojo/pull/797
|
||||||
|
|
||||||
|
## [7.4.0-rc1] - October 3, 2023
|
||||||
|
### Additions
|
||||||
|
#### Project format
|
||||||
|
* Added support for `.toml` files to `$path` ([#633])
|
||||||
|
* Added support for `Font` and `CFrame` attributes ([rbx-dom#299], [rbx-dom#296])
|
||||||
|
* Added the `emitLegacyScripts` field to the project format ([#765]). The behavior is outlined below:
|
||||||
|
|
||||||
|
| `emitLegacyScripts` Value | Action Taken by Rojo |
|
||||||
|
|---------------------------|------------------------------------------------------------------------------------------------------------------|
|
||||||
|
| false | Rojo emits Scripts with the appropriate `RunContext` for `*.client.lua` and `*.server.lua` files in the project. |
|
||||||
|
| true (default) | Rojo emits LocalScripts and Scripts with legacy `RunContext` (same behavior as previously). |
|
||||||
|
|
||||||
|
|
||||||
|
It can be used like this:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"emitLegacyScripts": false,
|
||||||
|
"name": "MyCoolRunContextProject",
|
||||||
|
"tree": {
|
||||||
|
"$path": "src"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
* Added `Terrain` classname inference, similar to services ([#771])
|
||||||
|
|
||||||
|
`Terrain` may now be defined in projects without using `$className`:
|
||||||
|
```json
|
||||||
|
"Workspace": {
|
||||||
|
"Terrain": {
|
||||||
|
"$path": "path/to/terrain.rbxm"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
* Added support for `Terrain.MaterialColors` ([#770])
|
||||||
|
|
||||||
|
`Terrain.MaterialColors` is now represented in projects in a human readable format:
|
||||||
|
```json
|
||||||
|
"Workspace": {
|
||||||
|
"Terrain": {
|
||||||
|
"$path": "path/to/terrain.rbxm"
|
||||||
|
"$properties": {
|
||||||
|
"MaterialColors": {
|
||||||
|
"Grass": [10, 20, 30],
|
||||||
|
"Asphalt": [40, 50, 60],
|
||||||
|
"LeafyGrass": [255, 155, 55]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
* Added better support for `Font` properties ([#731])
|
||||||
|
|
||||||
|
`FontFace` properties may now be defined using implicit property syntax:
|
||||||
|
```json
|
||||||
|
"TextBox": {
|
||||||
|
"$className": "TextBox",
|
||||||
|
"$properties": {
|
||||||
|
"FontFace": {
|
||||||
|
"family": "rbxasset://fonts/families/RobotoMono.json",
|
||||||
|
"weight": "Thin",
|
||||||
|
"style": "Normal"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Patch visualizer and notifications
|
||||||
|
* Added a setting to control patch confirmation behavior ([#774])
|
||||||
|
|
||||||
|
This is a new setting for controlling when the Rojo plugin prompts for confirmation before syncing. It has four options:
|
||||||
|
* Initial (default): prompts only once for a project in a given Studio session
|
||||||
|
* Always: always prompts for confirmation
|
||||||
|
* Large Changes: only prompts when there are more than X changed instances. The number of instances is configurable - an additional setting for the number of instances becomes available when this option is chosen
|
||||||
|
* Unlisted PlaceId: only prompts if the place ID is not present in servePlaceIds
|
||||||
|
|
||||||
|
* Added the ability to select Instances in patch visualizer ([#709])
|
||||||
|
|
||||||
|
Double-clicking an instance in the patch visualizer sets Roblox Studio's selection to the instance.
|
||||||
|
|
||||||
|
* Added a sync reminder notification. ([#689])
|
||||||
|
|
||||||
|
Rojo detects if you have previously synced to a place, and displays a notification reminding you to sync again:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
* Added rich Source diffs in patch visualizer ([#748])
|
||||||
|
|
||||||
|
A "View Diff" button for script sources is now present in the patch visualizer. Clicking it displays a side-by-side diff of the script changes:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
* Patch visualizer now indicates what changes failed to apply. ([#717])
|
||||||
|
|
||||||
|
A clickable warning label is displayed when the Rojo plugin is unable to apply changes. Clicking the label displays precise information about which changes failed:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
#### Miscellaneous
|
||||||
|
* Added `plugin` flag to the `build` command that outputs to the local plugins folder ([#735])
|
||||||
|
|
||||||
|
This is a flag that builds a Rojo project into Roblox Studio's plugins directory. This allows you to build a Rojo project and load it into Studio as a plugin without having to type the full path to the plugins directory. It can be used like this: `rojo build <PATH-TO-PROJECT> --plugin <FILE-NAME>`
|
||||||
|
|
||||||
|
* Added new plugin template to the `init` command ([#738])
|
||||||
|
|
||||||
|
This is a new template geared towards plugins. It is similar to the model template, but creates a `Script` instead of a `ModuleScript` in the `src` directory. It can be used like this: `rojo init --kind plugin`
|
||||||
|
|
||||||
|
* Added protection against syncing non-place projects as a place. ([#691])
|
||||||
|
* Add buttons for navigation on the Connected page ([#722])
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
* Significantly improved performance of `rojo sourcemap` ([#668])
|
||||||
|
* Fixed the diff visualizer of connected sessions. ([#674])
|
||||||
|
* Fixed disconnected session activity. ([#675])
|
||||||
|
* Skip confirming patches that contain only a datamodel name change. ([#688])
|
||||||
|
* Fix Rojo breaking when users undo/redo in Studio ([#708])
|
||||||
|
* Improve tooltip behavior ([#723])
|
||||||
|
* Better settings controls ([#725])
|
||||||
|
* Rework patch visualizer with many fixes and improvements ([#713], [#726], [#755])
|
||||||
|
|
||||||
|
[#668]: https://github.com/rojo-rbx/rojo/pull/668
|
||||||
|
[#674]: https://github.com/rojo-rbx/rojo/pull/674
|
||||||
|
[#675]: https://github.com/rojo-rbx/rojo/pull/675
|
||||||
|
[#688]: https://github.com/rojo-rbx/rojo/pull/688
|
||||||
|
[#689]: https://github.com/rojo-rbx/rojo/pull/689
|
||||||
|
[#691]: https://github.com/rojo-rbx/rojo/pull/691
|
||||||
|
[#709]: https://github.com/rojo-rbx/rojo/pull/709
|
||||||
|
[#708]: https://github.com/rojo-rbx/rojo/pull/708
|
||||||
|
[#713]: https://github.com/rojo-rbx/rojo/pull/713
|
||||||
|
[#717]: https://github.com/rojo-rbx/rojo/pull/717
|
||||||
|
[#722]: https://github.com/rojo-rbx/rojo/pull/722
|
||||||
|
[#723]: https://github.com/rojo-rbx/rojo/pull/723
|
||||||
|
[#725]: https://github.com/rojo-rbx/rojo/pull/725
|
||||||
|
[#726]: https://github.com/rojo-rbx/rojo/pull/726
|
||||||
|
[#633]: https://github.com/rojo-rbx/rojo/pull/633
|
||||||
|
[#735]: https://github.com/rojo-rbx/rojo/pull/735
|
||||||
|
[#731]: https://github.com/rojo-rbx/rojo/pull/731
|
||||||
|
[#738]: https://github.com/rojo-rbx/rojo/pull/738
|
||||||
|
[#748]: https://github.com/rojo-rbx/rojo/pull/748
|
||||||
|
[#755]: https://github.com/rojo-rbx/rojo/pull/755
|
||||||
|
[#765]: https://github.com/rojo-rbx/rojo/pull/765
|
||||||
|
[#770]: https://github.com/rojo-rbx/rojo/pull/770
|
||||||
|
[#771]: https://github.com/rojo-rbx/rojo/pull/771
|
||||||
|
[#774]: https://github.com/rojo-rbx/rojo/pull/774
|
||||||
|
[rbx-dom#299]: https://github.com/rojo-rbx/rbx-dom/pull/299
|
||||||
|
[rbx-dom#296]: https://github.com/rojo-rbx/rbx-dom/pull/296
|
||||||
|
|
||||||
|
## [7.3.0] - April 22, 2023
|
||||||
|
* Added `$attributes` to project format. ([#574])
|
||||||
|
* Added `--watch` flag to `rojo sourcemap`. ([#602])
|
||||||
|
* Added support for `init.csv` files. ([#594])
|
||||||
|
* Added real-time sync status to the Studio plugin. ([#569])
|
||||||
|
* Added support for copying error messages to the clipboard. ([#614])
|
||||||
|
* Added sync locking for Team Create. ([#590])
|
||||||
|
* Added support for specifying HTTP or HTTPS protocol in plugin. ([#642])
|
||||||
|
* Added tooltips to buttons in the Studio plugin. ([#637])
|
||||||
|
* Added visual diffs when connecting from the Studio plugin. ([#603])
|
||||||
|
* Host and port are now saved in the Studio plugin. ([#613])
|
||||||
|
* Improved padding on notifications in Studio plugin. ([#589])
|
||||||
|
* Renamed `Common` to `Shared` in the default Rojo project. ([#611])
|
||||||
|
* Reduced the minimum size of the Studio plugin widget. ([#606])
|
||||||
|
* Fixed current directory in `rojo fmt-project`. ([#581])
|
||||||
|
* Fixed errors after a session has already ended. ([#587])
|
||||||
|
* Fixed an uncommon security permission error ([#619])
|
||||||
|
|
||||||
|
[#569]: https://github.com/rojo-rbx/rojo/pull/569
|
||||||
|
[#574]: https://github.com/rojo-rbx/rojo/pull/574
|
||||||
|
[#581]: https://github.com/rojo-rbx/rojo/pull/581
|
||||||
|
[#587]: https://github.com/rojo-rbx/rojo/pull/587
|
||||||
|
[#589]: https://github.com/rojo-rbx/rojo/pull/589
|
||||||
|
[#590]: https://github.com/rojo-rbx/rojo/pull/590
|
||||||
|
[#594]: https://github.com/rojo-rbx/rojo/pull/594
|
||||||
|
[#602]: https://github.com/rojo-rbx/rojo/pull/602
|
||||||
|
[#603]: https://github.com/rojo-rbx/rojo/pull/603
|
||||||
|
[#606]: https://github.com/rojo-rbx/rojo/pull/606
|
||||||
|
[#611]: https://github.com/rojo-rbx/rojo/pull/611
|
||||||
|
[#613]: https://github.com/rojo-rbx/rojo/pull/613
|
||||||
|
[#614]: https://github.com/rojo-rbx/rojo/pull/614
|
||||||
|
[#619]: https://github.com/rojo-rbx/rojo/pull/619
|
||||||
|
[#637]: https://github.com/rojo-rbx/rojo/pull/637
|
||||||
|
[#642]: https://github.com/rojo-rbx/rojo/pull/642
|
||||||
|
[7.3.0]: https://github.com/rojo-rbx/rojo/releases/tag/v7.3.0
|
||||||
|
|
||||||
|
## [7.2.1] - July 8, 2022
|
||||||
|
* Fixed notification sound by changing it to a generic sound. ([#566])
|
||||||
|
* Added setting to turn off sound effects. ([#568])
|
||||||
|
|
||||||
|
[#566]: https://github.com/rojo-rbx/rojo/pull/566
|
||||||
|
[#568]: https://github.com/rojo-rbx/rojo/pull/568
|
||||||
|
[7.2.1]: https://github.com/rojo-rbx/rojo/releases/tag/v7.2.1
|
||||||
|
|
||||||
|
## [7.2.0] - June 29, 2022
|
||||||
|
* Added support for `.luau` files. ([#552])
|
||||||
|
* Added support for live syncing Attributes and Tags. ([#553])
|
||||||
|
* Added notification popups in the Roblox Studio plugin. ([#540])
|
||||||
|
* Fixed `init.meta.json` when used with `init.lua` and related files. ([#549])
|
||||||
|
* Fixed incorrect output when serving from a non-default address or port ([#556])
|
||||||
|
* Fixed Linux binaries not running on systems with older glibc. ([#561])
|
||||||
|
* Added `camelCase` casing for JSON models, deprecating `PascalCase` names. ([#563])
|
||||||
|
* Switched from structopt to clap for command line argument parsing.
|
||||||
|
* Significantly improved performance of building and serving. ([#548])
|
||||||
|
* Increased minimum supported Rust version to 1.57.0. ([#564])
|
||||||
|
|
||||||
|
[#540]: https://github.com/rojo-rbx/rojo/pull/540
|
||||||
|
[#548]: https://github.com/rojo-rbx/rojo/pull/548
|
||||||
|
[#549]: https://github.com/rojo-rbx/rojo/pull/549
|
||||||
|
[#552]: https://github.com/rojo-rbx/rojo/pull/552
|
||||||
|
[#553]: https://github.com/rojo-rbx/rojo/pull/553
|
||||||
|
[#556]: https://github.com/rojo-rbx/rojo/pull/556
|
||||||
|
[#561]: https://github.com/rojo-rbx/rojo/pull/561
|
||||||
|
[#563]: https://github.com/rojo-rbx/rojo/pull/563
|
||||||
|
[#564]: https://github.com/rojo-rbx/rojo/pull/564
|
||||||
|
[7.2.0]: https://github.com/rojo-rbx/rojo/releases/tag/v7.2.0
|
||||||
|
|
||||||
|
## [7.1.1] - May 26, 2022
|
||||||
|
* Fixed sourcemap command not stripping paths correctly ([#544])
|
||||||
|
* Fixed Studio plugin settings not saving correctly.
|
||||||
|
|
||||||
|
[#544]: https://github.com/rojo-rbx/rojo/pull/544
|
||||||
|
[#545]: https://github.com/rojo-rbx/rojo/pull/545
|
||||||
|
[7.1.1]: https://github.com/rojo-rbx/rojo/releases/tag/v7.1.1
|
||||||
|
|
||||||
|
## [7.1.0] - May 22, 2022
|
||||||
|
* Added support for specifying an address to be used by default in project files. ([#507])
|
||||||
|
* Added support for optional paths in project files. ([#472])
|
||||||
|
* Added support for the new Open Cloud API when uploading. ([#504])
|
||||||
|
* Added `sourcemap` command for generating sourcemaps to feed into other tools. ([#530])
|
||||||
|
* Added PluginActions for connecting/disconnecting a session ([#537])
|
||||||
|
* Added changing toolbar icon to indicate state ([#538])
|
||||||
|
|
||||||
|
[#472]: https://github.com/rojo-rbx/rojo/pull/472
|
||||||
|
[#504]: https://github.com/rojo-rbx/rojo/pull/504
|
||||||
|
[#507]: https://github.com/rojo-rbx/rojo/pull/507
|
||||||
|
[#530]: https://github.com/rojo-rbx/rojo/pull/530
|
||||||
|
[#537]: https://github.com/rojo-rbx/rojo/pull/537
|
||||||
|
[#538]: https://github.com/rojo-rbx/rojo/pull/538
|
||||||
|
[7.1.0]: https://github.com/rojo-rbx/rojo/releases/tag/v7.1.0
|
||||||
|
|
||||||
|
## [7.0.0] - December 10, 2021
|
||||||
|
* Fixed Rojo's interactions with properties enabled by FFlags that are not yet enabled. ([#493])
|
||||||
|
* Improved output in Roblox Studio plugin when bad property data is encountered.
|
||||||
|
* Reintroduced support for CFrame shorthand syntax in Rojo project and `.meta.json` files, matching Rojo 6. ([#430])
|
||||||
|
* Connection settings are now remembered when reconnecting in Roblox Studio. ([#500])
|
||||||
|
* Updated reflection database to Roblox v503.
|
||||||
|
|
||||||
|
[#430]: https://github.com/rojo-rbx/rojo/issues/430
|
||||||
|
[#493]: https://github.com/rojo-rbx/rojo/pull/493
|
||||||
|
[#500]: https://github.com/rojo-rbx/rojo/pull/500
|
||||||
|
[7.0.0]: https://github.com/rojo-rbx/rojo/releases/tag/v7.0.0
|
||||||
|
|
||||||
|
## [7.0.0-rc.3] - October 19, 2021
|
||||||
|
This is the last release candidate for Rojo 7. In an effort to get Rojo 7 out the door, we'll be freezing features from here on out, something we should've done a couple months ago.
|
||||||
|
|
||||||
|
Expect to see Rojo 7 stable soon!
|
||||||
|
|
||||||
|
* Added support for writing `Tags` in project files, model files, and meta files. ([#484])
|
||||||
|
* Adjusted Studio plugin colors to match Roblox Studio palette. ([#482])
|
||||||
|
* Improved experimental two-way sync feature by batching changes. ([#478])
|
||||||
|
|
||||||
|
[#482]: https://github.com/rojo-rbx/rojo/pull/482
|
||||||
|
[#484]: https://github.com/rojo-rbx/rojo/pull/484
|
||||||
|
[#478]: https://github.com/rojo-rbx/rojo/pull/478
|
||||||
|
[7.0.0-rc.3]: https://github.com/rojo-rbx/rojo/releases/tag/v7.0.0-rc.3
|
||||||
|
|
||||||
|
## 7.0.0-rc.2 - October 19, 2021
|
||||||
|
(Botched release due to Git mishap, oops!)
|
||||||
|
|
||||||
|
## [7.0.0-rc.1] - August 23, 2021
|
||||||
|
In Rojo 6 and previous Rojo 7 alphas, an explicit Vector3 property would be written like this:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"className": "Part",
|
||||||
|
"properties": {
|
||||||
|
"Position": {
|
||||||
|
"Type": "Vector3",
|
||||||
|
"Value": [1, 2, 3]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
For Rojo 7, this will need to be changed to:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"className": "Part",
|
||||||
|
"properties": {
|
||||||
|
"Position": {
|
||||||
|
"Vector3": [1, 2, 3]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The shorthand property format that most users use is not impacted. For reference, it looks like this:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"className": "Part",
|
||||||
|
"properties": {
|
||||||
|
"Position": [1, 2, 3]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
* Major breaking change: changed property syntax for project files; shorthand syntax is unchanged.
|
||||||
|
* Added the `fmt-project` subcommand for formatting Rojo project files.
|
||||||
|
* Improved error output for many subcommands.
|
||||||
|
* Updated to stable versions of rbx-dom libraries.
|
||||||
|
* Updated async infrastructure, which should fix a handful of bugs. ([#459])
|
||||||
|
* Fixed syncing refs in the Roblox Studio plugin ([#462], [#466])
|
||||||
|
* Added support for long paths on Windows. ([#464])
|
||||||
|
|
||||||
|
[#459]: https://github.com/rojo-rbx/rojo/pull/459
|
||||||
|
[#462]: https://github.com/rojo-rbx/rojo/pull/462
|
||||||
|
[#464]: https://github.com/rojo-rbx/rojo/pull/464
|
||||||
|
[#466]: https://github.com/rojo-rbx/rojo/pull/466
|
||||||
|
[7.0.0-rc.1]: https://github.com/rojo-rbx/rojo/releases/tag/v7.0.0-rc.1
|
||||||
|
|
||||||
|
## [7.0.0-alpha.4][7.0.0-alpha.4] (May 5, 2021)
|
||||||
|
* Added the `gameId` and `placeId` optional properties to project files.
|
||||||
|
* When connecting from the Rojo Roblox Studio plugin, Rojo will set the game and place ID of the current place to these values, if set.
|
||||||
|
* This is equivalent to running `game:SetUniverseId(...)` and `game:SetPlaceId(...)` from the command bar in Studio.
|
||||||
|
* Added "EXPERIMENTAL!" label to two-way sync toggle in Rojo's Roblox Studio plugin.
|
||||||
|
* Fixed `Name` and `Parent` properties being allowed in Rojo projects. ([#413][pr-413])
|
||||||
|
* Fixed "Open Scripts Externally" feature crashing Studio. ([#369][issue-369])
|
||||||
|
* Empty `.model.json` files will no longer cause errors. ([#420][pr-420])
|
||||||
|
* When specifying `$path` on a service, Rojo now keeps the correct class name. ([#331][issue-331])
|
||||||
|
* Improved error messages for misconfigured projects.
|
||||||
|
|
||||||
|
[issue-331]: https://github.com/rojo-rbx/rojo/issues/331
|
||||||
|
[issue-369]: https://github.com/rojo-rbx/rojo/issues/369
|
||||||
|
[pr-420]: https://github.com/rojo-rbx/rojo/pull/420
|
||||||
|
[pr-413]: https://github.com/rojo-rbx/rojo/pull/413
|
||||||
|
[7.0.0-alpha.4]: https://github.com/rojo-rbx/rojo/releases/tag/v7.0.0-alpha.4
|
||||||
|
|
||||||
|
## [7.0.0-alpha.3][7.0.0-alpha.3] (February 19, 2021)
|
||||||
|
* Updated dependencies, fixing `OptionalCoordinateFrame`-related issues.
|
||||||
|
* Added `--address` flag to `rojo serve` to allow for external connections. ([#403][pr-403])
|
||||||
|
|
||||||
|
[pr-403]: https://github.com/rojo-rbx/rojo/pull/403
|
||||||
|
[7.0.0-alpha.3]: https://github.com/rojo-rbx/rojo/releases/tag/v7.0.0-alpha.3
|
||||||
|
|
||||||
|
## [7.0.0-alpha.2][7.0.0-alpha.2] (February 19, 2021)
|
||||||
|
* Fixed incorrect protocol version between the client and server.
|
||||||
|
|
||||||
|
[7.0.0-alpha.2]: https://github.com/rojo-rbx/rojo/releases/tag/v7.0.0-alpha.2
|
||||||
|
|
||||||
|
## [7.0.0-alpha.1][7.0.0-alpha.1] (February 18, 2021)
|
||||||
|
This release includes a brand new implementation of the Roblox DOM. It brings performance improvements, much better support for `rbxl` and `rbxm` files, and a better internal API.
|
||||||
|
|
||||||
|
* Added support for all remaining property types.
|
||||||
|
* Added support for the entire Roblox binary model format.
|
||||||
|
* Changed `rojo upload` to upload binary places and models instead of XML.
|
||||||
|
* This should make using `rojo upload` much more feasible for large places.
|
||||||
|
* **Breaking**: Changed format of some types of values in `project.json`, `model.json`, and `meta.json` files.
|
||||||
|
* This should impact few projects. See [this file][allValues.json] for new examples of each property type.
|
||||||
|
|
||||||
|
Formatting of types will change more before the stable release of Rojo 7. We're hoping to use this opportunity to normalize some of the case inconsistency introduced in Rojo 0.5.
|
||||||
|
|
||||||
|
[7.0.0-alpha.1]: https://github.com/rojo-rbx/rojo/releases/tag/v7.0.0-alpha.1
|
||||||
|
[allValues.json]: https://github.com/rojo-rbx/rojo/blob/f4a790eb50b74e482000bad1dcfe22533992fb20/plugin/rbx_dom_lua/src/allValues.json
|
||||||
|
|
||||||
|
## [6.0.2](https://github.com/rojo-rbx/rojo/releases/tag/v6.0.2) (February 9, 2021)
|
||||||
|
* Fixed `rojo upload` to handle CSRF challenges.
|
||||||
|
|
||||||
|
## [6.0.1](https://github.com/rojo-rbx/rojo/releases/tag/v6.0.1) (January 22, 2021)
|
||||||
|
* Fixed `rojo upload` requests being rejected by Roblox
|
||||||
|
|
||||||
|
## [6.0.0](https://github.com/rojo-rbx/rojo/releases/tag/v6.0.0) (January 16, 2021)
|
||||||
|
* Improved server error messages
|
||||||
|
* The server will now keep running in more error cases
|
||||||
|
* Fixed Rojo being unable to diff ClassName changes
|
||||||
|
|
||||||
|
## [6.0.0 Release Candidate 4](https://github.com/rojo-rbx/rojo/releases/tag/v6.0.0-rc.4) (December 14, 2020)
|
||||||
|
* Added brand new Rojo UI ([#367](https://github.com/rojo-rbx/rojo/pull/367))
|
||||||
|
* Added `projectName` to `/api/rojo` output.
|
||||||
|
|
||||||
|
## [6.0.0 Release Candidate 3](https://github.com/rojo-rbx/rojo/releases/tag/v6.0.0-rc.3) (November 19, 2020)
|
||||||
|
* Fixed the Rojo plugin attempting to write the non-scriptable properties `Instance.SourceAssetId` and `HttpServer.HttpEnabled`.
|
||||||
|
* Fixed the Rojo plugin's handling of null referents.
|
||||||
|
|
||||||
|
## [6.0.0 Release Candidate 2](https://github.com/rojo-rbx/rojo/releases/tag/v6.0.0-rc.2) (November 19, 2020)
|
||||||
|
* Fixed crash when malformed CSV files are put into a project. ([#310](https://github.com/rojo-rbx/rojo/issues/310))
|
||||||
|
* Fixed incorrect string escaping when producing Lua code from JSON files. ([#314](https://github.com/rojo-rbx/rojo/issues/314))
|
||||||
|
* Fixed performance issues introduced in Rojo 6.0.0-rc.1. ([#317](https://github.com/rojo-rbx/rojo/issues/317))
|
||||||
|
* Fixed `rojo plugin install` subcommand failing for everyone except Rojo developers. ([#320](https://github.com/rojo-rbx/rojo/issues/320))
|
||||||
|
* Updated default place template to take advantage of [#210](https://github.com/rojo-rbx/rojo/pull/210).
|
||||||
|
* Enabled glob ignore patterns by default and removed the `unstable_glob_ignore` feature.
|
||||||
|
* `globIgnorePaths` can be set on a project to a list of globs to ignore.
|
||||||
|
* The Rojo plugin now completes as much as it can from a patch without disconnecting. Warnings are shown in the console.
|
||||||
|
* Fixed 6.0.0-rc.1 regression causing instances that changed ClassName to instead... not change ClassName.
|
||||||
|
|
||||||
|
## [6.0.0 Release Candidate 1](https://github.com/rojo-rbx/rojo/releases/tag/v6.0.0-rc.1) (March 29, 2020)
|
||||||
|
This release jumped from 0.6.0 to 6.0.0. Rojo has been in use in production for many users for quite a long times, and so 6.0 is a more accurate reflection of Rojo's version than a pre-1.0 version.
|
||||||
|
|
||||||
|
* Added basic settings panel to plugin, with two settings:
|
||||||
|
* "Open Scripts Externally": When enabled, opening a script in Studio will instead open it in your default text editor.
|
||||||
|
* "Two-Way Sync": When enabled, Rojo will attempt to save changes to your place back to the filesystem. **Very early feature, very broken, beware!**
|
||||||
|
* Added `--color` option to force-enable or force-disable color in Rojo's output.
|
||||||
|
* Added support for turning `.json` files into `ModuleScript` instances ([#308](https://github.com/rojo-rbx/rojo/pull/308))
|
||||||
|
* Added `rojo plugin install` and `rojo plugin uninstall` to allow Rojo to manage its Roblox Studio plugin. ([#304](https://github.com/rojo-rbx/rojo/pull/304))
|
||||||
|
* Class names no longer need to be specified for Roblox services in Rojo projects. ([#210](https://github.com/rojo-rbx/rojo/pull/210))
|
||||||
|
* The server half of **experimental** two-way sync is now enabled by default.
|
||||||
|
* Increased default logging verbosity in commands like `rojo build`.
|
||||||
|
* Rojo now requires a project file again, just like 0.5.4.
|
||||||
|
|
||||||
|
## [0.6.0 Alpha 3](https://github.com/rojo-rbx/rojo/releases/tag/v0.6.0-alpha.3) (March 13, 2020)
|
||||||
|
* Added `--watch` argument to `rojo build`. ([#284](https://github.com/rojo-rbx/rojo/pull/284))
|
||||||
|
* Added dark theme support to plugin. ([#241](https://github.com/rojo-rbx/rojo/issues/241))
|
||||||
|
* Added a revamped `rojo init` command, which will now create more complete projects.
|
||||||
|
* Added the `rojo doc` command, which opens Rojo's documentation in your browser.
|
||||||
|
* Fixed many crashes from malformed projects and filesystem edge cases in `rojo serve`.
|
||||||
|
* Simplified filesystem access code dramatically.
|
||||||
|
* Improved error reporting and logging across the board.
|
||||||
|
* Log messages have a less noisy prefix.
|
||||||
|
* Any thread panicking now causes Rojo to abort instead of existing as a zombie.
|
||||||
|
* Errors now have a list of causes, helping make many errors more clear.
|
||||||
|
|
||||||
|
## [0.6.0 Alpha 2](https://github.com/rojo-rbx/rojo/releases/tag/v0.6.0-alpha.2) (March 6, 2020)
|
||||||
|
* Fixed `rojo upload` command always uploading models.
|
||||||
|
* Removed `--kind` parameter to `rojo upload`; Rojo now automatically uploads the correct kind of asset based on your project file.
|
||||||
|
|
||||||
|
## [0.5.4](https://github.com/rojo-rbx/rojo/releases/tag/v0.5.4) (February 26, 2020)
|
||||||
|
This is a general maintenance release for the Rojo 0.5.x release series.
|
||||||
|
|
||||||
|
* Updated reflection database and other dependencies.
|
||||||
|
* First stable release with binaries for macOS and Linux.
|
||||||
|
|
||||||
|
## [0.6.0 Alpha 1](https://github.com/rojo-rbx/rojo/releases/tag/v0.6.0-alpha.1) (January 22, 2020)
|
||||||
|
|
||||||
|
### General
|
||||||
|
* Added support for nested project files. ([#95](https://github.com/rojo-rbx/rojo/issues/95))
|
||||||
|
* Added project file hot-reloading. ([#10](https://github.com/rojo-rbx/rojo/issues/10)])
|
||||||
|
* Fixed Rojo dropping Ref properties ([#142](https://github.com/rojo-rbx/rojo/issues/142))
|
||||||
|
* This means that properties like `PrimaryPart` now work!
|
||||||
|
* Improved live sync protocol to reduce round-trips and improve syncing consistency.
|
||||||
|
* Improved support for binary model files and places.
|
||||||
|
|
||||||
|
### Command Line
|
||||||
|
* Added `--verbose`/`-v` flag, which can be specified multiple times to increase verbosity.
|
||||||
|
* Added support for automatically finding Roblox Studio's auth cookie for `rojo upload` on Windows.
|
||||||
|
* Added support for building, serving and uploading sources that aren't Rojo projects.
|
||||||
|
* Improved feedback from `rojo serve`.
|
||||||
|
* Removed support for legacy `roblox-project.json` projects, deprecated in an early Rojo 0.5.0 alpha.
|
||||||
|
* Rojo no longer traverses directories upwards looking for project files.
|
||||||
|
* Though undocumented, Rojo 0.5.x will search for a project file contained in any ancestor folders. This feature was removed to better support other 0.6.x features.
|
||||||
|
|
||||||
|
### Roblox Studio Plugin
|
||||||
|
* Added "connecting" state to improve experience when live syncing.
|
||||||
|
* Added "error" state to show errors in a place that isn't the output panel.
|
||||||
|
* Improved diagnostics for when the Rojo plugin cannot create an instance.
|
||||||
|
|
||||||
|
## [0.5.3](https://github.com/rojo-rbx/rojo/releases/tag/v0.5.3) (October 15, 2019)
|
||||||
|
* Fixed an issue where Rojo would throw an error when encountering recently-added instance classes.
|
||||||
|
|
||||||
|
## [0.5.2](https://github.com/rojo-rbx/rojo/releases/tag/v0.5.2) (October 14, 2019)
|
||||||
|
* Fixed an issue where `LocalizationTable` instances would have their column order randomized. ([#173](https://github.com/rojo-rbx/rojo/issues/173))
|
||||||
|
|
||||||
|
## [0.5.1](https://github.com/rojo-rbx/rojo/releases/tag/v0.5.1) (October 4, 2019)
|
||||||
|
* Fixed an issue where Rojo would drop changes if they happened too quickly ([#252](https://github.com/rojo-rbx/rojo/issues/252))
|
||||||
|
* Improved diagnostics for when the Rojo plugin cannot create an instance.
|
||||||
|
* Updated dependencies
|
||||||
|
* This brings Rojo's reflection database from client release 395 to client release 404.
|
||||||
|
|
||||||
|
## [0.5.0](https://github.com/rojo-rbx/rojo/releases/tag/v0.5.0) (August 27, 2019)
|
||||||
|
* Changed `.model.json` naming, which may require projects to migrate ambiguous cases:
|
||||||
|
* The file name now takes precedence over the `Name` field in the model, like Rojo 0.4.x.
|
||||||
|
* The `Name` field of the top-level instance is now optional. It's recommended that you remove it from your models.
|
||||||
|
* Rojo will emit a warning when `Name` is specified and does not match the name from the file.
|
||||||
|
* Fixed `Rect` values being set to `0, 0, 0, 0` when synced with the Rojo plugin. ([#201](https://github.com/rojo-rbx/rojo/issues/201))
|
||||||
|
* Fixed live-syncing of `PhysicalProperties`, `NumberSequence`, and `ColorSequence` values
|
||||||
|
|
||||||
|
## [0.5.0 Alpha 13](https://github.com/rojo-rbx/rojo/releases/tag/v0.5.0-alpha.13) (August 2, 2019)
|
||||||
|
* Bumped minimum Rust version to 1.34.0.
|
||||||
|
* Fixed default port documentation in `rojo serve --help` ([#219](https://github.com/rojo-rbx/rojo/issues/219))
|
||||||
|
* Fixed BrickColor support by upgrading Roblox-related dependencies
|
||||||
|
|
||||||
## [0.5.0 Alpha 12](https://github.com/rojo-rbx/rojo/releases/tag/v0.5.0-alpha.12) (July 2, 2019)
|
## [0.5.0 Alpha 12](https://github.com/rojo-rbx/rojo/releases/tag/v0.5.0-alpha.12) (July 2, 2019)
|
||||||
* Added `.meta.json` files
|
* Added `.meta.json` files
|
||||||
* `init.meta.json` files replace `init.model.json` files from Rojo 0.4.x ([#183](https://github.com/rojo-rbx/rojo/pull/183))
|
* `init.meta.json` files replace `init.model.json` files from Rojo 0.4.x ([#183](https://github.com/rojo-rbx/rojo/pull/183))
|
||||||
@@ -35,7 +676,7 @@
|
|||||||
|
|
||||||
## [0.5.0 Alpha 9](https://github.com/rojo-rbx/rojo/releases/tag/v0.5.0-alpha.9) (April 4, 2019)
|
## [0.5.0 Alpha 9](https://github.com/rojo-rbx/rojo/releases/tag/v0.5.0-alpha.9) (April 4, 2019)
|
||||||
* Changed `rojo build` to use buffered I/O, which can make it up to 2x faster in some cases.
|
* Changed `rojo build` to use buffered I/O, which can make it up to 2x faster in some cases.
|
||||||
* Building [*Road Not Taken*](https://github.com/rojo-rbx/roads) to an `rbxlx` file dropped from 150ms to 70ms on my machine
|
* Building [*Road Not Taken*](https://github.com/LPGhatguy/roads) to an `rbxlx` file dropped from 150ms to 70ms on my machine
|
||||||
* Fixed `LocalizationTable` instances being made from `csv` files incorrectly interpreting empty rows and columns. ([#149](https://github.com/rojo-rbx/rojo/pull/149))
|
* Fixed `LocalizationTable` instances being made from `csv` files incorrectly interpreting empty rows and columns. ([#149](https://github.com/rojo-rbx/rojo/pull/149))
|
||||||
* Fixed CSV files with entries that parse as numbers causing Rojo to panic. ([#152](https://github.com/rojo-rbx/rojo/pull/152))
|
* Fixed CSV files with entries that parse as numbers causing Rojo to panic. ([#152](https://github.com/rojo-rbx/rojo/pull/152))
|
||||||
* Improved error messages when malformed CSV files are found in a Rojo project.
|
* Improved error messages when malformed CSV files are found in a Rojo project.
|
||||||
@@ -232,4 +873,4 @@
|
|||||||
* More robust syncing with a new reconciler
|
* More robust syncing with a new reconciler
|
||||||
|
|
||||||
## [0.1.0](https://github.com/rojo-rbx/rojo/releases/tag/v0.1.0) (November 29, 2017)
|
## [0.1.0](https://github.com/rojo-rbx/rojo/releases/tag/v0.1.0) (November 29, 2017)
|
||||||
* Initial release, functionally very similar to [rbxfs](https://github.com/rojo-rbx/rbxfs)
|
* Initial release, functionally very similar to [rbxfs](https://github.com/LPGhatguy/rbxfs)
|
||||||
|
|||||||
57
CONTRIBUTING.md
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
# Contributing to the Rojo Project
|
||||||
|
Rojo is a big project and can always use more help!
|
||||||
|
|
||||||
|
Some of the repositories covered are:
|
||||||
|
|
||||||
|
* https://github.com/rojo-rbx/rojo
|
||||||
|
* https://github.com/rojo-rbx/rbx-dom
|
||||||
|
* https://github.com/rojo-rbx/vscode-rojo
|
||||||
|
* https://github.com/rojo-rbx/rbxlx-to-rojo
|
||||||
|
|
||||||
|
## Code
|
||||||
|
Code contributions are welcome for features and bugs that have been reported in the project's bug tracker. We want to make sure that no one wastes their time, so be sure to talk with maintainers about what changes would be accepted before doing any work!
|
||||||
|
|
||||||
|
You'll want these tools to work on Rojo:
|
||||||
|
|
||||||
|
* Latest stable Rust compiler
|
||||||
|
* Latest stable [Rojo](https://github.com/rojo-rbx/rojo)
|
||||||
|
* [Foreman](https://github.com/Roblox/foreman)
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
Documentation impacts way more people than the individual lines of code we write.
|
||||||
|
|
||||||
|
If you find any problems in documentation, including typos, bad grammar, misleading phrasing, or missing content, feel free to file issues and pull requests to fix them.
|
||||||
|
|
||||||
|
## Bug Reports and Feature Requests
|
||||||
|
Most of the tools around Rojo try to be clear when an issue is a bug. Even if they aren't, sometimes things don't work quite right.
|
||||||
|
|
||||||
|
Sometimes there's something that Rojo doesn't do that it probably should.
|
||||||
|
|
||||||
|
Please file issues and we'll try to help figure out what the best way forward is.
|
||||||
|
|
||||||
|
## Local Development Gotchas
|
||||||
|
|
||||||
|
If your build fails with "Error: failed to open file `D:\code\rojo\plugin\modules\roact\src`" you need to update your Git submodules.
|
||||||
|
Run the command and try building again: `git submodule update --init --recursive`.
|
||||||
|
|
||||||
|
## Pushing a Rojo Release
|
||||||
|
The Rojo release process is pretty manual right now. If you need to do it, here's how:
|
||||||
|
|
||||||
|
1. Bump server version in [`Cargo.toml`](Cargo.toml)
|
||||||
|
2. Bump plugin version in [`plugin/src/Config.lua`](plugin/src/Config.lua)
|
||||||
|
3. Run `cargo test` to update `Cargo.lock` and run tests
|
||||||
|
4. Update [`CHANGELOG.md`](CHANGELOG.md)
|
||||||
|
5. Commit!
|
||||||
|
* `git add . && git commit -m "Release vX.Y.Z"`
|
||||||
|
6. Tag the commit
|
||||||
|
* `git tag vX.Y.Z`
|
||||||
|
7. Publish the CLI
|
||||||
|
* `cargo publish`
|
||||||
|
8. Publish the Plugin
|
||||||
|
* `cargo run -- upload plugin --asset_id 6415005344`
|
||||||
|
9. Push commits and tags
|
||||||
|
* `git push && git push --tags`
|
||||||
|
10. Copy GitHub release content from previous release
|
||||||
|
* Update the leading text with a summary about the release
|
||||||
|
* Paste the changelog notes (as-is!) from [`CHANGELOG.md`](CHANGELOG.md)
|
||||||
|
* Write a small summary of each major feature
|
||||||
3145
Cargo.lock
generated
119
Cargo.toml
@@ -1,7 +1,116 @@
|
|||||||
[workspace]
|
[package]
|
||||||
members = [
|
name = "rojo"
|
||||||
"server",
|
version = "7.4.0"
|
||||||
]
|
rust-version = "1.70.0"
|
||||||
|
authors = ["Lucien Greathouse <me@lpghatguy.com>"]
|
||||||
|
description = "Enables professional-grade development tools for Roblox developers"
|
||||||
|
license = "MPL-2.0"
|
||||||
|
homepage = "https://rojo.space"
|
||||||
|
documentation = "https://rojo.space/docs"
|
||||||
|
repository = "https://github.com/rojo-rbx/rojo"
|
||||||
|
readme = "README.md"
|
||||||
|
edition = "2021"
|
||||||
|
build = "build.rs"
|
||||||
|
|
||||||
|
exclude = ["/test-projects/**"]
|
||||||
|
|
||||||
[profile.dev]
|
[profile.dev]
|
||||||
opt-level = 1
|
panic = "abort"
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
panic = "abort"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = []
|
||||||
|
|
||||||
|
# Enable this feature to live-reload assets from the web UI.
|
||||||
|
dev_live_assets = []
|
||||||
|
|
||||||
|
# Run Rojo with this feature to open a Tracy session.
|
||||||
|
# Currently uses protocol v63, last supported in Tracy 0.9.1.
|
||||||
|
profile-with-tracy = ["profiling/profile-with-tracy"]
|
||||||
|
|
||||||
|
[workspace]
|
||||||
|
members = ["crates/*"]
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
name = "librojo"
|
||||||
|
path = "src/lib.rs"
|
||||||
|
|
||||||
|
[[bench]]
|
||||||
|
name = "build"
|
||||||
|
harness = false
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
memofs = { version = "0.3.0", path = "crates/memofs" }
|
||||||
|
|
||||||
|
# These dependencies can be uncommented when working on rbx-dom simultaneously
|
||||||
|
# rbx_binary = { path = "../rbx-dom/rbx_binary" }
|
||||||
|
# rbx_dom_weak = { path = "../rbx-dom/rbx_dom_weak" }
|
||||||
|
# rbx_reflection = { path = "../rbx-dom/rbx_reflection" }
|
||||||
|
# rbx_reflection_database = { path = "../rbx-dom/rbx_reflection_database" }
|
||||||
|
# rbx_xml = { path = "../rbx-dom/rbx_xml" }
|
||||||
|
|
||||||
|
rbx_binary = "0.7.7"
|
||||||
|
rbx_dom_weak = "2.9.0"
|
||||||
|
rbx_reflection = "4.7.0"
|
||||||
|
rbx_reflection_database = "0.2.12"
|
||||||
|
rbx_xml = "0.13.5"
|
||||||
|
|
||||||
|
anyhow = "1.0.80"
|
||||||
|
backtrace = "0.3.69"
|
||||||
|
bincode = "1.3.3"
|
||||||
|
crossbeam-channel = "0.5.12"
|
||||||
|
csv = "1.3.0"
|
||||||
|
env_logger = "0.9.3"
|
||||||
|
fs-err = "2.11.0"
|
||||||
|
futures = "0.3.30"
|
||||||
|
globset = "0.4.14"
|
||||||
|
humantime = "2.1.0"
|
||||||
|
hyper = { version = "0.14.28", features = ["server", "tcp", "http1"] }
|
||||||
|
jod-thread = "0.1.2"
|
||||||
|
log = "0.4.21"
|
||||||
|
maplit = "1.0.2"
|
||||||
|
num_cpus = "1.16.0"
|
||||||
|
opener = "0.5.2"
|
||||||
|
rayon = "1.9.0"
|
||||||
|
reqwest = { version = "0.11.24", default-features = false, features = [
|
||||||
|
"blocking",
|
||||||
|
"json",
|
||||||
|
"rustls-tls",
|
||||||
|
] }
|
||||||
|
ritz = "0.1.0"
|
||||||
|
roblox_install = "1.0.0"
|
||||||
|
serde = { version = "1.0.197", features = ["derive", "rc"] }
|
||||||
|
serde_json = "1.0.114"
|
||||||
|
toml = "0.5.11"
|
||||||
|
termcolor = "1.4.1"
|
||||||
|
thiserror = "1.0.57"
|
||||||
|
tokio = { version = "1.36.0", features = ["rt", "rt-multi-thread"] }
|
||||||
|
uuid = { version = "1.7.0", features = ["v4", "serde"] }
|
||||||
|
clap = { version = "3.2.25", features = ["derive"] }
|
||||||
|
profiling = "1.0.15"
|
||||||
|
|
||||||
|
[target.'cfg(windows)'.dependencies]
|
||||||
|
winreg = "0.10.1"
|
||||||
|
|
||||||
|
[build-dependencies]
|
||||||
|
memofs = { version = "0.3.0", path = "crates/memofs" }
|
||||||
|
|
||||||
|
embed-resource = "1.8.0"
|
||||||
|
anyhow = "1.0.80"
|
||||||
|
bincode = "1.3.3"
|
||||||
|
fs-err = "2.11.0"
|
||||||
|
maplit = "1.0.2"
|
||||||
|
semver = "1.0.22"
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
rojo-insta-ext = { path = "crates/rojo-insta-ext" }
|
||||||
|
|
||||||
|
criterion = "0.3.6"
|
||||||
|
insta = { version = "1.36.1", features = ["redactions", "yaml"] }
|
||||||
|
paste = "1.0.14"
|
||||||
|
pretty_assertions = "1.4.0"
|
||||||
|
serde_yaml = "0.8.26"
|
||||||
|
tempfile = "3.10.1"
|
||||||
|
walkdir = "2.5.0"
|
||||||
|
|||||||
34
README.md
@@ -1,24 +1,13 @@
|
|||||||
<div align="center">
|
<div align="center">
|
||||||
<a href="https://rojo.space">
|
<a href="https://rojo.space"><img src="assets/brand_images/logo-512.png" alt="Rojo" height="217" /></a>
|
||||||
<img src="assets/rojo-logo.png" alt="Rojo" height="217" />
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div> </div>
|
<div> </div>
|
||||||
|
|
||||||
<div align="center">
|
<div align="center">
|
||||||
<a href="https://travis-ci.org/rojo-rbx/rojo">
|
<a href="https://github.com/rojo-rbx/rojo/actions"><img src="https://github.com/rojo-rbx/rojo/workflows/CI/badge.svg" alt="Actions status" /></a>
|
||||||
<img src="https://api.travis-ci.org/rojo-rbx/rojo.svg?branch=master" alt="Travis-CI Build Status" />
|
<a href="https://crates.io/crates/rojo"><img src="https://img.shields.io/crates/v/rojo.svg?label=latest%20release" alt="Latest server version" /></a>
|
||||||
</a>
|
<a href="https://rojo.space/docs"><img src="https://img.shields.io/badge/docs-website-brightgreen.svg" alt="Rojo Documentation" /></a>
|
||||||
<a href="https://crates.io/crates/rojo">
|
|
||||||
<img src="https://img.shields.io/crates/v/rojo.svg?label=version" alt="Latest server version" />
|
|
||||||
</a>
|
|
||||||
<a href="https://rojo.space/docs/0.4.x">
|
|
||||||
<img src="https://img.shields.io/badge/docs-0.4.x-brightgreen.svg" alt="Rojo 0.4.x Documentation" />
|
|
||||||
</a>
|
|
||||||
<a href="https://rojo.space/docs/0.5.x">
|
|
||||||
<img src="https://img.shields.io/badge/docs-0.5.x-brightgreen.svg" alt="Rojo 0.5.x Documentation" />
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
@@ -37,20 +26,21 @@ Rojo enables:
|
|||||||
* Streaming `rbxmx` and `rbxm` models into your game in real time
|
* Streaming `rbxmx` and `rbxm` models into your game in real time
|
||||||
* Packaging and deploying your project to Roblox.com from the command line
|
* Packaging and deploying your project to Roblox.com from the command line
|
||||||
|
|
||||||
Soon, Rojo will be able to:
|
In the future, Rojo will be able to:
|
||||||
|
|
||||||
* Automatically convert your existing game to work with Rojo
|
|
||||||
* Sync instances from Roblox Studio to the filesystem
|
* Sync instances from Roblox Studio to the filesystem
|
||||||
* Automatically manage your assets on Roblox.com, like images and sounds
|
* Automatically convert your existing game to work with Rojo
|
||||||
* Import custom instances like MoonScript code
|
* Import custom instances like MoonScript code
|
||||||
|
|
||||||
## [Documentation](https://rojo.space/docs/latest)
|
## [Documentation](https://rojo.space/docs)
|
||||||
If you find any mistakes, feel free to make changes in the [docs](https://github.com/rojo-rbx/rojo/tree/master/docs) folder of this repository and submit a pull request!
|
Documentation is hosted in the [rojo.space repository](https://github.com/rojo-rbx/rojo.space).
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
Check out our [contribution guide](CONTRIBUTING.md) for detailed instructions for helping work on Rojo!
|
||||||
|
|
||||||
Pull requests are welcome!
|
Pull requests are welcome!
|
||||||
|
|
||||||
Rojo supports Rust 1.32 and newer.
|
Rojo supports Rust 1.70.0 and newer. The minimum supported version of Rust is based on the latest versions of the dependencies that Rojo has.
|
||||||
|
|
||||||
## License
|
## License
|
||||||
Rojo is available under the terms of the Mozilla Public License, Version 2.0. See [LICENSE.txt](LICENSE.txt) for details.
|
Rojo is available under the terms of the Mozilla Public License, Version 2.0. See [LICENSE.txt](LICENSE.txt) for details.
|
||||||
|
|||||||
5
aftman.toml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
[tools]
|
||||||
|
rojo = "rojo-rbx/rojo@7.3.0"
|
||||||
|
selene = "Kampfkarren/selene@0.26.1"
|
||||||
|
stylua = "JohnnyMorganz/stylua@0.18.2"
|
||||||
|
run-in-roblox = "rojo-rbx/run-in-roblox@0.3.0"
|
||||||
BIN
assets/NotificationPop.mp3
Normal file
BIN
assets/brand_images/icon-32.png
Normal file
|
After Width: | Height: | Size: 975 B |
BIN
assets/brand_images/icon-link-32.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
assets/brand_images/icon-warn-32.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
assets/brand_images/logo-512.png
Normal file
|
After Width: | Height: | Size: 33 KiB |
11
assets/default-model-project/README.md
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
# {project_name}
|
||||||
|
Generated by [Rojo](https://github.com/rojo-rbx/rojo) {rojo_version}.
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
To build this library, use:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
rojo build -o "{project_name}.rbxmx"
|
||||||
|
```
|
||||||
|
|
||||||
|
For more help, check out [the Rojo documentation](https://rojo.space/docs).
|
||||||
6
assets/default-model-project/default.project.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"name": "{project_name}",
|
||||||
|
"tree": {
|
||||||
|
"$path": "src"
|
||||||
|
}
|
||||||
|
}
|
||||||
3
assets/default-model-project/gitignore.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# Roblox Studio lock files
|
||||||
|
/*.rbxlx.lock
|
||||||
|
/*.rbxl.lock
|
||||||
5
assets/default-model-project/src-init.luau
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
return {
|
||||||
|
hello = function()
|
||||||
|
print("Hello world, from {project_name}!")
|
||||||
|
end,
|
||||||
|
}
|
||||||
17
assets/default-place-project/README.md
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
# {project_name}
|
||||||
|
Generated by [Rojo](https://github.com/rojo-rbx/rojo) {rojo_version}.
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
To build the place from scratch, use:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
rojo build -o "{project_name}.rbxlx"
|
||||||
|
```
|
||||||
|
|
||||||
|
Next, open `{project_name}.rbxlx` in Roblox Studio and start the Rojo server:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
rojo serve
|
||||||
|
```
|
||||||
|
|
||||||
|
For more help, check out [the Rojo documentation](https://rojo.space/docs).
|
||||||
@@ -1,41 +1,29 @@
|
|||||||
{
|
{
|
||||||
"name": "[placeholder]",
|
"name": "{project_name}",
|
||||||
"tree": {
|
"tree": {
|
||||||
"$className": "DataModel",
|
"$className": "DataModel",
|
||||||
"HttpService": {
|
|
||||||
"$className": "HttpService",
|
|
||||||
"$properties": {
|
|
||||||
"HttpEnabled": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"Lighting": {
|
|
||||||
"$className": "Lighting",
|
|
||||||
"$properties": {
|
|
||||||
"Ambient": [
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"Brightness": 2,
|
|
||||||
"GlobalShadows": true,
|
|
||||||
"Outlines": false,
|
|
||||||
"Technology": "Voxel"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"ReplicatedStorage": {
|
"ReplicatedStorage": {
|
||||||
"$className": "ReplicatedStorage",
|
"Shared": {
|
||||||
"Source": {
|
"$path": "src/shared"
|
||||||
"$path": "src"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"SoundService": {
|
|
||||||
"$className": "SoundService",
|
"ServerScriptService": {
|
||||||
"$properties": {
|
"Server": {
|
||||||
"RespectFilteringEnabled": true
|
"$path": "src/server"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"StarterPlayer": {
|
||||||
|
"StarterPlayerScripts": {
|
||||||
|
"Client": {
|
||||||
|
"$path": "src/client"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
"Workspace": {
|
"Workspace": {
|
||||||
"$className": "Workspace",
|
|
||||||
"$properties": {
|
"$properties": {
|
||||||
"FilteringEnabled": true
|
"FilteringEnabled": true
|
||||||
},
|
},
|
||||||
@@ -61,6 +49,24 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"Lighting": {
|
||||||
|
"$properties": {
|
||||||
|
"Ambient": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"Brightness": 2,
|
||||||
|
"GlobalShadows": true,
|
||||||
|
"Outlines": false,
|
||||||
|
"Technology": "Voxel"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"SoundService": {
|
||||||
|
"$properties": {
|
||||||
|
"RespectFilteringEnabled": true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
6
assets/default-place-project/gitignore.txt
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# Project place file
|
||||||
|
/{project_name}.rbxlx
|
||||||
|
|
||||||
|
# Roblox Studio lock files
|
||||||
|
/*.rbxlx.lock
|
||||||
|
/*.rbxl.lock
|
||||||
17
assets/default-plugin-project/README.md
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
# {project_name}
|
||||||
|
Generated by [Rojo](https://github.com/rojo-rbx/rojo) {rojo_version}.
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
To build this plugin to your local plugins folder, use:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
rojo build -p "{project_name}.rbxm"
|
||||||
|
```
|
||||||
|
|
||||||
|
You can include the `watch` flag to re-build it on save:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
rojo build -p "{project_name}.rbxm" --watch
|
||||||
|
```
|
||||||
|
|
||||||
|
For more help, check out [the Rojo documentation](https://rojo.space/docs).
|
||||||
6
assets/default-plugin-project/default.project.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"name": "{project_name}",
|
||||||
|
"tree": {
|
||||||
|
"$path": "src"
|
||||||
|
}
|
||||||
|
}
|
||||||
3
assets/default-plugin-project/gitignore.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# Plugin model files
|
||||||
|
/{project_name}.rbxmx
|
||||||
|
/{project_name}.rbxm
|
||||||
BIN
assets/images/checkbox-off.png
Normal file
|
After Width: | Height: | Size: 269 B |
15
assets/images/checkbox-off.svg
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg width="100%" height="100%" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.5;">
|
||||||
|
<g transform="matrix(1,0,0,1,-54,-1)">
|
||||||
|
<g id="Artboard3" transform="matrix(1.77778,0,0,1.45455,-42,-0.454545)">
|
||||||
|
<rect x="54" y="1" width="9" height="11" style="fill:none;"/>
|
||||||
|
<g transform="matrix(3.375,0,0,4.125,-3654,-2753.12)">
|
||||||
|
<path d="M1099,670L1101,668" style="fill:none;stroke:white;stroke-width:0.5px;"/>
|
||||||
|
<g transform="matrix(-1,0,0,1,2200,0)">
|
||||||
|
<path d="M1099,670L1101,668" style="fill:none;stroke:white;stroke-width:0.5px;"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.0 KiB |
BIN
assets/images/checkbox-on.png
Normal file
|
After Width: | Height: | Size: 249 B |
12
assets/images/checkbox-on.svg
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg width="100%" height="100%" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.5;">
|
||||||
|
<g transform="matrix(1,0,0,1,-32,0)">
|
||||||
|
<g id="Artboard2" transform="matrix(0.8,0,0,0.941176,6.4,0)">
|
||||||
|
<rect x="32" y="0" width="20" height="17" style="fill:none;"/>
|
||||||
|
<g transform="matrix(5,0,0,4.25,-5470.5,-2371.5)">
|
||||||
|
<path d="M1101,560L1102,561L1104,559" style="fill:none;stroke:white;stroke-width:0.75px;"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 870 B |
BIN
assets/images/circle-128.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
assets/images/circle-16.png
Normal file
|
After Width: | Height: | Size: 196 B |
BIN
assets/images/circle-32.png
Normal file
|
After Width: | Height: | Size: 317 B |
BIN
assets/images/circle-500.png
Normal file
|
After Width: | Height: | Size: 7.3 KiB |
BIN
assets/images/circle-64.png
Normal file
|
After Width: | Height: | Size: 613 B |
BIN
assets/images/header-logo.png
Normal file
|
After Width: | Height: | Size: 3.0 KiB |
21
assets/images/header-logo.svg
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg width="100%" height="100%" viewBox="0 0 60 27" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||||
|
<g id="Artboard1" transform="matrix(0.952381,0,0,0.710526,-228.571,-156.316)">
|
||||||
|
<rect x="240" y="220" width="63" height="38" style="fill:none;"/>
|
||||||
|
<g transform="matrix(0.0789166,0,0,0.105779,211.848,170.749)">
|
||||||
|
<g transform="matrix(340.635,0,0,340.635,376,753)">
|
||||||
|
<path d="M0.302,-0.836L0.306,-0.836L0.302,-0.829L0.302,-0.814C0.333,-0.82 0.349,-0.828 0.349,-0.836L0.371,-0.833C0.408,-0.835 0.441,-0.836 0.472,-0.836L0.476,-0.836C0.524,-0.836 0.58,-0.81 0.646,-0.757C0.66,-0.734 0.668,-0.714 0.672,-0.695L0.672,-0.659C0.664,-0.609 0.65,-0.571 0.632,-0.546C0.621,-0.537 0.597,-0.507 0.56,-0.456L0.556,-0.456L0.556,-0.463L0.566,-0.478L0.56,-0.478C0.474,-0.405 0.378,-0.349 0.27,-0.311C0.243,-0.304 0.216,-0.3 0.19,-0.3C0.224,-0.26 0.287,-0.207 0.378,-0.141C0.387,-0.136 0.445,-0.099 0.552,-0.028C0.641,0.027 0.747,0.087 0.871,0.153L0.871,0.157L0.856,0.157C0.832,0.148 0.82,0.141 0.82,0.138L0.813,0.142L0.806,0.142C0.803,0.142 0.802,0.141 0.802,0.138C0.793,0.14 0.786,0.149 0.78,0.164C0.795,0.168 0.802,0.173 0.802,0.178C0.796,0.183 0.792,0.186 0.788,0.186L0.77,0.182L0.77,0.186C0.77,0.19 0.773,0.193 0.78,0.193L0.78,0.204L0.777,0.204C0.772,0.204 0.717,0.172 0.614,0.109C0.541,0.072 0.451,0.015 0.346,-0.061C0.311,-0.077 0.247,-0.124 0.153,-0.202L0.143,-0.202C0.129,-0.181 0.111,-0.129 0.088,-0.046C0.083,-0.027 0.059,0.001 0.016,0.037L0.008,0.037L0.001,0.026L0.001,0.022C0.001,0.017 0.005,0.006 0.012,-0.01L0.012,-0.014L0.008,-0.014C0.008,-0.007 -0.007,0.004 -0.035,0.019L-0.039,0.019L-0.039,0.012C0.046,-0.24 0.105,-0.404 0.139,-0.481C0.197,-0.614 0.226,-0.69 0.226,-0.709C0.213,-0.709 0.184,-0.693 0.139,-0.659L0.132,-0.659L0.135,-0.666L0.135,-0.673C0.122,-0.673 0.092,-0.652 0.045,-0.608L0.041,-0.608L0.041,-0.612L0.088,-0.666L0.096,-0.677L0.096,-0.681L0.088,-0.681L0.045,-0.645C0.04,-0.645 0.038,-0.647 0.038,-0.651C0.083,-0.701 0.138,-0.744 0.204,-0.778C0.265,-0.794 0.295,-0.812 0.295,-0.833L0.302,-0.836ZM0.632,-0.735L0.632,-0.731C0.632,-0.727 0.635,-0.724 0.639,-0.724L0.639,-0.728C0.639,-0.732 0.637,-0.735 0.632,-0.735ZM0.208,-0.387L0.211,-0.387C0.255,-0.396 0.277,-0.403 0.277,-0.409C0.274,-0.414 0.273,-0.417 0.273,-0.42C0.365,-0.451 0.427,-0.482 0.458,-0.514C0.461,-0.514 0.48,-0.534 0.516,-0.576L0.52,-0.576L0.52,-0.572C0.515,-0.564 0.512,-0.558 0.512,-0.554L0.516,-0.554C0.547,-0.578 0.563,-0.604 0.563,-0.633L0.563,-0.655C0.556,-0.655 0.552,-0.658 0.552,-0.663C0.564,-0.665 0.57,-0.671 0.57,-0.681C0.57,-0.693 0.546,-0.705 0.498,-0.717C0.459,-0.727 0.417,-0.731 0.371,-0.731C0.348,-0.731 0.325,-0.689 0.302,-0.604C0.292,-0.594 0.261,-0.522 0.208,-0.387ZM0.251,-0.695L0.251,-0.691C0.255,-0.691 0.258,-0.695 0.262,-0.702L0.262,-0.706C0.259,-0.706 0.255,-0.702 0.251,-0.695ZM0.255,-0.626L0.259,-0.626C0.266,-0.629 0.27,-0.636 0.27,-0.648C0.266,-0.648 0.261,-0.641 0.255,-0.626ZM0.596,-0.612L0.596,-0.604C0.599,-0.604 0.603,-0.608 0.606,-0.615L0.606,-0.619L0.603,-0.619C0.598,-0.618 0.596,-0.616 0.596,-0.612ZM0.204,-0.369L0.204,-0.365L0.211,-0.365C0.216,-0.368 0.22,-0.369 0.222,-0.369L0.222,-0.365C0.281,-0.376 0.316,-0.388 0.328,-0.401L0.324,-0.401C0.271,-0.389 0.231,-0.378 0.204,-0.369ZM0.19,-0.333L0.193,-0.333L0.259,-0.347L0.255,-0.354C0.212,-0.349 0.19,-0.341 0.19,-0.333ZM0.334,-0.108L0.334,-0.101C0.372,-0.072 0.395,-0.057 0.403,-0.057C0.394,-0.064 0.389,-0.07 0.389,-0.075L0.334,-0.108ZM0.44,-0.028C0.442,-0.019 0.449,-0.014 0.461,-0.014L0.465,-0.014L0.465,-0.018C0.459,-0.018 0.452,-0.021 0.443,-0.028L0.44,-0.028ZM0.675,0.102C0.694,0.119 0.723,0.136 0.762,0.153L0.766,0.146C0.736,0.128 0.708,0.113 0.683,0.102L0.675,0.102ZM0.875,0.16L0.886,0.16C0.89,0.161 0.893,0.163 0.893,0.167C0.888,0.167 0.886,0.171 0.886,0.178L0.878,0.178L0.882,0.171L0.882,0.167L0.875,0.167L0.875,0.16Z" style="fill:white;fill-rule:nonzero;"/>
|
||||||
|
</g>
|
||||||
|
<g transform="matrix(340.635,0,0,340.635,588.398,753)">
|
||||||
|
<path d="M0.631,-0.705C0.646,-0.705 0.661,-0.696 0.673,-0.678L0.646,-0.678C0.62,-0.678 0.587,-0.67 0.546,-0.653L0.546,-0.65L0.549,-0.65C0.607,-0.654 0.649,-0.656 0.677,-0.656L0.683,-0.656L0.683,-0.65L0.67,-0.65C0.668,-0.65 0.667,-0.651 0.667,-0.653L0.503,-0.629C0.503,-0.627 0.493,-0.624 0.473,-0.62L0.473,-0.614L0.519,-0.623L0.521,-0.623L0.521,-0.617C0.386,-0.581 0.318,-0.555 0.318,-0.538C0.252,-0.483 0.204,-0.431 0.175,-0.383C0.131,-0.304 0.108,-0.243 0.108,-0.201C0.108,-0.157 0.131,-0.125 0.175,-0.104C0.183,-0.102 0.19,-0.101 0.196,-0.101C0.286,-0.136 0.353,-0.196 0.397,-0.28C0.409,-0.318 0.419,-0.363 0.427,-0.417L0.434,-0.417L0.427,-0.359C0.433,-0.359 0.439,-0.374 0.443,-0.404C0.441,-0.412 0.439,-0.42 0.439,-0.429L0.439,-0.438L0.446,-0.438C0.448,-0.407 0.449,-0.386 0.449,-0.374C0.449,-0.358 0.444,-0.331 0.434,-0.292C0.445,-0.302 0.458,-0.335 0.473,-0.392C0.48,-0.447 0.486,-0.474 0.491,-0.474C0.491,-0.472 0.492,-0.471 0.494,-0.471C0.492,-0.469 0.49,-0.457 0.488,-0.435L0.488,-0.432L0.491,-0.432C0.499,-0.454 0.504,-0.48 0.506,-0.508C0.502,-0.516 0.5,-0.522 0.5,-0.526L0.506,-0.529C0.512,-0.529 0.518,-0.513 0.525,-0.48C0.525,-0.4 0.491,-0.297 0.424,-0.17C0.372,-0.093 0.305,-0.042 0.224,-0.019C0.188,-0.006 0.154,-0 0.121,-0C0.04,-0.022 -0.001,-0.083 -0.001,-0.183C-0.001,-0.296 0.045,-0.398 0.136,-0.489C0.165,-0.522 0.227,-0.568 0.321,-0.629C0.425,-0.68 0.529,-0.705 0.631,-0.705ZM0.482,-0.656L0.482,-0.653C0.499,-0.653 0.508,-0.652 0.509,-0.65C0.526,-0.659 0.536,-0.663 0.54,-0.663L0.54,-0.668L0.482,-0.656ZM0.099,-0.417C0.144,-0.458 0.179,-0.494 0.206,-0.523C0.23,-0.538 0.242,-0.55 0.242,-0.559C0.201,-0.535 0.156,-0.493 0.108,-0.432C0.102,-0.427 0.099,-0.422 0.099,-0.417ZM0.105,-0.261C0.108,-0.261 0.118,-0.284 0.136,-0.328C0.158,-0.378 0.203,-0.439 0.272,-0.511L0.272,-0.514C0.204,-0.463 0.167,-0.422 0.16,-0.392C0.142,-0.371 0.124,-0.328 0.105,-0.261ZM0.069,-0.334L0.069,-0.332L0.072,-0.332C0.116,-0.393 0.139,-0.429 0.139,-0.438C0.11,-0.413 0.086,-0.378 0.069,-0.334ZM0.467,-0.31L0.467,-0.307L0.47,-0.307C0.492,-0.371 0.503,-0.413 0.503,-0.432C0.49,-0.409 0.478,-0.369 0.467,-0.31ZM0.087,-0.404L0.087,-0.401C0.091,-0.401 0.093,-0.403 0.093,-0.407L0.093,-0.41C0.089,-0.41 0.087,-0.408 0.087,-0.404ZM0.063,-0.368C0.032,-0.297 0.017,-0.245 0.017,-0.213C0.021,-0.148 0.028,-0.107 0.039,-0.088L0.042,-0.088L0.042,-0.094C0.035,-0.107 0.032,-0.129 0.032,-0.158C0.032,-0.191 0.035,-0.227 0.042,-0.268L0.039,-0.273C0.045,-0.3 0.054,-0.331 0.066,-0.365L0.066,-0.368L0.063,-0.368ZM0.096,-0.24L0.096,-0.237C0.1,-0.237 0.103,-0.239 0.103,-0.243L0.103,-0.246C0.098,-0.245 0.096,-0.243 0.096,-0.24ZM0.397,-0.222L0.397,-0.219L0.4,-0.219C0.408,-0.232 0.412,-0.241 0.412,-0.243C0.407,-0.242 0.402,-0.235 0.397,-0.222ZM0.066,-0.24C0.06,-0.222 0.055,-0.202 0.051,-0.179C0.055,-0.138 0.061,-0.108 0.069,-0.088L0.072,-0.088L0.072,-0.094C0.066,-0.121 0.063,-0.139 0.063,-0.146L0.066,-0.152C0.064,-0.155 0.063,-0.16 0.063,-0.164C0.063,-0.169 0.064,-0.173 0.066,-0.176C0.064,-0.18 0.063,-0.183 0.063,-0.186C0.067,-0.218 0.069,-0.235 0.069,-0.237L0.069,-0.24L0.066,-0.24ZM0.294,-0.125L0.294,-0.122C0.3,-0.122 0.322,-0.143 0.357,-0.186L0.357,-0.188L0.354,-0.188C0.314,-0.151 0.294,-0.129 0.294,-0.125ZM0.379,-0.149C0.379,-0.146 0.36,-0.126 0.321,-0.088L0.324,-0.088C0.351,-0.112 0.37,-0.132 0.382,-0.146L0.385,-0.146L0.385,-0.149L0.379,-0.149ZM0.09,-0.104L0.09,-0.101C0.094,-0.08 0.104,-0.07 0.121,-0.07L0.13,-0.07L0.13,-0.073L0.09,-0.104ZM0.151,-0.055L0.188,-0.055L0.203,-0.058L0.203,-0.061L0.157,-0.061C0.153,-0.06 0.151,-0.058 0.151,-0.055ZM0.096,-0.058L0.096,-0.055C0.104,-0.045 0.113,-0.04 0.124,-0.04L0.13,-0.04L0.13,-0.042C0.127,-0.042 0.116,-0.048 0.096,-0.058Z" style="fill:white;fill-rule:nonzero;"/>
|
||||||
|
</g>
|
||||||
|
<g transform="matrix(340.635,0,0,340.635,758.882,753)">
|
||||||
|
<path d="M0.208,-0.7L0.223,-0.7C0.227,-0.7 0.229,-0.697 0.229,-0.691C0.294,-0.687 0.328,-0.684 0.331,-0.682C0.333,-0.682 0.333,-0.683 0.333,-0.685C0.364,-0.683 0.387,-0.682 0.401,-0.682L0.462,-0.682C0.466,-0.682 0.468,-0.684 0.468,-0.688L0.45,-0.688L0.45,-0.694L0.49,-0.694L0.49,-0.688L0.475,-0.688L0.475,-0.682L0.557,-0.682C0.564,-0.682 0.573,-0.681 0.584,-0.679C0.603,-0.681 0.612,-0.685 0.612,-0.691L0.658,-0.691C0.678,-0.691 0.688,-0.692 0.689,-0.694C0.706,-0.692 0.72,-0.691 0.731,-0.691L0.903,-0.691L0.921,-0.688L0.928,-0.691C1.035,-0.686 1.096,-0.681 1.111,-0.676L1.13,-0.682L1.13,-0.676L1.068,-0.667L1.068,-0.664C1.075,-0.664 1.078,-0.661 1.078,-0.657C1.078,-0.654 1.075,-0.651 1.068,-0.648C1.064,-0.65 1.061,-0.651 1.059,-0.651C1.059,-0.647 1.055,-0.645 1.047,-0.645L1.047,-0.642C1.048,-0.638 1.05,-0.636 1.053,-0.636L1.059,-0.636C1.072,-0.636 1.087,-0.635 1.105,-0.633C1.113,-0.635 1.12,-0.636 1.126,-0.636C1.139,-0.625 1.145,-0.619 1.145,-0.618C1.138,-0.613 1.132,-0.611 1.126,-0.611L1.099,-0.611C1.088,-0.611 1.079,-0.608 1.071,-0.602L1.029,-0.602C1.024,-0.602 1.02,-0.603 1.017,-0.605L1.01,-0.602C0.993,-0.604 0.98,-0.605 0.971,-0.605C0.962,-0.605 0.958,-0.604 0.958,-0.602L0.928,-0.605L0.695,-0.605C0.69,-0.605 0.686,-0.604 0.683,-0.602C0.679,-0.604 0.675,-0.605 0.67,-0.605L0.563,-0.605C0.555,-0.605 0.547,-0.604 0.539,-0.602C0.531,-0.604 0.523,-0.605 0.514,-0.605L0.453,-0.605C0.429,-0.578 0.401,-0.525 0.37,-0.446C0.37,-0.439 0.334,-0.358 0.263,-0.201L0.177,-0.021C0.185,-0.001 0.189,0.011 0.189,0.013C0.186,0.013 0.177,0.001 0.162,-0.023L0.156,-0.023L0.153,-0.008C0.159,-0.001 0.162,0.006 0.162,0.013L0.162,0.017L0.15,0.007L0.128,0.007C0.128,-0.005 0.108,-0.045 0.067,-0.112C0.012,-0.235 -0.028,-0.332 -0.052,-0.403L-0.052,-0.412C-0.048,-0.412 -0.046,-0.409 -0.046,-0.403L-0.043,-0.403C-0.039,-0.403 -0.037,-0.405 -0.037,-0.409L-0.046,-0.443L-0.046,-0.446L-0.04,-0.446L0.034,-0.293L0.037,-0.293L0.037,-0.296C0.008,-0.37 -0.006,-0.41 -0.006,-0.416L-0.006,-0.421C0.009,-0.398 0.037,-0.343 0.076,-0.256C0.118,-0.177 0.142,-0.135 0.147,-0.13C0.212,-0.285 0.285,-0.442 0.364,-0.602C0.36,-0.602 0.358,-0.604 0.358,-0.608L0.352,-0.605L0.333,-0.605C0.332,-0.605 0.331,-0.606 0.331,-0.608C0.327,-0.606 0.324,-0.605 0.321,-0.605L0.315,-0.608C0.313,-0.608 0.312,-0.607 0.312,-0.605L0.291,-0.608L0.263,-0.608C0.263,-0.615 0.261,-0.618 0.257,-0.618L0.254,-0.618C0.247,-0.618 0.215,-0.621 0.159,-0.626L0.159,-0.63L0.162,-0.636L0.156,-0.636L0.156,-0.639C0.156,-0.641 0.163,-0.646 0.177,-0.654L0.184,-0.654L0.189,-0.651C0.189,-0.653 0.191,-0.659 0.193,-0.669C0.188,-0.671 0.178,-0.674 0.162,-0.676L0.162,-0.682L0.184,-0.682C0.191,-0.682 0.199,-0.688 0.208,-0.7ZM0.291,-0.697L0.352,-0.697C0.356,-0.697 0.358,-0.694 0.358,-0.691L0.291,-0.691L0.291,-0.697ZM0.41,-0.694L0.419,-0.694L0.419,-0.688L0.41,-0.688L0.41,-0.694ZM0.505,-0.694L0.533,-0.694L0.533,-0.688L0.505,-0.688L0.505,-0.694ZM0.603,-0.694L0.603,-0.691C0.603,-0.687 0.601,-0.685 0.597,-0.685L0.563,-0.685L0.563,-0.691L0.588,-0.691L0.603,-0.694ZM0.202,-0.667L0.202,-0.664L0.239,-0.664L0.239,-0.667L0.202,-0.667ZM0.269,-0.339L0.266,-0.327L0.266,-0.324L0.269,-0.324L0.272,-0.336L0.272,-0.339L0.269,-0.339ZM0.257,-0.308C0.237,-0.266 0.211,-0.205 0.177,-0.125C0.195,-0.147 0.223,-0.207 0.26,-0.305L0.26,-0.308L0.257,-0.308Z" style="fill:white;fill-rule:nonzero;"/>
|
||||||
|
</g>
|
||||||
|
<g transform="matrix(340.635,0,0,340.635,891.444,753)">
|
||||||
|
<path d="M0.631,-0.705C0.646,-0.705 0.661,-0.696 0.673,-0.678L0.646,-0.678C0.62,-0.678 0.587,-0.67 0.546,-0.653L0.546,-0.65L0.549,-0.65C0.607,-0.654 0.649,-0.656 0.677,-0.656L0.683,-0.656L0.683,-0.65L0.67,-0.65C0.668,-0.65 0.667,-0.651 0.667,-0.653L0.503,-0.629C0.503,-0.627 0.493,-0.624 0.473,-0.62L0.473,-0.614L0.519,-0.623L0.521,-0.623L0.521,-0.617C0.386,-0.581 0.318,-0.555 0.318,-0.538C0.252,-0.483 0.204,-0.431 0.175,-0.383C0.131,-0.304 0.108,-0.243 0.108,-0.201C0.108,-0.157 0.131,-0.125 0.175,-0.104C0.183,-0.102 0.19,-0.101 0.196,-0.101C0.286,-0.136 0.353,-0.196 0.397,-0.28C0.409,-0.318 0.419,-0.363 0.427,-0.417L0.434,-0.417L0.427,-0.359C0.433,-0.359 0.439,-0.374 0.443,-0.404C0.441,-0.412 0.439,-0.42 0.439,-0.429L0.439,-0.438L0.446,-0.438C0.448,-0.407 0.449,-0.386 0.449,-0.374C0.449,-0.358 0.444,-0.331 0.434,-0.292C0.445,-0.302 0.458,-0.335 0.473,-0.392C0.48,-0.447 0.486,-0.474 0.491,-0.474C0.491,-0.472 0.492,-0.471 0.494,-0.471C0.492,-0.469 0.49,-0.457 0.488,-0.435L0.488,-0.432L0.491,-0.432C0.499,-0.454 0.504,-0.48 0.506,-0.508C0.502,-0.516 0.5,-0.522 0.5,-0.526L0.506,-0.529C0.512,-0.529 0.518,-0.513 0.525,-0.48C0.525,-0.4 0.491,-0.297 0.424,-0.17C0.372,-0.093 0.305,-0.042 0.224,-0.019C0.188,-0.006 0.154,-0 0.121,-0C0.04,-0.022 -0.001,-0.083 -0.001,-0.183C-0.001,-0.296 0.045,-0.398 0.136,-0.489C0.165,-0.522 0.227,-0.568 0.321,-0.629C0.425,-0.68 0.529,-0.705 0.631,-0.705ZM0.482,-0.656L0.482,-0.653C0.499,-0.653 0.508,-0.652 0.509,-0.65C0.526,-0.659 0.536,-0.663 0.54,-0.663L0.54,-0.668L0.482,-0.656ZM0.099,-0.417C0.144,-0.458 0.179,-0.494 0.206,-0.523C0.23,-0.538 0.242,-0.55 0.242,-0.559C0.201,-0.535 0.156,-0.493 0.108,-0.432C0.102,-0.427 0.099,-0.422 0.099,-0.417ZM0.105,-0.261C0.108,-0.261 0.118,-0.284 0.136,-0.328C0.158,-0.378 0.203,-0.439 0.272,-0.511L0.272,-0.514C0.204,-0.463 0.167,-0.422 0.16,-0.392C0.142,-0.371 0.124,-0.328 0.105,-0.261ZM0.069,-0.334L0.069,-0.332L0.072,-0.332C0.116,-0.393 0.139,-0.429 0.139,-0.438C0.11,-0.413 0.086,-0.378 0.069,-0.334ZM0.467,-0.31L0.467,-0.307L0.47,-0.307C0.492,-0.371 0.503,-0.413 0.503,-0.432C0.49,-0.409 0.478,-0.369 0.467,-0.31ZM0.087,-0.404L0.087,-0.401C0.091,-0.401 0.093,-0.403 0.093,-0.407L0.093,-0.41C0.089,-0.41 0.087,-0.408 0.087,-0.404ZM0.063,-0.368C0.032,-0.297 0.017,-0.245 0.017,-0.213C0.021,-0.148 0.028,-0.107 0.039,-0.088L0.042,-0.088L0.042,-0.094C0.035,-0.107 0.032,-0.129 0.032,-0.158C0.032,-0.191 0.035,-0.227 0.042,-0.268L0.039,-0.273C0.045,-0.3 0.054,-0.331 0.066,-0.365L0.066,-0.368L0.063,-0.368ZM0.096,-0.24L0.096,-0.237C0.1,-0.237 0.103,-0.239 0.103,-0.243L0.103,-0.246C0.098,-0.245 0.096,-0.243 0.096,-0.24ZM0.397,-0.222L0.397,-0.219L0.4,-0.219C0.408,-0.232 0.412,-0.241 0.412,-0.243C0.407,-0.242 0.402,-0.235 0.397,-0.222ZM0.066,-0.24C0.06,-0.222 0.055,-0.202 0.051,-0.179C0.055,-0.138 0.061,-0.108 0.069,-0.088L0.072,-0.088L0.072,-0.094C0.066,-0.121 0.063,-0.139 0.063,-0.146L0.066,-0.152C0.064,-0.155 0.063,-0.16 0.063,-0.164C0.063,-0.169 0.064,-0.173 0.066,-0.176C0.064,-0.18 0.063,-0.183 0.063,-0.186C0.067,-0.218 0.069,-0.235 0.069,-0.237L0.069,-0.24L0.066,-0.24ZM0.294,-0.125L0.294,-0.122C0.3,-0.122 0.322,-0.143 0.357,-0.186L0.357,-0.188L0.354,-0.188C0.314,-0.151 0.294,-0.129 0.294,-0.125ZM0.379,-0.149C0.379,-0.146 0.36,-0.126 0.321,-0.088L0.324,-0.088C0.351,-0.112 0.37,-0.132 0.382,-0.146L0.385,-0.146L0.385,-0.149L0.379,-0.149ZM0.09,-0.104L0.09,-0.101C0.094,-0.08 0.104,-0.07 0.121,-0.07L0.13,-0.07L0.13,-0.073L0.09,-0.104ZM0.151,-0.055L0.188,-0.055L0.203,-0.058L0.203,-0.061L0.157,-0.061C0.153,-0.06 0.151,-0.058 0.151,-0.055ZM0.096,-0.058L0.096,-0.055C0.104,-0.045 0.113,-0.04 0.124,-0.04L0.13,-0.04L0.13,-0.042C0.127,-0.042 0.116,-0.048 0.096,-0.058Z" style="fill:white;fill-rule:nonzero;"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 15 KiB |
BIN
assets/images/icons/back.png
Normal file
|
After Width: | Height: | Size: 229 B |
5
assets/images/icons/back.svg
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg width="100%" height="100%" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||||
|
<path d="M20,11L20,13L8,13L13.5,18.5L12.08,19.92L4.16,12L12.08,4.08L13.5,5.5L8,11L20,11Z" style="fill:white;fill-rule:nonzero;"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 584 B |
BIN
assets/images/icons/close.png
Normal file
|
After Width: | Height: | Size: 295 B |
15
assets/images/icons/close.svg
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg width="100%" height="100%" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.5;">
|
||||||
|
<g id="Artboard1" transform="matrix(0.0666667,0,0,0.097561,-31,-18.6341)">
|
||||||
|
<rect x="465" y="191" width="360" height="246" style="fill:none;"/>
|
||||||
|
<g transform="matrix(134.328,0,0,102.5,-74228.5,-15214.7)">
|
||||||
|
<g transform="matrix(1.11667,0,0,1,-57.3333,0)">
|
||||||
|
<path d="M551,152L550,151" style="fill:none;stroke:white;stroke-width:0.3px;"/>
|
||||||
|
</g>
|
||||||
|
<g transform="matrix(1.11667,0,0,1,-57.3333,0)">
|
||||||
|
<path d="M550,152L551,151" style="fill:none;stroke:white;stroke-width:0.3px;"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.0 KiB |
BIN
assets/images/icons/debug.png
Normal file
|
After Width: | Height: | Size: 183 B |
BIN
assets/images/icons/expand.png
Normal file
|
After Width: | Height: | Size: 273 B |
BIN
assets/images/icons/reset.png
Normal file
|
After Width: | Height: | Size: 933 B |
BIN
assets/images/icons/warning.png
Normal file
|
After Width: | Height: | Size: 241 B |
|
Before Width: | Height: | Size: 175 B After Width: | Height: | Size: 175 B |
BIN
assets/images/rounded-background.png
Normal file
|
After Width: | Height: | Size: 228 B |
BIN
assets/images/rounded-border.png
Normal file
|
After Width: | Height: | Size: 315 B |
BIN
assets/images/scrollbar-bottom.png
Normal file
|
After Width: | Height: | Size: 105 B |
17
assets/images/scrollbar-bottom.svg
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg width="100%" height="100%" viewBox="0 0 9 7" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||||
|
<g transform="matrix(1,0,0,1,0,-10)">
|
||||||
|
<g id="Bottom" transform="matrix(0.243243,0,0,0.179487,-59.1081,-30.2051)">
|
||||||
|
<rect x="243" y="224" width="37" height="39" style="fill:none;"/>
|
||||||
|
<clipPath id="_clip1">
|
||||||
|
<rect x="243" y="224" width="37" height="39"/>
|
||||||
|
</clipPath>
|
||||||
|
<g clip-path="url(#_clip1)">
|
||||||
|
<g transform="matrix(-4.11111,6.82303e-16,-3.59619e-16,-3.97959,280,259.816)">
|
||||||
|
<path d="M7,5.5C7,3.568 5.88,2 4.5,2C3.12,2 2,3.568 2,5.5L2,9L7,9L7,5.5Z" style="fill:white;"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.1 KiB |
BIN
assets/images/scrollbar-middle.png
Normal file
|
After Width: | Height: | Size: 75 B |
12
assets/images/scrollbar-middle.svg
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg width="100%" height="100%" viewBox="0 0 9 1" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||||
|
<g transform="matrix(1,0,0,1,0,-8)">
|
||||||
|
<g id="Middle" transform="matrix(1,0,0,0.111111,0,7.11111)">
|
||||||
|
<rect x="0" y="8" width="9" height="9" style="fill:none;"/>
|
||||||
|
<g transform="matrix(1,0,0,9,0,-64)">
|
||||||
|
<rect x="2" y="8" width="5" height="1" style="fill:white;"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 796 B |
BIN
assets/images/scrollbar-top.png
Normal file
|
After Width: | Height: | Size: 132 B |
10
assets/images/scrollbar-top.svg
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg width="100%" height="100%" viewBox="0 0 9 7" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||||
|
<g id="Top" transform="matrix(0.243243,0,0,0.179487,-59.1081,-40.2051)">
|
||||||
|
<rect x="243" y="224" width="37" height="39" style="fill:none;"/>
|
||||||
|
<g transform="matrix(4.11111,0,0,3.97959,243,227.184)">
|
||||||
|
<path d="M7,5.5C7,3.568 5.88,2 4.5,2C3.12,2 2,3.568 2,5.5L2,9L7,9L7,5.5Z" style="fill:white;"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 793 B |
BIN
assets/images/spinner-background.png
Normal file
|
After Width: | Height: | Size: 684 B |
8
assets/images/spinner-background.svg
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg width="100%" height="100%" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||||
|
<g id="Artboard1" transform="matrix(0.5,0,0,0.5,0,0)">
|
||||||
|
<rect x="0" y="0" width="48" height="48" style="fill:none;"/>
|
||||||
|
<path d="M24,0C37.246,0 48,10.754 48,24C48,37.246 37.246,48 24,48C10.754,48 0,37.246 0,24C0,10.754 10.754,0 24,0ZM24,8.4C32.61,8.4 39.6,15.39 39.6,24C39.6,32.61 32.61,39.6 24,39.6C15.39,39.6 8.4,32.61 8.4,24C8.4,15.39 15.39,8.4 24,8.4Z" style="fill:white;"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 855 B |
BIN
assets/images/spinner-foreground.png
Normal file
|
After Width: | Height: | Size: 340 B |
8
assets/images/spinner-foreground.svg
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg width="100%" height="100%" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||||
|
<g id="Artboard1" transform="matrix(0.5,0,0,0.5,0,0)">
|
||||||
|
<rect x="0" y="0" width="48" height="48" style="fill:none;"/>
|
||||||
|
<path d="M48,24C48,10.745 37.255,0 24,0L24,8.4C32.616,8.4 39.6,15.384 39.6,24L48,24Z" style="fill:white;"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 704 B |
BIN
assets/images/syncsuccess.png
Normal file
|
After Width: | Height: | Size: 574 B |
BIN
assets/images/syncwarning.png
Normal file
|
After Width: | Height: | Size: 607 B |
181
assets/index.css
Normal file
@@ -0,0 +1,181 @@
|
|||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
border: none;
|
||||||
|
text-decoration: inherit;
|
||||||
|
color: inherit;
|
||||||
|
font: inherit;
|
||||||
|
box-sizing: inherit;
|
||||||
|
line-height: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
html {
|
||||||
|
box-sizing: border-box;
|
||||||
|
font-family: sans-serif;
|
||||||
|
font-size: 18px;
|
||||||
|
text-decoration: none;
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
max-width:100%;
|
||||||
|
max-height:100%;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.path-list > li {
|
||||||
|
margin-left: 1.2em;
|
||||||
|
font-family: monospace;
|
||||||
|
}
|
||||||
|
|
||||||
|
.root {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
margin: 0.5rem auto;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 50rem;
|
||||||
|
background-color: #efefef;
|
||||||
|
border: 1px solid #666;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
flex: 0 0;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: center;
|
||||||
|
border-bottom: 1px solid #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main {
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-logo {
|
||||||
|
flex: 0 0 10rem;
|
||||||
|
margin: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stats {
|
||||||
|
flex: 0 0 20rem;
|
||||||
|
margin: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-name {
|
||||||
|
display: inline;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-section:not(:last-of-type) {
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
font-size: 1.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-list {
|
||||||
|
flex: 0 0;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: space-around;
|
||||||
|
margin: -1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
display: inline-block;
|
||||||
|
border: 1px solid #666;
|
||||||
|
padding: 0.3em 1em;
|
||||||
|
margin: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.instance {
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.instance-title {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
padding: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.expandable-section {
|
||||||
|
margin: 0.25rem 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.expandable-items {
|
||||||
|
padding: 0.5rem 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.expandable-input {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.expandable-label > label {
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
align-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.expandable-input ~ .expandable-label .expandable-visualizer {
|
||||||
|
font-family: monospace;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
align-content: center;
|
||||||
|
text-align: center;
|
||||||
|
width: 1rem;
|
||||||
|
height: 1rem;
|
||||||
|
font-size: 2rem;
|
||||||
|
margin: 0 0.5rem;
|
||||||
|
transition: transform 100ms ease-in-out;
|
||||||
|
transform-origin: 60% 60%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.expandable-visualizer::before {
|
||||||
|
content: "›";
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.expandable-input:checked ~ .expandable-label {
|
||||||
|
border-bottom: 1px solid #bbb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.expandable-input:checked ~ .expandable-label .expandable-visualizer {
|
||||||
|
transform: rotate(90deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.expandable-input:not(:checked) ~ .expandable-items {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vfs-entry {
|
||||||
|
}
|
||||||
|
|
||||||
|
.vfs-entry-name {
|
||||||
|
position: relative;
|
||||||
|
font-family: monospace;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vfs-entry-children .vfs-entry-name::before {
|
||||||
|
content: "";
|
||||||
|
width: 0.6em;
|
||||||
|
height: 1px;
|
||||||
|
background-color: #999;
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: -0.8em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vfs-entry-note {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vfs-entry-children {
|
||||||
|
padding-left: 0.8em;
|
||||||
|
margin-left: 0.2em;
|
||||||
|
border-left: 1px solid #999;
|
||||||
|
}
|
||||||
|
Before Width: | Height: | Size: 13 KiB |
@@ -1,41 +0,0 @@
|
|||||||
<TextureAtlas imagePath="sheet.png">
|
|
||||||
<SubTexture name="grey_arrowDownGrey.png" x="78" y="498" width="15" height="10"/>
|
|
||||||
<SubTexture name="grey_arrowDownWhite.png" x="123" y="496" width="15" height="10"/>
|
|
||||||
<SubTexture name="grey_arrowUpGrey.png" x="108" y="498" width="15" height="10"/>
|
|
||||||
<SubTexture name="grey_arrowUpWhite.png" x="93" y="498" width="15" height="10"/>
|
|
||||||
<SubTexture name="grey_box.png" x="147" y="433" width="38" height="36"/>
|
|
||||||
<SubTexture name="grey_boxCheckmark.png" x="147" y="469" width="38" height="36"/>
|
|
||||||
<SubTexture name="grey_boxCross.png" x="185" y="433" width="38" height="36"/>
|
|
||||||
<SubTexture name="grey_boxTick.png" x="190" y="198" width="36" height="36"/>
|
|
||||||
<SubTexture name="grey_button00.png" x="0" y="143" width="190" height="45"/>
|
|
||||||
<SubTexture name="grey_button01.png" x="0" y="188" width="190" height="49"/>
|
|
||||||
<SubTexture name="grey_button02.png" x="0" y="98" width="190" height="45"/>
|
|
||||||
<SubTexture name="grey_button03.png" x="0" y="331" width="190" height="49"/>
|
|
||||||
<SubTexture name="grey_button04.png" x="0" y="286" width="190" height="45"/>
|
|
||||||
<SubTexture name="grey_button05.png" x="0" y="0" width="195" height="49"/>
|
|
||||||
<SubTexture name="grey_button06.png" x="0" y="49" width="191" height="49"/>
|
|
||||||
<SubTexture name="grey_button07.png" x="195" y="0" width="49" height="49"/>
|
|
||||||
<SubTexture name="grey_button08.png" x="240" y="49" width="49" height="49"/>
|
|
||||||
<SubTexture name="grey_button09.png" x="98" y="433" width="49" height="45"/>
|
|
||||||
<SubTexture name="grey_button10.png" x="191" y="49" width="49" height="49"/>
|
|
||||||
<SubTexture name="grey_button11.png" x="0" y="433" width="49" height="45"/>
|
|
||||||
<SubTexture name="grey_button12.png" x="244" y="0" width="49" height="49"/>
|
|
||||||
<SubTexture name="grey_button13.png" x="49" y="433" width="49" height="45"/>
|
|
||||||
<SubTexture name="grey_button14.png" x="0" y="384" width="190" height="49"/>
|
|
||||||
<SubTexture name="grey_button15.png" x="0" y="237" width="190" height="49"/>
|
|
||||||
<SubTexture name="grey_checkmarkGrey.png" x="99" y="478" width="21" height="20"/>
|
|
||||||
<SubTexture name="grey_checkmarkWhite.png" x="78" y="478" width="21" height="20"/>
|
|
||||||
<SubTexture name="grey_circle.png" x="185" y="469" width="36" height="36"/>
|
|
||||||
<SubTexture name="grey_crossGrey.png" x="120" y="478" width="18" height="18"/>
|
|
||||||
<SubTexture name="grey_crossWhite.png" x="190" y="318" width="18" height="18"/>
|
|
||||||
<SubTexture name="grey_panel.png" x="190" y="98" width="100" height="100"/>
|
|
||||||
<SubTexture name="grey_sliderDown.png" x="190" y="234" width="28" height="42"/>
|
|
||||||
<SubTexture name="grey_sliderEnd.png" x="138" y="478" width="8" height="10"/>
|
|
||||||
<SubTexture name="grey_sliderHorizontal.png" x="0" y="380" width="190" height="4"/>
|
|
||||||
<SubTexture name="grey_sliderLeft.png" x="0" y="478" width="39" height="31"/>
|
|
||||||
<SubTexture name="grey_sliderRight.png" x="39" y="478" width="39" height="31"/>
|
|
||||||
<SubTexture name="grey_sliderUp.png" x="190" y="276" width="28" height="42"/>
|
|
||||||
<SubTexture name="grey_sliderVertical.png" x="208" y="318" width="4" height="100"/>
|
|
||||||
<SubTexture name="grey_tickGrey.png" x="190" y="336" width="17" height="17"/>
|
|
||||||
<SubTexture name="grey_tickWhite.png" x="190" y="353" width="17" height="17"/>
|
|
||||||
</TextureAtlas>
|
|
||||||
BIN
assets/test-folder.rbxm
Normal file
44
benches/build.rs
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
use criterion::{criterion_group, criterion_main, BatchSize, Criterion};
|
||||||
|
use tempfile::{tempdir, TempDir};
|
||||||
|
|
||||||
|
use librojo::cli::BuildCommand;
|
||||||
|
|
||||||
|
pub fn benchmark_small_place(c: &mut Criterion) {
|
||||||
|
bench_build_place(c, "Small Place", "test-projects/benchmark_small_place")
|
||||||
|
}
|
||||||
|
|
||||||
|
criterion_group!(benches, benchmark_small_place);
|
||||||
|
criterion_main!(benches);
|
||||||
|
|
||||||
|
fn bench_build_place(c: &mut Criterion, name: &str, path: &str) {
|
||||||
|
let mut group = c.benchmark_group(name);
|
||||||
|
|
||||||
|
// 'rojo build' generally takes a fair bit of time to execute.
|
||||||
|
group.sample_size(10);
|
||||||
|
group.bench_function("build", |b| {
|
||||||
|
b.iter_batched(
|
||||||
|
|| place_setup(path),
|
||||||
|
|(_dir, options)| options.run().unwrap(),
|
||||||
|
BatchSize::SmallInput,
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
|
group.finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn place_setup<P: AsRef<Path>>(input_path: P) -> (TempDir, BuildCommand) {
|
||||||
|
let dir = tempdir().unwrap();
|
||||||
|
let input = input_path.as_ref().to_path_buf();
|
||||||
|
let output = Some(dir.path().join("output.rbxlx"));
|
||||||
|
|
||||||
|
let options = BuildCommand {
|
||||||
|
project: input,
|
||||||
|
watch: false,
|
||||||
|
plugin: None,
|
||||||
|
output,
|
||||||
|
};
|
||||||
|
|
||||||
|
(dir, options)
|
||||||
|
}
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
# Copies a project from 'test-projects' into a folder that can be messed with
|
|
||||||
# without accidentally checking the results into version control.
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
if [ ! -d "test-projects/$1" ]
|
|
||||||
then
|
|
||||||
echo "Pick a project that exists!"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -d "scratch-project/$1" ]
|
|
||||||
then
|
|
||||||
rm -rf "scratch-project/$1"
|
|
||||||
fi
|
|
||||||
|
|
||||||
mkdir -p scratch-project
|
|
||||||
cp -r "test-projects/$1" scratch-project
|
|
||||||
cargo run -- serve "scratch-project/$1"
|
|
||||||
77
build.rs
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
use std::{
|
||||||
|
env, io,
|
||||||
|
path::{Path, PathBuf},
|
||||||
|
};
|
||||||
|
|
||||||
|
use fs_err as fs;
|
||||||
|
use fs_err::File;
|
||||||
|
use maplit::hashmap;
|
||||||
|
use memofs::VfsSnapshot;
|
||||||
|
use semver::Version;
|
||||||
|
|
||||||
|
fn snapshot_from_fs_path(path: &Path) -> io::Result<VfsSnapshot> {
|
||||||
|
println!("cargo:rerun-if-changed={}", path.display());
|
||||||
|
|
||||||
|
if path.is_dir() {
|
||||||
|
let mut children = Vec::new();
|
||||||
|
|
||||||
|
for entry in fs::read_dir(path)? {
|
||||||
|
let entry = entry?;
|
||||||
|
|
||||||
|
let file_name = entry.file_name().to_str().unwrap().to_owned();
|
||||||
|
|
||||||
|
// We can skip any TestEZ test files since they aren't necessary for
|
||||||
|
// the plugin to run.
|
||||||
|
if file_name.ends_with(".spec.lua") || file_name.ends_with(".spec.luau") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let child_snapshot = snapshot_from_fs_path(&entry.path())?;
|
||||||
|
children.push((file_name, child_snapshot));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(VfsSnapshot::dir(children))
|
||||||
|
} else {
|
||||||
|
let content = fs::read_to_string(path)?;
|
||||||
|
|
||||||
|
Ok(VfsSnapshot::file(content))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() -> Result<(), anyhow::Error> {
|
||||||
|
let out_dir = env::var_os("OUT_DIR").unwrap();
|
||||||
|
|
||||||
|
let root_dir = env::var_os("CARGO_MANIFEST_DIR").unwrap();
|
||||||
|
let plugin_root = PathBuf::from(root_dir).join("plugin");
|
||||||
|
|
||||||
|
let our_version = Version::parse(env::var_os("CARGO_PKG_VERSION").unwrap().to_str().unwrap())?;
|
||||||
|
let plugin_version =
|
||||||
|
Version::parse(fs::read_to_string(plugin_root.join("Version.txt"))?.trim())?;
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
our_version, plugin_version,
|
||||||
|
"plugin version does not match Cargo version"
|
||||||
|
);
|
||||||
|
|
||||||
|
let snapshot = VfsSnapshot::dir(hashmap! {
|
||||||
|
"default.project.json" => snapshot_from_fs_path(&plugin_root.join("default.project.json"))?,
|
||||||
|
"fmt" => snapshot_from_fs_path(&plugin_root.join("fmt"))?,
|
||||||
|
"http" => snapshot_from_fs_path(&plugin_root.join("http"))?,
|
||||||
|
"log" => snapshot_from_fs_path(&plugin_root.join("log"))?,
|
||||||
|
"rbx_dom_lua" => snapshot_from_fs_path(&plugin_root.join("rbx_dom_lua"))?,
|
||||||
|
"src" => snapshot_from_fs_path(&plugin_root.join("src"))?,
|
||||||
|
"Packages" => snapshot_from_fs_path(&plugin_root.join("Packages"))?,
|
||||||
|
"Version.txt" => snapshot_from_fs_path(&plugin_root.join("Version.txt"))?,
|
||||||
|
});
|
||||||
|
|
||||||
|
let out_path = Path::new(&out_dir).join("plugin.bincode");
|
||||||
|
let out_file = File::create(out_path)?;
|
||||||
|
|
||||||
|
bincode::serialize_into(out_file, &snapshot)?;
|
||||||
|
|
||||||
|
println!("cargo:rerun-if-changed=build/windows/rojo-manifest.rc");
|
||||||
|
println!("cargo:rerun-if-changed=build/windows/rojo.manifest");
|
||||||
|
embed_resource::compile("build/windows/rojo-manifest.rc");
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
2
build/windows/rojo-manifest.rc
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
#define RT_MANIFEST 24
|
||||||
|
1 RT_MANIFEST "rojo.manifest"
|
||||||
8
build/windows/rojo.manifest
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version='1.0' encoding='utf-8' standalone='yes'?>
|
||||||
|
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
||||||
|
<application xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||||
|
<windowsSettings xmlns:ws2="http://schemas.microsoft.com/SMI/2016/WindowsSettings">
|
||||||
|
<ws2:longPathAware>true</ws2:longPathAware>
|
||||||
|
</windowsSettings>
|
||||||
|
</application>
|
||||||
|
</assembly>
|
||||||
25
crates/memofs/CHANGELOG.md
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
# memofs Changelog
|
||||||
|
|
||||||
|
## Unreleased Changes
|
||||||
|
|
||||||
|
## 0.3.0 (2024-03-15)
|
||||||
|
* Changed `StdBackend` file watching component to use minimal recursive watches. [#830]
|
||||||
|
* Added `Vfs::read_to_string` and `Vfs::read_to_string_lf_normalized` [#854]
|
||||||
|
|
||||||
|
[#830]: https://github.com/rojo-rbx/rojo/pull/830
|
||||||
|
[#854]: https://github.com/rojo-rbx/rojo/pull/854
|
||||||
|
|
||||||
|
## 0.2.0 (2021-08-23)
|
||||||
|
* Updated to `crossbeam-channel` 0.5.1.
|
||||||
|
|
||||||
|
## 0.1.3 (2020-11-19)
|
||||||
|
* Added `set_watch_enabled` to `Vfs` and `VfsLock` to allow turning off file watching.
|
||||||
|
|
||||||
|
## 0.1.2 (2020-03-29)
|
||||||
|
* `VfsSnapshot` now implements Serde's `Serialize` and `Deserialize` traits.
|
||||||
|
|
||||||
|
## 0.1.1 (2020-03-18)
|
||||||
|
* Improved error messages using the [fs-err](https://crates.io/crates/fs-err) crate.
|
||||||
|
|
||||||
|
## 0.1.0 (2020-03-10)
|
||||||
|
* Initial release
|
||||||
17
crates/memofs/Cargo.toml
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
[package]
|
||||||
|
name = "memofs"
|
||||||
|
description = "Virtual filesystem with configurable backends."
|
||||||
|
version = "0.3.0"
|
||||||
|
authors = ["Lucien Greathouse <me@lpghatguy.com>"]
|
||||||
|
edition = "2018"
|
||||||
|
readme = "README.md"
|
||||||
|
license = "MIT"
|
||||||
|
homepage = "https://github.com/rojo-rbx/rojo/tree/master/memofs"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
crossbeam-channel = "0.5.12"
|
||||||
|
fs-err = "2.11.0"
|
||||||
|
notify = "4.0.17"
|
||||||
|
serde = { version = "1.0.197", features = ["derive"] }
|
||||||
7
crates/memofs/LICENSE.txt
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
Copyright 2020 The Rojo Developers
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
22
crates/memofs/README.md
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
# memofs
|
||||||
|
[](https://crates.io/crates/memofs)
|
||||||
|
|
||||||
|
Implementation of a virtual filesystem with a configurable backend and file
|
||||||
|
watching.
|
||||||
|
|
||||||
|
memofs is currently an unstable minimum viable library. Its primary consumer is
|
||||||
|
[Rojo](https://github.com/rojo-rbx/rojo), a build system for Roblox.
|
||||||
|
|
||||||
|
### Current Features
|
||||||
|
* API similar to `std::fs`
|
||||||
|
* Configurable backends
|
||||||
|
* `StdBackend`, which uses `std::fs` and the `notify` crate
|
||||||
|
* `NoopBackend`, which always throws errors
|
||||||
|
* `InMemoryFs`, a simple in-memory filesystem useful for testing
|
||||||
|
|
||||||
|
### Future Features
|
||||||
|
* Hash-based hierarchical memoization keys (hence the name)
|
||||||
|
* Configurable caching (write-through, write-around, write-back)
|
||||||
|
|
||||||
|
## License
|
||||||
|
memofs is available under the terms of the MIT license. See [LICENSE.txt](LICENSE.txt) or <https://opensource.org/licenses/MIT> for more details.
|
||||||
7
crates/memofs/README.tpl
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# {{crate}}
|
||||||
|
[](https://crates.io/crates/memofs)
|
||||||
|
|
||||||
|
{{readme}}
|
||||||
|
|
||||||
|
## License
|
||||||
|
memofs is available under the terms of the MIT license. See [LICENSE.txt](LICENSE.txt) or <https://opensource.org/licenses/MIT> for more details.
|
||||||
255
crates/memofs/src/in_memory_fs.rs
Normal file
@@ -0,0 +1,255 @@
|
|||||||
|
use std::collections::{BTreeSet, HashMap, VecDeque};
|
||||||
|
use std::io;
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
|
use crossbeam_channel::{Receiver, Sender};
|
||||||
|
|
||||||
|
use crate::{DirEntry, Metadata, ReadDir, VfsBackend, VfsEvent, VfsSnapshot};
|
||||||
|
|
||||||
|
/// In-memory filesystem that can be used as a VFS backend.
|
||||||
|
///
|
||||||
|
/// Internally reference counted to enable giving a copy to
|
||||||
|
/// [`Vfs`](struct.Vfs.html) and keeping the original to mutate the filesystem's
|
||||||
|
/// state with.
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct InMemoryFs {
|
||||||
|
inner: Arc<Mutex<InMemoryFsInner>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl InMemoryFs {
|
||||||
|
/// Create a new empty `InMemoryFs`.
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
inner: Arc::new(Mutex::new(InMemoryFsInner::new())),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Load a [`VfsSnapshot`](enum.VfsSnapshot.html) into a subtree of the
|
||||||
|
/// in-memory filesystem.
|
||||||
|
///
|
||||||
|
/// This function will return an error if the operations required to apply
|
||||||
|
/// the snapshot result in errors, like trying to create a file inside a
|
||||||
|
/// file.
|
||||||
|
pub fn load_snapshot<P: Into<PathBuf>>(
|
||||||
|
&mut self,
|
||||||
|
path: P,
|
||||||
|
snapshot: VfsSnapshot,
|
||||||
|
) -> io::Result<()> {
|
||||||
|
let mut inner = self.inner.lock().unwrap();
|
||||||
|
inner.load_snapshot(path.into(), snapshot)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Raises a filesystem change event.
|
||||||
|
///
|
||||||
|
/// If this `InMemoryFs` is being used as the backend of a
|
||||||
|
/// [`Vfs`](struct.Vfs.html), then any listeners be notified of this event.
|
||||||
|
pub fn raise_event(&mut self, event: VfsEvent) {
|
||||||
|
let inner = self.inner.lock().unwrap();
|
||||||
|
inner.event_sender.send(event).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for InMemoryFs {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct InMemoryFsInner {
|
||||||
|
entries: HashMap<PathBuf, Entry>,
|
||||||
|
orphans: BTreeSet<PathBuf>,
|
||||||
|
|
||||||
|
event_receiver: Receiver<VfsEvent>,
|
||||||
|
event_sender: Sender<VfsEvent>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl InMemoryFsInner {
|
||||||
|
fn new() -> Self {
|
||||||
|
let (event_sender, event_receiver) = crossbeam_channel::unbounded();
|
||||||
|
|
||||||
|
Self {
|
||||||
|
entries: HashMap::new(),
|
||||||
|
orphans: BTreeSet::new(),
|
||||||
|
event_receiver,
|
||||||
|
event_sender,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn load_snapshot(&mut self, path: PathBuf, snapshot: VfsSnapshot) -> io::Result<()> {
|
||||||
|
if let Some(parent_path) = path.parent() {
|
||||||
|
if let Some(parent_entry) = self.entries.get_mut(parent_path) {
|
||||||
|
if let Entry::Dir { children } = parent_entry {
|
||||||
|
children.insert(path.clone());
|
||||||
|
} else {
|
||||||
|
return must_be_dir(parent_path);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
self.orphans.insert(path.clone());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
self.orphans.insert(path.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
match snapshot {
|
||||||
|
VfsSnapshot::File { contents } => {
|
||||||
|
self.entries.insert(path, Entry::File { contents });
|
||||||
|
}
|
||||||
|
VfsSnapshot::Dir { children } => {
|
||||||
|
self.entries.insert(
|
||||||
|
path.clone(),
|
||||||
|
Entry::Dir {
|
||||||
|
children: BTreeSet::new(),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
for (child_name, child) in children {
|
||||||
|
let full_path = path.join(child_name);
|
||||||
|
self.load_snapshot(full_path, child)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove(&mut self, root_path: PathBuf) {
|
||||||
|
self.orphans.remove(&root_path);
|
||||||
|
|
||||||
|
let mut to_remove = VecDeque::new();
|
||||||
|
to_remove.push_back(root_path);
|
||||||
|
|
||||||
|
while let Some(path) = to_remove.pop_front() {
|
||||||
|
if let Some(Entry::Dir { children }) = self.entries.remove(&path) {
|
||||||
|
to_remove.extend(children);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
enum Entry {
|
||||||
|
File { contents: Vec<u8> },
|
||||||
|
|
||||||
|
Dir { children: BTreeSet<PathBuf> },
|
||||||
|
}
|
||||||
|
|
||||||
|
impl VfsBackend for InMemoryFs {
|
||||||
|
fn read(&mut self, path: &Path) -> io::Result<Vec<u8>> {
|
||||||
|
let inner = self.inner.lock().unwrap();
|
||||||
|
|
||||||
|
match inner.entries.get(path) {
|
||||||
|
Some(Entry::File { contents }) => Ok(contents.clone()),
|
||||||
|
Some(Entry::Dir { .. }) => must_be_file(path),
|
||||||
|
None => not_found(path),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write(&mut self, path: &Path, data: &[u8]) -> io::Result<()> {
|
||||||
|
let mut inner = self.inner.lock().unwrap();
|
||||||
|
|
||||||
|
inner.load_snapshot(
|
||||||
|
path.to_path_buf(),
|
||||||
|
VfsSnapshot::File {
|
||||||
|
contents: data.to_owned(),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_dir(&mut self, path: &Path) -> io::Result<ReadDir> {
|
||||||
|
let inner = self.inner.lock().unwrap();
|
||||||
|
|
||||||
|
match inner.entries.get(path) {
|
||||||
|
Some(Entry::Dir { children }) => {
|
||||||
|
let iter = children
|
||||||
|
.clone()
|
||||||
|
.into_iter()
|
||||||
|
.map(|path| Ok(DirEntry { path }));
|
||||||
|
|
||||||
|
Ok(ReadDir {
|
||||||
|
inner: Box::new(iter),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Some(Entry::File { .. }) => must_be_dir(path),
|
||||||
|
None => not_found(path),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove_file(&mut self, path: &Path) -> io::Result<()> {
|
||||||
|
let mut inner = self.inner.lock().unwrap();
|
||||||
|
|
||||||
|
match inner.entries.get(path) {
|
||||||
|
Some(Entry::File { .. }) => {
|
||||||
|
inner.remove(path.to_owned());
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
Some(Entry::Dir { .. }) => must_be_file(path),
|
||||||
|
None => not_found(path),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove_dir_all(&mut self, path: &Path) -> io::Result<()> {
|
||||||
|
let mut inner = self.inner.lock().unwrap();
|
||||||
|
|
||||||
|
match inner.entries.get(path) {
|
||||||
|
Some(Entry::Dir { .. }) => {
|
||||||
|
inner.remove(path.to_owned());
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
Some(Entry::File { .. }) => must_be_dir(path),
|
||||||
|
None => not_found(path),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn metadata(&mut self, path: &Path) -> io::Result<Metadata> {
|
||||||
|
let inner = self.inner.lock().unwrap();
|
||||||
|
|
||||||
|
match inner.entries.get(path) {
|
||||||
|
Some(Entry::File { .. }) => Ok(Metadata { is_file: true }),
|
||||||
|
Some(Entry::Dir { .. }) => Ok(Metadata { is_file: false }),
|
||||||
|
None => not_found(path),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn event_receiver(&self) -> crossbeam_channel::Receiver<VfsEvent> {
|
||||||
|
let inner = self.inner.lock().unwrap();
|
||||||
|
|
||||||
|
inner.event_receiver.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn watch(&mut self, _path: &Path) -> io::Result<()> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unwatch(&mut self, _path: &Path) -> io::Result<()> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn must_be_file<T>(path: &Path) -> io::Result<T> {
|
||||||
|
Err(io::Error::new(
|
||||||
|
io::ErrorKind::Other,
|
||||||
|
format!(
|
||||||
|
"path {} was a directory, but must be a file",
|
||||||
|
path.display()
|
||||||
|
),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn must_be_dir<T>(path: &Path) -> io::Result<T> {
|
||||||
|
Err(io::Error::new(
|
||||||
|
io::ErrorKind::Other,
|
||||||
|
format!(
|
||||||
|
"path {} was a file, but must be a directory",
|
||||||
|
path.display()
|
||||||
|
),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn not_found<T>(path: &Path) -> io::Result<T> {
|
||||||
|
Err(io::Error::new(
|
||||||
|
io::ErrorKind::NotFound,
|
||||||
|
format!("path {} not found", path.display()),
|
||||||
|
))
|
||||||
|
}
|
||||||
495
crates/memofs/src/lib.rs
Normal file
@@ -0,0 +1,495 @@
|
|||||||
|
/*!
|
||||||
|
Implementation of a virtual filesystem with a configurable backend and file
|
||||||
|
watching.
|
||||||
|
|
||||||
|
memofs is currently an unstable minimum viable library. Its primary consumer is
|
||||||
|
[Rojo](https://github.com/rojo-rbx/rojo), a build system for Roblox.
|
||||||
|
|
||||||
|
## Current Features
|
||||||
|
* API similar to `std::fs`
|
||||||
|
* Configurable backends
|
||||||
|
* `StdBackend`, which uses `std::fs` and the `notify` crate
|
||||||
|
* `NoopBackend`, which always throws errors
|
||||||
|
* `InMemoryFs`, a simple in-memory filesystem useful for testing
|
||||||
|
|
||||||
|
## Future Features
|
||||||
|
* Hash-based hierarchical memoization keys (hence the name)
|
||||||
|
* Configurable caching (write-through, write-around, write-back)
|
||||||
|
*/
|
||||||
|
|
||||||
|
mod in_memory_fs;
|
||||||
|
mod noop_backend;
|
||||||
|
mod snapshot;
|
||||||
|
mod std_backend;
|
||||||
|
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
use std::sync::{Arc, Mutex, MutexGuard};
|
||||||
|
use std::{io, str};
|
||||||
|
|
||||||
|
pub use in_memory_fs::InMemoryFs;
|
||||||
|
pub use noop_backend::NoopBackend;
|
||||||
|
pub use snapshot::VfsSnapshot;
|
||||||
|
pub use std_backend::StdBackend;
|
||||||
|
|
||||||
|
mod sealed {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
/// Sealing trait for VfsBackend.
|
||||||
|
pub trait Sealed {}
|
||||||
|
|
||||||
|
impl Sealed for NoopBackend {}
|
||||||
|
impl Sealed for StdBackend {}
|
||||||
|
impl Sealed for InMemoryFs {}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Trait that transforms `io::Result<T>` into `io::Result<Option<T>>`.
|
||||||
|
///
|
||||||
|
/// `Ok(None)` takes the place of IO errors whose `io::ErrorKind` is `NotFound`.
|
||||||
|
pub trait IoResultExt<T> {
|
||||||
|
fn with_not_found(self) -> io::Result<Option<T>>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> IoResultExt<T> for io::Result<T> {
|
||||||
|
fn with_not_found(self) -> io::Result<Option<T>> {
|
||||||
|
match self {
|
||||||
|
Ok(v) => Ok(Some(v)),
|
||||||
|
Err(err) => {
|
||||||
|
if err.kind() == io::ErrorKind::NotFound {
|
||||||
|
Ok(None)
|
||||||
|
} else {
|
||||||
|
Err(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Backend that can be used to create a `Vfs`.
|
||||||
|
///
|
||||||
|
/// This trait is sealed and cannot not be implemented outside this crate.
|
||||||
|
pub trait VfsBackend: sealed::Sealed + Send + 'static {
|
||||||
|
fn read(&mut self, path: &Path) -> io::Result<Vec<u8>>;
|
||||||
|
fn write(&mut self, path: &Path, data: &[u8]) -> io::Result<()>;
|
||||||
|
fn read_dir(&mut self, path: &Path) -> io::Result<ReadDir>;
|
||||||
|
fn metadata(&mut self, path: &Path) -> io::Result<Metadata>;
|
||||||
|
fn remove_file(&mut self, path: &Path) -> io::Result<()>;
|
||||||
|
fn remove_dir_all(&mut self, path: &Path) -> io::Result<()>;
|
||||||
|
|
||||||
|
fn event_receiver(&self) -> crossbeam_channel::Receiver<VfsEvent>;
|
||||||
|
fn watch(&mut self, path: &Path) -> io::Result<()>;
|
||||||
|
fn unwatch(&mut self, path: &Path) -> io::Result<()>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Vfs equivalent to [`std::fs::DirEntry`][std::fs::DirEntry].
|
||||||
|
///
|
||||||
|
/// [std::fs::DirEntry]: https://doc.rust-lang.org/stable/std/fs/struct.DirEntry.html
|
||||||
|
pub struct DirEntry {
|
||||||
|
pub(crate) path: PathBuf,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DirEntry {
|
||||||
|
pub fn path(&self) -> &Path {
|
||||||
|
&self.path
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Vfs equivalent to [`std::fs::ReadDir`][std::fs::ReadDir].
|
||||||
|
///
|
||||||
|
/// [std::fs::ReadDir]: https://doc.rust-lang.org/stable/std/fs/struct.ReadDir.html
|
||||||
|
pub struct ReadDir {
|
||||||
|
pub(crate) inner: Box<dyn Iterator<Item = io::Result<DirEntry>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Iterator for ReadDir {
|
||||||
|
type Item = io::Result<DirEntry>;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
self.inner.next()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Vfs equivalent to [`std::fs::Metadata`][std::fs::Metadata].
|
||||||
|
///
|
||||||
|
/// [std::fs::Metadata]: https://doc.rust-lang.org/stable/std/fs/struct.Metadata.html
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Metadata {
|
||||||
|
pub(crate) is_file: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Metadata {
|
||||||
|
pub fn is_file(&self) -> bool {
|
||||||
|
self.is_file
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_dir(&self) -> bool {
|
||||||
|
!self.is_file
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Represents an event that a filesystem can raise that might need to be
|
||||||
|
/// handled.
|
||||||
|
#[derive(Debug)]
|
||||||
|
#[non_exhaustive]
|
||||||
|
pub enum VfsEvent {
|
||||||
|
Create(PathBuf),
|
||||||
|
Write(PathBuf),
|
||||||
|
Remove(PathBuf),
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Contains implementation details of the Vfs, wrapped by `Vfs` and `VfsLock`,
|
||||||
|
/// the public interfaces to this type.
|
||||||
|
struct VfsInner {
|
||||||
|
backend: Box<dyn VfsBackend>,
|
||||||
|
watch_enabled: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl VfsInner {
|
||||||
|
fn read<P: AsRef<Path>>(&mut self, path: P) -> io::Result<Arc<Vec<u8>>> {
|
||||||
|
let path = path.as_ref();
|
||||||
|
let contents = self.backend.read(path)?;
|
||||||
|
|
||||||
|
if self.watch_enabled {
|
||||||
|
self.backend.watch(path)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Arc::new(contents))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_to_string<P: AsRef<Path>>(&mut self, path: P) -> io::Result<Arc<String>> {
|
||||||
|
let path = path.as_ref();
|
||||||
|
let contents = self.backend.read(path)?;
|
||||||
|
|
||||||
|
if self.watch_enabled {
|
||||||
|
self.backend.watch(path)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
let contents_str = str::from_utf8(&contents).map_err(|_| {
|
||||||
|
io::Error::new(
|
||||||
|
io::ErrorKind::InvalidData,
|
||||||
|
format!("File was not valid UTF-8: {}", path.display()),
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
|
||||||
|
Ok(Arc::new(contents_str.into()))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write<P: AsRef<Path>, C: AsRef<[u8]>>(&mut self, path: P, contents: C) -> io::Result<()> {
|
||||||
|
let path = path.as_ref();
|
||||||
|
let contents = contents.as_ref();
|
||||||
|
self.backend.write(path, contents)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_dir<P: AsRef<Path>>(&mut self, path: P) -> io::Result<ReadDir> {
|
||||||
|
let path = path.as_ref();
|
||||||
|
let dir = self.backend.read_dir(path)?;
|
||||||
|
|
||||||
|
if self.watch_enabled {
|
||||||
|
self.backend.watch(path)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(dir)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove_file<P: AsRef<Path>>(&mut self, path: P) -> io::Result<()> {
|
||||||
|
let path = path.as_ref();
|
||||||
|
let _ = self.backend.unwatch(path);
|
||||||
|
self.backend.remove_file(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove_dir_all<P: AsRef<Path>>(&mut self, path: P) -> io::Result<()> {
|
||||||
|
let path = path.as_ref();
|
||||||
|
let _ = self.backend.unwatch(path);
|
||||||
|
self.backend.remove_dir_all(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn metadata<P: AsRef<Path>>(&mut self, path: P) -> io::Result<Metadata> {
|
||||||
|
let path = path.as_ref();
|
||||||
|
self.backend.metadata(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn event_receiver(&self) -> crossbeam_channel::Receiver<VfsEvent> {
|
||||||
|
self.backend.event_receiver()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn commit_event(&mut self, event: &VfsEvent) -> io::Result<()> {
|
||||||
|
if let VfsEvent::Remove(path) = event {
|
||||||
|
let _ = self.backend.unwatch(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A virtual filesystem with a configurable backend.
|
||||||
|
///
|
||||||
|
/// All operations on the Vfs take a lock on an internal backend. For performing
|
||||||
|
/// large batches of operations, it might be more performant to call `lock()`
|
||||||
|
/// and use [`VfsLock`](struct.VfsLock.html) instead.
|
||||||
|
pub struct Vfs {
|
||||||
|
inner: Mutex<VfsInner>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Vfs {
|
||||||
|
/// Creates a new `Vfs` with the default backend, `StdBackend`.
|
||||||
|
pub fn new_default() -> Self {
|
||||||
|
Self::new(StdBackend::new())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a new `Vfs` with the given backend.
|
||||||
|
pub fn new<B: VfsBackend>(backend: B) -> Self {
|
||||||
|
let lock = VfsInner {
|
||||||
|
backend: Box::new(backend),
|
||||||
|
watch_enabled: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
Self {
|
||||||
|
inner: Mutex::new(lock),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Manually lock the Vfs, useful for large batches of operations.
|
||||||
|
pub fn lock(&self) -> VfsLock<'_> {
|
||||||
|
VfsLock {
|
||||||
|
inner: self.inner.lock().unwrap(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Turns automatic file watching on or off. Enabled by default.
|
||||||
|
///
|
||||||
|
/// Turning off file watching may be useful for single-use cases, especially
|
||||||
|
/// on platforms like macOS where registering file watches has significant
|
||||||
|
/// performance cost.
|
||||||
|
pub fn set_watch_enabled(&self, enabled: bool) {
|
||||||
|
let mut inner = self.inner.lock().unwrap();
|
||||||
|
inner.watch_enabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Read a file from the VFS, or the underlying backend if it isn't
|
||||||
|
/// resident.
|
||||||
|
///
|
||||||
|
/// Roughly equivalent to [`std::fs::read`][std::fs::read].
|
||||||
|
///
|
||||||
|
/// [std::fs::read]: https://doc.rust-lang.org/stable/std/fs/fn.read.html
|
||||||
|
#[inline]
|
||||||
|
pub fn read<P: AsRef<Path>>(&self, path: P) -> io::Result<Arc<Vec<u8>>> {
|
||||||
|
let path = path.as_ref();
|
||||||
|
self.inner.lock().unwrap().read(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Read a file from the VFS (or from the underlying backend if it isn't
|
||||||
|
/// resident) into a string.
|
||||||
|
///
|
||||||
|
/// Roughly equivalent to [`std::fs::read_to_string`][std::fs::read_to_string].
|
||||||
|
///
|
||||||
|
/// [std::fs::read_to_string]: https://doc.rust-lang.org/stable/std/fs/fn.read_to_string.html
|
||||||
|
#[inline]
|
||||||
|
pub fn read_to_string<P: AsRef<Path>>(&self, path: P) -> io::Result<Arc<String>> {
|
||||||
|
let path = path.as_ref();
|
||||||
|
self.inner.lock().unwrap().read_to_string(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Read a file from the VFS (or the underlying backend if it isn't
|
||||||
|
/// resident) into a string, and normalize its line endings to LF.
|
||||||
|
///
|
||||||
|
/// Roughly equivalent to [`std::fs::read_to_string`][std::fs::read_to_string], but also performs
|
||||||
|
/// line ending normalization.
|
||||||
|
///
|
||||||
|
/// [std::fs::read_to_string]: https://doc.rust-lang.org/stable/std/fs/fn.read_to_string.html
|
||||||
|
#[inline]
|
||||||
|
pub fn read_to_string_lf_normalized<P: AsRef<Path>>(&self, path: P) -> io::Result<Arc<String>> {
|
||||||
|
let path = path.as_ref();
|
||||||
|
let contents = self.inner.lock().unwrap().read_to_string(path)?;
|
||||||
|
|
||||||
|
Ok(contents.replace("\r\n", "\n").into())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Write a file to the VFS and the underlying backend.
|
||||||
|
///
|
||||||
|
/// Roughly equivalent to [`std::fs::write`][std::fs::write].
|
||||||
|
///
|
||||||
|
/// [std::fs::write]: https://doc.rust-lang.org/stable/std/fs/fn.write.html
|
||||||
|
#[inline]
|
||||||
|
pub fn write<P: AsRef<Path>, C: AsRef<[u8]>>(&self, path: P, contents: C) -> io::Result<()> {
|
||||||
|
let path = path.as_ref();
|
||||||
|
let contents = contents.as_ref();
|
||||||
|
self.inner.lock().unwrap().write(path, contents)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Read all of the children of a directory.
|
||||||
|
///
|
||||||
|
/// Roughly equivalent to [`std::fs::read_dir`][std::fs::read_dir].
|
||||||
|
///
|
||||||
|
/// [std::fs::read_dir]: https://doc.rust-lang.org/stable/std/fs/fn.read_dir.html
|
||||||
|
#[inline]
|
||||||
|
pub fn read_dir<P: AsRef<Path>>(&self, path: P) -> io::Result<ReadDir> {
|
||||||
|
let path = path.as_ref();
|
||||||
|
self.inner.lock().unwrap().read_dir(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Remove a file.
|
||||||
|
///
|
||||||
|
/// Roughly equivalent to [`std::fs::remove_file`][std::fs::remove_file].
|
||||||
|
///
|
||||||
|
/// [std::fs::remove_file]: https://doc.rust-lang.org/stable/std/fs/fn.remove_file.html
|
||||||
|
#[inline]
|
||||||
|
pub fn remove_file<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {
|
||||||
|
let path = path.as_ref();
|
||||||
|
self.inner.lock().unwrap().remove_file(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Remove a directory and all of its descendants.
|
||||||
|
///
|
||||||
|
/// Roughly equivalent to [`std::fs::remove_dir_all`][std::fs::remove_dir_all].
|
||||||
|
///
|
||||||
|
/// [std::fs::remove_dir_all]: https://doc.rust-lang.org/stable/std/fs/fn.remove_dir_all.html
|
||||||
|
#[inline]
|
||||||
|
pub fn remove_dir_all<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {
|
||||||
|
let path = path.as_ref();
|
||||||
|
self.inner.lock().unwrap().remove_dir_all(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Query metadata about the given path.
|
||||||
|
///
|
||||||
|
/// Roughly equivalent to [`std::fs::metadata`][std::fs::metadata].
|
||||||
|
///
|
||||||
|
/// [std::fs::metadata]: https://doc.rust-lang.org/stable/std/fs/fn.metadata.html
|
||||||
|
#[inline]
|
||||||
|
pub fn metadata<P: AsRef<Path>>(&self, path: P) -> io::Result<Metadata> {
|
||||||
|
let path = path.as_ref();
|
||||||
|
self.inner.lock().unwrap().metadata(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Retrieve a handle to the event receiver for this `Vfs`.
|
||||||
|
#[inline]
|
||||||
|
pub fn event_receiver(&self) -> crossbeam_channel::Receiver<VfsEvent> {
|
||||||
|
self.inner.lock().unwrap().event_receiver()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Commit an event to this `Vfs`.
|
||||||
|
#[inline]
|
||||||
|
pub fn commit_event(&self, event: &VfsEvent) -> io::Result<()> {
|
||||||
|
self.inner.lock().unwrap().commit_event(event)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A locked handle to a [`Vfs`](struct.Vfs.html), created by `Vfs::lock`.
|
||||||
|
///
|
||||||
|
/// Implements roughly the same API as [`Vfs`](struct.Vfs.html).
|
||||||
|
pub struct VfsLock<'a> {
|
||||||
|
inner: MutexGuard<'a, VfsInner>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl VfsLock<'_> {
|
||||||
|
/// Turns automatic file watching on or off. Enabled by default.
|
||||||
|
///
|
||||||
|
/// Turning off file watching may be useful for single-use cases, especially
|
||||||
|
/// on platforms like macOS where registering file watches has significant
|
||||||
|
/// performance cost.
|
||||||
|
pub fn set_watch_enabled(&mut self, enabled: bool) {
|
||||||
|
self.inner.watch_enabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Read a file from the VFS, or the underlying backend if it isn't
|
||||||
|
/// resident.
|
||||||
|
///
|
||||||
|
/// Roughly equivalent to [`std::fs::read`][std::fs::read].
|
||||||
|
///
|
||||||
|
/// [std::fs::read]: https://doc.rust-lang.org/stable/std/fs/fn.read.html
|
||||||
|
#[inline]
|
||||||
|
pub fn read<P: AsRef<Path>>(&mut self, path: P) -> io::Result<Arc<Vec<u8>>> {
|
||||||
|
let path = path.as_ref();
|
||||||
|
self.inner.read(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Write a file to the VFS and the underlying backend.
|
||||||
|
///
|
||||||
|
/// Roughly equivalent to [`std::fs::write`][std::fs::write].
|
||||||
|
///
|
||||||
|
/// [std::fs::write]: https://doc.rust-lang.org/stable/std/fs/fn.write.html
|
||||||
|
#[inline]
|
||||||
|
pub fn write<P: AsRef<Path>, C: AsRef<[u8]>>(
|
||||||
|
&mut self,
|
||||||
|
path: P,
|
||||||
|
contents: C,
|
||||||
|
) -> io::Result<()> {
|
||||||
|
let path = path.as_ref();
|
||||||
|
let contents = contents.as_ref();
|
||||||
|
self.inner.write(path, contents)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Read all of the children of a directory.
|
||||||
|
///
|
||||||
|
/// Roughly equivalent to [`std::fs::read_dir`][std::fs::read_dir].
|
||||||
|
///
|
||||||
|
/// [std::fs::read_dir]: https://doc.rust-lang.org/stable/std/fs/fn.read_dir.html
|
||||||
|
#[inline]
|
||||||
|
pub fn read_dir<P: AsRef<Path>>(&mut self, path: P) -> io::Result<ReadDir> {
|
||||||
|
let path = path.as_ref();
|
||||||
|
self.inner.read_dir(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Remove a file.
|
||||||
|
///
|
||||||
|
/// Roughly equivalent to [`std::fs::remove_file`][std::fs::remove_file].
|
||||||
|
///
|
||||||
|
/// [std::fs::remove_file]: https://doc.rust-lang.org/stable/std/fs/fn.remove_file.html
|
||||||
|
#[inline]
|
||||||
|
pub fn remove_file<P: AsRef<Path>>(&mut self, path: P) -> io::Result<()> {
|
||||||
|
let path = path.as_ref();
|
||||||
|
self.inner.remove_file(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Remove a directory and all of its descendants.
|
||||||
|
///
|
||||||
|
/// Roughly equivalent to [`std::fs::remove_dir_all`][std::fs::remove_dir_all].
|
||||||
|
///
|
||||||
|
/// [std::fs::remove_dir_all]: https://doc.rust-lang.org/stable/std/fs/fn.remove_dir_all.html
|
||||||
|
#[inline]
|
||||||
|
pub fn remove_dir_all<P: AsRef<Path>>(&mut self, path: P) -> io::Result<()> {
|
||||||
|
let path = path.as_ref();
|
||||||
|
self.inner.remove_dir_all(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Query metadata about the given path.
|
||||||
|
///
|
||||||
|
/// Roughly equivalent to [`std::fs::metadata`][std::fs::metadata].
|
||||||
|
///
|
||||||
|
/// [std::fs::metadata]: https://doc.rust-lang.org/stable/std/fs/fn.metadata.html
|
||||||
|
#[inline]
|
||||||
|
pub fn metadata<P: AsRef<Path>>(&mut self, path: P) -> io::Result<Metadata> {
|
||||||
|
let path = path.as_ref();
|
||||||
|
self.inner.metadata(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Retrieve a handle to the event receiver for this `Vfs`.
|
||||||
|
#[inline]
|
||||||
|
pub fn event_receiver(&self) -> crossbeam_channel::Receiver<VfsEvent> {
|
||||||
|
self.inner.event_receiver()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Commit an event to this `Vfs`.
|
||||||
|
#[inline]
|
||||||
|
pub fn commit_event(&mut self, event: &VfsEvent) -> io::Result<()> {
|
||||||
|
self.inner.commit_event(event)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use crate::{InMemoryFs, Vfs, VfsSnapshot};
|
||||||
|
|
||||||
|
/// https://github.com/rojo-rbx/rojo/issues/899
|
||||||
|
#[test]
|
||||||
|
fn read_to_string_lf_normalized_keeps_trailing_newline() {
|
||||||
|
let mut imfs = InMemoryFs::new();
|
||||||
|
imfs.load_snapshot("test", VfsSnapshot::file("bar\r\nfoo\r\n\r\n"))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let vfs = Vfs::new(imfs);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
vfs.read_to_string_lf_normalized("test").unwrap().as_str(),
|
||||||
|
"bar\nfoo\n\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
82
crates/memofs/src/noop_backend.rs
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
use std::io;
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
use crate::{Metadata, ReadDir, VfsBackend, VfsEvent};
|
||||||
|
|
||||||
|
/// `VfsBackend` that returns an error on every operation.
|
||||||
|
#[non_exhaustive]
|
||||||
|
pub struct NoopBackend;
|
||||||
|
|
||||||
|
impl NoopBackend {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl VfsBackend for NoopBackend {
|
||||||
|
fn read(&mut self, _path: &Path) -> io::Result<Vec<u8>> {
|
||||||
|
Err(io::Error::new(
|
||||||
|
io::ErrorKind::Other,
|
||||||
|
"NoopBackend doesn't do anything",
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write(&mut self, _path: &Path, _data: &[u8]) -> io::Result<()> {
|
||||||
|
Err(io::Error::new(
|
||||||
|
io::ErrorKind::Other,
|
||||||
|
"NoopBackend doesn't do anything",
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_dir(&mut self, _path: &Path) -> io::Result<ReadDir> {
|
||||||
|
Err(io::Error::new(
|
||||||
|
io::ErrorKind::Other,
|
||||||
|
"NoopBackend doesn't do anything",
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove_file(&mut self, _path: &Path) -> io::Result<()> {
|
||||||
|
Err(io::Error::new(
|
||||||
|
io::ErrorKind::Other,
|
||||||
|
"NoopBackend doesn't do anything",
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove_dir_all(&mut self, _path: &Path) -> io::Result<()> {
|
||||||
|
Err(io::Error::new(
|
||||||
|
io::ErrorKind::Other,
|
||||||
|
"NoopBackend doesn't do anything",
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn metadata(&mut self, _path: &Path) -> io::Result<Metadata> {
|
||||||
|
Err(io::Error::new(
|
||||||
|
io::ErrorKind::Other,
|
||||||
|
"NoopBackend doesn't do anything",
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn event_receiver(&self) -> crossbeam_channel::Receiver<VfsEvent> {
|
||||||
|
crossbeam_channel::never()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn watch(&mut self, _path: &Path) -> io::Result<()> {
|
||||||
|
Err(io::Error::new(
|
||||||
|
io::ErrorKind::Other,
|
||||||
|
"NoopBackend doesn't do anything",
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unwatch(&mut self, _path: &Path) -> io::Result<()> {
|
||||||
|
Err(io::Error::new(
|
||||||
|
io::ErrorKind::Other,
|
||||||
|
"NoopBackend doesn't do anything",
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for NoopBackend {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
45
crates/memofs/src/snapshot.rs
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
|
/// A slice of a tree of files. Can be loaded into an
|
||||||
|
/// [`InMemoryFs`](struct.InMemoryFs.html).
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
#[non_exhaustive]
|
||||||
|
pub enum VfsSnapshot {
|
||||||
|
File {
|
||||||
|
contents: Vec<u8>,
|
||||||
|
},
|
||||||
|
|
||||||
|
Dir {
|
||||||
|
children: BTreeMap<String, VfsSnapshot>,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
impl VfsSnapshot {
|
||||||
|
pub fn file<C: Into<Vec<u8>>>(contents: C) -> Self {
|
||||||
|
Self::File {
|
||||||
|
contents: contents.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn dir<K: Into<String>, I: IntoIterator<Item = (K, VfsSnapshot)>>(children: I) -> Self {
|
||||||
|
Self::Dir {
|
||||||
|
children: children
|
||||||
|
.into_iter()
|
||||||
|
.map(|(key, value)| (key.into(), value))
|
||||||
|
.collect(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn empty_file() -> Self {
|
||||||
|
Self::File {
|
||||||
|
contents: Vec::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn empty_dir() -> Self {
|
||||||
|
Self::Dir {
|
||||||
|
children: BTreeMap::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
128
crates/memofs/src/std_backend.rs
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
use std::sync::mpsc;
|
||||||
|
use std::thread;
|
||||||
|
use std::time::Duration;
|
||||||
|
use std::{collections::HashSet, io};
|
||||||
|
|
||||||
|
use crossbeam_channel::Receiver;
|
||||||
|
use notify::{watcher, DebouncedEvent, RecommendedWatcher, RecursiveMode, Watcher};
|
||||||
|
|
||||||
|
use crate::{DirEntry, Metadata, ReadDir, VfsBackend, VfsEvent};
|
||||||
|
|
||||||
|
/// `VfsBackend` that uses `std::fs` and the `notify` crate.
|
||||||
|
pub struct StdBackend {
|
||||||
|
watcher: RecommendedWatcher,
|
||||||
|
watcher_receiver: Receiver<VfsEvent>,
|
||||||
|
watches: HashSet<PathBuf>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl StdBackend {
|
||||||
|
pub fn new() -> StdBackend {
|
||||||
|
let (notify_tx, notify_rx) = mpsc::channel();
|
||||||
|
let watcher = watcher(notify_tx, Duration::from_millis(50)).unwrap();
|
||||||
|
|
||||||
|
let (tx, rx) = crossbeam_channel::unbounded();
|
||||||
|
|
||||||
|
thread::spawn(move || {
|
||||||
|
for event in notify_rx {
|
||||||
|
match event {
|
||||||
|
DebouncedEvent::Create(path) => {
|
||||||
|
tx.send(VfsEvent::Create(path))?;
|
||||||
|
}
|
||||||
|
DebouncedEvent::Write(path) => {
|
||||||
|
tx.send(VfsEvent::Write(path))?;
|
||||||
|
}
|
||||||
|
DebouncedEvent::Remove(path) => {
|
||||||
|
tx.send(VfsEvent::Remove(path))?;
|
||||||
|
}
|
||||||
|
DebouncedEvent::Rename(from, to) => {
|
||||||
|
tx.send(VfsEvent::Remove(from))?;
|
||||||
|
tx.send(VfsEvent::Create(to))?;
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Result::<(), crossbeam_channel::SendError<VfsEvent>>::Ok(())
|
||||||
|
});
|
||||||
|
|
||||||
|
Self {
|
||||||
|
watcher,
|
||||||
|
watcher_receiver: rx,
|
||||||
|
watches: HashSet::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl VfsBackend for StdBackend {
|
||||||
|
fn read(&mut self, path: &Path) -> io::Result<Vec<u8>> {
|
||||||
|
fs_err::read(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write(&mut self, path: &Path, data: &[u8]) -> io::Result<()> {
|
||||||
|
fs_err::write(path, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_dir(&mut self, path: &Path) -> io::Result<ReadDir> {
|
||||||
|
let entries: Result<Vec<_>, _> = fs_err::read_dir(path)?.collect();
|
||||||
|
let mut entries = entries?;
|
||||||
|
|
||||||
|
entries.sort_by_cached_key(|entry| entry.file_name());
|
||||||
|
|
||||||
|
let inner = entries
|
||||||
|
.into_iter()
|
||||||
|
.map(|entry| Ok(DirEntry { path: entry.path() }));
|
||||||
|
|
||||||
|
Ok(ReadDir {
|
||||||
|
inner: Box::new(inner),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove_file(&mut self, path: &Path) -> io::Result<()> {
|
||||||
|
fs_err::remove_file(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove_dir_all(&mut self, path: &Path) -> io::Result<()> {
|
||||||
|
fs_err::remove_dir_all(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn metadata(&mut self, path: &Path) -> io::Result<Metadata> {
|
||||||
|
let inner = fs_err::metadata(path)?;
|
||||||
|
|
||||||
|
Ok(Metadata {
|
||||||
|
is_file: inner.is_file(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn event_receiver(&self) -> crossbeam_channel::Receiver<VfsEvent> {
|
||||||
|
self.watcher_receiver.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn watch(&mut self, path: &Path) -> io::Result<()> {
|
||||||
|
if self.watches.contains(path)
|
||||||
|
|| path
|
||||||
|
.ancestors()
|
||||||
|
.any(|ancestor| self.watches.contains(ancestor))
|
||||||
|
{
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
self.watches.insert(path.to_path_buf());
|
||||||
|
self.watcher
|
||||||
|
.watch(path, RecursiveMode::Recursive)
|
||||||
|
.map_err(|inner| io::Error::new(io::ErrorKind::Other, inner))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unwatch(&mut self, path: &Path) -> io::Result<()> {
|
||||||
|
self.watches.remove(path);
|
||||||
|
self.watcher
|
||||||
|
.unwatch(path)
|
||||||
|
.map_err(|inner| io::Error::new(io::ErrorKind::Other, inner))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for StdBackend {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
10
crates/rojo-insta-ext/Cargo.toml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
[package]
|
||||||
|
name = "rojo-insta-ext"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Lucien Greathouse <me@lpghatguy.com>"]
|
||||||
|
edition = "2018"
|
||||||
|
publish = false
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
serde = "1.0.197"
|
||||||
|
serde_yaml = "0.8.26"
|
||||||
2
crates/rojo-insta-ext/README.md
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
# Rojo Insta Extensions
|
||||||
|
This crate has add-ons intended for use with Insta that are useful for snapshot tests.
|
||||||
3
crates/rojo-insta-ext/src/lib.rs
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
mod redaction_map;
|
||||||
|
|
||||||
|
pub use redaction_map::*;
|
||||||
85
crates/rojo-insta-ext/src/redaction_map.rs
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
|
/// Enables redacting any value that serializes as a string.
|
||||||
|
///
|
||||||
|
/// Used for transforming Rojo instance IDs into something deterministic.
|
||||||
|
pub struct RedactionMap {
|
||||||
|
ids: HashMap<String, usize>,
|
||||||
|
last_id: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RedactionMap {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
ids: HashMap::new(),
|
||||||
|
last_id: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_redacted_value(&self, id: impl ToString) -> Option<String> {
|
||||||
|
let id = id.to_string();
|
||||||
|
|
||||||
|
if self.ids.contains_key(&id) {
|
||||||
|
Some(id)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn intern(&mut self, id: impl ToString) {
|
||||||
|
let last_id = &mut self.last_id;
|
||||||
|
|
||||||
|
self.ids.entry(id.to_string()).or_insert_with(|| {
|
||||||
|
*last_id += 1;
|
||||||
|
*last_id
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn intern_iter<S: ToString>(&mut self, ids: impl Iterator<Item = S>) {
|
||||||
|
for id in ids {
|
||||||
|
self.intern(id.to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn redacted_yaml(&self, value: impl Serialize) -> serde_yaml::Value {
|
||||||
|
let mut encoded = serde_yaml::to_value(value).expect("Couldn't encode value as YAML");
|
||||||
|
|
||||||
|
self.redact(&mut encoded);
|
||||||
|
encoded
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn redact(&self, yaml_value: &mut serde_yaml::Value) {
|
||||||
|
use serde_yaml::{Mapping, Value};
|
||||||
|
|
||||||
|
match yaml_value {
|
||||||
|
Value::String(value) => {
|
||||||
|
if let Some(redacted) = self.ids.get(value) {
|
||||||
|
*yaml_value = Value::String(format!("id-{}", *redacted));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Value::Sequence(sequence) => {
|
||||||
|
for value in sequence {
|
||||||
|
self.redact(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Value::Mapping(mapping) => {
|
||||||
|
// We can't mutate the keys of a map in-place, so we take
|
||||||
|
// ownership of the map and rebuild it.
|
||||||
|
|
||||||
|
let owned_map = std::mem::replace(mapping, Mapping::new());
|
||||||
|
let mut new_map = Mapping::with_capacity(owned_map.len());
|
||||||
|
|
||||||
|
for (mut key, mut value) in owned_map {
|
||||||
|
self.redact(&mut key);
|
||||||
|
self.redact(&mut value);
|
||||||
|
new_map.insert(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
*mapping = new_map;
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
.md-typeset__table {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.feature-image img {
|
|
||||||
border: 1px solid rgba(0, 0, 0, 0.2);
|
|
||||||
box-shadow: 1px 1px 4px rgba(0, 0, 0, 0.2);
|
|
||||||
}
|
|
||||||
|
|
||||||
.codehilite {
|
|
||||||
border: 1px solid rgba(0, 0, 0, 0.2);
|
|
||||||
box-shadow: 1px 1px 4px rgba(0, 0, 0, 0.2);
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
**This page is under construction!**
|
|
||||||
|
|
||||||
## Summary
|
|
||||||
* Tools to port existing games are in progress!
|
|
||||||
* [rbxlx-to-rojo](https://github.com/rojo/rbxlx-to-rojo)
|
|
||||||
* `rojo export` ([issue #208](https://github.com/rojo-rbx/rojo/issues/208))
|
|
||||||
* Can port as much or as little of your game as you like
|
|
||||||
* Rojo can manage just a slice of your game!
|
|
||||||
* Some Roblox idioms aren't very well supported
|
|
||||||
* Redundant copies of scripts don't work well with files
|
|
||||||
* Having only a couple places with scripts simplifies your project dramatically!
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
This is this installation guide for Rojo **0.5.x**.
|
|
||||||
|
|
||||||
[TOC]
|
|
||||||
|
|
||||||
## Overview
|
|
||||||
Rojo has two components:
|
|
||||||
|
|
||||||
* The command line interface (CLI)
|
|
||||||
* The Roblox Studio plugin
|
|
||||||
|
|
||||||
!!! info
|
|
||||||
It's important that your installed version of the plugin and CLI are compatible.
|
|
||||||
|
|
||||||
The plugin will show errors in the Roblox Studio output window if there is a version mismatch.
|
|
||||||
|
|
||||||
## Visual Studio Code Extension
|
|
||||||
If you use Visual Studio Code, you can install [the Rojo VS Code extension](https://marketplace.visualstudio.com/items?itemName=evaera.vscode-rojo), which will install both halves of Rojo for you. It even has a nifty UI to sync files and start/stop the Rojo server!
|
|
||||||
|
|
||||||
## Installing the CLI
|
|
||||||
|
|
||||||
### Installing from GitHub
|
|
||||||
If you're on Windows, there are pre-built binaries available from Rojo's [GitHub Releases page](https://github.com/LPGhatguy/rojo/releases).
|
|
||||||
|
|
||||||
The Rojo CLI must be run from the command line, like Terminal.app on MacOS or `cmd.exe` on Windows. It's recommended that you put the Rojo CLI executable on your `PATH` to make this easier.
|
|
||||||
|
|
||||||
### Installing from Cargo
|
|
||||||
If you have Rust installed, the easiest way to get Rojo is with Cargo!
|
|
||||||
|
|
||||||
To install the latest 0.5.0 alpha, use:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
cargo install rojo --version 0.5.0-alpha.12
|
|
||||||
```
|
|
||||||
|
|
||||||
## Installing the Plugin
|
|
||||||
|
|
||||||
### Installing from GitHub
|
|
||||||
The Rojo Roblox Studio plugin is available from Rojo's [GitHub Releases page](https://github.com/LPGhatguy/rojo/releases).
|
|
||||||
|
|
||||||
Download the attached `rbxm` file and put it into your Roblox Studio plugins folder. You can find that folder by pressing **Plugins Folder** from your Plugins toolbar in Roblox Studio:
|
|
||||||
|
|
||||||

|
|
||||||
{: align="center" }
|
|
||||||
|
|
||||||
### Installing from Roblox.com
|
|
||||||
Visit [Rojo's Roblox.com Plugin page](https://www.roblox.com/library/1997686364/Rojo-0-5-0-alpha-3) in Roblox Studio and press **Install**.
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
Rojo underwent a large refactor during most of 2018 to enable a bunch of new features and lay groundwork for lots more in 2019. As such, Rojo **0.5.x** projects are not compatible with Rojo **0.4.x** projects.
|
|
||||||
|
|
||||||
[TOC]
|
|
||||||
|
|
||||||
## Supporting Both 0.4.x and 0.5.x
|
|
||||||
Rojo 0.5.x uses a different name for its project format. While 0.4.x used `rojo.json`, 0.5.x uses `default.project.json`, which allows them to coexist.
|
|
||||||
|
|
||||||
If you aren't sure about upgrading or want to upgrade gradually, it's possible to keep both files in the same project without causing problems.
|
|
||||||
|
|
||||||
## Upgrading Your Project File
|
|
||||||
Project files in 0.5.x are more explicit and flexible than they were in 0.4.x. Project files can now describe models and plugins in addition to places.
|
|
||||||
|
|
||||||
This new project file format also guards against two of the biggest pitfalls when writing a config file:
|
|
||||||
|
|
||||||
* Using a service as a partition target directly, which often wiped away extra instances
|
|
||||||
* Defining two partitions that overlapped, which made Rojo act unpredictably
|
|
||||||
|
|
||||||
The biggest change is that the `partitions` field has been replaced with a new field, `tree`, that describes the entire hierarchy of your project from the top-down.
|
|
||||||
|
|
||||||
A project for 0.4.x that syncs from the `src` directory into `ReplicatedStorage.Source` would look like this:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"name": "Rojo 0.4.x Example",
|
|
||||||
"partitions": {
|
|
||||||
"path": "src",
|
|
||||||
"target": "ReplicatedStorage.Source"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
In 0.5.x, the project format is more explicit:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"name": "Rojo 0.5.x Example",
|
|
||||||
"tree": {
|
|
||||||
"$className": "DataModel",
|
|
||||||
"ReplicatedStorage": {
|
|
||||||
"$className": "ReplicatedStorage",
|
|
||||||
"Source": {
|
|
||||||
"$path": "src"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
For each object in the tree, we define *metadata* and *children*.
|
|
||||||
|
|
||||||
Metadata begins with a dollar sign (`$`), like `$className`. This is so that children and metadata can coexist without creating too many nested layers.
|
|
||||||
|
|
||||||
All other values are considered children, where the key is the instance's name, and the value is an object, repeating the process.
|
|
||||||
|
|
||||||
## Migrating Unknown Files
|
|
||||||
If you used Rojo to sync in files as `StringValue` objects, you'll need to make sure those files end with the `txt` extension to preserve this in Rojo 0.5.x.
|
|
||||||
|
|
||||||
Unknown files are now ignored in Rojo instead of being converted to `StringValue` objects.
|
|
||||||
|
|
||||||
## Migrating `init.model.json` files
|
|
||||||
In Rojo 0.4.x, it's possible to create a file named `init.model.json` that lets you describe a model that becomes the container for all of the other files in the folder, just like `init.lua`.
|
|
||||||
|
|
||||||
In Rojo 0.5.x, this feature has been replaced with `init.meta.json` files. See [Sync Details](../reference/sync-details) for more information about these new files.
|
|
||||||
@@ -1,90 +0,0 @@
|
|||||||
[TOC]
|
|
||||||
|
|
||||||
## Creating the Rojo Project
|
|
||||||
To use Rojo to build a game, you'll need to create a new project file, which tells Rojo how to turn your files into a Roblox place.
|
|
||||||
|
|
||||||
First, create a new folder to contain the files for your game and open up a new terminal inside of it, like cmd.exe or Bash.
|
|
||||||
|
|
||||||
It's convenient to make the folder from the command line:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
mkdir my-new-project
|
|
||||||
cd my-new-project
|
|
||||||
```
|
|
||||||
|
|
||||||
Inside the folder, initialize a new Rojo project:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
rojo init
|
|
||||||
```
|
|
||||||
|
|
||||||
Rojo will make a small project file in your directory, named `default.project.json`. It matches the "Baseplate" template from Roblox Studio, except that it'll take any files you put in a folder called `src` and put it into `ReplicatedStorage.Source`.
|
|
||||||
|
|
||||||
Speaking of files, make sure to create a directory named `src` in this folder, or Rojo will be upset about missing files!
|
|
||||||
|
|
||||||
```sh
|
|
||||||
mkdir src
|
|
||||||
```
|
|
||||||
|
|
||||||
Let's also add a Lua file, `hello.lua` to the `src` folder, so that we can make this project our own.
|
|
||||||
|
|
||||||
```sh
|
|
||||||
echo 'return "Hello, Rojo!"' > src/hello.lua
|
|
||||||
```
|
|
||||||
|
|
||||||
## Building Your Place
|
|
||||||
Now that we have a project, one thing we can do is build a Roblox place file for our project. This is a great way to get started with a project quickly with no fuss.
|
|
||||||
|
|
||||||
All we have to do is call `rojo build`:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
rojo build -o MyNewProject.rbxlx
|
|
||||||
```
|
|
||||||
|
|
||||||
If you open `MyNewProject.rbxlx` in Roblox Studio now, you should see a `Folder` containing a `ModuleScript` under `ReplicatedStorage`!
|
|
||||||
|
|
||||||
!!! info
|
|
||||||
To generate a binary place file instead, use `rbxl`. Note that support for binary model/place files (`rbxm` and `rbxl`) is very limited in Rojo presently.
|
|
||||||
|
|
||||||
## Live-Syncing into Studio
|
|
||||||
Building a place file is great for starting to work on a game, but for active iteration, you'll want something faster.
|
|
||||||
|
|
||||||
In Roblox Studio, make sure the Rojo plugin is installed. If you need it, check out [the installation guide](installation) to learn how to install it.
|
|
||||||
|
|
||||||
To expose your project to the plugin, you'll need to start a new **live sync session** from the command line:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
rojo serve
|
|
||||||
```
|
|
||||||
|
|
||||||
You should see output like this in your terminal:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
$ rojo serve
|
|
||||||
Rojo server listening on port 34872
|
|
||||||
```
|
|
||||||
|
|
||||||
Switch into Roblox Studio and press the **Connect** button on the Rojo plugin toolbar. A dialog should appear:
|
|
||||||
|
|
||||||

|
|
||||||
{: class="feature-image" align="center" }
|
|
||||||
|
|
||||||
If the port number doesn't match the output from the command line, change it, and then press **Connect**.
|
|
||||||
|
|
||||||
If all went well, you should now be able to change files in the `src` directory and watch them sync into Roblox Studio in real time!
|
|
||||||
|
|
||||||
## Uploading Your Place
|
|
||||||
Aimed at teams that want serious levels of automation, Rojo can upload places to Roblox.com automatically.
|
|
||||||
|
|
||||||
You'll need an existing game on Roblox.com as well as the `.ROBLOSECURITY` cookie of an account that has write access to that game.
|
|
||||||
|
|
||||||
!!! warning
|
|
||||||
It's recommended that you set up a Roblox account dedicated to deploying your game instead of your personal account in case your security cookie is compromised.
|
|
||||||
|
|
||||||
Generating and publishing your game is as simple as:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
rojo upload --asset_id [PLACE ID] --cookie "[SECURITY COOKIE]"
|
|
||||||
```
|
|
||||||
|
|
||||||
An example project is available on GitHub that deploys to Roblox.com from GitHub and Travis-CI automatically: [https://github.com/LPGhatguy/roads](https://github.com/LPGhatguy/roads)
|
|
||||||
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 19 KiB |
@@ -1,17 +0,0 @@
|
|||||||
digraph "Sync Files" {
|
|
||||||
graph [
|
|
||||||
ranksep = "0.7",
|
|
||||||
nodesep = "0.5",
|
|
||||||
];
|
|
||||||
node [
|
|
||||||
fontname = "monospace",
|
|
||||||
shape = "record",
|
|
||||||
];
|
|
||||||
|
|
||||||
my_model [label = "MyModel"]
|
|
||||||
init_server [label = "init.server.lua"]
|
|
||||||
foo [label = "foo.lua"]
|
|
||||||
|
|
||||||
my_model -> init_server
|
|
||||||
my_model -> foo
|
|
||||||
}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
|
||||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
|
||||||
<!-- Generated by graphviz version 2.38.0 (20140413.2041)
|
|
||||||
-->
|
|
||||||
<!-- Title: Sync Files Pages: 1 -->
|
|
||||||
<svg width="258pt" height="132pt"
|
|
||||||
viewBox="0.00 0.00 258.00 132.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
||||||
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 128)">
|
|
||||||
<title>Sync Files</title>
|
|
||||||
<polygon fill="white" stroke="none" points="-4,4 -4,-128 254,-128 254,4 -4,4"/>
|
|
||||||
<!-- my_model -->
|
|
||||||
<g id="node1" class="node"><title>my_model</title>
|
|
||||||
<polygon fill="none" stroke="black" points="104,-87.5 104,-123.5 178,-123.5 178,-87.5 104,-87.5"/>
|
|
||||||
<text text-anchor="middle" x="141" y="-101.8" font-family="monospace" font-size="14.00">MyModel</text>
|
|
||||||
</g>
|
|
||||||
<!-- init_server -->
|
|
||||||
<g id="node2" class="node"><title>init_server</title>
|
|
||||||
<polygon fill="none" stroke="black" points="0,-0.5 0,-36.5 140,-36.5 140,-0.5 0,-0.5"/>
|
|
||||||
<text text-anchor="middle" x="70" y="-14.8" font-family="monospace" font-size="14.00">init.server.lua</text>
|
|
||||||
</g>
|
|
||||||
<!-- my_model->init_server -->
|
|
||||||
<g id="edge1" class="edge"><title>my_model->init_server</title>
|
|
||||||
<path fill="none" stroke="black" d="M126.632,-87.299C116.335,-74.9713 102.308,-58.1787 90.7907,-44.3902"/>
|
|
||||||
<polygon fill="black" stroke="black" points="93.4435,-42.1065 84.3465,-36.6754 88.0711,-46.594 93.4435,-42.1065"/>
|
|
||||||
</g>
|
|
||||||
<!-- foo -->
|
|
||||||
<g id="node3" class="node"><title>foo</title>
|
|
||||||
<polygon fill="none" stroke="black" points="176,-0.5 176,-36.5 250,-36.5 250,-0.5 176,-0.5"/>
|
|
||||||
<text text-anchor="middle" x="213" y="-14.8" font-family="monospace" font-size="14.00">foo.lua</text>
|
|
||||||
</g>
|
|
||||||
<!-- my_model->foo -->
|
|
||||||
<g id="edge2" class="edge"><title>my_model->foo</title>
|
|
||||||
<path fill="none" stroke="black" d="M155.57,-87.299C166.013,-74.9713 180.237,-58.1787 191.917,-44.3902"/>
|
|
||||||
<polygon fill="black" stroke="black" points="194.659,-46.5681 198.451,-36.6754 189.317,-42.0437 194.659,-46.5681"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 2.0 KiB |
@@ -1,15 +0,0 @@
|
|||||||
digraph "Sync Files" {
|
|
||||||
graph [
|
|
||||||
ranksep = "0.7",
|
|
||||||
nodesep = "0.5",
|
|
||||||
];
|
|
||||||
node [
|
|
||||||
fontname = "monospace",
|
|
||||||
shape = "record",
|
|
||||||
];
|
|
||||||
|
|
||||||
my_model [label = "MyModel (Script)"]
|
|
||||||
foo [label = "foo (ModuleScript)"]
|
|
||||||
|
|
||||||
my_model -> foo
|
|
||||||
}
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
|
||||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
|
||||||
<!-- Generated by graphviz version 2.38.0 (20140413.2041)
|
|
||||||
-->
|
|
||||||
<!-- Title: Sync Files Pages: 1 -->
|
|
||||||
<svg width="173pt" height="132pt"
|
|
||||||
viewBox="0.00 0.00 173.00 132.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
||||||
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 128)">
|
|
||||||
<title>Sync Files</title>
|
|
||||||
<polygon fill="white" stroke="none" points="-4,4 -4,-128 169,-128 169,4 -4,4"/>
|
|
||||||
<!-- my_model -->
|
|
||||||
<g id="node1" class="node"><title>my_model</title>
|
|
||||||
<polygon fill="none" stroke="black" points="8,-87.5 8,-123.5 157,-123.5 157,-87.5 8,-87.5"/>
|
|
||||||
<text text-anchor="middle" x="82.5" y="-101.8" font-family="monospace" font-size="14.00">MyModel (Script)</text>
|
|
||||||
</g>
|
|
||||||
<!-- foo -->
|
|
||||||
<g id="node2" class="node"><title>foo</title>
|
|
||||||
<polygon fill="none" stroke="black" points="0,-0.5 0,-36.5 165,-36.5 165,-0.5 0,-0.5"/>
|
|
||||||
<text text-anchor="middle" x="82.5" y="-14.8" font-family="monospace" font-size="14.00">foo (ModuleScript)</text>
|
|
||||||
</g>
|
|
||||||
<!-- my_model->foo -->
|
|
||||||
<g id="edge1" class="edge"><title>my_model->foo</title>
|
|
||||||
<path fill="none" stroke="black" d="M82.5,-87.299C82.5,-75.6626 82.5,-60.0479 82.5,-46.7368"/>
|
|
||||||
<polygon fill="black" stroke="black" points="86.0001,-46.6754 82.5,-36.6754 79.0001,-46.6755 86.0001,-46.6754"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.4 KiB |
@@ -1,17 +0,0 @@
|
|||||||
digraph "Sync Files" {
|
|
||||||
graph [
|
|
||||||
ranksep = "0.7",
|
|
||||||
nodesep = "0.5",
|
|
||||||
];
|
|
||||||
node [
|
|
||||||
fontname = "monospace",
|
|
||||||
shape = "record",
|
|
||||||
];
|
|
||||||
|
|
||||||
model [label = "My Cool Model (Folder)"]
|
|
||||||
root_part [label = "RootPart (Part)"]
|
|
||||||
send_money [label = "SendMoney (RemoteEvent)"]
|
|
||||||
|
|
||||||
model -> root_part
|
|
||||||
model -> send_money
|
|
||||||
}
|
|
||||||