forked from rojo-rbx/rojo
Compare commits
17 Commits
v0.5.0-alp
...
v0.5.0-alp
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
459673bd59 | ||
|
|
2968b70e6b | ||
|
|
b6989a18fc | ||
|
|
4d6a504836 | ||
|
|
6c3737df68 | ||
|
|
9f382ed9bd | ||
|
|
f9e86e58d6 | ||
|
|
469f9c927f | ||
|
|
312724189b | ||
|
|
ec0a1f1ce4 | ||
|
|
ad93631ef8 | ||
|
|
3b6238ff93 | ||
|
|
5b9facee00 | ||
|
|
376f2a554a | ||
|
|
5fd0bd3db9 | ||
|
|
2deb3bbf23 | ||
|
|
01bef0c2b8 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -2,4 +2,4 @@
|
||||
/target
|
||||
/scratch-project
|
||||
**/*.rs.bk
|
||||
/generate-docs.run
|
||||
/server/failed-snapshots/
|
||||
9
.gitmodules
vendored
9
.gitmodules
vendored
@@ -1,12 +1,6 @@
|
||||
[submodule "plugin/modules/roact"]
|
||||
path = plugin/modules/roact
|
||||
url = https://github.com/Roblox/roact.git
|
||||
[submodule "plugin/modules/rodux"]
|
||||
path = plugin/modules/rodux
|
||||
url = https://github.com/Roblox/rodux.git
|
||||
[submodule "plugin/modules/roact-rodux"]
|
||||
path = plugin/modules/roact-rodux
|
||||
url = https://github.com/Roblox/roact-rodux.git
|
||||
[submodule "plugin/modules/testez"]
|
||||
path = plugin/modules/testez
|
||||
url = https://github.com/Roblox/testez.git
|
||||
@@ -16,3 +10,6 @@
|
||||
[submodule "plugin/modules/promise"]
|
||||
path = plugin/modules/promise
|
||||
url = https://github.com/LPGhatguy/roblox-lua-promise.git
|
||||
[submodule "plugin/modules/t"]
|
||||
path = plugin/modules/t
|
||||
url = https://github.com/osyrisrblx/t.git
|
||||
10
CHANGELOG.md
10
CHANGELOG.md
@@ -2,6 +2,16 @@
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [0.5.0 Alpha 6](https://github.com/LPGhatguy/rojo/releases/tag/v0.5.0-alpha.6) (March 19, 2019)
|
||||
* Fixed `rojo init` giving unexpected results by upgrading to `rbx_dom_weak` 1.1.0
|
||||
* Fixed live server not responding when the Rojo plugin is connected ([#133](https://github.com/LPGhatguy/rojo/issues/133))
|
||||
* Updated default place file:
|
||||
* Improved default properties to be closer to Studio's built-in 'Baseplate' template
|
||||
* Added a baseplate to the project file (Thanks, [@AmaranthineCodices](https://github.com/AmaranthineCodices/)!)
|
||||
* Added more type support to Rojo plugin
|
||||
* Fixed some cases where the Rojo plugin would leave around objects that it knows should be deleted
|
||||
* Updated plugin to correctly listen to `Plugin.Unloading` when installing or uninstalling new plugins
|
||||
|
||||
## [0.5.0 Alpha 5](https://github.com/LPGhatguy/rojo/releases/tag/v0.5.0-alpha.5) (March 1, 2019)
|
||||
* Upgraded core dependencies, which improves compatibility for lots of instance types
|
||||
* Upgraded from `rbx_tree` 0.2.0 to `rbx_dom_weak` 1.0.0
|
||||
|
||||
331
Cargo.lock
generated
331
Cargo.lock
generated
@@ -3,7 +3,7 @@ name = "MacTypes-sys"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -40,7 +40,7 @@ name = "atty"
|
||||
version = "0.2.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@@ -57,8 +57,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-demangle 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@@ -69,7 +69,7 @@ version = "0.1.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cc 1.0.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -102,7 +102,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "0.4.11"
|
||||
version = "0.4.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -128,7 +128,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "0.1.6"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
@@ -159,7 +159,7 @@ version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"core-foundation-sys 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -167,44 +167,20 @@ name = "core-foundation-sys"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
version = "1.1.2"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"crossbeam-deque 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"crossbeam-epoch 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-channel"
|
||||
version = "0.3.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-deque"
|
||||
version = "0.6.3"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"crossbeam-epoch 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -217,19 +193,27 @@ version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-queue"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.6.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@@ -250,6 +234,15 @@ dependencies = [
|
||||
"memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ctor"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "difference"
|
||||
version = "2.0.0"
|
||||
@@ -265,12 +258,12 @@ name = "encoding_rs"
|
||||
version = "0.8.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "env_logger"
|
||||
version = "0.6.0"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -304,7 +297,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@@ -313,8 +306,8 @@ name = "filetime"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@@ -343,7 +336,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fsevent-sys 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -351,7 +344,7 @@ name = "fsevent-sys"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -398,7 +391,7 @@ version = "0.1.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"http 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -406,7 +399,7 @@ dependencies = [
|
||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"string 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -419,7 +412,7 @@ name = "http"
|
||||
version = "0.1.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@@ -442,7 +435,7 @@ name = "hyper"
|
||||
version = "0.12.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"h2 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -454,12 +447,12 @@ dependencies = [
|
||||
"net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-reactor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-threadpool 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-threadpool 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"want 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@@ -469,11 +462,11 @@ name = "hyper-tls"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"hyper 0.12.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"native-tls 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -498,7 +491,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"inotify-sys 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -506,7 +499,7 @@ name = "inotify-sys"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -514,7 +507,7 @@ name = "iovec"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@@ -544,17 +537,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.49"
|
||||
version = "0.2.50"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "libflate"
|
||||
version = "0.1.20"
|
||||
version = "0.1.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"crc32fast 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -571,7 +564,7 @@ name = "log"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -579,7 +572,7 @@ name = "lz4"
|
||||
version = "1.23.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lz4-sys 1.8.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"skeptic 0.13.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@@ -590,7 +583,7 @@ version = "1.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cc 1.0.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -608,7 +601,7 @@ name = "memchr"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -621,7 +614,7 @@ name = "mime"
|
||||
version = "0.3.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"unicase 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicase 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -645,7 +638,7 @@ dependencies = [
|
||||
"iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -681,7 +674,7 @@ version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"openssl 0.10.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -697,8 +690,8 @@ name = "net2"
|
||||
version = "0.2.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@@ -709,7 +702,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "notify"
|
||||
version = "4.0.9"
|
||||
version = "4.0.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -718,7 +711,7 @@ dependencies = [
|
||||
"fsevent-sys 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"inotify 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -735,7 +728,7 @@ name = "num_cpus"
|
||||
version = "1.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -744,10 +737,10 @@ version = "0.10.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"openssl-sys 0.9.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@@ -762,12 +755,20 @@ version = "0.9.42"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cc 1.0.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "output_vt100"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "owning_ref"
|
||||
version = "0.4.0"
|
||||
@@ -790,7 +791,7 @@ name = "parking_lot_core"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -814,7 +815,7 @@ dependencies = [
|
||||
"proc-macro-hack 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -864,11 +865,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "pretty_assertions"
|
||||
version = "0.5.1"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ctor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"output_vt100 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -878,12 +881,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-nested"
|
||||
version = "0.1.2"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
@@ -921,7 +924,7 @@ version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -933,13 +936,13 @@ version = "0.6.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_jitter 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_os 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -988,19 +991,19 @@ name = "rand_jitter"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_os"
|
||||
version = "0.1.2"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1031,12 +1034,12 @@ dependencies = [
|
||||
"byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lz4 1.23.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rbx_dom_weak 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rbx_dom_weak 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rbx_dom_weak"
|
||||
version = "1.0.0"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1052,12 +1055,12 @@ dependencies = [
|
||||
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rbx_dom_weak 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rbx_dom_weak 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rbx_xml"
|
||||
version = "0.4.0"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1065,7 +1068,7 @@ dependencies = [
|
||||
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"maplit 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rbx_dom_weak 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rbx_dom_weak 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"xml-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@@ -1120,17 +1123,17 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reqwest"
|
||||
version = "0.9.10"
|
||||
version = "0.9.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"encoding_rs 0.8.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"http 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"hyper 0.12.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"hyper-tls 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libflate 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libflate 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mime 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mime_guess 2.0.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1138,10 +1141,10 @@ dependencies = [
|
||||
"serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_urlencoded 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-threadpool 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-threadpool 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"uuid 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1154,7 +1157,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"htmlescape 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro-hack 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro-nested 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro-nested 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ritz_impl 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@@ -1176,33 +1179,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cc 1.0.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rojo"
|
||||
version = "0.5.0-alpha.5"
|
||||
version = "0.5.0-alpha.6"
|
||||
dependencies = [
|
||||
"clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"csv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"env_logger 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"env_logger 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"hyper 0.12.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"maplit 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"notify 4.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"notify 4.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"paste 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pretty_assertions 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rbx_binary 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rbx_dom_weak 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rbx_dom_weak 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rbx_reflection 2.0.374 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rbx_xml 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rbx_xml 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"reqwest 0.9.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"reqwest 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ritz 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rlua 0.16.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1264,7 +1266,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"core-foundation 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"core-foundation-sys 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"security-framework-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@@ -1275,7 +1277,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"MacTypes-sys 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"core-foundation-sys 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1304,7 +1306,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1383,7 +1385,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "0.15.27"
|
||||
version = "0.15.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1398,7 +1400,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@@ -1416,8 +1418,8 @@ name = "tempfile"
|
||||
version = "3.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1437,7 +1439,7 @@ name = "termion"
|
||||
version = "1.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@@ -1463,31 +1465,31 @@ name = "time"
|
||||
version = "0.1.42"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "0.1.15"
|
||||
version = "0.1.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-current-thread 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-current-thread 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-reactor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-threadpool 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-threadpool 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-current-thread"
|
||||
version = "0.1.4"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1505,17 +1507,17 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tokio-io"
|
||||
version = "0.1.11"
|
||||
version = "0.1.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-reactor"
|
||||
version = "0.1.8"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1527,7 +1529,17 @@ dependencies = [
|
||||
"parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-sync 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-sync"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1535,22 +1547,21 @@ name = "tokio-tcp"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-reactor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-threadpool"
|
||||
version = "0.1.11"
|
||||
version = "0.1.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"crossbeam 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"crossbeam-deque 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1591,7 +1602,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "unicase"
|
||||
version = "2.2.0"
|
||||
version = "2.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1757,26 +1768,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12"
|
||||
"checksum bytecount 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b92204551573580e078dc80017f36a213eb77a0450e4ddd8cfa0f3f2d1f0178f"
|
||||
"checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb"
|
||||
"checksum bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "40ade3d27603c2cb345eb0912aec461a6dec7e06a4ae48589904e808335c7afa"
|
||||
"checksum bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c"
|
||||
"checksum cargo_metadata 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e5d1b4d380e1bab994591a24c2bdd1b054f64b60bef483a8c598c7c345bc3bbe"
|
||||
"checksum cc 1.0.30 (registry+https://github.com/rust-lang/crates.io-index)" = "d01c69d08ff207f231f07196e30f84c70f1c815b04f980f8b7b01ff01f05eb92"
|
||||
"checksum cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4"
|
||||
"checksum cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11d43355396e872eefb45ce6342e4374ed7bc2b3a502d1b28e36d6e23c05d1f4"
|
||||
"checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e"
|
||||
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
|
||||
"checksum core-foundation 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "286e0b41c3a20da26536c6000a280585d519fd07b3956b43aed8a79e9edce980"
|
||||
"checksum core-foundation-sys 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "716c271e8613ace48344f723b60b900a93150271e5be206212d052bbc0883efa"
|
||||
"checksum crc32fast 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e91d5240c6975ef33aeb5f148f35275c25eda8e8a5f95abe421978b05b8bf192"
|
||||
"checksum crossbeam 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ad4c7ea749d9fb09e23c5cb17e3b70650860553a0e2744e38446b1803bf7db94"
|
||||
"checksum crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "0f0ed1a4de2235cabda8558ff5840bffb97fcb64c97827f354a451307df5f72b"
|
||||
"checksum crossbeam-deque 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "05e44b8cf3e1a625844d1750e1f7820da46044ff6d28f4d43e455ba3e5bb2c13"
|
||||
"checksum crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1"
|
||||
"checksum crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b18cd2e169ad86297e6bc0ad9aa679aee9daa4f19e8163860faf7c164e4f5a71"
|
||||
"checksum crossbeam-epoch 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "04c9e3102cc2d69cd681412141b390abd55a362afc1540965dad0ad4d34280b4"
|
||||
"checksum crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c979cd6cfe72335896575c6b5688da489e420d36a27a0b9eb0c73db574b4a4b"
|
||||
"checksum crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f8306fcef4a7b563b76b7dd949ca48f52bc1141aa067d2ea09565f3e2652aa5c"
|
||||
"checksum csv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "9fd1c44c58078cfbeaf11fbb3eac9ae5534c23004ed770cc4bfb48e658ae4f04"
|
||||
"checksum csv-core 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fa5cdef62f37e6ffe7d1f07a381bc0db32b7a3ff1cac0de56cb0d81e71f53d65"
|
||||
"checksum ctor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "9a43db2bba5cafdc6aa068c892a518e477ee0df3705e53ec70247a9ff93546d5"
|
||||
"checksum difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198"
|
||||
"checksum dtoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6d301140eb411af13d3115f9a562c85cc6b541ade9dfa314132244aaee7489dd"
|
||||
"checksum encoding_rs 0.8.17 (registry+https://github.com/rust-lang/crates.io-index)" = "4155785c79f2f6701f185eb2e6b4caf0555ec03477cb4c70db67b465311620ed"
|
||||
"checksum env_logger 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "afb070faf94c85d17d50ca44f6ad076bce18ae92f0037d350947240a36e9d42e"
|
||||
"checksum env_logger 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b61fa891024a945da30a9581546e8cfaf5602c7b3f4c137a2805cf388f92075a"
|
||||
"checksum error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "07e791d3be96241c77c43846b665ef1384606da2cd2a48730abe606a12906e02"
|
||||
"checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2"
|
||||
"checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1"
|
||||
@@ -1808,8 +1819,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
|
||||
"checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14"
|
||||
"checksum lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f"
|
||||
"checksum libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)" = "413f3dfc802c5dc91dc570b05125b6cda9855edfaa9825c9849807876376e70e"
|
||||
"checksum libflate 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)" = "54d1ddf9c52870243c5689d7638d888331c1116aa5b398f3ba1acfa7d8758ca1"
|
||||
"checksum libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)" = "aab692d7759f5cd8c859e169db98ae5b52c924add2af5fbbca11d12fefb567c1"
|
||||
"checksum libflate 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)" = "7346a83e8a2c3958d44d24225d905385dc31fc16e89dffb356c457b278914d20"
|
||||
"checksum lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c"
|
||||
"checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6"
|
||||
"checksum lz4 1.23.1 (registry+https://github.com/rust-lang/crates.io-index)" = "43c94a9f09a60017f373020cc93d4291db4cd92b0db64ff25927f27d09dc23d5"
|
||||
@@ -1826,12 +1837,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
"checksum native-tls 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ff8e08de0070bbf4c31f452ea2a70db092f36f6f2e4d897adf5674477d488fb2"
|
||||
"checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88"
|
||||
"checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945"
|
||||
"checksum notify 4.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9cc7ed2bd4b7edad3ee93b659c38e53dabb619f7274e127a0fab054ad2bb998d"
|
||||
"checksum notify 4.0.10 (registry+https://github.com/rust-lang/crates.io-index)" = "abb1581693e44d8a0ec347ef12289625063f52a1dddc3f3c9befd5fc59e88943"
|
||||
"checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1"
|
||||
"checksum num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1a23f0ed30a54abaa0c7e83b1d2d87ada7c3c23078d1d87815af3e3b6385fbba"
|
||||
"checksum openssl 0.10.19 (registry+https://github.com/rust-lang/crates.io-index)" = "84321fb9004c3bce5611188a644d6171f895fa2889d155927d528782edb21c5d"
|
||||
"checksum openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de"
|
||||
"checksum openssl-sys 0.9.42 (registry+https://github.com/rust-lang/crates.io-index)" = "cb534d752bf98cf363b473950659ac2546517f9c6be9723771614ab3f03bbc9e"
|
||||
"checksum output_vt100 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "53cdc5b785b7a58c5aad8216b3dfa114df64b0b06ae6e1501cef91df2fbdf8f9"
|
||||
"checksum owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13"
|
||||
"checksum parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab41b4aed082705d1056416ae4468b6ea99d52599ecf3169b00088d43113e337"
|
||||
"checksum parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94c8c7923936b28d546dfd14d4472eaf34c99b14e1c973a32b3e6d4eb04298c9"
|
||||
@@ -1843,9 +1855,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
"checksum phf_generator 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "09364cc93c159b8b06b1f4dd8a4398984503483891b0c26b867cf431fb132662"
|
||||
"checksum phf_shared 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "234f71a15de2288bcb7e3b6515828d22af7ec8598ee6d24c3b526fa0a80b67a0"
|
||||
"checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c"
|
||||
"checksum pretty_assertions 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3a029430f0d744bc3d15dd474d591bed2402b645d024583082b9f63bb936dac6"
|
||||
"checksum pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3f81e1644e1b54f5a68959a29aa86cde704219254669da328ecfdf6a1f09d427"
|
||||
"checksum proc-macro-hack 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3e90aa19cd73dedc2d0e1e8407473f073d735fef0ab521438de6da8ee449ab66"
|
||||
"checksum proc-macro-nested 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e9968e025d6368d1273a93bc23051e30dbf5482475e716d7385d8ec8fbd5b5b6"
|
||||
"checksum proc-macro-nested 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "369a6ed065f249a159e06c45752c780bda2fb53c995718f9e484d08daa9eb42e"
|
||||
"checksum proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)" = "4d317f9caece796be1980837fd5cb3dfec5613ebdb04ad0956deea83ce168915"
|
||||
"checksum pulldown-cmark 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "eef52fac62d0ea7b9b4dc7da092aa64ea7ec3d90af6679422d3d7e0e14b6ee15"
|
||||
"checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0"
|
||||
@@ -1858,20 +1870,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
"checksum rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4"
|
||||
"checksum rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08"
|
||||
"checksum rand_jitter 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b9ea758282efe12823e0d952ddb269d2e1897227e464919a554f2a03ef1b832"
|
||||
"checksum rand_os 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b7c690732391ae0abafced5015ffb53656abfaec61b342290e5eb56b286a679d"
|
||||
"checksum rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071"
|
||||
"checksum rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44"
|
||||
"checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c"
|
||||
"checksum rbx_binary 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b147f236284747ac1b4643476265dd36b402877d97adb7cbd0fafc1d247de0a5"
|
||||
"checksum rbx_dom_weak 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "088a494e42fed50a2b12ba51807910187133ee7e81077cf7c08a57323b8d755f"
|
||||
"checksum rbx_dom_weak 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e31ec3223caeb1a57254a8a10b33614a2d457517be01ef93694f83d995833b04"
|
||||
"checksum rbx_reflection 2.0.374 (registry+https://github.com/rust-lang/crates.io-index)" = "8a826ff869b33b54db727f9776f1dc7a8a779791f5a46ddd4941b8334bf909fe"
|
||||
"checksum rbx_xml 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de8408fec1a0b4b73fda1bfcd70757f34a38ef2af84618b57da69d422ea13841"
|
||||
"checksum rbx_xml 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a240c155684b744c4985f283702b61f6ab0a2d4479694051d875844632c9f454"
|
||||
"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
|
||||
"checksum redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)" = "423e376fffca3dfa06c9e9790a9ccd282fafb3cc6e6397d01dbf64f9bacc6b85"
|
||||
"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
|
||||
"checksum regex 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "53ee8cfdddb2e0291adfb9f13d31d3bbe0a03c9a402c01b1e24188d86c35b24f"
|
||||
"checksum regex-syntax 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "8c2f35eedad5295fdf00a63d7d4b238135723f92b434ec06774dad15c7ab0861"
|
||||
"checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5"
|
||||
"checksum reqwest 0.9.10 (registry+https://github.com/rust-lang/crates.io-index)" = "f205a95638627fc0d21c53901671b06f439dc2830311ff11ecdff34ae2d839a8"
|
||||
"checksum reqwest 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)" = "e542d9f077c126af32536b6aacc75bb7325400eab8cd0743543be5d91660780d"
|
||||
"checksum ritz 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e7b52479a28408dacd24819d32f3562146b5f03eb0a06a8b2d7b11e34fbfe52d"
|
||||
"checksum ritz_impl 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fa7bba143ce94ca7e580094b8c4f6338b960b3bfa5ad7f479700e414b24d5d7b"
|
||||
"checksum rlua 0.16.2 (registry+https://github.com/rust-lang/crates.io-index)" = "51acb42c134a6568911a2aef2cea5feb80503804cc8986b903983ebfb1342a2c"
|
||||
@@ -1897,7 +1909,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
"checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8"
|
||||
"checksum string 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b639411d0b9c738748b5397d5ceba08e648f4f1992231aa859af1a017f31f60b"
|
||||
"checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550"
|
||||
"checksum syn 0.15.27 (registry+https://github.com/rust-lang/crates.io-index)" = "525bd55255f03c816e5d7f615587bd13030c7103354fadb104993dcee6a788ec"
|
||||
"checksum syn 0.15.29 (registry+https://github.com/rust-lang/crates.io-index)" = "1825685f977249735d510a242a6727b46efe914bb67e38d30c071b1b72b1d5c2"
|
||||
"checksum synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73687139bf99285483c96ac0add482c3776528beac1d97d444f6e91f203a2015"
|
||||
"checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8"
|
||||
"checksum tempfile 3.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "b86c784c88d98c801132806dadd3819ed29d8600836c4088e855cdf3e178ed8a"
|
||||
@@ -1906,18 +1918,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
"checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6"
|
||||
"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b"
|
||||
"checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f"
|
||||
"checksum tokio 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "e0500b88064f08bebddd0c0bed39e19f5c567a5f30975bee52b0c0d3e2eeb38c"
|
||||
"checksum tokio-current-thread 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "331c8acc267855ec06eb0c94618dcbbfea45bed2d20b77252940095273fb58f6"
|
||||
"checksum tokio 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "fcaabb3cec70485d0df6e9454fe514393ad1c4070dee8915f11041e95630b230"
|
||||
"checksum tokio-current-thread 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "c756b04680eea21902a46fca4e9f410a2332c04995af590e07ff262e2193a9a3"
|
||||
"checksum tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "30c6dbf2d1ad1de300b393910e8a3aa272b724a400b6531da03eed99e329fbf0"
|
||||
"checksum tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b53aeb9d3f5ccf2ebb29e19788f96987fa1355f8fe45ea193928eaaaf3ae820f"
|
||||
"checksum tokio-reactor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "afbcdb0f0d2a1e4c440af82d7bbf0bf91a8a8c0575bcd20c05d15be7e9d3a02f"
|
||||
"checksum tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "5090db468dad16e1a7a54c8c67280c5e4b544f3d3e018f0b913b400261f85926"
|
||||
"checksum tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "6af16bfac7e112bea8b0442542161bfc41cbfa4466b580bdda7d18cb88b911ce"
|
||||
"checksum tokio-sync 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1bf2b9dac2a0509b5cfd1df5aa25eafacb616a42a491a13604d6bbeab4486363"
|
||||
"checksum tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1d14b10654be682ac43efee27401d792507e30fd8d26389e1da3b185de2e4119"
|
||||
"checksum tokio-threadpool 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "c3fd86cb15547d02daa2b21aadaf4e37dee3368df38a526178a5afa3c034d2fb"
|
||||
"checksum tokio-threadpool 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "742e511f6ce2298aeb86fc9ea0d8df81c2388c6ebae3dc8a7316e8c9df0df801"
|
||||
"checksum tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "2910970404ba6fa78c5539126a9ae2045d62e3713041e447f695f41405a120c6"
|
||||
"checksum try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382"
|
||||
"checksum ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535c204ee4d8434478593480b8f86ab45ec9aae0e83c568ca81abf0fd0e88f86"
|
||||
"checksum unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33"
|
||||
"checksum unicase 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9d3218ea14b4edcaccfa0df0a64a3792a2c32cc706f1b336e48867f9d3147f90"
|
||||
"checksum unicase 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "41d17211f887da8e4a70a45b9536f26fc5de166b81e2d5d80de4a17fd22553bd"
|
||||
"checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5"
|
||||
"checksum unicode-normalization 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "141339a08b982d942be2ca06ff8b076563cbe223d1befd5450716790d44e2426"
|
||||
"checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526"
|
||||
|
||||
@@ -25,7 +25,7 @@ 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.5
|
||||
cargo install rojo --version 0.5.0-alpha.6
|
||||
```
|
||||
|
||||
## Installing the Plugin
|
||||
|
||||
@@ -8,14 +8,11 @@
|
||||
"Roact": {
|
||||
"$path": "modules/roact/lib"
|
||||
},
|
||||
"Rodux": {
|
||||
"$path": "modules/rodux/lib"
|
||||
},
|
||||
"RoactRodux": {
|
||||
"$path": "modules/roact-rodux/lib"
|
||||
},
|
||||
"Promise": {
|
||||
"$path": "modules/promise/lib"
|
||||
},
|
||||
"t": {
|
||||
"$path": "modules/t/lib/t.lua"
|
||||
}
|
||||
}
|
||||
}
|
||||
Submodule plugin/modules/roact-rodux deleted from 5d2e6885fc
Submodule plugin/modules/rodux deleted from 862f1c769a
1
plugin/modules/t
Submodule
1
plugin/modules/t
Submodule
Submodule plugin/modules/t added at a3a80ebf0a
@@ -15,14 +15,11 @@
|
||||
"Roact": {
|
||||
"$path": "modules/roact/lib"
|
||||
},
|
||||
"Rodux": {
|
||||
"$path": "modules/rodux/lib"
|
||||
},
|
||||
"RoactRodux": {
|
||||
"$path": "modules/roact-rodux/lib"
|
||||
},
|
||||
"Promise": {
|
||||
"$path": "modules/promise/lib"
|
||||
},
|
||||
"t": {
|
||||
"$path": "modules/t/lib/t.lua"
|
||||
}
|
||||
},
|
||||
"TestEZ": {
|
||||
@@ -40,8 +37,8 @@
|
||||
}
|
||||
},
|
||||
|
||||
"TestService": {
|
||||
"$className": "TestService",
|
||||
"ServerScriptService": {
|
||||
"$className": "ServerScriptService",
|
||||
|
||||
"TestBootstrap": {
|
||||
"$path": "testBootstrap.server.lua"
|
||||
|
||||
@@ -182,6 +182,13 @@ function App:didMount()
|
||||
preloadAssets()
|
||||
end
|
||||
|
||||
function App:willUnmount()
|
||||
if self.currentSession ~= nil then
|
||||
self.currentSession:disconnect()
|
||||
self.currentSession = nil
|
||||
end
|
||||
end
|
||||
|
||||
function App:didUpdate()
|
||||
local connectActive = self.state.sessionStatus == SessionStatus.ConfiguringSession
|
||||
or self.state.sessionStatus == SessionStatus.Connected
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
return {
|
||||
codename = "Epiphany",
|
||||
version = {0, 5, 0, "-alpha.5"},
|
||||
version = {0, 5, 0, "-alpha.6"},
|
||||
expectedServerVersionString = "0.5.0 or newer",
|
||||
protocolVersion = 2,
|
||||
defaultHost = "localhost",
|
||||
|
||||
@@ -1,10 +1,27 @@
|
||||
local Config = require(script.Parent.Config)
|
||||
|
||||
local Environment = {
|
||||
User = "User",
|
||||
Dev = "Dev",
|
||||
Test = "Test",
|
||||
}
|
||||
|
||||
local VALUES = {
|
||||
LogLevel = {
|
||||
type = "IntValue",
|
||||
defaultUserValue = 2,
|
||||
defaultDevValue = 3,
|
||||
values = {
|
||||
[Environment.User] = 2,
|
||||
[Environment.Dev] = 3,
|
||||
[Environment.Test] = 3,
|
||||
},
|
||||
},
|
||||
TypecheckingEnabled = {
|
||||
type = "BoolValue",
|
||||
values = {
|
||||
[Environment.User] = false,
|
||||
[Environment.Dev] = true,
|
||||
[Environment.Test] = true,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -42,7 +59,9 @@ local function setStoredValue(name, kind, value)
|
||||
object.Value = value
|
||||
end
|
||||
|
||||
local function createAllValues()
|
||||
local function createAllValues(environment)
|
||||
assert(Environment[environment] ~= nil, "Invalid environment")
|
||||
|
||||
valueContainer = getValueContainer()
|
||||
|
||||
if valueContainer == nil then
|
||||
@@ -52,20 +71,57 @@ local function createAllValues()
|
||||
end
|
||||
|
||||
for name, value in pairs(VALUES) do
|
||||
setStoredValue(name, value.type, value.defaultDevValue)
|
||||
setStoredValue(name, value.type, value.values[environment])
|
||||
end
|
||||
end
|
||||
|
||||
_G[("ROJO_%s_DEV_CREATE"):format(Config.codename:upper())] = createAllValues
|
||||
local function getValue(name)
|
||||
assert(VALUES[name] ~= nil, "Invalid DevSettings name")
|
||||
|
||||
local stored = getStoredValue(name)
|
||||
|
||||
if stored ~= nil then
|
||||
return stored
|
||||
end
|
||||
|
||||
return VALUES[name].values[Environment.User]
|
||||
end
|
||||
|
||||
local DevSettings = {}
|
||||
|
||||
function DevSettings:createDevSettings()
|
||||
createAllValues(Environment.Dev)
|
||||
end
|
||||
|
||||
function DevSettings:createTestSettings()
|
||||
createAllValues(Environment.Test)
|
||||
end
|
||||
|
||||
function DevSettings:hasChangedValues()
|
||||
return valueContainer ~= nil
|
||||
end
|
||||
|
||||
function DevSettings:resetValues()
|
||||
if valueContainer then
|
||||
valueContainer:Destroy()
|
||||
valueContainer = nil
|
||||
end
|
||||
end
|
||||
|
||||
function DevSettings:isEnabled()
|
||||
return valueContainer ~= nil
|
||||
end
|
||||
|
||||
function DevSettings:getLogLevel()
|
||||
return getStoredValue("LogLevel") or VALUES.LogLevel.defaultUserValue
|
||||
return getValue("LogLevel")
|
||||
end
|
||||
|
||||
function DevSettings:shouldTypecheck()
|
||||
return getValue("TypecheckingEnabled")
|
||||
end
|
||||
|
||||
function _G.ROJO_DEV_CREATE()
|
||||
DevSettings:createDevSettings()
|
||||
end
|
||||
|
||||
return DevSettings
|
||||
@@ -45,6 +45,16 @@ function InstanceMap:removeInstance(instance)
|
||||
end
|
||||
end
|
||||
|
||||
function InstanceMap:destroyInstance(instance)
|
||||
local id = self.fromInstances[instance]
|
||||
|
||||
if id ~= nil then
|
||||
self:destroyId(id)
|
||||
else
|
||||
Logging.warn("Attempted to destroy untracked instance %s", tostring(instance))
|
||||
end
|
||||
end
|
||||
|
||||
function InstanceMap:destroyId(id)
|
||||
local instance = self.fromIds[id]
|
||||
self:removeId(id)
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
local t = require(script.Parent.Parent.t)
|
||||
|
||||
local InstanceMap = require(script.Parent.InstanceMap)
|
||||
local Logging = require(script.Parent.Logging)
|
||||
local setProperty = require(script.Parent.setProperty)
|
||||
local setCanonicalProperty = require(script.Parent.setCanonicalProperty)
|
||||
local rojoValueToRobloxValue = require(script.Parent.rojoValueToRobloxValue)
|
||||
local Types = require(script.Parent.Types)
|
||||
|
||||
local Reconciler = {}
|
||||
Reconciler.__index = Reconciler
|
||||
@@ -24,11 +27,18 @@ function Reconciler:applyUpdate(requestedIds, virtualInstancesById)
|
||||
end
|
||||
end
|
||||
|
||||
local reconcileSchema = Types.ifEnabled(t.tuple(
|
||||
t.map(t.string, Types.VirtualInstance),
|
||||
t.string,
|
||||
t.Instance
|
||||
))
|
||||
--[[
|
||||
Update an existing instance, including its properties and children, to match
|
||||
the given information.
|
||||
]]
|
||||
function Reconciler:reconcile(virtualInstancesById, id, instance)
|
||||
assert(reconcileSchema(virtualInstancesById, id, instance))
|
||||
|
||||
local virtualInstance = virtualInstancesById[id]
|
||||
|
||||
-- If an instance changes ClassName, we assume it's very different. That's
|
||||
@@ -43,10 +53,10 @@ function Reconciler:reconcile(virtualInstancesById, id, instance)
|
||||
self.instanceMap:insert(id, instance)
|
||||
|
||||
-- Some instances don't like being named, even if their name already matches
|
||||
setProperty(instance, "Name", virtualInstance.Name)
|
||||
setCanonicalProperty(instance, "Name", virtualInstance.Name)
|
||||
|
||||
for key, value in pairs(virtualInstance.Properties) do
|
||||
setProperty(instance, key, rojoValueToRobloxValue(value))
|
||||
setCanonicalProperty(instance, key, rojoValueToRobloxValue(value))
|
||||
end
|
||||
|
||||
local existingChildren = instance:GetChildren()
|
||||
@@ -81,10 +91,17 @@ function Reconciler:reconcile(virtualInstancesById, id, instance)
|
||||
end
|
||||
end
|
||||
|
||||
if self:__shouldClearUnknownInstances(virtualInstance) then
|
||||
for existingChildInstance in pairs(unvisitedExistingChildren) do
|
||||
self.instanceMap:removeInstance(existingChildInstance)
|
||||
existingChildInstance:Destroy()
|
||||
local shouldClearUnknown = self:__shouldClearUnknownChildren(virtualInstance)
|
||||
|
||||
for existingChildInstance in pairs(unvisitedExistingChildren) do
|
||||
local childId = self.instanceMap.fromInstances[existingChildInstance]
|
||||
|
||||
if childId == nil then
|
||||
if shouldClearUnknown then
|
||||
existingChildInstance:Destroy()
|
||||
end
|
||||
else
|
||||
self.instanceMap:destroyInstance(existingChildInstance)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -100,13 +117,13 @@ function Reconciler:reconcile(virtualInstancesById, id, instance)
|
||||
|
||||
-- Some instances, like services, don't like having their Parent
|
||||
-- property poked, even if we're setting it to the same value.
|
||||
setProperty(instance, "Parent", parent)
|
||||
setCanonicalProperty(instance, "Parent", parent)
|
||||
end
|
||||
|
||||
return instance
|
||||
end
|
||||
|
||||
function Reconciler:__shouldClearUnknownInstances(virtualInstance)
|
||||
function Reconciler:__shouldClearUnknownChildren(virtualInstance)
|
||||
if virtualInstance.Metadata ~= nil then
|
||||
return not virtualInstance.Metadata.ignoreUnknownInstances
|
||||
else
|
||||
@@ -114,28 +131,44 @@ function Reconciler:__shouldClearUnknownInstances(virtualInstance)
|
||||
end
|
||||
end
|
||||
|
||||
local reifySchema = Types.ifEnabled(t.tuple(
|
||||
t.map(t.string, Types.VirtualInstance),
|
||||
t.string,
|
||||
t.Instance
|
||||
))
|
||||
|
||||
function Reconciler:__reify(virtualInstancesById, id, parent)
|
||||
assert(reifySchema(virtualInstancesById, id, parent))
|
||||
|
||||
local virtualInstance = virtualInstancesById[id]
|
||||
|
||||
local instance = Instance.new(virtualInstance.ClassName)
|
||||
|
||||
for key, value in pairs(virtualInstance.Properties) do
|
||||
setProperty(instance, key, rojoValueToRobloxValue(value))
|
||||
setCanonicalProperty(instance, key, rojoValueToRobloxValue(value))
|
||||
end
|
||||
|
||||
instance.Name = virtualInstance.Name
|
||||
setCanonicalProperty(instance, "Name", virtualInstance.Name)
|
||||
|
||||
for _, childId in ipairs(virtualInstance.Children) do
|
||||
self:__reify(virtualInstancesById, childId, instance)
|
||||
end
|
||||
|
||||
setProperty(instance, "Parent", parent)
|
||||
setCanonicalProperty(instance, "Parent", parent)
|
||||
self.instanceMap:insert(id, instance)
|
||||
|
||||
return instance
|
||||
end
|
||||
|
||||
local applyUpdatePieceSchema = Types.ifEnabled(t.tuple(
|
||||
t.string,
|
||||
t.map(t.string, t.boolean),
|
||||
t.map(t.string, Types.VirtualInstance)
|
||||
))
|
||||
|
||||
function Reconciler:__applyUpdatePiece(id, visitedIds, virtualInstancesById)
|
||||
assert(applyUpdatePieceSchema(id, visitedIds, virtualInstancesById))
|
||||
|
||||
if visitedIds[id] then
|
||||
return
|
||||
end
|
||||
|
||||
218
plugin/src/Reconciler.spec.lua
Normal file
218
plugin/src/Reconciler.spec.lua
Normal file
@@ -0,0 +1,218 @@
|
||||
local Reconciler = require(script.Parent.Reconciler)
|
||||
|
||||
return function()
|
||||
it("should leave instances alone if there's nothing specified", function()
|
||||
local instance = Instance.new("Folder")
|
||||
instance.Name = "TestFolder"
|
||||
|
||||
local instanceId = "test-id"
|
||||
local virtualInstancesById = {
|
||||
[instanceId] = {
|
||||
Name = "TestFolder",
|
||||
ClassName = "Folder",
|
||||
Children = {},
|
||||
Properties = {},
|
||||
},
|
||||
}
|
||||
|
||||
local reconciler = Reconciler.new()
|
||||
reconciler:reconcile(virtualInstancesById, instanceId, instance)
|
||||
end)
|
||||
|
||||
it("should assign names from virtual instances", function()
|
||||
local instance = Instance.new("Folder")
|
||||
instance.Name = "InitialName"
|
||||
|
||||
local instanceId = "test-id"
|
||||
local virtualInstancesById = {
|
||||
[instanceId] = {
|
||||
Name = "NewName",
|
||||
ClassName = "Folder",
|
||||
Children = {},
|
||||
Properties = {},
|
||||
},
|
||||
}
|
||||
|
||||
local reconciler = Reconciler.new()
|
||||
reconciler:reconcile(virtualInstancesById, instanceId, instance)
|
||||
|
||||
expect(instance.Name).to.equal("NewName")
|
||||
end)
|
||||
|
||||
it("should assign properties from virtual instances", function()
|
||||
local instance = Instance.new("IntValue")
|
||||
instance.Name = "TestValue"
|
||||
instance.Value = 5
|
||||
|
||||
local instanceId = "test-id"
|
||||
local virtualInstancesById = {
|
||||
[instanceId] = {
|
||||
Name = "TestValue",
|
||||
ClassName = "IntValue",
|
||||
Children = {},
|
||||
Properties = {
|
||||
Value = {
|
||||
Type = "Int32",
|
||||
Value = 9
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
local reconciler = Reconciler.new()
|
||||
reconciler:reconcile(virtualInstancesById, instanceId, instance)
|
||||
|
||||
expect(instance.Value).to.equal(9)
|
||||
end)
|
||||
|
||||
it("should wipe unknown children by default", function()
|
||||
local parent = Instance.new("Folder")
|
||||
parent.Name = "Parent"
|
||||
|
||||
local child = Instance.new("Folder")
|
||||
child.Name = "Child"
|
||||
|
||||
local parentId = "test-id"
|
||||
local virtualInstancesById = {
|
||||
[parentId] = {
|
||||
Name = "Parent",
|
||||
ClassName = "Folder",
|
||||
Children = {},
|
||||
Properties = {},
|
||||
},
|
||||
}
|
||||
|
||||
local reconciler = Reconciler.new()
|
||||
reconciler:reconcile(virtualInstancesById, parentId, parent)
|
||||
|
||||
expect(#parent:GetChildren()).to.equal(0)
|
||||
end)
|
||||
|
||||
it("should preserve unknown children if ignoreUnknownInstances is set", function()
|
||||
local parent = Instance.new("Folder")
|
||||
parent.Name = "Parent"
|
||||
|
||||
local child = Instance.new("Folder")
|
||||
child.Parent = parent
|
||||
child.Name = "Child"
|
||||
|
||||
local parentId = "test-id"
|
||||
local virtualInstancesById = {
|
||||
[parentId] = {
|
||||
Name = "Parent",
|
||||
ClassName = "Folder",
|
||||
Children = {},
|
||||
Properties = {},
|
||||
Metadata = {
|
||||
ignoreUnknownInstances = true,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
local reconciler = Reconciler.new()
|
||||
reconciler:reconcile(virtualInstancesById, parentId, parent)
|
||||
|
||||
expect(child.Parent).to.equal(parent)
|
||||
expect(#parent:GetChildren()).to.equal(1)
|
||||
end)
|
||||
|
||||
it("should remove known removed children", function()
|
||||
local parent = Instance.new("Folder")
|
||||
parent.Name = "Parent"
|
||||
|
||||
local child = Instance.new("Folder")
|
||||
child.Parent = parent
|
||||
child.Name = "Child"
|
||||
|
||||
local parentId = "parent-id"
|
||||
local childId = "child-id"
|
||||
|
||||
local reconciler = Reconciler.new()
|
||||
|
||||
local virtualInstancesById = {
|
||||
[parentId] = {
|
||||
Name = "Parent",
|
||||
ClassName = "Folder",
|
||||
Children = {childId},
|
||||
Properties = {},
|
||||
},
|
||||
[childId] = {
|
||||
Name = "Child",
|
||||
ClassName = "Folder",
|
||||
Children = {},
|
||||
Properties = {},
|
||||
},
|
||||
}
|
||||
reconciler:reconcile(virtualInstancesById, parentId, parent)
|
||||
|
||||
expect(child.Parent).to.equal(parent)
|
||||
expect(#parent:GetChildren()).to.equal(1)
|
||||
|
||||
local newVirtualInstances = {
|
||||
[parentId] = {
|
||||
Name = "Parent",
|
||||
ClassName = "Folder",
|
||||
Children = {},
|
||||
Properties = {},
|
||||
},
|
||||
[childId] = nil,
|
||||
}
|
||||
reconciler:reconcile(newVirtualInstances, parentId, parent)
|
||||
|
||||
expect(child.Parent).to.equal(nil)
|
||||
expect(#parent:GetChildren()).to.equal(0)
|
||||
end)
|
||||
|
||||
it("should remove known removed children if ignoreUnknownInstances is set", function()
|
||||
local parent = Instance.new("Folder")
|
||||
parent.Name = "Parent"
|
||||
|
||||
local child = Instance.new("Folder")
|
||||
child.Parent = parent
|
||||
child.Name = "Child"
|
||||
|
||||
local parentId = "parent-id"
|
||||
local childId = "child-id"
|
||||
|
||||
local reconciler = Reconciler.new()
|
||||
|
||||
local virtualInstancesById = {
|
||||
[parentId] = {
|
||||
Name = "Parent",
|
||||
ClassName = "Folder",
|
||||
Children = {childId},
|
||||
Properties = {},
|
||||
Metadata = {
|
||||
ignoreUnknownInstances = true,
|
||||
},
|
||||
},
|
||||
[childId] = {
|
||||
Name = "Child",
|
||||
ClassName = "Folder",
|
||||
Children = {},
|
||||
Properties = {},
|
||||
},
|
||||
}
|
||||
reconciler:reconcile(virtualInstancesById, parentId, parent)
|
||||
|
||||
expect(child.Parent).to.equal(parent)
|
||||
expect(#parent:GetChildren()).to.equal(1)
|
||||
|
||||
local newVirtualInstances = {
|
||||
[parentId] = {
|
||||
Name = "Parent",
|
||||
ClassName = "Folder",
|
||||
Children = {},
|
||||
Properties = {},
|
||||
Metadata = {
|
||||
ignoreUnknownInstances = true,
|
||||
},
|
||||
},
|
||||
[childId] = nil,
|
||||
}
|
||||
reconciler:reconcile(newVirtualInstances, parentId, parent)
|
||||
|
||||
expect(child.Parent).to.equal(nil)
|
||||
expect(#parent:GetChildren()).to.equal(0)
|
||||
end)
|
||||
end
|
||||
36
plugin/src/Types.lua
Normal file
36
plugin/src/Types.lua
Normal file
@@ -0,0 +1,36 @@
|
||||
local t = require(script.Parent.Parent.t)
|
||||
|
||||
local DevSettings = require(script.Parent.DevSettings)
|
||||
|
||||
local VirtualValue = t.interface({
|
||||
Type = t.string,
|
||||
Value = t.optional(t.any),
|
||||
})
|
||||
|
||||
local VirtualMetadata = t.interface({
|
||||
ignoreUnknownInstances = t.optional(t.boolean),
|
||||
})
|
||||
|
||||
local VirtualInstance = t.interface({
|
||||
Name = t.string,
|
||||
ClassName = t.string,
|
||||
Properties = t.map(t.string, VirtualValue),
|
||||
Metadata = t.optional(VirtualMetadata)
|
||||
})
|
||||
|
||||
local function ifEnabled(innerCheck)
|
||||
return function(...)
|
||||
if DevSettings:shouldTypecheck() then
|
||||
return innerCheck(...)
|
||||
else
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return {
|
||||
ifEnabled = ifEnabled,
|
||||
VirtualInstance = VirtualInstance,
|
||||
VirtualMetadata = VirtualMetadata,
|
||||
VirtualValue = VirtualValue,
|
||||
}
|
||||
@@ -4,10 +4,6 @@ end
|
||||
|
||||
local Roact = require(script.Parent.Roact)
|
||||
|
||||
Roact.setGlobalConfig({
|
||||
elementTracing = true,
|
||||
})
|
||||
|
||||
local App = require(script.Components.App)
|
||||
|
||||
local app = Roact.createElement(App, {
|
||||
@@ -16,4 +12,6 @@ local app = Roact.createElement(App, {
|
||||
|
||||
Roact.mount(app, game:GetService("CoreGui"), "Rojo UI")
|
||||
|
||||
-- TODO: Detect another instance of Rojo coming online and shut down this one.
|
||||
plugin.Unloading:Connect(function()
|
||||
Roact.unmount(app)
|
||||
end)
|
||||
@@ -1,14 +1,20 @@
|
||||
local primitiveTypes = {
|
||||
String = true,
|
||||
Bool = true,
|
||||
Int32 = true,
|
||||
Float32 = true,
|
||||
Enum = true,
|
||||
Float32 = true,
|
||||
Float64 = true,
|
||||
Int32 = true,
|
||||
Int64 = true,
|
||||
String = true,
|
||||
}
|
||||
|
||||
local directConstructors = {
|
||||
CFrame = CFrame.new,
|
||||
Color3 = Color3.new,
|
||||
Color3uint8 = Color3.fromRGB,
|
||||
Rect = Rect.new,
|
||||
UDim = UDim.new,
|
||||
UDim2 = UDim2.new,
|
||||
Vector2 = Vector2.new,
|
||||
Vector2int16 = Vector2int16.new,
|
||||
Vector3 = Vector3.new,
|
||||
|
||||
@@ -1,10 +1,17 @@
|
||||
local Logging = require(script.Parent.Logging)
|
||||
|
||||
--[[
|
||||
Attempts to set a property on the given instance, correctly handling
|
||||
'virtual properties', which aren't reflected directly to Lua.
|
||||
Attempts to set a property on the given instance.
|
||||
|
||||
This method deals in terms of what Rojo calls 'canonical properties', which
|
||||
don't necessarily exist either in serialization or in Lua-reflected APIs,
|
||||
but may be present in the API dump.
|
||||
|
||||
Ideally, canonical properties map 1:1 with properties we can assign, but in
|
||||
some cases like LocalizationTable contents and CollectionService tags, we
|
||||
have to read/write properties a little differently.
|
||||
]]
|
||||
local function setProperty(instance, key, value)
|
||||
local function setCanonicalProperty(instance, key, value)
|
||||
-- The 'Contents' property of LocalizationTable isn't directly exposed, but
|
||||
-- has corresponding (deprecated) getters and setters.
|
||||
if instance.ClassName == "LocalizationTable" and key == "Contents" then
|
||||
@@ -42,4 +49,4 @@ local function setProperty(instance, key, value)
|
||||
return true
|
||||
end
|
||||
|
||||
return setProperty
|
||||
return setCanonicalProperty
|
||||
@@ -1,2 +1,19 @@
|
||||
local TestEZ = require(game.ReplicatedStorage.TestEZ)
|
||||
TestEZ.TestBootstrap:run({game.ReplicatedStorage.Rojo.Plugin})
|
||||
local ReplicatedStorage = game:GetService("ReplicatedStorage")
|
||||
|
||||
local TestEZ = require(ReplicatedStorage.TestEZ)
|
||||
|
||||
local Rojo = ReplicatedStorage.Rojo
|
||||
|
||||
local DevSettings = require(Rojo.Plugin.DevSettings)
|
||||
|
||||
local setDevSettings = not DevSettings:hasChangedValues()
|
||||
|
||||
if setDevSettings then
|
||||
DevSettings:createTestSettings()
|
||||
end
|
||||
|
||||
TestEZ.TestBootstrap:run({Rojo.Plugin})
|
||||
|
||||
if setDevSettings then
|
||||
DevSettings:resetValues()
|
||||
end
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "rojo"
|
||||
version = "0.5.0-alpha.5"
|
||||
version = "0.5.0-alpha.6"
|
||||
authors = ["Lucien Greathouse <me@lpghatguy.com>"]
|
||||
description = "A tool to create robust Roblox projects"
|
||||
license = "MIT"
|
||||
@@ -29,10 +29,9 @@ hyper = "0.12"
|
||||
log = "0.4"
|
||||
maplit = "1.0.1"
|
||||
notify = "4.0"
|
||||
rand = "0.4"
|
||||
rbx_binary = "0.4.0"
|
||||
rbx_dom_weak = "1.0.0"
|
||||
rbx_xml = "0.4.0"
|
||||
rbx_dom_weak = "1.2.0"
|
||||
rbx_xml = "0.5.0"
|
||||
rbx_reflection = "2.0.374"
|
||||
regex = "1.0"
|
||||
reqwest = "0.9.5"
|
||||
@@ -47,5 +46,5 @@ uuid = { version = "0.7", features = ["v4", "serde"] }
|
||||
tempfile = "3.0"
|
||||
walkdir = "2.1"
|
||||
lazy_static = "1.2"
|
||||
pretty_assertions = "0.5.1"
|
||||
pretty_assertions = "0.6.1"
|
||||
paste = "0.1"
|
||||
66
server/assets/place.project.json
Normal file
66
server/assets/place.project.json
Normal file
@@ -0,0 +1,66 @@
|
||||
{
|
||||
"name": "[placeholder]",
|
||||
"tree": {
|
||||
"$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": {
|
||||
"$className": "ReplicatedStorage",
|
||||
"Source": {
|
||||
"$path": "src"
|
||||
}
|
||||
},
|
||||
"SoundService": {
|
||||
"$className": "SoundService",
|
||||
"$properties": {
|
||||
"RespectFilteringEnabled": true
|
||||
}
|
||||
},
|
||||
"Workspace": {
|
||||
"$className": "Workspace",
|
||||
"$properties": {
|
||||
"FilteringEnabled": true
|
||||
},
|
||||
"Baseplate": {
|
||||
"$className": "Part",
|
||||
"$properties": {
|
||||
"Anchored": true,
|
||||
"Color": [
|
||||
0.38823,
|
||||
0.37254,
|
||||
0.38823
|
||||
],
|
||||
"Locked": true,
|
||||
"Position": [
|
||||
0,
|
||||
-10,
|
||||
0
|
||||
],
|
||||
"Size": [
|
||||
512,
|
||||
20,
|
||||
512
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,10 @@
|
||||
use std::{
|
||||
collections::{HashMap, HashSet},
|
||||
path::{self, Path, PathBuf},
|
||||
cmp::Ordering,
|
||||
collections::{HashMap, HashSet, BTreeSet},
|
||||
fmt,
|
||||
fs,
|
||||
io,
|
||||
path::{self, Path, PathBuf},
|
||||
};
|
||||
|
||||
use failure::Fail;
|
||||
@@ -237,7 +238,7 @@ impl Imfs {
|
||||
} else if metadata.is_dir() {
|
||||
let item = ImfsItem::Directory(ImfsDirectory {
|
||||
path: path.to_path_buf(),
|
||||
children: HashSet::new(),
|
||||
children: BTreeSet::new(),
|
||||
});
|
||||
|
||||
self.items.insert(path.to_path_buf(), item);
|
||||
@@ -285,19 +286,43 @@ impl Imfs {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct ImfsFile {
|
||||
pub path: PathBuf,
|
||||
pub contents: Vec<u8>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub struct ImfsDirectory {
|
||||
pub path: PathBuf,
|
||||
pub children: HashSet<PathBuf>,
|
||||
impl PartialOrd for ImfsFile {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
impl Ord for ImfsFile {
|
||||
fn cmp(&self, other: &Self) -> Ordering {
|
||||
self.path.cmp(&other.path)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct ImfsDirectory {
|
||||
pub path: PathBuf,
|
||||
pub children: BTreeSet<PathBuf>,
|
||||
}
|
||||
|
||||
impl PartialOrd for ImfsDirectory {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
impl Ord for ImfsDirectory {
|
||||
fn cmp(&self, other: &Self) -> Ordering {
|
||||
self.path.cmp(&other.path)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||
pub enum ImfsItem {
|
||||
File(ImfsFile),
|
||||
Directory(ImfsDirectory),
|
||||
|
||||
@@ -85,6 +85,10 @@ impl LiveSession {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn root_project(&self) -> &Project {
|
||||
&self.project
|
||||
}
|
||||
|
||||
pub fn session_id(&self) -> SessionId {
|
||||
self.session_id
|
||||
}
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
sync::{
|
||||
mpsc,
|
||||
atomic::{AtomicUsize, Ordering},
|
||||
RwLock,
|
||||
Mutex,
|
||||
},
|
||||
};
|
||||
|
||||
use futures::sync::mpsc;
|
||||
|
||||
/// A unique identifier, not guaranteed to be generated in any order.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct ListenerId(usize);
|
||||
@@ -21,8 +22,7 @@ pub fn get_listener_id() -> ListenerId {
|
||||
|
||||
/// A message queue with persistent history that can be subscribed to.
|
||||
///
|
||||
/// Definitely non-optimal, but a simple design that works well for the
|
||||
/// synchronous web server Rojo uses, Rouille.
|
||||
/// Definitely non-optimal. This would ideally be a lockless mpmc queue.
|
||||
#[derive(Default)]
|
||||
pub struct MessageQueue<T> {
|
||||
messages: RwLock<Vec<T>>,
|
||||
@@ -38,15 +38,15 @@ impl<T: Clone> MessageQueue<T> {
|
||||
}
|
||||
|
||||
pub fn push_messages(&self, new_messages: &[T]) {
|
||||
let message_listeners = self.message_listeners.lock().unwrap();
|
||||
let mut message_listeners = self.message_listeners.lock().unwrap();
|
||||
|
||||
{
|
||||
let mut messages = self.messages.write().unwrap();
|
||||
messages.extend_from_slice(new_messages);
|
||||
}
|
||||
|
||||
for listener in message_listeners.values() {
|
||||
listener.send(()).unwrap();
|
||||
for listener in message_listeners.values_mut() {
|
||||
listener.try_send(()).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,12 @@ pub struct PathMap<T> {
|
||||
nodes: HashMap<PathBuf, PathMapNode<T>>,
|
||||
}
|
||||
|
||||
impl<T> Default for PathMap<T> {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> PathMap<T> {
|
||||
pub fn new() -> PathMap<T> {
|
||||
PathMap {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use std::{
|
||||
collections::{HashMap, HashSet},
|
||||
collections::{HashMap, HashSet, BTreeMap},
|
||||
fmt,
|
||||
fs::{self, File},
|
||||
io,
|
||||
@@ -8,9 +8,11 @@ use std::{
|
||||
|
||||
use log::warn;
|
||||
use failure::Fail;
|
||||
use maplit::hashmap;
|
||||
use rbx_dom_weak::{UnresolvedRbxValue, RbxValue};
|
||||
use serde_derive::{Serialize, Deserialize};
|
||||
use serde::{Serialize, Serializer};
|
||||
|
||||
static DEFAULT_PLACE: &'static str = include_str!("../assets/place.project.json");
|
||||
|
||||
pub static PROJECT_FILENAME: &'static str = "default.project.json";
|
||||
pub static COMPAT_PROJECT_FILENAME: &'static str = "roblox-project.json";
|
||||
@@ -55,15 +57,88 @@ impl SourceProject {
|
||||
}
|
||||
}
|
||||
|
||||
/// An alternative serializer for `UnresolvedRbxValue` that uses the minimum
|
||||
/// representation of the value.
|
||||
///
|
||||
/// For example, the default Serialize impl might give you:
|
||||
///
|
||||
/// ```json
|
||||
/// {
|
||||
/// "Type": "Bool",
|
||||
/// "Value": true
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// But in reality, users are expected to write just:
|
||||
///
|
||||
/// ```json
|
||||
/// true
|
||||
/// ```
|
||||
///
|
||||
/// This holds true for other values that might be ambiguous or just have more
|
||||
/// complicated representations like enums.
|
||||
fn serialize_unresolved_minimal<S>(unresolved: &UnresolvedRbxValue, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where S: Serializer
|
||||
{
|
||||
match unresolved {
|
||||
UnresolvedRbxValue::Ambiguous(_) => unresolved.serialize(serializer),
|
||||
UnresolvedRbxValue::Concrete(concrete) => {
|
||||
match concrete {
|
||||
RbxValue::Bool { value } => value.serialize(serializer),
|
||||
RbxValue::CFrame { value } => value.serialize(serializer),
|
||||
RbxValue::Color3 { value } => value.serialize(serializer),
|
||||
RbxValue::Color3uint8 { value } => value.serialize(serializer),
|
||||
RbxValue::Content { value } => value.serialize(serializer),
|
||||
RbxValue::Enum { value } => value.serialize(serializer),
|
||||
RbxValue::Float32 { value } => value.serialize(serializer),
|
||||
RbxValue::Int32 { value } => value.serialize(serializer),
|
||||
RbxValue::String { value } => value.serialize(serializer),
|
||||
RbxValue::UDim { value } => value.serialize(serializer),
|
||||
RbxValue::UDim2 { value } => value.serialize(serializer),
|
||||
RbxValue::Vector2 { value } => value.serialize(serializer),
|
||||
RbxValue::Vector2int16 { value } => value.serialize(serializer),
|
||||
RbxValue::Vector3 { value } => value.serialize(serializer),
|
||||
RbxValue::Vector3int16 { value } => value.serialize(serializer),
|
||||
_ => concrete.serialize(serializer),
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// A wrapper around serialize_unresolved_minimal that handles the HashMap case.
|
||||
fn serialize_unresolved_map<S>(value: &HashMap<String, UnresolvedRbxValue>, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where S: Serializer
|
||||
{
|
||||
use serde::ser::SerializeMap;
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct Minimal<'a>(
|
||||
#[serde(serialize_with = "serialize_unresolved_minimal")]
|
||||
&'a UnresolvedRbxValue
|
||||
);
|
||||
|
||||
let mut map = serializer.serialize_map(Some(value.len()))?;
|
||||
for (k, v) in value {
|
||||
map.serialize_key(k)?;
|
||||
map.serialize_value(&Minimal(v))?;
|
||||
}
|
||||
map.end()
|
||||
}
|
||||
|
||||
/// Similar to SourceProject, the structure of nodes in the project tree is
|
||||
/// slightly different on-disk than how we want to handle them in the rest of
|
||||
/// Rojo.
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
struct SourceProjectNode {
|
||||
#[serde(rename = "$className", skip_serializing_if = "Option::is_none")]
|
||||
class_name: Option<String>,
|
||||
|
||||
#[serde(rename = "$properties", default = "HashMap::new", skip_serializing_if = "HashMap::is_empty")]
|
||||
#[serde(
|
||||
rename = "$properties",
|
||||
default = "HashMap::new",
|
||||
skip_serializing_if = "HashMap::is_empty",
|
||||
serialize_with = "serialize_unresolved_map",
|
||||
)]
|
||||
properties: HashMap<String, UnresolvedRbxValue>,
|
||||
|
||||
#[serde(rename = "$ignoreUnknownInstances", skip_serializing_if = "Option::is_none")]
|
||||
@@ -73,14 +148,14 @@ struct SourceProjectNode {
|
||||
path: Option<String>,
|
||||
|
||||
#[serde(flatten)]
|
||||
children: HashMap<String, SourceProjectNode>,
|
||||
children: BTreeMap<String, SourceProjectNode>,
|
||||
}
|
||||
|
||||
impl SourceProjectNode {
|
||||
/// Consumes the SourceProjectNode and turns it into a ProjectNode.
|
||||
pub fn into_project_node(mut self, project_file_location: &Path) -> ProjectNode {
|
||||
let children = self.children.drain()
|
||||
.map(|(key, value)| (key, value.into_project_node(project_file_location)))
|
||||
pub fn into_project_node(self, project_file_location: &Path) -> ProjectNode {
|
||||
let children = self.children.iter()
|
||||
.map(|(key, value)| (key.clone(), value.clone().into_project_node(project_file_location)))
|
||||
.collect();
|
||||
|
||||
// Make sure that paths are absolute, transforming them by adding the
|
||||
@@ -162,6 +237,7 @@ pub enum ProjectInitError {
|
||||
AlreadyExists(PathBuf),
|
||||
IoError(#[fail(cause)] io::Error),
|
||||
SaveError(#[fail(cause)] ProjectSaveError),
|
||||
JsonError(#[fail(cause)] serde_json::Error),
|
||||
}
|
||||
|
||||
impl fmt::Display for ProjectInitError {
|
||||
@@ -170,6 +246,7 @@ impl fmt::Display for ProjectInitError {
|
||||
ProjectInitError::AlreadyExists(path) => write!(output, "Path {} already exists", path.display()),
|
||||
ProjectInitError::IoError(inner) => write!(output, "IO error: {}", inner),
|
||||
ProjectInitError::SaveError(inner) => write!(output, "{}", inner),
|
||||
ProjectInitError::JsonError(inner) => write!(output, "{}", inner),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -187,7 +264,7 @@ pub enum ProjectSaveError {
|
||||
#[derive(Debug, Clone, PartialEq, Default, Serialize, Deserialize)]
|
||||
pub struct ProjectNode {
|
||||
pub class_name: Option<String>,
|
||||
pub children: HashMap<String, ProjectNode>,
|
||||
pub children: BTreeMap<String, ProjectNode>,
|
||||
pub properties: HashMap<String, UnresolvedRbxValue>,
|
||||
pub ignore_unknown_instances: Option<bool>,
|
||||
|
||||
@@ -259,47 +336,16 @@ pub struct Project {
|
||||
impl Project {
|
||||
pub fn init_place(project_fuzzy_path: &Path) -> Result<PathBuf, ProjectInitError> {
|
||||
let project_path = Project::init_pick_path(project_fuzzy_path)?;
|
||||
let project_folder_path = project_path.parent().unwrap();
|
||||
let project_name = if project_fuzzy_path == project_path {
|
||||
project_fuzzy_path.parent().unwrap().file_name().unwrap().to_str().unwrap()
|
||||
} else {
|
||||
project_fuzzy_path.file_name().unwrap().to_str().unwrap()
|
||||
};
|
||||
|
||||
let tree = ProjectNode {
|
||||
class_name: Some(String::from("DataModel")),
|
||||
children: hashmap! {
|
||||
String::from("ReplicatedStorage") => ProjectNode {
|
||||
class_name: Some(String::from("ReplicatedStorage")),
|
||||
children: hashmap! {
|
||||
String::from("Source") => ProjectNode {
|
||||
path: Some(project_folder_path.join("src")),
|
||||
..Default::default()
|
||||
},
|
||||
},
|
||||
..Default::default()
|
||||
},
|
||||
String::from("HttpService") => ProjectNode {
|
||||
class_name: Some(String::from("HttpService")),
|
||||
properties: hashmap! {
|
||||
String::from("HttpEnabled") => RbxValue::Bool {
|
||||
value: true,
|
||||
}.into(),
|
||||
},
|
||||
..Default::default()
|
||||
},
|
||||
},
|
||||
..Default::default()
|
||||
};
|
||||
let mut project = Project::load_from_str(DEFAULT_PLACE, &project_path)
|
||||
.map_err(ProjectInitError::JsonError)?;
|
||||
|
||||
let project = Project {
|
||||
name: project_name.to_string(),
|
||||
tree,
|
||||
plugins: Vec::new(),
|
||||
serve_port: None,
|
||||
serve_place_ids: None,
|
||||
file_location: project_path.clone(),
|
||||
};
|
||||
project.name = project_name.to_owned();
|
||||
|
||||
project.save()
|
||||
.map_err(ProjectInitError::SaveError)?;
|
||||
@@ -387,6 +433,12 @@ impl Project {
|
||||
}
|
||||
}
|
||||
|
||||
fn load_from_str(contents: &str, project_file_location: &Path) -> Result<Project, serde_json::Error> {
|
||||
let parsed: SourceProject = serde_json::from_str(&contents)?;
|
||||
|
||||
Ok(parsed.into_project(project_file_location))
|
||||
}
|
||||
|
||||
pub fn load_fuzzy(fuzzy_project_location: &Path) -> Result<Project, ProjectLoadFuzzyError> {
|
||||
let project_path = Self::locate(fuzzy_project_location)
|
||||
.ok_or(ProjectLoadFuzzyError::NotFound)?;
|
||||
@@ -434,6 +486,10 @@ impl Project {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn folder_location(&self) -> &Path {
|
||||
self.file_location.parent().unwrap()
|
||||
}
|
||||
|
||||
fn to_source_project(&self) -> SourceProject {
|
||||
let plugins = self.plugins
|
||||
.iter()
|
||||
|
||||
@@ -251,6 +251,10 @@ impl RbxSession {
|
||||
&self.tree
|
||||
}
|
||||
|
||||
pub fn get_all_instance_metadata(&self) -> &HashMap<RbxId, MetadataPerInstance> {
|
||||
&self.metadata_per_instance
|
||||
}
|
||||
|
||||
pub fn get_instance_metadata(&self, id: RbxId) -> Option<&MetadataPerInstance> {
|
||||
self.metadata_per_instance.get(&id)
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ impl InstanceChanges {
|
||||
|
||||
/// A lightweight, hierarchical representation of an instance that can be
|
||||
/// applied to the tree.
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
|
||||
pub struct RbxSnapshotInstance<'a> {
|
||||
pub name: Cow<'a, str>,
|
||||
pub class_name: Cow<'a, str>,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
fmt,
|
||||
io::Write,
|
||||
path::Path,
|
||||
@@ -6,12 +7,13 @@ use std::{
|
||||
};
|
||||
|
||||
use log::warn;
|
||||
use rbx_dom_weak::RbxId;
|
||||
use rbx_dom_weak::{RbxTree, RbxId};
|
||||
|
||||
use crate::{
|
||||
imfs::{Imfs, ImfsItem},
|
||||
rbx_session::RbxSession,
|
||||
web::api::PublicInstanceMetadata,
|
||||
rbx_session::MetadataPerInstance,
|
||||
};
|
||||
|
||||
static GRAPHVIZ_HEADER: &str = r#"
|
||||
@@ -53,42 +55,59 @@ pub fn graphviz_to_svg(source: &str) -> Option<String> {
|
||||
Some(String::from_utf8(output.stdout).expect("Failed to parse stdout as UTF-8"))
|
||||
}
|
||||
|
||||
pub struct VisualizeRbxTree<'a, 'b> {
|
||||
pub tree: &'a RbxTree,
|
||||
pub metadata: &'b HashMap<RbxId, MetadataPerInstance>,
|
||||
}
|
||||
|
||||
impl<'a, 'b> fmt::Display for VisualizeRbxTree<'a, 'b> {
|
||||
fn fmt(&self, output: &mut fmt::Formatter) -> fmt::Result {
|
||||
writeln!(output, "{}", GRAPHVIZ_HEADER)?;
|
||||
|
||||
visualize_instance(&self.tree, self.tree.get_root_id(), &self.metadata, output)?;
|
||||
|
||||
writeln!(output, "}}")
|
||||
}
|
||||
}
|
||||
|
||||
/// A Display wrapper struct to visualize an RbxSession as SVG.
|
||||
pub struct VisualizeRbxSession<'a>(pub &'a RbxSession);
|
||||
|
||||
impl<'a> fmt::Display for VisualizeRbxSession<'a> {
|
||||
fn fmt(&self, output: &mut fmt::Formatter) -> fmt::Result {
|
||||
writeln!(output, "{}", GRAPHVIZ_HEADER)?;
|
||||
|
||||
visualize_rbx_node(self.0, self.0.get_tree().get_root_id(), output)?;
|
||||
|
||||
writeln!(output, "}}")?;
|
||||
|
||||
Ok(())
|
||||
writeln!(output, "{}", VisualizeRbxTree {
|
||||
tree: self.0.get_tree(),
|
||||
metadata: self.0.get_all_instance_metadata(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn visualize_rbx_node(session: &RbxSession, id: RbxId, output: &mut fmt::Formatter) -> fmt::Result {
|
||||
let node = session.get_tree().get_instance(id).unwrap();
|
||||
fn visualize_instance(
|
||||
tree: &RbxTree,
|
||||
id: RbxId,
|
||||
metadata: &HashMap<RbxId, MetadataPerInstance>,
|
||||
output: &mut fmt::Formatter,
|
||||
) -> fmt::Result {
|
||||
let instance = tree.get_instance(id).unwrap();
|
||||
|
||||
let mut node_label = format!("{}|{}|{}", node.name, node.class_name, id);
|
||||
let mut instance_label = format!("{}|{}|{}", instance.name, instance.class_name, id);
|
||||
|
||||
if let Some(session_metadata) = session.get_instance_metadata(id) {
|
||||
if let Some(session_metadata) = metadata.get(&id) {
|
||||
let metadata = PublicInstanceMetadata::from_session_metadata(session_metadata);
|
||||
node_label.push('|');
|
||||
node_label.push_str(&serde_json::to_string(&metadata).unwrap());
|
||||
instance_label.push('|');
|
||||
instance_label.push_str(&serde_json::to_string(&metadata).unwrap());
|
||||
}
|
||||
|
||||
node_label = node_label
|
||||
instance_label = instance_label
|
||||
.replace("\"", """)
|
||||
.replace("{", "\\{")
|
||||
.replace("}", "\\}");
|
||||
|
||||
writeln!(output, " \"{}\" [label=\"{}\"]", id, node_label)?;
|
||||
writeln!(output, " \"{}\" [label=\"{}\"]", id, instance_label)?;
|
||||
|
||||
for &child_id in node.get_children_ids() {
|
||||
for &child_id in instance.get_children_ids() {
|
||||
writeln!(output, " \"{}\" -> \"{}\"", id, child_id)?;
|
||||
visualize_rbx_node(session, child_id, output)?;
|
||||
visualize_instance(tree, child_id, metadata, output)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
||||
@@ -4,10 +4,10 @@
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
collections::{HashMap, HashSet},
|
||||
sync::{mpsc, Arc},
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
use futures::{future, Future};
|
||||
use futures::{future, Future, stream::Stream, sync::mpsc};
|
||||
use hyper::{
|
||||
service::Service,
|
||||
header,
|
||||
@@ -114,14 +114,16 @@ impl Service for ApiService {
|
||||
fn call(&mut self, request: hyper::Request<Self::ReqBody>) -> Self::Future {
|
||||
let response = match (request.method(), request.uri().path()) {
|
||||
(&Method::GET, "/api/rojo") => self.handle_api_rojo(),
|
||||
(&Method::GET, path) if path.starts_with("/api/subscribe/") => self.handle_api_subscribe(request),
|
||||
(&Method::GET, path) if path.starts_with("/api/read/") => self.handle_api_read(request),
|
||||
(&Method::GET, path) if path.starts_with("/api/subscribe/") => {
|
||||
return self.handle_api_subscribe(request);
|
||||
}
|
||||
_ => {
|
||||
Response::builder()
|
||||
.status(StatusCode::NOT_FOUND)
|
||||
.body(Body::empty())
|
||||
.unwrap()
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
Box::new(future::ok(response))
|
||||
@@ -152,16 +154,16 @@ impl ApiService {
|
||||
|
||||
/// Retrieve any messages past the given cursor index, and if
|
||||
/// there weren't any, subscribe to receive any new messages.
|
||||
fn handle_api_subscribe(&self, request: Request<Body>) -> Response<Body> {
|
||||
fn handle_api_subscribe(&self, request: Request<Body>) -> <ApiService as Service>::Future {
|
||||
let argument = &request.uri().path()["/api/subscribe/".len()..];
|
||||
let cursor: u32 = match argument.parse() {
|
||||
Ok(v) => v,
|
||||
Err(err) => {
|
||||
return Response::builder()
|
||||
return Box::new(future::ok(Response::builder()
|
||||
.status(StatusCode::BAD_REQUEST)
|
||||
.header(header::CONTENT_TYPE, "text/plain")
|
||||
.body(Body::from(err.to_string()))
|
||||
.unwrap();
|
||||
.unwrap()));
|
||||
},
|
||||
};
|
||||
|
||||
@@ -172,37 +174,38 @@ impl ApiService {
|
||||
let (new_cursor, new_messages) = message_queue.get_messages_since(cursor);
|
||||
|
||||
if !new_messages.is_empty() {
|
||||
return response_json(&SubscribeResponse {
|
||||
return Box::new(future::ok(response_json(&SubscribeResponse {
|
||||
session_id: self.live_session.session_id(),
|
||||
messages: Cow::Borrowed(&new_messages),
|
||||
message_cursor: new_cursor,
|
||||
})
|
||||
})));
|
||||
}
|
||||
}
|
||||
|
||||
// TOOD: Switch to futures mpsc instead to not block this task
|
||||
let (tx, rx) = mpsc::channel();
|
||||
let (tx, rx) = mpsc::channel(1024);
|
||||
let sender_id = message_queue.subscribe(tx);
|
||||
let session_id = self.live_session.session_id();
|
||||
|
||||
match rx.recv() {
|
||||
Ok(_) => (),
|
||||
Err(_) => return Response::builder()
|
||||
.status(500)
|
||||
.body(Body::from("error!"))
|
||||
.unwrap(),
|
||||
}
|
||||
let result = rx.into_future()
|
||||
.and_then(move |_| {
|
||||
message_queue.unsubscribe(sender_id);
|
||||
|
||||
message_queue.unsubscribe(sender_id);
|
||||
let (new_cursor, new_messages) = message_queue.get_messages_since(cursor);
|
||||
|
||||
{
|
||||
let (new_cursor, new_messages) = message_queue.get_messages_since(cursor);
|
||||
|
||||
return response_json(&SubscribeResponse {
|
||||
session_id: self.live_session.session_id(),
|
||||
messages: Cow::Owned(new_messages),
|
||||
message_cursor: new_cursor,
|
||||
Box::new(future::ok(response_json(SubscribeResponse {
|
||||
session_id: session_id,
|
||||
messages: Cow::Owned(new_messages),
|
||||
message_cursor: new_cursor,
|
||||
})))
|
||||
})
|
||||
}
|
||||
.or_else(|e| {
|
||||
Box::new(future::ok(Response::builder()
|
||||
.status(500)
|
||||
.body(Body::from(format!("Internal Error: {:?}", e)))
|
||||
.unwrap()))
|
||||
});
|
||||
|
||||
Box::new(result)
|
||||
}
|
||||
|
||||
fn handle_api_read(&self, request: Request<Body>) -> Response<Body> {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use std::{
|
||||
collections::{HashMap, HashSet},
|
||||
collections::{HashMap, HashSet, BTreeSet},
|
||||
fs,
|
||||
path::PathBuf,
|
||||
};
|
||||
@@ -80,7 +80,7 @@ fn base_tree() -> Result<(TempDir, Imfs, ExpectedImfs, TestResources), Error> {
|
||||
expected_roots.insert(root.path().to_path_buf());
|
||||
|
||||
let root_item = {
|
||||
let mut children = HashSet::new();
|
||||
let mut children = BTreeSet::new();
|
||||
children.insert(foo_path.clone());
|
||||
children.insert(bar_path.clone());
|
||||
|
||||
@@ -91,7 +91,7 @@ fn base_tree() -> Result<(TempDir, Imfs, ExpectedImfs, TestResources), Error> {
|
||||
};
|
||||
|
||||
let foo_item = {
|
||||
let mut children = HashSet::new();
|
||||
let mut children = BTreeSet::new();
|
||||
children.insert(baz_path.clone());
|
||||
|
||||
ImfsItem::Directory(ImfsDirectory {
|
||||
@@ -199,7 +199,7 @@ fn adding_folder() -> Result<(), Error> {
|
||||
}
|
||||
|
||||
let folder_item = {
|
||||
let mut children = HashSet::new();
|
||||
let mut children = BTreeSet::new();
|
||||
children.insert(file1_path.clone());
|
||||
children.insert(file2_path.clone());
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#[macro_use] extern crate lazy_static;
|
||||
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
collections::{HashMap, BTreeMap},
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
@@ -53,7 +53,7 @@ fn single_partition_game() {
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let mut replicated_storage_children = HashMap::new();
|
||||
let mut replicated_storage_children = BTreeMap::new();
|
||||
replicated_storage_children.insert("Foo".to_string(), foo);
|
||||
|
||||
let replicated_storage = ProjectNode {
|
||||
@@ -73,7 +73,7 @@ fn single_partition_game() {
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let mut root_children = HashMap::new();
|
||||
let mut root_children = BTreeMap::new();
|
||||
root_children.insert("ReplicatedStorage".to_string(), replicated_storage);
|
||||
root_children.insert("HttpService".to_string(), http_service);
|
||||
|
||||
|
||||
115
server/tests/snapshot_reconciler.rs
Normal file
115
server/tests/snapshot_reconciler.rs
Normal file
@@ -0,0 +1,115 @@
|
||||
mod test_util;
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
use pretty_assertions::assert_eq;
|
||||
use rbx_dom_weak::{RbxTree, RbxInstanceProperties};
|
||||
|
||||
use librojo::{
|
||||
snapshot_reconciler::{RbxSnapshotInstance, reconcile_subtree},
|
||||
};
|
||||
|
||||
use test_util::tree::trees_equal;
|
||||
|
||||
// TODO: Snapshot application isn't communicative right now with the current
|
||||
// snapshot reconciler. In practice this mostly isn't a problem, but presents
|
||||
// a problem trying to rely on determinism to make snapshot tests.
|
||||
// #[test]
|
||||
fn patch_communicativity() {
|
||||
let base_tree = RbxTree::new(RbxInstanceProperties {
|
||||
name: "DataModel".into(),
|
||||
class_name: "DataModel".into(),
|
||||
properties: HashMap::new(),
|
||||
});
|
||||
|
||||
let patch_a = RbxSnapshotInstance {
|
||||
name: "DataModel".into(),
|
||||
class_name: "DataModel".into(),
|
||||
children: vec![
|
||||
RbxSnapshotInstance {
|
||||
name: "Child-A".into(),
|
||||
class_name: "Folder".into(),
|
||||
..Default::default()
|
||||
},
|
||||
],
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let patch_b = RbxSnapshotInstance {
|
||||
name: "DataModel".into(),
|
||||
class_name: "DataModel".into(),
|
||||
children: vec![
|
||||
RbxSnapshotInstance {
|
||||
name: "Child-B".into(),
|
||||
class_name: "Folder".into(),
|
||||
..Default::default()
|
||||
},
|
||||
],
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let patch_combined = RbxSnapshotInstance {
|
||||
name: "DataModel".into(),
|
||||
class_name: "DataModel".into(),
|
||||
children: vec![
|
||||
RbxSnapshotInstance {
|
||||
name: "Child-A".into(),
|
||||
class_name: "Folder".into(),
|
||||
..Default::default()
|
||||
},
|
||||
RbxSnapshotInstance {
|
||||
name: "Child-B".into(),
|
||||
class_name: "Folder".into(),
|
||||
..Default::default()
|
||||
},
|
||||
],
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let root_id = base_tree.get_root_id();
|
||||
|
||||
let mut tree_a = base_tree.clone();
|
||||
|
||||
reconcile_subtree(
|
||||
&mut tree_a,
|
||||
root_id,
|
||||
&patch_a,
|
||||
&mut Default::default(),
|
||||
&mut Default::default(),
|
||||
&mut Default::default(),
|
||||
);
|
||||
|
||||
reconcile_subtree(
|
||||
&mut tree_a,
|
||||
root_id,
|
||||
&patch_combined,
|
||||
&mut Default::default(),
|
||||
&mut Default::default(),
|
||||
&mut Default::default(),
|
||||
);
|
||||
|
||||
let mut tree_b = base_tree.clone();
|
||||
|
||||
reconcile_subtree(
|
||||
&mut tree_b,
|
||||
root_id,
|
||||
&patch_b,
|
||||
&mut Default::default(),
|
||||
&mut Default::default(),
|
||||
&mut Default::default(),
|
||||
);
|
||||
|
||||
reconcile_subtree(
|
||||
&mut tree_b,
|
||||
root_id,
|
||||
&patch_combined,
|
||||
&mut Default::default(),
|
||||
&mut Default::default(),
|
||||
&mut Default::default(),
|
||||
);
|
||||
|
||||
match trees_equal(&tree_a, &tree_b) {
|
||||
Ok(_) => {}
|
||||
Err(e) => panic!("{}", e),
|
||||
}
|
||||
}
|
||||
68
server/tests/snapshot_snapshots.rs
Normal file
68
server/tests/snapshot_snapshots.rs
Normal file
@@ -0,0 +1,68 @@
|
||||
mod test_util;
|
||||
|
||||
use std::path::Path;
|
||||
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
use librojo::{
|
||||
imfs::Imfs,
|
||||
project::Project,
|
||||
rbx_snapshot::{SnapshotContext, snapshot_project_tree},
|
||||
};
|
||||
|
||||
use crate::test_util::{
|
||||
snapshot::*,
|
||||
};
|
||||
|
||||
macro_rules! generate_snapshot_tests {
|
||||
($($name: ident),*) => {
|
||||
$(
|
||||
paste::item! {
|
||||
#[test]
|
||||
fn [<snapshot_ $name>]() {
|
||||
let _ = env_logger::try_init();
|
||||
|
||||
let tests_folder = Path::new(env!("CARGO_MANIFEST_DIR")).join("../test-projects");
|
||||
let project_folder = tests_folder.join(stringify!($name));
|
||||
run_snapshot_test(&project_folder);
|
||||
}
|
||||
}
|
||||
)*
|
||||
};
|
||||
}
|
||||
|
||||
generate_snapshot_tests!(
|
||||
empty,
|
||||
multi_partition_game,
|
||||
nested_partitions,
|
||||
single_partition_game,
|
||||
single_partition_model,
|
||||
transmute_partition
|
||||
);
|
||||
|
||||
fn run_snapshot_test(path: &Path) {
|
||||
println!("Running snapshot from project: {}", path.display());
|
||||
|
||||
let project = Project::load_fuzzy(path)
|
||||
.expect("Couldn't load project file for snapshot test");
|
||||
|
||||
let mut imfs = Imfs::new();
|
||||
imfs.add_roots_from_project(&project)
|
||||
.expect("Could not add IMFS roots to snapshot project");
|
||||
|
||||
let context = SnapshotContext {
|
||||
plugin_context: None,
|
||||
};
|
||||
|
||||
let mut snapshot = snapshot_project_tree(&context, &imfs, &project)
|
||||
.expect("Could not generate snapshot for snapshot test");
|
||||
|
||||
if let Some(snapshot) = snapshot.as_mut() {
|
||||
anonymize_snapshot(path, snapshot);
|
||||
}
|
||||
|
||||
match read_expected_snapshot(path) {
|
||||
Some(expected_snapshot) => assert_eq!(snapshot, expected_snapshot),
|
||||
None => write_expected_snapshot(path, &snapshot),
|
||||
}
|
||||
}
|
||||
@@ -1,128 +0,0 @@
|
||||
use std::{
|
||||
fs::{self, File},
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
use librojo::{
|
||||
imfs::Imfs,
|
||||
project::{Project, ProjectNode},
|
||||
rbx_snapshot::{SnapshotContext, snapshot_project_tree},
|
||||
snapshot_reconciler::{RbxSnapshotInstance},
|
||||
};
|
||||
|
||||
macro_rules! generate_snapshot_tests {
|
||||
($($name: ident),*) => {
|
||||
$(
|
||||
paste::item! {
|
||||
#[test]
|
||||
fn [<snapshot_ $name>]() {
|
||||
let tests_folder = Path::new(env!("CARGO_MANIFEST_DIR")).join("../test-projects");
|
||||
let project_folder = tests_folder.join(stringify!($name));
|
||||
run_snapshot_test(&project_folder);
|
||||
}
|
||||
}
|
||||
)*
|
||||
};
|
||||
}
|
||||
|
||||
generate_snapshot_tests!(
|
||||
empty,
|
||||
nested_partitions,
|
||||
single_partition_game,
|
||||
single_partition_model,
|
||||
transmute_partition
|
||||
);
|
||||
|
||||
const SNAPSHOT_EXPECTED_NAME: &str = "expected-snapshot.json";
|
||||
|
||||
fn run_snapshot_test(path: &Path) {
|
||||
println!("Running snapshot from project: {}", path.display());
|
||||
|
||||
let project = Project::load_fuzzy(path)
|
||||
.expect("Couldn't load project file for snapshot test");
|
||||
|
||||
let mut imfs = Imfs::new();
|
||||
imfs.add_roots_from_project(&project)
|
||||
.expect("Could not add IMFS roots to snapshot project");
|
||||
|
||||
let context = SnapshotContext {
|
||||
plugin_context: None,
|
||||
};
|
||||
|
||||
let mut snapshot = snapshot_project_tree(&context, &imfs, &project)
|
||||
.expect("Could not generate snapshot for snapshot test");
|
||||
|
||||
if let Some(snapshot) = snapshot.as_mut() {
|
||||
anonymize_snapshot(path, snapshot);
|
||||
}
|
||||
|
||||
match read_expected_snapshot(path) {
|
||||
Some(expected_snapshot) => assert_eq!(snapshot, expected_snapshot),
|
||||
None => write_expected_snapshot(path, &snapshot),
|
||||
}
|
||||
}
|
||||
|
||||
/// Snapshots contain absolute paths, which simplifies much of Rojo.
|
||||
///
|
||||
/// For saving snapshots to the disk, we should strip off the project folder
|
||||
/// path to make them machine-independent. This doesn't work for paths that fall
|
||||
/// outside of the project folder, but that's okay here.
|
||||
///
|
||||
/// We also need to sort children, since Rojo tends to enumerate the filesystem
|
||||
/// in an unpredictable order.
|
||||
fn anonymize_snapshot(project_folder_path: &Path, snapshot: &mut RbxSnapshotInstance) {
|
||||
match snapshot.metadata.source_path.as_mut() {
|
||||
Some(path) => *path = anonymize_path(project_folder_path, path),
|
||||
None => {},
|
||||
}
|
||||
|
||||
match snapshot.metadata.project_definition.as_mut() {
|
||||
Some((_, project_node)) => anonymize_project_node(project_folder_path, project_node),
|
||||
None => {},
|
||||
}
|
||||
|
||||
snapshot.children.sort_by(|a, b| a.partial_cmp(b).unwrap());
|
||||
|
||||
for child in snapshot.children.iter_mut() {
|
||||
anonymize_snapshot(project_folder_path, child);
|
||||
}
|
||||
}
|
||||
|
||||
fn anonymize_project_node(project_folder_path: &Path, project_node: &mut ProjectNode) {
|
||||
match project_node.path.as_mut() {
|
||||
Some(path) => *path = anonymize_path(project_folder_path, path),
|
||||
None => {},
|
||||
}
|
||||
|
||||
for child_node in project_node.children.values_mut() {
|
||||
anonymize_project_node(project_folder_path, child_node);
|
||||
}
|
||||
}
|
||||
|
||||
fn anonymize_path(project_folder_path: &Path, path: &Path) -> PathBuf {
|
||||
if path.is_absolute() {
|
||||
path.strip_prefix(project_folder_path)
|
||||
.expect("Could not anonymize absolute path")
|
||||
.to_path_buf()
|
||||
} else {
|
||||
path.to_path_buf()
|
||||
}
|
||||
}
|
||||
|
||||
fn read_expected_snapshot(path: &Path) -> Option<Option<RbxSnapshotInstance<'static>>> {
|
||||
let contents = fs::read(path.join(SNAPSHOT_EXPECTED_NAME)).ok()?;
|
||||
let snapshot: Option<RbxSnapshotInstance<'static>> = serde_json::from_slice(&contents)
|
||||
.expect("Could not deserialize snapshot");
|
||||
|
||||
Some(snapshot)
|
||||
}
|
||||
|
||||
fn write_expected_snapshot(path: &Path, snapshot: &Option<RbxSnapshotInstance>) {
|
||||
let mut file = File::create(path.join(SNAPSHOT_EXPECTED_NAME))
|
||||
.expect("Could not open file to write snapshot");
|
||||
|
||||
serde_json::to_writer_pretty(&mut file, snapshot)
|
||||
.expect("Could not serialize snapshot to file");
|
||||
}
|
||||
@@ -1,31 +1,13 @@
|
||||
#![allow(dead_code)]
|
||||
|
||||
use std::fs::{create_dir, copy};
|
||||
use std::path::Path;
|
||||
use std::io;
|
||||
|
||||
use rouille::Request;
|
||||
|
||||
use walkdir::WalkDir;
|
||||
|
||||
use librojo::web::Server;
|
||||
|
||||
pub trait HttpTestUtil {
|
||||
fn get_string(&self, url: &str) -> String;
|
||||
}
|
||||
|
||||
impl HttpTestUtil for Server {
|
||||
fn get_string(&self, url: &str) -> String {
|
||||
let info_request = Request::fake_http("GET", url, vec![], vec![]);
|
||||
let response = self.handle_request(&info_request);
|
||||
|
||||
assert_eq!(response.status_code, 200);
|
||||
|
||||
let (mut reader, _) = response.data.into_reader_and_size();
|
||||
let mut body = String::new();
|
||||
reader.read_to_string(&mut body).unwrap();
|
||||
|
||||
body
|
||||
}
|
||||
}
|
||||
pub mod snapshot;
|
||||
pub mod tree;
|
||||
|
||||
pub fn copy_recursive(from: &Path, to: &Path) -> io::Result<()> {
|
||||
for entry in WalkDir::new(from) {
|
||||
@@ -51,4 +33,4 @@ pub fn copy_recursive(from: &Path, to: &Path) -> io::Result<()> {
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
79
server/tests/test_util/snapshot.rs
Normal file
79
server/tests/test_util/snapshot.rs
Normal file
@@ -0,0 +1,79 @@
|
||||
use std::{
|
||||
fs::{self, File},
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
use librojo::{
|
||||
project::ProjectNode,
|
||||
snapshot_reconciler::RbxSnapshotInstance,
|
||||
rbx_session::MetadataPerInstance,
|
||||
};
|
||||
|
||||
const SNAPSHOT_EXPECTED_NAME: &str = "expected-snapshot.json";
|
||||
|
||||
/// Snapshots contain absolute paths, which simplifies much of Rojo.
|
||||
///
|
||||
/// For saving snapshots to the disk, we should strip off the project folder
|
||||
/// path to make them machine-independent. This doesn't work for paths that fall
|
||||
/// outside of the project folder, but that's okay here.
|
||||
///
|
||||
/// We also need to sort children, since Rojo tends to enumerate the filesystem
|
||||
/// in an unpredictable order.
|
||||
pub fn anonymize_snapshot(project_folder_path: &Path, snapshot: &mut RbxSnapshotInstance) {
|
||||
anonymize_metadata(project_folder_path, &mut snapshot.metadata);
|
||||
|
||||
snapshot.children.sort_by(|a, b| a.partial_cmp(b).unwrap());
|
||||
|
||||
for child in snapshot.children.iter_mut() {
|
||||
anonymize_snapshot(project_folder_path, child);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn anonymize_metadata(project_folder_path: &Path, metadata: &mut MetadataPerInstance) {
|
||||
match metadata.source_path.as_mut() {
|
||||
Some(path) => *path = anonymize_path(project_folder_path, path),
|
||||
None => {},
|
||||
}
|
||||
|
||||
match metadata.project_definition.as_mut() {
|
||||
Some((_, project_node)) => anonymize_project_node(project_folder_path, project_node),
|
||||
None => {},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn anonymize_project_node(project_folder_path: &Path, project_node: &mut ProjectNode) {
|
||||
match project_node.path.as_mut() {
|
||||
Some(path) => *path = anonymize_path(project_folder_path, path),
|
||||
None => {},
|
||||
}
|
||||
|
||||
for child_node in project_node.children.values_mut() {
|
||||
anonymize_project_node(project_folder_path, child_node);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn anonymize_path(project_folder_path: &Path, path: &Path) -> PathBuf {
|
||||
if path.is_absolute() {
|
||||
path.strip_prefix(project_folder_path)
|
||||
.expect("Could not anonymize absolute path")
|
||||
.to_path_buf()
|
||||
} else {
|
||||
path.to_path_buf()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read_expected_snapshot(path: &Path) -> Option<Option<RbxSnapshotInstance<'static>>> {
|
||||
let contents = fs::read(path.join(SNAPSHOT_EXPECTED_NAME)).ok()?;
|
||||
let snapshot: Option<RbxSnapshotInstance<'static>> = serde_json::from_slice(&contents)
|
||||
.expect("Could not deserialize snapshot");
|
||||
|
||||
Some(snapshot)
|
||||
}
|
||||
|
||||
pub fn write_expected_snapshot(path: &Path, snapshot: &Option<RbxSnapshotInstance>) {
|
||||
let mut file = File::create(path.join(SNAPSHOT_EXPECTED_NAME))
|
||||
.expect("Could not open file to write snapshot");
|
||||
|
||||
serde_json::to_writer_pretty(&mut file, snapshot)
|
||||
.expect("Could not serialize snapshot to file");
|
||||
}
|
||||
351
server/tests/test_util/tree.rs
Normal file
351
server/tests/test_util/tree.rs
Normal file
@@ -0,0 +1,351 @@
|
||||
//! Defines a mechanism to compare two RbxTree objects and generate a useful
|
||||
//! diff if they aren't the same. These methods ignore IDs, which are randomly
|
||||
//! generated whenever a tree is constructed anyways. This makes matching up
|
||||
//! pairs of instances that should be the same potentially difficult.
|
||||
//!
|
||||
//! It relies on a couple different ideas:
|
||||
//! - Instances with the same name and class name are matched as the same
|
||||
//! instance. See basic_equal for this logic
|
||||
//! - A path of period-delimited names (like Roblox's GetFullName) should be
|
||||
//! enough to debug most issues. If it isn't, we can do something fun like
|
||||
//! generate GraphViz graphs.
|
||||
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
collections::{HashMap, HashSet},
|
||||
fmt,
|
||||
fs::{self, File},
|
||||
hash::Hash,
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
use log::error;
|
||||
use serde_derive::{Serialize, Deserialize};
|
||||
use rbx_dom_weak::{RbxId, RbxTree};
|
||||
|
||||
use librojo::{
|
||||
rbx_session::MetadataPerInstance,
|
||||
live_session::LiveSession,
|
||||
visualize::{VisualizeRbxTree, graphviz_to_svg},
|
||||
};
|
||||
|
||||
use super::snapshot::anonymize_metadata;
|
||||
|
||||
/// Marks a 'step' in the test, which will snapshot the session's current
|
||||
/// RbxTree object and compare it against the saved snapshot if it exists.
|
||||
pub fn tree_step(step: &str, live_session: &LiveSession, source_path: &Path) {
|
||||
let rbx_session = live_session.rbx_session.lock().unwrap();
|
||||
let tree = rbx_session.get_tree();
|
||||
|
||||
let project_folder = live_session.root_project().folder_location();
|
||||
let metadata = rbx_session.get_all_instance_metadata()
|
||||
.iter()
|
||||
.map(|(key, meta)| {
|
||||
let mut meta = meta.clone();
|
||||
anonymize_metadata(project_folder, &mut meta);
|
||||
(*key, meta)
|
||||
})
|
||||
.collect();
|
||||
|
||||
let tree_with_metadata = TreeWithMetadata {
|
||||
tree: Cow::Borrowed(&tree),
|
||||
metadata: Cow::Owned(metadata),
|
||||
};
|
||||
|
||||
match read_tree_by_name(source_path, step) {
|
||||
Some(expected) => match trees_and_metadata_equal(&expected, &tree_with_metadata) {
|
||||
Ok(_) => {}
|
||||
Err(e) => {
|
||||
error!("Trees at step '{}' were not equal.\n{}", step, e);
|
||||
|
||||
let expected_gv = format!("{}", VisualizeRbxTree {
|
||||
tree: &expected.tree,
|
||||
metadata: &expected.metadata,
|
||||
});
|
||||
|
||||
let actual_gv = format!("{}", VisualizeRbxTree {
|
||||
tree: &tree_with_metadata.tree,
|
||||
metadata: &tree_with_metadata.metadata,
|
||||
});
|
||||
|
||||
let output_dir = PathBuf::from("failed-snapshots");
|
||||
fs::create_dir_all(&output_dir)
|
||||
.expect("Could not create failed-snapshots directory");
|
||||
|
||||
let expected_basename = format!("{}-{}-expected", live_session.root_project().name, step);
|
||||
let actual_basename = format!("{}-{}-actual", live_session.root_project().name, step);
|
||||
|
||||
let mut expected_out = output_dir.join(expected_basename);
|
||||
let mut actual_out = output_dir.join(actual_basename);
|
||||
|
||||
match (graphviz_to_svg(&expected_gv), graphviz_to_svg(&actual_gv)) {
|
||||
(Some(expected_svg), Some(actual_svg)) => {
|
||||
expected_out.set_extension("svg");
|
||||
actual_out.set_extension("svg");
|
||||
|
||||
fs::write(&expected_out, expected_svg)
|
||||
.expect("Couldn't write expected SVG");
|
||||
|
||||
fs::write(&actual_out, actual_svg)
|
||||
.expect("Couldn't write actual SVG");
|
||||
}
|
||||
_ => {
|
||||
expected_out.set_extension("gv");
|
||||
actual_out.set_extension("gv");
|
||||
|
||||
fs::write(&expected_out, expected_gv)
|
||||
.expect("Couldn't write expected GV");
|
||||
|
||||
fs::write(&actual_out, actual_gv)
|
||||
.expect("Couldn't write actual GV");
|
||||
}
|
||||
}
|
||||
|
||||
error!("Output at {} and {}", expected_out.display(), actual_out.display());
|
||||
|
||||
panic!("Tree mismatch at step '{}'", step);
|
||||
}
|
||||
}
|
||||
None => {
|
||||
write_tree_by_name(source_path, step, &tree_with_metadata);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn new_cow_map<K: Clone + Eq + Hash, V: Clone>() -> Cow<'static, HashMap<K, V>> {
|
||||
Cow::Owned(HashMap::new())
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
struct TreeWithMetadata<'a> {
|
||||
#[serde(flatten)]
|
||||
pub tree: Cow<'a, RbxTree>,
|
||||
|
||||
#[serde(default = "new_cow_map")]
|
||||
pub metadata: Cow<'a, HashMap<RbxId, MetadataPerInstance>>,
|
||||
}
|
||||
|
||||
fn read_tree_by_name(path: &Path, identifier: &str) -> Option<TreeWithMetadata<'static>> {
|
||||
let mut file_path = path.join(identifier);
|
||||
file_path.set_extension("tree.json");
|
||||
|
||||
let contents = fs::read(&file_path).ok()?;
|
||||
let tree: TreeWithMetadata = serde_json::from_slice(&contents)
|
||||
.expect("Could not deserialize tree");
|
||||
|
||||
Some(tree)
|
||||
}
|
||||
|
||||
fn write_tree_by_name(path: &Path, identifier: &str, tree: &TreeWithMetadata) {
|
||||
let mut file_path = path.join(identifier);
|
||||
file_path.set_extension("tree.json");
|
||||
|
||||
let mut file = File::create(file_path)
|
||||
.expect("Could not open file to write tree");
|
||||
|
||||
serde_json::to_writer_pretty(&mut file, tree)
|
||||
.expect("Could not serialize tree to file");
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct TreeMismatch {
|
||||
pub path: Cow<'static, str>,
|
||||
pub detail: Cow<'static, str>,
|
||||
}
|
||||
|
||||
impl TreeMismatch {
|
||||
pub fn new<'a, A: Into<Cow<'a, str>>, B: Into<Cow<'a, str>>>(path: A, detail: B) -> TreeMismatch {
|
||||
TreeMismatch {
|
||||
path: Cow::Owned(path.into().into_owned()),
|
||||
detail: Cow::Owned(detail.into().into_owned()),
|
||||
}
|
||||
}
|
||||
|
||||
fn add_parent(mut self, name: &str) -> TreeMismatch {
|
||||
self.path.to_mut().insert(0, '.');
|
||||
self.path.to_mut().insert_str(0, name);
|
||||
|
||||
TreeMismatch {
|
||||
path: self.path,
|
||||
detail: self.detail,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for TreeMismatch {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
writeln!(formatter, "Tree mismatch at path {}", self.path)?;
|
||||
writeln!(formatter, "{}", self.detail)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn trees_equal(
|
||||
left_tree: &RbxTree,
|
||||
right_tree: &RbxTree,
|
||||
) -> Result<(), TreeMismatch> {
|
||||
let left = TreeWithMetadata {
|
||||
tree: Cow::Borrowed(left_tree),
|
||||
metadata: Cow::Owned(HashMap::new()),
|
||||
};
|
||||
|
||||
let right = TreeWithMetadata {
|
||||
tree: Cow::Borrowed(right_tree),
|
||||
metadata: Cow::Owned(HashMap::new()),
|
||||
};
|
||||
|
||||
trees_and_metadata_equal(&left, &right)
|
||||
}
|
||||
|
||||
fn trees_and_metadata_equal(
|
||||
left_tree: &TreeWithMetadata,
|
||||
right_tree: &TreeWithMetadata,
|
||||
) -> Result<(), TreeMismatch> {
|
||||
let left_id = left_tree.tree.get_root_id();
|
||||
let right_id = right_tree.tree.get_root_id();
|
||||
|
||||
instances_equal(left_tree, left_id, right_tree, right_id)
|
||||
}
|
||||
|
||||
fn instances_equal(
|
||||
left_tree: &TreeWithMetadata,
|
||||
left_id: RbxId,
|
||||
right_tree: &TreeWithMetadata,
|
||||
right_id: RbxId,
|
||||
) -> Result<(), TreeMismatch> {
|
||||
basic_equal(left_tree, left_id, right_tree, right_id)?;
|
||||
properties_equal(left_tree, left_id, right_tree, right_id)?;
|
||||
children_equal(left_tree, left_id, right_tree, right_id)?;
|
||||
metadata_equal(left_tree, left_id, right_tree, right_id)
|
||||
}
|
||||
|
||||
fn basic_equal(
|
||||
left_tree: &TreeWithMetadata,
|
||||
left_id: RbxId,
|
||||
right_tree: &TreeWithMetadata,
|
||||
right_id: RbxId,
|
||||
) -> Result<(), TreeMismatch> {
|
||||
let left_instance = left_tree.tree.get_instance(left_id)
|
||||
.expect("ID did not exist in left tree");
|
||||
|
||||
let right_instance = right_tree.tree.get_instance(right_id)
|
||||
.expect("ID did not exist in right tree");
|
||||
|
||||
if left_instance.name != right_instance.name {
|
||||
let message = format!("Name did not match ('{}' vs '{}')", left_instance.name, right_instance.name);
|
||||
|
||||
return Err(TreeMismatch::new(&left_instance.name, message));
|
||||
}
|
||||
|
||||
if left_instance.class_name != right_instance.class_name {
|
||||
let message = format!("Class name did not match ('{}' vs '{}')", left_instance.class_name, right_instance.class_name);
|
||||
|
||||
return Err(TreeMismatch::new(&left_instance.name, message));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn properties_equal(
|
||||
left_tree: &TreeWithMetadata,
|
||||
left_id: RbxId,
|
||||
right_tree: &TreeWithMetadata,
|
||||
right_id: RbxId,
|
||||
) -> Result<(), TreeMismatch> {
|
||||
let left_instance = left_tree.tree.get_instance(left_id)
|
||||
.expect("ID did not exist in left tree");
|
||||
|
||||
let right_instance = right_tree.tree.get_instance(right_id)
|
||||
.expect("ID did not exist in right tree");
|
||||
|
||||
let mut visited = HashSet::new();
|
||||
|
||||
for (key, left_value) in &left_instance.properties {
|
||||
visited.insert(key);
|
||||
|
||||
let right_value = right_instance.properties.get(key);
|
||||
|
||||
if Some(left_value) != right_value {
|
||||
let message = format!(
|
||||
"Property {}:\n\tLeft: {:?}\n\tRight: {:?}",
|
||||
key,
|
||||
Some(left_value),
|
||||
right_value,
|
||||
);
|
||||
|
||||
return Err(TreeMismatch::new(&left_instance.name, message));
|
||||
}
|
||||
}
|
||||
|
||||
for (key, right_value) in &right_instance.properties {
|
||||
if visited.contains(key) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let left_value = left_instance.properties.get(key);
|
||||
|
||||
if left_value != Some(right_value) {
|
||||
let message = format!(
|
||||
"Property {}:\n\tLeft: {:?}\n\tRight: {:?}",
|
||||
key,
|
||||
left_value,
|
||||
Some(right_value),
|
||||
);
|
||||
|
||||
return Err(TreeMismatch::new(&left_instance.name, message));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn children_equal(
|
||||
left_tree: &TreeWithMetadata,
|
||||
left_id: RbxId,
|
||||
right_tree: &TreeWithMetadata,
|
||||
right_id: RbxId,
|
||||
) -> Result<(), TreeMismatch> {
|
||||
let left_instance = left_tree.tree.get_instance(left_id)
|
||||
.expect("ID did not exist in left tree");
|
||||
|
||||
let right_instance = right_tree.tree.get_instance(right_id)
|
||||
.expect("ID did not exist in right tree");
|
||||
|
||||
let left_children = left_instance.get_children_ids();
|
||||
let right_children = right_instance.get_children_ids();
|
||||
|
||||
if left_children.len() != right_children.len() {
|
||||
return Err(TreeMismatch::new(&left_instance.name, "Instances had different numbers of children"));
|
||||
}
|
||||
|
||||
for (left_child_id, right_child_id) in left_children.iter().zip(right_children) {
|
||||
instances_equal(left_tree, *left_child_id, right_tree, *right_child_id)
|
||||
.map_err(|e| e.add_parent(&left_instance.name))?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn metadata_equal(
|
||||
left_tree: &TreeWithMetadata,
|
||||
left_id: RbxId,
|
||||
right_tree: &TreeWithMetadata,
|
||||
right_id: RbxId,
|
||||
) -> Result<(), TreeMismatch> {
|
||||
let left_meta = left_tree.metadata.get(&left_id);
|
||||
let right_meta = right_tree.metadata.get(&right_id);
|
||||
|
||||
if left_meta != right_meta {
|
||||
let left_instance = left_tree.tree.get_instance(left_id)
|
||||
.expect("Left instance didn't exist in tree");
|
||||
|
||||
let message = format!(
|
||||
"Metadata mismatch:\n\tLeft: {:?}\n\tRight: {:?}",
|
||||
left_meta,
|
||||
right_meta,
|
||||
);
|
||||
|
||||
return Err(TreeMismatch::new(&left_instance.name, message));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
68
server/tests/tree_snapshots.rs
Normal file
68
server/tests/tree_snapshots.rs
Normal file
@@ -0,0 +1,68 @@
|
||||
mod test_util;
|
||||
|
||||
use std::{
|
||||
fs,
|
||||
path::{Path, PathBuf},
|
||||
sync::Arc,
|
||||
thread,
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
use tempfile::{tempdir, TempDir};
|
||||
|
||||
use librojo::{
|
||||
live_session::LiveSession,
|
||||
project::Project,
|
||||
};
|
||||
|
||||
use crate::test_util::{
|
||||
copy_recursive,
|
||||
tree::tree_step,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn multi_partition_game() {
|
||||
let _ = env_logger::try_init();
|
||||
let source_path = project_path("multi_partition_game");
|
||||
|
||||
let (dir, live_session) = start_session(&source_path);
|
||||
tree_step("initial", &live_session, &source_path);
|
||||
|
||||
let added_path = dir.path().join("a/added");
|
||||
fs::create_dir_all(&added_path)
|
||||
.expect("Couldn't create directory");
|
||||
thread::sleep(Duration::from_millis(250));
|
||||
|
||||
tree_step("with_dir", &live_session, &source_path);
|
||||
|
||||
let moved_path = dir.path().join("b/added");
|
||||
fs::rename(&added_path, &moved_path)
|
||||
.expect("Couldn't rename directory");
|
||||
thread::sleep(Duration::from_millis(250));
|
||||
|
||||
tree_step("with_moved_dir", &live_session, &source_path);
|
||||
}
|
||||
|
||||
/// Find the path to the given test project relative to the manifest.
|
||||
fn project_path(name: &str) -> PathBuf {
|
||||
let mut path = Path::new(env!("CARGO_MANIFEST_DIR")).join("../test-projects");
|
||||
path.push(name);
|
||||
path
|
||||
}
|
||||
|
||||
/// Starts a new LiveSession for the project located at the given file path.
|
||||
fn start_session(source_path: &Path) -> (TempDir, LiveSession) {
|
||||
let dir = tempdir()
|
||||
.expect("Couldn't create temporary directory");
|
||||
|
||||
copy_recursive(&source_path, dir.path())
|
||||
.expect("Couldn't copy project to temporary directory");
|
||||
|
||||
let project = Arc::new(Project::load_fuzzy(dir.path())
|
||||
.expect("Couldn't load project from temp directory"));
|
||||
|
||||
let live_session = LiveSession::new(Arc::clone(&project))
|
||||
.expect("Couldn't start live session");
|
||||
|
||||
(dir, live_session)
|
||||
}
|
||||
1
test-projects/multi_partition_game/a/foo.txt
Normal file
1
test-projects/multi_partition_game/a/foo.txt
Normal file
@@ -0,0 +1 @@
|
||||
Hello world, from a/foo.txt
|
||||
1
test-projects/multi_partition_game/a/main.lua
Normal file
1
test-projects/multi_partition_game/a/main.lua
Normal file
@@ -0,0 +1 @@
|
||||
-- hello, from a/main.lua
|
||||
1
test-projects/multi_partition_game/b/something.lua
Normal file
1
test-projects/multi_partition_game/b/something.lua
Normal file
@@ -0,0 +1 @@
|
||||
-- b/something.lua
|
||||
21
test-projects/multi_partition_game/default.project.json
Normal file
21
test-projects/multi_partition_game/default.project.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"name": "multi_partition_game",
|
||||
"tree": {
|
||||
"$className": "DataModel",
|
||||
"ReplicatedStorage": {
|
||||
"$className": "ReplicatedStorage",
|
||||
"Ack": {
|
||||
"$path": "a"
|
||||
},
|
||||
"Bar": {
|
||||
"$path": "b"
|
||||
}
|
||||
},
|
||||
"HttpService": {
|
||||
"$className": "HttpService",
|
||||
"$properties": {
|
||||
"HttpEnabled": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
212
test-projects/multi_partition_game/expected-snapshot.json
Normal file
212
test-projects/multi_partition_game/expected-snapshot.json
Normal file
@@ -0,0 +1,212 @@
|
||||
{
|
||||
"name": "multi_partition_game",
|
||||
"class_name": "DataModel",
|
||||
"properties": {},
|
||||
"children": [
|
||||
{
|
||||
"name": "HttpService",
|
||||
"class_name": "HttpService",
|
||||
"properties": {
|
||||
"HttpEnabled": {
|
||||
"Type": "Bool",
|
||||
"Value": true
|
||||
}
|
||||
},
|
||||
"children": [],
|
||||
"metadata": {
|
||||
"ignore_unknown_instances": true,
|
||||
"source_path": null,
|
||||
"project_definition": [
|
||||
"HttpService",
|
||||
{
|
||||
"class_name": "HttpService",
|
||||
"children": {},
|
||||
"properties": {
|
||||
"HttpEnabled": {
|
||||
"Type": "Bool",
|
||||
"Value": true
|
||||
}
|
||||
},
|
||||
"ignore_unknown_instances": null,
|
||||
"path": null
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ReplicatedStorage",
|
||||
"class_name": "ReplicatedStorage",
|
||||
"properties": {},
|
||||
"children": [
|
||||
{
|
||||
"name": "Ack",
|
||||
"class_name": "Folder",
|
||||
"properties": {},
|
||||
"children": [
|
||||
{
|
||||
"name": "foo",
|
||||
"class_name": "StringValue",
|
||||
"properties": {
|
||||
"Value": {
|
||||
"Type": "String",
|
||||
"Value": "Hello world, from a/foo.txt"
|
||||
}
|
||||
},
|
||||
"children": [],
|
||||
"metadata": {
|
||||
"ignore_unknown_instances": false,
|
||||
"source_path": "a/foo.txt",
|
||||
"project_definition": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "main",
|
||||
"class_name": "ModuleScript",
|
||||
"properties": {
|
||||
"Source": {
|
||||
"Type": "String",
|
||||
"Value": "-- hello, from a/main.lua"
|
||||
}
|
||||
},
|
||||
"children": [],
|
||||
"metadata": {
|
||||
"ignore_unknown_instances": false,
|
||||
"source_path": "a/main.lua",
|
||||
"project_definition": null
|
||||
}
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"ignore_unknown_instances": false,
|
||||
"source_path": "a",
|
||||
"project_definition": [
|
||||
"Ack",
|
||||
{
|
||||
"class_name": null,
|
||||
"children": {},
|
||||
"properties": {},
|
||||
"ignore_unknown_instances": null,
|
||||
"path": "a"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Bar",
|
||||
"class_name": "Folder",
|
||||
"properties": {},
|
||||
"children": [
|
||||
{
|
||||
"name": "something",
|
||||
"class_name": "ModuleScript",
|
||||
"properties": {
|
||||
"Source": {
|
||||
"Type": "String",
|
||||
"Value": "-- b/something.lua"
|
||||
}
|
||||
},
|
||||
"children": [],
|
||||
"metadata": {
|
||||
"ignore_unknown_instances": false,
|
||||
"source_path": "b/something.lua",
|
||||
"project_definition": null
|
||||
}
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"ignore_unknown_instances": false,
|
||||
"source_path": "b",
|
||||
"project_definition": [
|
||||
"Bar",
|
||||
{
|
||||
"class_name": null,
|
||||
"children": {},
|
||||
"properties": {},
|
||||
"ignore_unknown_instances": null,
|
||||
"path": "b"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"ignore_unknown_instances": true,
|
||||
"source_path": null,
|
||||
"project_definition": [
|
||||
"ReplicatedStorage",
|
||||
{
|
||||
"class_name": "ReplicatedStorage",
|
||||
"children": {
|
||||
"Bar": {
|
||||
"class_name": null,
|
||||
"children": {},
|
||||
"properties": {},
|
||||
"ignore_unknown_instances": null,
|
||||
"path": "b"
|
||||
},
|
||||
"Ack": {
|
||||
"class_name": null,
|
||||
"children": {},
|
||||
"properties": {},
|
||||
"ignore_unknown_instances": null,
|
||||
"path": "a"
|
||||
}
|
||||
},
|
||||
"properties": {},
|
||||
"ignore_unknown_instances": null,
|
||||
"path": null
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"ignore_unknown_instances": true,
|
||||
"source_path": null,
|
||||
"project_definition": [
|
||||
"multi_partition_game",
|
||||
{
|
||||
"class_name": "DataModel",
|
||||
"children": {
|
||||
"ReplicatedStorage": {
|
||||
"class_name": "ReplicatedStorage",
|
||||
"children": {
|
||||
"Bar": {
|
||||
"class_name": null,
|
||||
"children": {},
|
||||
"properties": {},
|
||||
"ignore_unknown_instances": null,
|
||||
"path": "b"
|
||||
},
|
||||
"Ack": {
|
||||
"class_name": null,
|
||||
"children": {},
|
||||
"properties": {},
|
||||
"ignore_unknown_instances": null,
|
||||
"path": "a"
|
||||
}
|
||||
},
|
||||
"properties": {},
|
||||
"ignore_unknown_instances": null,
|
||||
"path": null
|
||||
},
|
||||
"HttpService": {
|
||||
"class_name": "HttpService",
|
||||
"children": {},
|
||||
"properties": {
|
||||
"HttpEnabled": {
|
||||
"Type": "Bool",
|
||||
"Value": true
|
||||
}
|
||||
},
|
||||
"ignore_unknown_instances": null,
|
||||
"path": null
|
||||
}
|
||||
},
|
||||
"properties": {},
|
||||
"ignore_unknown_instances": null,
|
||||
"path": null
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
242
test-projects/multi_partition_game/initial.tree.json
Normal file
242
test-projects/multi_partition_game/initial.tree.json
Normal file
@@ -0,0 +1,242 @@
|
||||
{
|
||||
"instances": {
|
||||
"8d44bb30-db3c-4366-a6c5-633bd1441885": {
|
||||
"Name": "main",
|
||||
"ClassName": "ModuleScript",
|
||||
"Properties": {
|
||||
"Source": {
|
||||
"Type": "String",
|
||||
"Value": "-- hello, from a/main.lua"
|
||||
}
|
||||
},
|
||||
"Id": "8d44bb30-db3c-4366-a6c5-633bd1441885",
|
||||
"Children": [],
|
||||
"Parent": "1aafa29b-bdca-40a0-a677-7ead327b84ce"
|
||||
},
|
||||
"b1c9928c-bf11-427f-90eb-b672c811d859": {
|
||||
"Name": "Bar",
|
||||
"ClassName": "Folder",
|
||||
"Properties": {},
|
||||
"Id": "b1c9928c-bf11-427f-90eb-b672c811d859",
|
||||
"Children": [
|
||||
"8d690a2a-e987-4c86-b9ac-18e6d3a98503"
|
||||
],
|
||||
"Parent": "9f141826-14c2-492b-b360-2558712f0c08"
|
||||
},
|
||||
"645ba594-4482-441f-9f41-5bb9c444405b": {
|
||||
"Name": "multi_partition_game",
|
||||
"ClassName": "DataModel",
|
||||
"Properties": {},
|
||||
"Id": "645ba594-4482-441f-9f41-5bb9c444405b",
|
||||
"Children": [
|
||||
"b1298bcc-e370-44a6-9ef4-fbefa290124c",
|
||||
"9f141826-14c2-492b-b360-2558712f0c08"
|
||||
],
|
||||
"Parent": null
|
||||
},
|
||||
"9f141826-14c2-492b-b360-2558712f0c08": {
|
||||
"Name": "ReplicatedStorage",
|
||||
"ClassName": "ReplicatedStorage",
|
||||
"Properties": {},
|
||||
"Id": "9f141826-14c2-492b-b360-2558712f0c08",
|
||||
"Children": [
|
||||
"1aafa29b-bdca-40a0-a677-7ead327b84ce",
|
||||
"b1c9928c-bf11-427f-90eb-b672c811d859"
|
||||
],
|
||||
"Parent": "645ba594-4482-441f-9f41-5bb9c444405b"
|
||||
},
|
||||
"8d690a2a-e987-4c86-b9ac-18e6d3a98503": {
|
||||
"Name": "something",
|
||||
"ClassName": "ModuleScript",
|
||||
"Properties": {
|
||||
"Source": {
|
||||
"Type": "String",
|
||||
"Value": "-- b/something.lua"
|
||||
}
|
||||
},
|
||||
"Id": "8d690a2a-e987-4c86-b9ac-18e6d3a98503",
|
||||
"Children": [],
|
||||
"Parent": "b1c9928c-bf11-427f-90eb-b672c811d859"
|
||||
},
|
||||
"b1298bcc-e370-44a6-9ef4-fbefa290124c": {
|
||||
"Name": "HttpService",
|
||||
"ClassName": "HttpService",
|
||||
"Properties": {
|
||||
"HttpEnabled": {
|
||||
"Type": "Bool",
|
||||
"Value": true
|
||||
}
|
||||
},
|
||||
"Id": "b1298bcc-e370-44a6-9ef4-fbefa290124c",
|
||||
"Children": [],
|
||||
"Parent": "645ba594-4482-441f-9f41-5bb9c444405b"
|
||||
},
|
||||
"54f2f276-964f-4c60-87d8-5fb2209c97c9": {
|
||||
"Name": "foo",
|
||||
"ClassName": "StringValue",
|
||||
"Properties": {
|
||||
"Value": {
|
||||
"Type": "String",
|
||||
"Value": "Hello world, from a/foo.txt"
|
||||
}
|
||||
},
|
||||
"Id": "54f2f276-964f-4c60-87d8-5fb2209c97c9",
|
||||
"Children": [],
|
||||
"Parent": "1aafa29b-bdca-40a0-a677-7ead327b84ce"
|
||||
},
|
||||
"1aafa29b-bdca-40a0-a677-7ead327b84ce": {
|
||||
"Name": "Ack",
|
||||
"ClassName": "Folder",
|
||||
"Properties": {},
|
||||
"Id": "1aafa29b-bdca-40a0-a677-7ead327b84ce",
|
||||
"Children": [
|
||||
"54f2f276-964f-4c60-87d8-5fb2209c97c9",
|
||||
"8d44bb30-db3c-4366-a6c5-633bd1441885"
|
||||
],
|
||||
"Parent": "9f141826-14c2-492b-b360-2558712f0c08"
|
||||
}
|
||||
},
|
||||
"root_id": "645ba594-4482-441f-9f41-5bb9c444405b",
|
||||
"metadata": {
|
||||
"645ba594-4482-441f-9f41-5bb9c444405b": {
|
||||
"ignore_unknown_instances": true,
|
||||
"source_path": null,
|
||||
"project_definition": [
|
||||
"multi_partition_game",
|
||||
{
|
||||
"class_name": "DataModel",
|
||||
"children": {
|
||||
"HttpService": {
|
||||
"class_name": "HttpService",
|
||||
"children": {},
|
||||
"properties": {
|
||||
"HttpEnabled": {
|
||||
"Type": "Bool",
|
||||
"Value": true
|
||||
}
|
||||
},
|
||||
"ignore_unknown_instances": null,
|
||||
"path": null
|
||||
},
|
||||
"ReplicatedStorage": {
|
||||
"class_name": "ReplicatedStorage",
|
||||
"children": {
|
||||
"Ack": {
|
||||
"class_name": null,
|
||||
"children": {},
|
||||
"properties": {},
|
||||
"ignore_unknown_instances": null,
|
||||
"path": "a"
|
||||
},
|
||||
"Bar": {
|
||||
"class_name": null,
|
||||
"children": {},
|
||||
"properties": {},
|
||||
"ignore_unknown_instances": null,
|
||||
"path": "b"
|
||||
}
|
||||
},
|
||||
"properties": {},
|
||||
"ignore_unknown_instances": null,
|
||||
"path": null
|
||||
}
|
||||
},
|
||||
"properties": {},
|
||||
"ignore_unknown_instances": null,
|
||||
"path": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"1aafa29b-bdca-40a0-a677-7ead327b84ce": {
|
||||
"ignore_unknown_instances": false,
|
||||
"source_path": "a",
|
||||
"project_definition": [
|
||||
"Ack",
|
||||
{
|
||||
"class_name": null,
|
||||
"children": {},
|
||||
"properties": {},
|
||||
"ignore_unknown_instances": null,
|
||||
"path": "a"
|
||||
}
|
||||
]
|
||||
},
|
||||
"b1c9928c-bf11-427f-90eb-b672c811d859": {
|
||||
"ignore_unknown_instances": false,
|
||||
"source_path": "b",
|
||||
"project_definition": [
|
||||
"Bar",
|
||||
{
|
||||
"class_name": null,
|
||||
"children": {},
|
||||
"properties": {},
|
||||
"ignore_unknown_instances": null,
|
||||
"path": "b"
|
||||
}
|
||||
]
|
||||
},
|
||||
"54f2f276-964f-4c60-87d8-5fb2209c97c9": {
|
||||
"ignore_unknown_instances": false,
|
||||
"source_path": "a/foo.txt",
|
||||
"project_definition": null
|
||||
},
|
||||
"9f141826-14c2-492b-b360-2558712f0c08": {
|
||||
"ignore_unknown_instances": true,
|
||||
"source_path": null,
|
||||
"project_definition": [
|
||||
"ReplicatedStorage",
|
||||
{
|
||||
"class_name": "ReplicatedStorage",
|
||||
"children": {
|
||||
"Ack": {
|
||||
"class_name": null,
|
||||
"children": {},
|
||||
"properties": {},
|
||||
"ignore_unknown_instances": null,
|
||||
"path": "a"
|
||||
},
|
||||
"Bar": {
|
||||
"class_name": null,
|
||||
"children": {},
|
||||
"properties": {},
|
||||
"ignore_unknown_instances": null,
|
||||
"path": "b"
|
||||
}
|
||||
},
|
||||
"properties": {},
|
||||
"ignore_unknown_instances": null,
|
||||
"path": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"8d44bb30-db3c-4366-a6c5-633bd1441885": {
|
||||
"ignore_unknown_instances": false,
|
||||
"source_path": "a/main.lua",
|
||||
"project_definition": null
|
||||
},
|
||||
"b1298bcc-e370-44a6-9ef4-fbefa290124c": {
|
||||
"ignore_unknown_instances": true,
|
||||
"source_path": null,
|
||||
"project_definition": [
|
||||
"HttpService",
|
||||
{
|
||||
"class_name": "HttpService",
|
||||
"children": {},
|
||||
"properties": {
|
||||
"HttpEnabled": {
|
||||
"Type": "Bool",
|
||||
"Value": true
|
||||
}
|
||||
},
|
||||
"ignore_unknown_instances": null,
|
||||
"path": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"8d690a2a-e987-4c86-b9ac-18e6d3a98503": {
|
||||
"ignore_unknown_instances": false,
|
||||
"source_path": "b/something.lua",
|
||||
"project_definition": null
|
||||
}
|
||||
}
|
||||
}
|
||||
256
test-projects/multi_partition_game/with_dir.tree.json
Normal file
256
test-projects/multi_partition_game/with_dir.tree.json
Normal file
@@ -0,0 +1,256 @@
|
||||
{
|
||||
"instances": {
|
||||
"8d44bb30-db3c-4366-a6c5-633bd1441885": {
|
||||
"Name": "main",
|
||||
"ClassName": "ModuleScript",
|
||||
"Properties": {
|
||||
"Source": {
|
||||
"Type": "String",
|
||||
"Value": "-- hello, from a/main.lua"
|
||||
}
|
||||
},
|
||||
"Id": "8d44bb30-db3c-4366-a6c5-633bd1441885",
|
||||
"Children": [],
|
||||
"Parent": "1aafa29b-bdca-40a0-a677-7ead327b84ce"
|
||||
},
|
||||
"b1c9928c-bf11-427f-90eb-b672c811d859": {
|
||||
"Name": "Bar",
|
||||
"ClassName": "Folder",
|
||||
"Properties": {},
|
||||
"Id": "b1c9928c-bf11-427f-90eb-b672c811d859",
|
||||
"Children": [
|
||||
"8d690a2a-e987-4c86-b9ac-18e6d3a98503"
|
||||
],
|
||||
"Parent": "9f141826-14c2-492b-b360-2558712f0c08"
|
||||
},
|
||||
"645ba594-4482-441f-9f41-5bb9c444405b": {
|
||||
"Name": "multi_partition_game",
|
||||
"ClassName": "DataModel",
|
||||
"Properties": {},
|
||||
"Id": "645ba594-4482-441f-9f41-5bb9c444405b",
|
||||
"Children": [
|
||||
"b1298bcc-e370-44a6-9ef4-fbefa290124c",
|
||||
"9f141826-14c2-492b-b360-2558712f0c08"
|
||||
],
|
||||
"Parent": null
|
||||
},
|
||||
"9f141826-14c2-492b-b360-2558712f0c08": {
|
||||
"Name": "ReplicatedStorage",
|
||||
"ClassName": "ReplicatedStorage",
|
||||
"Properties": {},
|
||||
"Id": "9f141826-14c2-492b-b360-2558712f0c08",
|
||||
"Children": [
|
||||
"1aafa29b-bdca-40a0-a677-7ead327b84ce",
|
||||
"b1c9928c-bf11-427f-90eb-b672c811d859"
|
||||
],
|
||||
"Parent": "645ba594-4482-441f-9f41-5bb9c444405b"
|
||||
},
|
||||
"8d690a2a-e987-4c86-b9ac-18e6d3a98503": {
|
||||
"Name": "something",
|
||||
"ClassName": "ModuleScript",
|
||||
"Properties": {
|
||||
"Source": {
|
||||
"Type": "String",
|
||||
"Value": "-- b/something.lua"
|
||||
}
|
||||
},
|
||||
"Id": "8d690a2a-e987-4c86-b9ac-18e6d3a98503",
|
||||
"Children": [],
|
||||
"Parent": "b1c9928c-bf11-427f-90eb-b672c811d859"
|
||||
},
|
||||
"b1298bcc-e370-44a6-9ef4-fbefa290124c": {
|
||||
"Name": "HttpService",
|
||||
"ClassName": "HttpService",
|
||||
"Properties": {
|
||||
"HttpEnabled": {
|
||||
"Type": "Bool",
|
||||
"Value": true
|
||||
}
|
||||
},
|
||||
"Id": "b1298bcc-e370-44a6-9ef4-fbefa290124c",
|
||||
"Children": [],
|
||||
"Parent": "645ba594-4482-441f-9f41-5bb9c444405b"
|
||||
},
|
||||
"46353305-8818-48fe-94fd-80cf0c5d974c": {
|
||||
"Name": "added",
|
||||
"ClassName": "Folder",
|
||||
"Properties": {},
|
||||
"Id": "46353305-8818-48fe-94fd-80cf0c5d974c",
|
||||
"Children": [],
|
||||
"Parent": "1aafa29b-bdca-40a0-a677-7ead327b84ce"
|
||||
},
|
||||
"54f2f276-964f-4c60-87d8-5fb2209c97c9": {
|
||||
"Name": "foo",
|
||||
"ClassName": "StringValue",
|
||||
"Properties": {
|
||||
"Value": {
|
||||
"Type": "String",
|
||||
"Value": "Hello world, from a/foo.txt"
|
||||
}
|
||||
},
|
||||
"Id": "54f2f276-964f-4c60-87d8-5fb2209c97c9",
|
||||
"Children": [],
|
||||
"Parent": "1aafa29b-bdca-40a0-a677-7ead327b84ce"
|
||||
},
|
||||
"1aafa29b-bdca-40a0-a677-7ead327b84ce": {
|
||||
"Name": "Ack",
|
||||
"ClassName": "Folder",
|
||||
"Properties": {},
|
||||
"Id": "1aafa29b-bdca-40a0-a677-7ead327b84ce",
|
||||
"Children": [
|
||||
"54f2f276-964f-4c60-87d8-5fb2209c97c9",
|
||||
"8d44bb30-db3c-4366-a6c5-633bd1441885",
|
||||
"46353305-8818-48fe-94fd-80cf0c5d974c"
|
||||
],
|
||||
"Parent": "9f141826-14c2-492b-b360-2558712f0c08"
|
||||
}
|
||||
},
|
||||
"root_id": "645ba594-4482-441f-9f41-5bb9c444405b",
|
||||
"metadata": {
|
||||
"b1c9928c-bf11-427f-90eb-b672c811d859": {
|
||||
"ignore_unknown_instances": false,
|
||||
"source_path": "b",
|
||||
"project_definition": [
|
||||
"Bar",
|
||||
{
|
||||
"class_name": null,
|
||||
"children": {},
|
||||
"properties": {},
|
||||
"ignore_unknown_instances": null,
|
||||
"path": "b"
|
||||
}
|
||||
]
|
||||
},
|
||||
"54f2f276-964f-4c60-87d8-5fb2209c97c9": {
|
||||
"ignore_unknown_instances": false,
|
||||
"source_path": "a/foo.txt",
|
||||
"project_definition": null
|
||||
},
|
||||
"8d44bb30-db3c-4366-a6c5-633bd1441885": {
|
||||
"ignore_unknown_instances": false,
|
||||
"source_path": "a/main.lua",
|
||||
"project_definition": null
|
||||
},
|
||||
"9f141826-14c2-492b-b360-2558712f0c08": {
|
||||
"ignore_unknown_instances": true,
|
||||
"source_path": null,
|
||||
"project_definition": [
|
||||
"ReplicatedStorage",
|
||||
{
|
||||
"class_name": "ReplicatedStorage",
|
||||
"children": {
|
||||
"Ack": {
|
||||
"class_name": null,
|
||||
"children": {},
|
||||
"properties": {},
|
||||
"ignore_unknown_instances": null,
|
||||
"path": "a"
|
||||
},
|
||||
"Bar": {
|
||||
"class_name": null,
|
||||
"children": {},
|
||||
"properties": {},
|
||||
"ignore_unknown_instances": null,
|
||||
"path": "b"
|
||||
}
|
||||
},
|
||||
"properties": {},
|
||||
"ignore_unknown_instances": null,
|
||||
"path": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"b1298bcc-e370-44a6-9ef4-fbefa290124c": {
|
||||
"ignore_unknown_instances": true,
|
||||
"source_path": null,
|
||||
"project_definition": [
|
||||
"HttpService",
|
||||
{
|
||||
"class_name": "HttpService",
|
||||
"children": {},
|
||||
"properties": {
|
||||
"HttpEnabled": {
|
||||
"Type": "Bool",
|
||||
"Value": true
|
||||
}
|
||||
},
|
||||
"ignore_unknown_instances": null,
|
||||
"path": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"46353305-8818-48fe-94fd-80cf0c5d974c": {
|
||||
"ignore_unknown_instances": false,
|
||||
"source_path": "a/added",
|
||||
"project_definition": null
|
||||
},
|
||||
"1aafa29b-bdca-40a0-a677-7ead327b84ce": {
|
||||
"ignore_unknown_instances": false,
|
||||
"source_path": "a",
|
||||
"project_definition": [
|
||||
"Ack",
|
||||
{
|
||||
"class_name": null,
|
||||
"children": {},
|
||||
"properties": {},
|
||||
"ignore_unknown_instances": null,
|
||||
"path": "a"
|
||||
}
|
||||
]
|
||||
},
|
||||
"8d690a2a-e987-4c86-b9ac-18e6d3a98503": {
|
||||
"ignore_unknown_instances": false,
|
||||
"source_path": "b/something.lua",
|
||||
"project_definition": null
|
||||
},
|
||||
"645ba594-4482-441f-9f41-5bb9c444405b": {
|
||||
"ignore_unknown_instances": true,
|
||||
"source_path": null,
|
||||
"project_definition": [
|
||||
"multi_partition_game",
|
||||
{
|
||||
"class_name": "DataModel",
|
||||
"children": {
|
||||
"HttpService": {
|
||||
"class_name": "HttpService",
|
||||
"children": {},
|
||||
"properties": {
|
||||
"HttpEnabled": {
|
||||
"Type": "Bool",
|
||||
"Value": true
|
||||
}
|
||||
},
|
||||
"ignore_unknown_instances": null,
|
||||
"path": null
|
||||
},
|
||||
"ReplicatedStorage": {
|
||||
"class_name": "ReplicatedStorage",
|
||||
"children": {
|
||||
"Ack": {
|
||||
"class_name": null,
|
||||
"children": {},
|
||||
"properties": {},
|
||||
"ignore_unknown_instances": null,
|
||||
"path": "a"
|
||||
},
|
||||
"Bar": {
|
||||
"class_name": null,
|
||||
"children": {},
|
||||
"properties": {},
|
||||
"ignore_unknown_instances": null,
|
||||
"path": "b"
|
||||
}
|
||||
},
|
||||
"properties": {},
|
||||
"ignore_unknown_instances": null,
|
||||
"path": null
|
||||
}
|
||||
},
|
||||
"properties": {},
|
||||
"ignore_unknown_instances": null,
|
||||
"path": null
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
256
test-projects/multi_partition_game/with_moved_dir.tree.json
Normal file
256
test-projects/multi_partition_game/with_moved_dir.tree.json
Normal file
@@ -0,0 +1,256 @@
|
||||
{
|
||||
"instances": {
|
||||
"8d44bb30-db3c-4366-a6c5-633bd1441885": {
|
||||
"Name": "main",
|
||||
"ClassName": "ModuleScript",
|
||||
"Properties": {
|
||||
"Source": {
|
||||
"Type": "String",
|
||||
"Value": "-- hello, from a/main.lua"
|
||||
}
|
||||
},
|
||||
"Id": "8d44bb30-db3c-4366-a6c5-633bd1441885",
|
||||
"Children": [],
|
||||
"Parent": "1aafa29b-bdca-40a0-a677-7ead327b84ce"
|
||||
},
|
||||
"b1c9928c-bf11-427f-90eb-b672c811d859": {
|
||||
"Name": "Bar",
|
||||
"ClassName": "Folder",
|
||||
"Properties": {},
|
||||
"Id": "b1c9928c-bf11-427f-90eb-b672c811d859",
|
||||
"Children": [
|
||||
"8d690a2a-e987-4c86-b9ac-18e6d3a98503",
|
||||
"a8566e76-0495-45a3-a713-1c59ab39453b"
|
||||
],
|
||||
"Parent": "9f141826-14c2-492b-b360-2558712f0c08"
|
||||
},
|
||||
"645ba594-4482-441f-9f41-5bb9c444405b": {
|
||||
"Name": "multi_partition_game",
|
||||
"ClassName": "DataModel",
|
||||
"Properties": {},
|
||||
"Id": "645ba594-4482-441f-9f41-5bb9c444405b",
|
||||
"Children": [
|
||||
"b1298bcc-e370-44a6-9ef4-fbefa290124c",
|
||||
"9f141826-14c2-492b-b360-2558712f0c08"
|
||||
],
|
||||
"Parent": null
|
||||
},
|
||||
"9f141826-14c2-492b-b360-2558712f0c08": {
|
||||
"Name": "ReplicatedStorage",
|
||||
"ClassName": "ReplicatedStorage",
|
||||
"Properties": {},
|
||||
"Id": "9f141826-14c2-492b-b360-2558712f0c08",
|
||||
"Children": [
|
||||
"1aafa29b-bdca-40a0-a677-7ead327b84ce",
|
||||
"b1c9928c-bf11-427f-90eb-b672c811d859"
|
||||
],
|
||||
"Parent": "645ba594-4482-441f-9f41-5bb9c444405b"
|
||||
},
|
||||
"8d690a2a-e987-4c86-b9ac-18e6d3a98503": {
|
||||
"Name": "something",
|
||||
"ClassName": "ModuleScript",
|
||||
"Properties": {
|
||||
"Source": {
|
||||
"Type": "String",
|
||||
"Value": "-- b/something.lua"
|
||||
}
|
||||
},
|
||||
"Id": "8d690a2a-e987-4c86-b9ac-18e6d3a98503",
|
||||
"Children": [],
|
||||
"Parent": "b1c9928c-bf11-427f-90eb-b672c811d859"
|
||||
},
|
||||
"b1298bcc-e370-44a6-9ef4-fbefa290124c": {
|
||||
"Name": "HttpService",
|
||||
"ClassName": "HttpService",
|
||||
"Properties": {
|
||||
"HttpEnabled": {
|
||||
"Type": "Bool",
|
||||
"Value": true
|
||||
}
|
||||
},
|
||||
"Id": "b1298bcc-e370-44a6-9ef4-fbefa290124c",
|
||||
"Children": [],
|
||||
"Parent": "645ba594-4482-441f-9f41-5bb9c444405b"
|
||||
},
|
||||
"54f2f276-964f-4c60-87d8-5fb2209c97c9": {
|
||||
"Name": "foo",
|
||||
"ClassName": "StringValue",
|
||||
"Properties": {
|
||||
"Value": {
|
||||
"Type": "String",
|
||||
"Value": "Hello world, from a/foo.txt"
|
||||
}
|
||||
},
|
||||
"Id": "54f2f276-964f-4c60-87d8-5fb2209c97c9",
|
||||
"Children": [],
|
||||
"Parent": "1aafa29b-bdca-40a0-a677-7ead327b84ce"
|
||||
},
|
||||
"a8566e76-0495-45a3-a713-1c59ab39453b": {
|
||||
"Name": "added",
|
||||
"ClassName": "Folder",
|
||||
"Properties": {},
|
||||
"Id": "a8566e76-0495-45a3-a713-1c59ab39453b",
|
||||
"Children": [],
|
||||
"Parent": "b1c9928c-bf11-427f-90eb-b672c811d859"
|
||||
},
|
||||
"1aafa29b-bdca-40a0-a677-7ead327b84ce": {
|
||||
"Name": "Ack",
|
||||
"ClassName": "Folder",
|
||||
"Properties": {},
|
||||
"Id": "1aafa29b-bdca-40a0-a677-7ead327b84ce",
|
||||
"Children": [
|
||||
"54f2f276-964f-4c60-87d8-5fb2209c97c9",
|
||||
"8d44bb30-db3c-4366-a6c5-633bd1441885"
|
||||
],
|
||||
"Parent": "9f141826-14c2-492b-b360-2558712f0c08"
|
||||
}
|
||||
},
|
||||
"root_id": "645ba594-4482-441f-9f41-5bb9c444405b",
|
||||
"metadata": {
|
||||
"645ba594-4482-441f-9f41-5bb9c444405b": {
|
||||
"ignore_unknown_instances": true,
|
||||
"source_path": null,
|
||||
"project_definition": [
|
||||
"multi_partition_game",
|
||||
{
|
||||
"class_name": "DataModel",
|
||||
"children": {
|
||||
"HttpService": {
|
||||
"class_name": "HttpService",
|
||||
"children": {},
|
||||
"properties": {
|
||||
"HttpEnabled": {
|
||||
"Type": "Bool",
|
||||
"Value": true
|
||||
}
|
||||
},
|
||||
"ignore_unknown_instances": null,
|
||||
"path": null
|
||||
},
|
||||
"ReplicatedStorage": {
|
||||
"class_name": "ReplicatedStorage",
|
||||
"children": {
|
||||
"Ack": {
|
||||
"class_name": null,
|
||||
"children": {},
|
||||
"properties": {},
|
||||
"ignore_unknown_instances": null,
|
||||
"path": "a"
|
||||
},
|
||||
"Bar": {
|
||||
"class_name": null,
|
||||
"children": {},
|
||||
"properties": {},
|
||||
"ignore_unknown_instances": null,
|
||||
"path": "b"
|
||||
}
|
||||
},
|
||||
"properties": {},
|
||||
"ignore_unknown_instances": null,
|
||||
"path": null
|
||||
}
|
||||
},
|
||||
"properties": {},
|
||||
"ignore_unknown_instances": null,
|
||||
"path": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"1aafa29b-bdca-40a0-a677-7ead327b84ce": {
|
||||
"ignore_unknown_instances": false,
|
||||
"source_path": "a",
|
||||
"project_definition": [
|
||||
"Ack",
|
||||
{
|
||||
"class_name": null,
|
||||
"children": {},
|
||||
"properties": {},
|
||||
"ignore_unknown_instances": null,
|
||||
"path": "a"
|
||||
}
|
||||
]
|
||||
},
|
||||
"a8566e76-0495-45a3-a713-1c59ab39453b": {
|
||||
"ignore_unknown_instances": false,
|
||||
"source_path": "b/added",
|
||||
"project_definition": null
|
||||
},
|
||||
"8d690a2a-e987-4c86-b9ac-18e6d3a98503": {
|
||||
"ignore_unknown_instances": false,
|
||||
"source_path": "b/something.lua",
|
||||
"project_definition": null
|
||||
},
|
||||
"8d44bb30-db3c-4366-a6c5-633bd1441885": {
|
||||
"ignore_unknown_instances": false,
|
||||
"source_path": "a/main.lua",
|
||||
"project_definition": null
|
||||
},
|
||||
"9f141826-14c2-492b-b360-2558712f0c08": {
|
||||
"ignore_unknown_instances": true,
|
||||
"source_path": null,
|
||||
"project_definition": [
|
||||
"ReplicatedStorage",
|
||||
{
|
||||
"class_name": "ReplicatedStorage",
|
||||
"children": {
|
||||
"Ack": {
|
||||
"class_name": null,
|
||||
"children": {},
|
||||
"properties": {},
|
||||
"ignore_unknown_instances": null,
|
||||
"path": "a"
|
||||
},
|
||||
"Bar": {
|
||||
"class_name": null,
|
||||
"children": {},
|
||||
"properties": {},
|
||||
"ignore_unknown_instances": null,
|
||||
"path": "b"
|
||||
}
|
||||
},
|
||||
"properties": {},
|
||||
"ignore_unknown_instances": null,
|
||||
"path": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"b1c9928c-bf11-427f-90eb-b672c811d859": {
|
||||
"ignore_unknown_instances": false,
|
||||
"source_path": "b",
|
||||
"project_definition": [
|
||||
"Bar",
|
||||
{
|
||||
"class_name": null,
|
||||
"children": {},
|
||||
"properties": {},
|
||||
"ignore_unknown_instances": null,
|
||||
"path": "b"
|
||||
}
|
||||
]
|
||||
},
|
||||
"54f2f276-964f-4c60-87d8-5fb2209c97c9": {
|
||||
"ignore_unknown_instances": false,
|
||||
"source_path": "a/foo.txt",
|
||||
"project_definition": null
|
||||
},
|
||||
"b1298bcc-e370-44a6-9ef4-fbefa290124c": {
|
||||
"ignore_unknown_instances": true,
|
||||
"source_path": null,
|
||||
"project_definition": [
|
||||
"HttpService",
|
||||
{
|
||||
"class_name": "HttpService",
|
||||
"children": {},
|
||||
"properties": {
|
||||
"HttpEnabled": {
|
||||
"Type": "Bool",
|
||||
"Value": true
|
||||
}
|
||||
},
|
||||
"ignore_unknown_instances": null,
|
||||
"path": null
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user