diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 28565bb94..b7dbd5eea 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -19,16 +19,12 @@ jobs:
os: [ubuntu-latest, windows-latest, macos-latest]
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
with:
submodules: true
- name: Install Rust
- uses: actions-rs/toolchain@v1
- with:
- toolchain: stable
- override: true
- profile: minimal
+ uses: dtolnay/rust-toolchain@stable
- name: Rust cache
uses: Swatinem/rust-cache@v2
@@ -49,16 +45,12 @@ jobs:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
with:
submodules: true
- name: Install Rust
- uses: actions-rs/toolchain@v1
- with:
- toolchain: 1.70.0
- override: true
- profile: minimal
+ uses: dtolnay/rust-toolchain@1.70.0
- name: Rust cache
uses: Swatinem/rust-cache@v2
@@ -76,15 +68,13 @@ jobs:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
with:
submodules: true
- name: Install Rust
- uses: actions-rs/toolchain@v1
+ uses: dtolnay/rust-toolchain@stable
with:
- toolchain: stable
- override: true
components: rustfmt, clippy
- name: Rust cache
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 5cc781b06..8219cd1cc 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -8,26 +8,20 @@ jobs:
create-release:
name: Create Release
runs-on: ubuntu-latest
- outputs:
- upload_url: ${{ steps.create_release.outputs.upload_url }}
steps:
+ - uses: actions/checkout@v4
- name: Create Release
- id: create_release
- uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- with:
- tag_name: ${{ github.ref }}
- release_name: ${{ github.ref }}
- draft: true
- prerelease: false
+ run: |
+ gh release create ${{ github.ref_name }} --draft --verify-tag --title ${{ github.ref_name }}
build-plugin:
needs: ["create-release"]
name: Build Roblox Studio Plugin
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
with:
submodules: true
@@ -42,17 +36,13 @@ jobs:
run: rojo build plugin --output Rojo.rbxm
- name: Upload Plugin to Release
- uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- with:
- upload_url: ${{ needs.create-release.outputs.upload_url }}
- asset_path: Rojo.rbxm
- asset_name: Rojo.rbxm
- asset_content_type: application/octet-stream
+ run: |
+ gh release upload ${{ github.ref_name }} Rojo.rbxm
- name: Upload Plugin to Artifacts
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
with:
name: Rojo.rbxm
path: Rojo.rbxm
@@ -89,24 +79,14 @@ jobs:
env:
BIN: rojo
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
with:
submodules: true
- - name: Get Version from Tag
- shell: bash
- # https://github.community/t/how-to-get-just-the-tag-name/16241/7#M1027
- run: |
- echo "PROJECT_VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_ENV
- echo "Version is: ${{ env.PROJECT_VERSION }}"
-
- name: Install Rust
- uses: actions-rs/toolchain@v1
+ uses: dtolnay/rust-toolchain@stable
with:
- toolchain: stable
- target: ${{ matrix.target }}
- override: true
- profile: minimal
+ targets: ${{ matrix.target }}
- name: Setup Aftman
uses: ok-nick/setup-aftman@v0.1.0
@@ -122,37 +102,34 @@ jobs:
# easily.
CARGO_TARGET_DIR: output
- # On platforms that use OpenSSL, ensure it is statically linked to
- # make binaries more portable.
- OPENSSL_STATIC: 1
+ - name: Generate Artifact Name
+ shell: bash
+ env:
+ TAG_NAME: ${{ github.ref_name }}
+ run: |
+ echo "ARTIFACT_NAME=$BIN-${TAG_NAME#v}-${{ matrix.label }}.zip" >> "$GITHUB_ENV"
- - name: Create Release Archive
+ - name: Create Archive and Upload to Release
shell: bash
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
mkdir staging
if [ "${{ matrix.host }}" = "windows" ]; then
cp "output/${{ matrix.target }}/release/$BIN.exe" staging/
cd staging
- 7z a ../release.zip *
+ 7z a ../$ARTIFACT_NAME *
else
cp "output/${{ matrix.target }}/release/$BIN" staging/
cd staging
- zip ../release.zip *
+ zip ../$ARTIFACT_NAME *
fi
- - name: Upload Archive to Release
- uses: actions/upload-release-asset@v1
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- with:
- upload_url: ${{ needs.create-release.outputs.upload_url }}
- asset_path: release.zip
- asset_name: ${{ env.BIN }}-${{ env.PROJECT_VERSION }}-${{ matrix.label }}.zip
- asset_content_type: application/octet-stream
+ gh release upload ${{ github.ref_name }} ../$ARTIFACT_NAME
- name: Upload Archive to Artifacts
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
with:
- name: ${{ env.BIN }}-${{ env.PROJECT_VERSION }}-${{ matrix.label }}.zip
- path: release.zip
\ No newline at end of file
+ path: ${{ env.ARTIFACT_NAME }}
+ name: ${{ env.ARTIFACT_NAME }}
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 97ccb4053..ad9b44bbb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -20,12 +20,15 @@
This is a very rough implementation and the usage will become more ergonomic
over time.
-* Rojo now converts any line endings to LF, preventing spurious diffs when syncing Lua files on Windows ([#854])
-* Fixed Rojo plugin failing to connect when project contains certain unreadable properties ([#848])
+* Updated Undo/Redo history to be more robust ([#915])
+* Fixed removing trailing newlines ([#903])
+* Added Never option to Confirmation ([#893])
* Added popout diff visualizer for table properties like Attributes and Tags ([#834])
* Updated Theme to use Studio colors ([#838])
+* Improved patch visualizer UX ([#883])
* Added experimental setting for Auto Connect in playtests ([#840])
-* Fixed http error handling so Rojo can be used in Github Codespaces ([#847])
+* Improved settings UI ([#886])
+* `Open Scripts Externally` option can now be changed while syncing ([#911])
* Projects may now specify rules for syncing files as if they had a different file extension. ([#813])
This is specified via a new field on project files, `syncRules`:
@@ -77,10 +80,36 @@
[#834]: https://github.com/rojo-rbx/rojo/pull/834
[#838]: https://github.com/rojo-rbx/rojo/pull/838
[#840]: https://github.com/rojo-rbx/rojo/pull/840
-[#847]: https://github.com/rojo-rbx/rojo/pull/847
+[#843]: https://github.com/rojo-rbx/rojo/pull/843
+[#883]: https://github.com/rojo-rbx/rojo/pull/883
+[#886]: https://github.com/rojo-rbx/rojo/pull/886
+[#893]: https://github.com/rojo-rbx/rojo/pull/893
+[#903]: https://github.com/rojo-rbx/rojo/pull/903
+[#911]: https://github.com/rojo-rbx/rojo/pull/911
+[#915]: https://github.com/rojo-rbx/rojo/pull/915
+
+## [7.4.1] - February 20, 2024
+* Made the `name` field optional on project files ([#870])
+
+ Files named `default.project.json` inherit the name of the folder they're in and all other projects
+ are named as expect (e.g. `foo.project.json` becomes an Instance named `foo`)
+
+ There is no change in behavior if `name` is set.
+* Fixed incorrect results when building model pivots ([#865])
+* Fixed incorrect results when serving model pivots ([#868])
+* Rojo now converts any line endings to LF, preventing spurious diffs when syncing Lua files on Windows ([#854])
+* Fixed Rojo plugin failing to connect when project contains certain unreadable properties ([#848])
+* Fixed various cases where patch visualizer would not display sync failures ([#845], [#844])
+* Fixed http error handling so Rojo can be used in Github Codespaces ([#847])
+
[#848]: https://github.com/rojo-rbx/rojo/pull/848
+[#845]: https://github.com/rojo-rbx/rojo/pull/845
+[#844]: https://github.com/rojo-rbx/rojo/pull/844
+[#847]: https://github.com/rojo-rbx/rojo/pull/847
[#854]: https://github.com/rojo-rbx/rojo/pull/854
-[#843]: https://github.com/rojo-rbx/rojo/pull/843
+[#865]: https://github.com/rojo-rbx/rojo/pull/865
+[#868]: https://github.com/rojo-rbx/rojo/pull/868
+[#870]: https://github.com/rojo-rbx/rojo/pull/870
## [7.4.0] - January 16, 2024
* Improved the visualization for array properties like Tags ([#829])
diff --git a/Cargo.lock b/Cargo.lock
index 3e2556f20..1b2ae1809 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -19,18 +19,18 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "aho-corasick"
-version = "1.1.1"
+version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ea5d730647d4fadd988536d06fecce94b7b4f2a7efdae548f1cf4b63205518ab"
+checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0"
dependencies = [
"memchr",
]
[[package]]
name = "anyhow"
-version = "1.0.75"
+version = "1.0.80"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"
+checksum = "5ad32ce52e4161730f7098c077cd2ed6229b5804ccf99e5366be1ab72a98b4e1"
[[package]]
name = "arrayref"
@@ -84,9 +84,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
[[package]]
name = "base64"
-version = "0.21.4"
+version = "0.21.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2"
+checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
[[package]]
name = "bincode"
@@ -105,9 +105,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitflags"
-version = "2.4.0"
+version = "2.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635"
+checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf"
[[package]]
name = "blake3"
@@ -133,26 +133,26 @@ dependencies = [
[[package]]
name = "bstr"
-version = "1.6.2"
+version = "1.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4c2f7349907b712260e64b0afe2f84692af14a454be26187d9df565c7f69266a"
+checksum = "05efc5cfd9110c8416e471df0e96702d58690178e206e61b7173706673c93706"
dependencies = [
"memchr",
- "regex-automata 0.3.9",
+ "regex-automata 0.4.6",
"serde",
]
[[package]]
name = "bumpalo"
-version = "3.14.0"
+version = "3.15.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec"
+checksum = "8ea184aa71bb362a1157c896979544cc23974e08fd265f29ea96b59f0b4a555b"
[[package]]
name = "byteorder"
-version = "1.4.3"
+version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
+checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "bytes"
@@ -168,12 +168,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5"
[[package]]
name = "cc"
-version = "1.0.83"
+version = "1.0.89"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0"
-dependencies = [
- "libc",
-]
+checksum = "a0ba8f7aaa012f30d5b2861462f6708eccd49c3c39863fe083a308035f63d723"
[[package]]
name = "cfg-if"
@@ -208,11 +205,11 @@ dependencies = [
"bitflags 1.3.2",
"clap_derive",
"clap_lex",
- "indexmap",
+ "indexmap 1.9.3",
"once_cell",
"strsim",
"termcolor",
- "textwrap 0.16.0",
+ "textwrap 0.16.1",
]
[[package]]
@@ -223,8 +220,8 @@ checksum = "ae6371b8bdc8b7d3959e9cf7b22d4435ef3e79e138688421ec654acf8c81b008"
dependencies = [
"heck",
"proc-macro-error",
- "proc-macro2 1.0.67",
- "quote 1.0.33",
+ "proc-macro2 1.0.78",
+ "quote 1.0.35",
"syn 1.0.109",
]
@@ -239,14 +236,14 @@ dependencies = [
[[package]]
name = "console"
-version = "0.15.7"
+version = "0.15.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c926e00cc70edefdc64d3a5ff31cc65bb97a3460097762bd23afb4d8145fccf8"
+checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb"
dependencies = [
"encode_unicode",
"lazy_static",
"libc",
- "windows-sys 0.45.0",
+ "windows-sys 0.52.0",
]
[[package]]
@@ -257,9 +254,9 @@ checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2"
[[package]]
name = "core-foundation"
-version = "0.9.3"
+version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146"
+checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f"
dependencies = [
"core-foundation-sys",
"libc",
@@ -267,15 +264,15 @@ dependencies = [
[[package]]
name = "core-foundation-sys"
-version = "0.8.4"
+version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa"
+checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f"
[[package]]
name = "cpufeatures"
-version = "0.2.9"
+version = "0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1"
+checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504"
dependencies = [
"libc",
]
@@ -318,46 +315,37 @@ dependencies = [
[[package]]
name = "crossbeam-channel"
-version = "0.5.8"
+version = "0.5.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200"
+checksum = "ab3db02a9c5b5121e1e42fbdb1aeb65f5e02624cc58c43f2884c6ccac0b82f95"
dependencies = [
- "cfg-if 1.0.0",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-deque"
-version = "0.8.3"
+version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef"
+checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d"
dependencies = [
- "cfg-if 1.0.0",
"crossbeam-epoch",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-epoch"
-version = "0.9.15"
+version = "0.9.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7"
+checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
dependencies = [
- "autocfg",
- "cfg-if 1.0.0",
"crossbeam-utils",
- "memoffset",
- "scopeguard",
]
[[package]]
name = "crossbeam-utils"
-version = "0.8.16"
+version = "0.8.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294"
-dependencies = [
- "cfg-if 1.0.0",
-]
+checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345"
[[package]]
name = "crypto-common"
@@ -429,9 +417,9 @@ dependencies = [
[[package]]
name = "either"
-version = "1.9.0"
+version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
+checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a"
[[package]]
name = "embed-resource"
@@ -475,24 +463,19 @@ dependencies = [
]
[[package]]
-name = "errno"
-version = "0.3.4"
+name = "equivalent"
+version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "add4f07d43996f76ef320709726a556a9d4f965d9410d8d0271132d2f8293480"
-dependencies = [
- "errno-dragonfly",
- "libc",
- "windows-sys 0.48.0",
-]
+checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]]
-name = "errno-dragonfly"
-version = "0.1.2"
+name = "errno"
+version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
+checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245"
dependencies = [
- "cc",
"libc",
+ "windows-sys 0.52.0",
]
[[package]]
@@ -503,14 +486,14 @@ checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5"
[[package]]
name = "filetime"
-version = "0.2.22"
+version = "0.2.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d4029edd3e734da6fe05b6cd7bd2960760a616bd2ddd0d59a0124746d6272af0"
+checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd"
dependencies = [
"cfg-if 1.0.0",
"libc",
- "redox_syscall 0.3.5",
- "windows-sys 0.48.0",
+ "redox_syscall",
+ "windows-sys 0.52.0",
]
[[package]]
@@ -519,35 +502,23 @@ version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
-[[package]]
-name = "foreign-types"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
-dependencies = [
- "foreign-types-shared",
-]
-
-[[package]]
-name = "foreign-types-shared"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
-
[[package]]
name = "form_urlencoded"
-version = "1.2.0"
+version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652"
+checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456"
dependencies = [
"percent-encoding",
]
[[package]]
name = "fs-err"
-version = "2.9.0"
+version = "2.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0845fa252299212f0389d64ba26f34fa32cfe41588355f21ed507c59a0f64541"
+checksum = "88a41f105fe1d5b6b34b2055e3dc59bb79b46b48b2040b9e6c7b4b5de097aa41"
+dependencies = [
+ "autocfg",
+]
[[package]]
name = "fsevent"
@@ -586,9 +557,9 @@ checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
[[package]]
name = "futures"
-version = "0.3.28"
+version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40"
+checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0"
dependencies = [
"futures-channel",
"futures-core",
@@ -601,9 +572,9 @@ dependencies = [
[[package]]
name = "futures-channel"
-version = "0.3.28"
+version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2"
+checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78"
dependencies = [
"futures-core",
"futures-sink",
@@ -611,15 +582,15 @@ dependencies = [
[[package]]
name = "futures-core"
-version = "0.3.28"
+version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c"
+checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d"
[[package]]
name = "futures-executor"
-version = "0.3.28"
+version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0"
+checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d"
dependencies = [
"futures-core",
"futures-task",
@@ -628,38 +599,38 @@ dependencies = [
[[package]]
name = "futures-io"
-version = "0.3.28"
+version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964"
+checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1"
[[package]]
name = "futures-macro"
-version = "0.3.28"
+version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72"
+checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
dependencies = [
- "proc-macro2 1.0.67",
- "quote 1.0.33",
- "syn 2.0.37",
+ "proc-macro2 1.0.78",
+ "quote 1.0.35",
+ "syn 2.0.52",
]
[[package]]
name = "futures-sink"
-version = "0.3.28"
+version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e"
+checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5"
[[package]]
name = "futures-task"
-version = "0.3.28"
+version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65"
+checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004"
[[package]]
name = "futures-util"
-version = "0.3.28"
+version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533"
+checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48"
dependencies = [
"futures-channel",
"futures-core",
@@ -698,9 +669,9 @@ dependencies = [
[[package]]
name = "getrandom"
-version = "0.2.10"
+version = "0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
+checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5"
dependencies = [
"cfg-if 1.0.0",
"libc",
@@ -709,28 +680,28 @@ dependencies = [
[[package]]
name = "gimli"
-version = "0.28.0"
+version = "0.28.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0"
+checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
[[package]]
name = "globset"
-version = "0.4.13"
+version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "759c97c1e17c55525b57192c06a267cda0ac5210b222d6b82189a2338fa1c13d"
+checksum = "57da3b9b5b85bd66f31093f8c408b90a74431672542466497dcbdfdc02034be1"
dependencies = [
"aho-corasick",
"bstr",
- "fnv",
"log",
- "regex",
+ "regex-automata 0.4.6",
+ "regex-syntax 0.8.2",
]
[[package]]
name = "h2"
-version = "0.3.21"
+version = "0.3.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833"
+checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8"
dependencies = [
"bytes",
"fnv",
@@ -738,7 +709,7 @@ dependencies = [
"futures-sink",
"futures-util",
"http",
- "indexmap",
+ "indexmap 2.2.5",
"slab",
"tokio",
"tokio-util",
@@ -747,9 +718,9 @@ dependencies = [
[[package]]
name = "half"
-version = "1.8.2"
+version = "1.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7"
+checksum = "1b43ede17f21864e81be2fa654110bf1e793774238d86ef8555c37e6519c0403"
[[package]]
name = "hashbrown"
@@ -757,6 +728,12 @@ version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
+[[package]]
+name = "hashbrown"
+version = "0.14.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
+
[[package]]
name = "heck"
version = "0.4.1"
@@ -774,9 +751,9 @@ dependencies = [
[[package]]
name = "hermit-abi"
-version = "0.3.3"
+version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7"
+checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
[[package]]
name = "htmlescape"
@@ -786,9 +763,9 @@ checksum = "e9025058dae765dee5070ec375f591e2ba14638c63feff74f13805a72e523163"
[[package]]
name = "http"
-version = "0.2.9"
+version = "0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482"
+checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1"
dependencies = [
"bytes",
"fnv",
@@ -797,9 +774,9 @@ dependencies = [
[[package]]
name = "http-body"
-version = "0.4.5"
+version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1"
+checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2"
dependencies = [
"bytes",
"http",
@@ -826,9 +803,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
[[package]]
name = "hyper"
-version = "0.14.27"
+version = "0.14.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468"
+checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80"
dependencies = [
"bytes",
"futures-channel",
@@ -841,7 +818,7 @@ dependencies = [
"httpdate",
"itoa",
"pin-project-lite",
- "socket2 0.4.9",
+ "socket2",
"tokio",
"tower-service",
"tracing",
@@ -849,23 +826,24 @@ dependencies = [
]
[[package]]
-name = "hyper-tls"
-version = "0.5.0"
+name = "hyper-rustls"
+version = "0.24.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905"
+checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590"
dependencies = [
- "bytes",
+ "futures-util",
+ "http",
"hyper",
- "native-tls",
+ "rustls",
"tokio",
- "tokio-native-tls",
+ "tokio-rustls",
]
[[package]]
name = "idna"
-version = "0.4.0"
+version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c"
+checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6"
dependencies = [
"unicode-bidi",
"unicode-normalization",
@@ -878,7 +856,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
dependencies = [
"autocfg",
- "hashbrown",
+ "hashbrown 0.12.3",
+]
+
+[[package]]
+name = "indexmap"
+version = "2.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7b0b929d511467233429c45a44ac1dcaa21ba0f5ba11e4879e6ed28ddb4f9df4"
+dependencies = [
+ "equivalent",
+ "hashbrown 0.14.3",
]
[[package]]
@@ -903,9 +891,9 @@ dependencies = [
[[package]]
name = "insta"
-version = "1.33.0"
+version = "1.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1aa511b2e298cd49b1856746f6bb73e17036bcd66b25f5e92cdcdbec9bd75686"
+checksum = "0a7c22c4d34ef4788c351e971c52bfdfe7ea2766f8c5466bc175dd46e52ac22e"
dependencies = [
"console",
"lazy_static",
@@ -928,9 +916,9 @@ dependencies = [
[[package]]
name = "ipnet"
-version = "2.8.0"
+version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6"
+checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3"
[[package]]
name = "itertools"
@@ -943,9 +931,9 @@ dependencies = [
[[package]]
name = "itoa"
-version = "1.0.9"
+version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38"
+checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
[[package]]
name = "jod-thread"
@@ -955,9 +943,9 @@ checksum = "8b23360e99b8717f20aaa4598f5a6541efbe30630039fbc7706cf954a87947ae"
[[package]]
name = "js-sys"
-version = "0.3.64"
+version = "0.3.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a"
+checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d"
dependencies = [
"wasm-bindgen",
]
@@ -986,9 +974,20 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
[[package]]
name = "libc"
-version = "0.2.148"
+version = "0.2.153"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
+
+[[package]]
+name = "libredox"
+version = "0.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b"
+checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8"
+dependencies = [
+ "bitflags 2.4.2",
+ "libc",
+ "redox_syscall",
+]
[[package]]
name = "linked-hash-map"
@@ -998,21 +997,21 @@ checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
[[package]]
name = "linux-raw-sys"
-version = "0.4.8"
+version = "0.4.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3852614a3bd9ca9804678ba6be5e3b8ce76dfc902cae004e3e0c44051b6e88db"
+checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c"
[[package]]
name = "log"
-version = "0.4.20"
+version = "0.4.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
+checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
[[package]]
name = "loom"
-version = "0.5.6"
+version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ff50ecb28bb86013e935fb6683ab1f6d3a20016f123c76fd4c27470076ac30f5"
+checksum = "7e045d70ddfbc984eacfa964ded019534e8f6cbf36f6410aee0ed5cefa5a9175"
dependencies = [
"cfg-if 1.0.0",
"generator",
@@ -1058,22 +1057,13 @@ dependencies = [
[[package]]
name = "memchr"
-version = "2.6.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167"
-
-[[package]]
-name = "memoffset"
-version = "0.9.0"
+version = "2.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c"
-dependencies = [
- "autocfg",
-]
+checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149"
[[package]]
name = "memofs"
-version = "0.2.0"
+version = "0.3.0"
dependencies = [
"crossbeam-channel",
"fs-err",
@@ -1089,9 +1079,9 @@ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
[[package]]
name = "miniz_oxide"
-version = "0.7.1"
+version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7"
+checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7"
dependencies = [
"adler",
]
@@ -1117,9 +1107,9 @@ dependencies = [
[[package]]
name = "mio"
-version = "0.8.8"
+version = "0.8.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2"
+checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c"
dependencies = [
"libc",
"wasi",
@@ -1150,24 +1140,6 @@ dependencies = [
"ws2_32-sys",
]
-[[package]]
-name = "native-tls"
-version = "0.2.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e"
-dependencies = [
- "lazy_static",
- "libc",
- "log",
- "openssl",
- "openssl-probe",
- "openssl-sys",
- "schannel",
- "security-framework",
- "security-framework-sys",
- "tempfile",
-]
-
[[package]]
name = "net2"
version = "0.2.39"
@@ -1209,9 +1181,9 @@ dependencies = [
[[package]]
name = "num-traits"
-version = "0.2.16"
+version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2"
+checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a"
dependencies = [
"autocfg",
]
@@ -1222,24 +1194,24 @@ version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
dependencies = [
- "hermit-abi 0.3.3",
+ "hermit-abi 0.3.9",
"libc",
]
[[package]]
name = "object"
-version = "0.32.1"
+version = "0.32.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0"
+checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441"
dependencies = [
"memchr",
]
[[package]]
name = "once_cell"
-version = "1.18.0"
+version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
+checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
[[package]]
name = "oorandom"
@@ -1257,65 +1229,11 @@ dependencies = [
"winapi 0.3.9",
]
-[[package]]
-name = "openssl"
-version = "0.10.57"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bac25ee399abb46215765b1cb35bc0212377e58a061560d8b29b024fd0430e7c"
-dependencies = [
- "bitflags 2.4.0",
- "cfg-if 1.0.0",
- "foreign-types",
- "libc",
- "once_cell",
- "openssl-macros",
- "openssl-sys",
-]
-
-[[package]]
-name = "openssl-macros"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
-dependencies = [
- "proc-macro2 1.0.67",
- "quote 1.0.33",
- "syn 2.0.37",
-]
-
-[[package]]
-name = "openssl-probe"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
-
-[[package]]
-name = "openssl-src"
-version = "300.1.5+3.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "559068e4c12950d7dcaa1857a61725c0d38d4fc03ff8e070ab31a75d6e316491"
-dependencies = [
- "cc",
-]
-
-[[package]]
-name = "openssl-sys"
-version = "0.9.93"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "db4d56a4c0478783083cfafcc42493dd4a981d41669da64b4572a2a089b51b1d"
-dependencies = [
- "cc",
- "libc",
- "openssl-src",
- "pkg-config",
- "vcpkg",
-]
-
[[package]]
name = "os_str_bytes"
-version = "6.5.1"
+version = "6.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4d5d9eb14b174ee9aa2ef96dc2b94637a2d4b6e7cb873c7e171f0c20c6cf3eac"
+checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1"
[[package]]
name = "overload"
@@ -1331,15 +1249,15 @@ checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c"
[[package]]
name = "percent-encoding"
-version = "2.3.0"
+version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94"
+checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
[[package]]
name = "pest"
-version = "2.7.4"
+version = "2.7.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c022f1e7b65d6a24c0dbbd5fb344c66881bc01f3e5ae74a1c8100f2f985d98a4"
+checksum = "56f8023d0fb78c8e03784ea1c7f3fa36e68a723138990b8d5a47d916b651e7a8"
dependencies = [
"memchr",
"thiserror",
@@ -1348,9 +1266,9 @@ dependencies = [
[[package]]
name = "pest_derive"
-version = "2.7.4"
+version = "2.7.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "35513f630d46400a977c4cb58f78e1bfbe01434316e60c37d27b9ad6139c66d8"
+checksum = "b0d24f72393fd16ab6ac5738bc33cdb6a9aa73f8b902e8fe29cf4e67d7dd1026"
dependencies = [
"pest",
"pest_generator",
@@ -1358,22 +1276,22 @@ dependencies = [
[[package]]
name = "pest_generator"
-version = "2.7.4"
+version = "2.7.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bc9fc1b9e7057baba189b5c626e2d6f40681ae5b6eb064dc7c7834101ec8123a"
+checksum = "fdc17e2a6c7d0a492f0158d7a4bd66cc17280308bbaff78d5bef566dca35ab80"
dependencies = [
"pest",
"pest_meta",
- "proc-macro2 1.0.67",
- "quote 1.0.33",
- "syn 2.0.37",
+ "proc-macro2 1.0.78",
+ "quote 1.0.35",
+ "syn 2.0.52",
]
[[package]]
name = "pest_meta"
-version = "2.7.4"
+version = "2.7.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1df74e9e7ec4053ceb980e7c0c8bd3594e977fde1af91daba9c928e8e8c6708d"
+checksum = "934cd7631c050f4674352a6e835d5f6711ffbfb9345c2fc0107155ac495ae293"
dependencies = [
"once_cell",
"pest",
@@ -1392,12 +1310,6 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
-[[package]]
-name = "pkg-config"
-version = "0.3.27"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964"
-
[[package]]
name = "plotters"
version = "0.3.5"
@@ -1449,8 +1361,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
dependencies = [
"proc-macro-error-attr",
- "proc-macro2 1.0.67",
- "quote 1.0.33",
+ "proc-macro2 1.0.78",
+ "quote 1.0.35",
"syn 1.0.109",
"version_check",
]
@@ -1461,8 +1373,8 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
dependencies = [
- "proc-macro2 1.0.67",
- "quote 1.0.33",
+ "proc-macro2 1.0.78",
+ "quote 1.0.35",
"version_check",
]
@@ -1489,31 +1401,31 @@ dependencies = [
[[package]]
name = "proc-macro2"
-version = "1.0.67"
+version = "1.0.78"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328"
+checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae"
dependencies = [
"unicode-ident",
]
[[package]]
name = "profiling"
-version = "1.0.11"
+version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f89dff0959d98c9758c88826cc002e2c3d0b9dfac4139711d1f30de442f1139b"
+checksum = "43d84d1d7a6ac92673717f9f6d1518374ef257669c24ebc5ac25d5033828be58"
dependencies = [
"profiling-procmacros",
- "tracy-client 0.16.3",
+ "tracy-client",
]
[[package]]
name = "profiling-procmacros"
-version = "1.0.11"
+version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eb156a45b6b9fe8027497422179fb65afc84d36707a7ca98297bf06bccb8d43f"
+checksum = "8021cf59c8ec9c432cfc2526ac6b8aa508ecaf29cd415f271b8406c1b851c3fd"
dependencies = [
- "quote 1.0.33",
- "syn 2.0.37",
+ "quote 1.0.35",
+ "syn 2.0.52",
]
[[package]]
@@ -1527,11 +1439,11 @@ dependencies = [
[[package]]
name = "quote"
-version = "1.0.33"
+version = "1.0.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
+checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
dependencies = [
- "proc-macro2 1.0.67",
+ "proc-macro2 1.0.78",
]
[[package]]
@@ -1566,9 +1478,9 @@ dependencies = [
[[package]]
name = "rayon"
-version = "1.8.0"
+version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1"
+checksum = "e4963ed1bc86e4f3ee217022bd855b297cef07fb9eac5dfa1f788b220b49b3bd"
dependencies = [
"either",
"rayon-core",
@@ -1576,9 +1488,9 @@ dependencies = [
[[package]]
name = "rayon-core"
-version = "1.12.0"
+version = "1.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed"
+checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2"
dependencies = [
"crossbeam-deque",
"crossbeam-utils",
@@ -1663,43 +1575,34 @@ dependencies = [
[[package]]
name = "redox_syscall"
-version = "0.2.16"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
-dependencies = [
- "bitflags 1.3.2",
-]
-
-[[package]]
-name = "redox_syscall"
-version = "0.3.5"
+version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29"
+checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa"
dependencies = [
"bitflags 1.3.2",
]
[[package]]
name = "redox_users"
-version = "0.4.3"
+version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b"
+checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4"
dependencies = [
"getrandom",
- "redox_syscall 0.2.16",
+ "libredox",
"thiserror",
]
[[package]]
name = "regex"
-version = "1.9.6"
+version = "1.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ebee201405406dbf528b8b672104ae6d6d63e6d118cb10e4d51abbc7b58044ff"
+checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15"
dependencies = [
"aho-corasick",
"memchr",
- "regex-automata 0.3.9",
- "regex-syntax 0.7.5",
+ "regex-automata 0.4.6",
+ "regex-syntax 0.8.2",
]
[[package]]
@@ -1713,13 +1616,13 @@ dependencies = [
[[package]]
name = "regex-automata"
-version = "0.3.9"
+version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "59b23e92ee4318893fa3fe3e6fb365258efbfe6ac6ab30f090cdcbb7aa37efa9"
+checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea"
dependencies = [
"aho-corasick",
"memchr",
- "regex-syntax 0.7.5",
+ "regex-syntax 0.8.2",
]
[[package]]
@@ -1730,17 +1633,17 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
[[package]]
name = "regex-syntax"
-version = "0.7.5"
+version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da"
+checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
[[package]]
name = "reqwest"
-version = "0.11.22"
+version = "0.11.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b"
+checksum = "c6920094eb85afde5e4a138be3f2de8bbdf28000f0029e72c45025a56b042251"
dependencies = [
- "base64 0.21.4",
+ "base64 0.21.7",
"bytes",
"encoding_rs",
"futures-core",
@@ -1749,29 +1652,47 @@ dependencies = [
"http",
"http-body",
"hyper",
- "hyper-tls",
+ "hyper-rustls",
"ipnet",
"js-sys",
"log",
"mime",
- "native-tls",
"once_cell",
"percent-encoding",
"pin-project-lite",
+ "rustls",
+ "rustls-pemfile",
"serde",
"serde_json",
"serde_urlencoded",
+ "sync_wrapper",
"system-configuration",
"tokio",
- "tokio-native-tls",
+ "tokio-rustls",
"tower-service",
"url",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
+ "webpki-roots",
"winreg 0.50.0",
]
+[[package]]
+name = "ring"
+version = "0.17.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d"
+dependencies = [
+ "cc",
+ "cfg-if 1.0.0",
+ "getrandom",
+ "libc",
+ "spin",
+ "untrusted",
+ "windows-sys 0.52.0",
+]
+
[[package]]
name = "ritz"
version = "0.1.0"
@@ -1876,7 +1797,6 @@ dependencies = [
"thiserror",
"tokio",
"toml",
- "tracy-client 0.13.2",
"uuid",
"walkdir",
"winreg 0.10.1",
@@ -1907,15 +1827,46 @@ dependencies = [
[[package]]
name = "rustix"
-version = "0.38.20"
+version = "0.38.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "67ce50cb2e16c2903e30d1cbccfd8387a74b9d4c938b6a4c5ec6cc7556f7a8a0"
+checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949"
dependencies = [
- "bitflags 2.4.0",
+ "bitflags 2.4.2",
"errno",
"libc",
"linux-raw-sys",
- "windows-sys 0.48.0",
+ "windows-sys 0.52.0",
+]
+
+[[package]]
+name = "rustls"
+version = "0.21.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7fecbfb7b1444f477b345853b1fce097a2c6fb637b2bfb87e6bc5db0f043fae4"
+dependencies = [
+ "log",
+ "ring",
+ "rustls-webpki",
+ "sct",
+]
+
+[[package]]
+name = "rustls-pemfile"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c"
+dependencies = [
+ "base64 0.21.7",
+]
+
+[[package]]
+name = "rustls-webpki"
+version = "0.101.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765"
+dependencies = [
+ "ring",
+ "untrusted",
]
[[package]]
@@ -1926,9 +1877,9 @@ checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4"
[[package]]
name = "ryu"
-version = "1.0.15"
+version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741"
+checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1"
[[package]]
name = "same-file"
@@ -1939,15 +1890,6 @@ dependencies = [
"winapi-util",
]
-[[package]]
-name = "schannel"
-version = "0.1.22"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88"
-dependencies = [
- "windows-sys 0.48.0",
-]
-
[[package]]
name = "scoped-tls"
version = "1.0.1"
@@ -1955,45 +1897,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294"
[[package]]
-name = "scopeguard"
-version = "1.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
-
-[[package]]
-name = "security-framework"
-version = "2.9.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de"
-dependencies = [
- "bitflags 1.3.2",
- "core-foundation",
- "core-foundation-sys",
- "libc",
- "security-framework-sys",
-]
-
-[[package]]
-name = "security-framework-sys"
-version = "2.9.1"
+name = "sct"
+version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a"
+checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414"
dependencies = [
- "core-foundation-sys",
- "libc",
+ "ring",
+ "untrusted",
]
[[package]]
name = "semver"
-version = "1.0.19"
+version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ad977052201c6de01a8ef2aa3378c4bd23217a056337d1d6da40468d267a4fb0"
+checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca"
[[package]]
name = "serde"
-version = "1.0.188"
+version = "1.0.197"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e"
+checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2"
dependencies = [
"serde_derive",
]
@@ -2010,20 +1933,20 @@ dependencies = [
[[package]]
name = "serde_derive"
-version = "1.0.188"
+version = "1.0.197"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2"
+checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b"
dependencies = [
- "proc-macro2 1.0.67",
- "quote 1.0.33",
- "syn 2.0.37",
+ "proc-macro2 1.0.78",
+ "quote 1.0.35",
+ "syn 2.0.52",
]
[[package]]
name = "serde_json"
-version = "1.0.107"
+version = "1.0.114"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65"
+checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0"
dependencies = [
"itoa",
"ryu",
@@ -2048,7 +1971,7 @@ version = "0.8.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "578a7433b776b56a35785ed5ce9a7e777ac0598aac5a6dd1b4b18a307c7fc71b"
dependencies = [
- "indexmap",
+ "indexmap 1.9.3",
"ryu",
"serde",
"yaml-rust",
@@ -2067,18 +1990,18 @@ dependencies = [
[[package]]
name = "sharded-slab"
-version = "0.1.6"
+version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c1b21f559e07218024e7e9f90f96f601825397de0e25420135f7f952453fed0b"
+checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6"
dependencies = [
"lazy_static",
]
[[package]]
name = "similar"
-version = "2.2.1"
+version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "420acb44afdae038210c99e69aae24109f32f15500aa708e81d46c9f29d55fcf"
+checksum = "32fea41aca09ee824cc9724996433064c89f7777e60762749a4170a14abbfa21"
[[package]]
name = "slab"
@@ -2091,9 +2014,9 @@ dependencies = [
[[package]]
name = "smallvec"
-version = "1.11.1"
+version = "1.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a"
+checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7"
[[package]]
name = "snax"
@@ -2106,23 +2029,19 @@ dependencies = [
[[package]]
name = "socket2"
-version = "0.4.9"
+version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662"
+checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871"
dependencies = [
"libc",
- "winapi 0.3.9",
+ "windows-sys 0.52.0",
]
[[package]]
-name = "socket2"
-version = "0.5.4"
+name = "spin"
+version = "0.9.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4031e820eb552adee9295814c0ced9e5cf38ddf1e8b7d566d6de8e2538ea989e"
-dependencies = [
- "libc",
- "windows-sys 0.48.0",
-]
+checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
[[package]]
name = "strsim"
@@ -2136,22 +2055,28 @@ version = "1.0.109"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
dependencies = [
- "proc-macro2 1.0.67",
- "quote 1.0.33",
+ "proc-macro2 1.0.78",
+ "quote 1.0.35",
"unicode-ident",
]
[[package]]
name = "syn"
-version = "2.0.37"
+version = "2.0.52"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7303ef2c05cd654186cb250d29049a24840ca25d2747c25c0381c8d9e2f582e8"
+checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07"
dependencies = [
- "proc-macro2 1.0.67",
- "quote 1.0.33",
+ "proc-macro2 1.0.78",
+ "quote 1.0.35",
"unicode-ident",
]
+[[package]]
+name = "sync_wrapper"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160"
+
[[package]]
name = "system-configuration"
version = "0.5.1"
@@ -2175,22 +2100,21 @@ dependencies = [
[[package]]
name = "tempfile"
-version = "3.8.0"
+version = "3.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef"
+checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1"
dependencies = [
"cfg-if 1.0.0",
"fastrand",
- "redox_syscall 0.3.5",
"rustix",
- "windows-sys 0.48.0",
+ "windows-sys 0.52.0",
]
[[package]]
name = "termcolor"
-version = "1.3.0"
+version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6093bad37da69aab9d123a8091e4be0aa4a03e4d601ec641c327398315f62b64"
+checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755"
dependencies = [
"winapi-util",
]
@@ -2206,35 +2130,35 @@ dependencies = [
[[package]]
name = "textwrap"
-version = "0.16.0"
+version = "0.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d"
+checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9"
[[package]]
name = "thiserror"
-version = "1.0.49"
+version = "1.0.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1177e8c6d7ede7afde3585fd2513e611227efd6481bd78d2e82ba1ce16557ed4"
+checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
-version = "1.0.49"
+version = "1.0.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc"
+checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81"
dependencies = [
- "proc-macro2 1.0.67",
- "quote 1.0.33",
- "syn 2.0.37",
+ "proc-macro2 1.0.78",
+ "quote 1.0.35",
+ "syn 2.0.52",
]
[[package]]
name = "thread_local"
-version = "1.1.7"
+version = "1.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152"
+checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c"
dependencies = [
"cfg-if 1.0.0",
"once_cell",
@@ -2267,35 +2191,35 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "tokio"
-version = "1.32.0"
+version = "1.36.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9"
+checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931"
dependencies = [
"backtrace",
"bytes",
"libc",
- "mio 0.8.8",
+ "mio 0.8.11",
"num_cpus",
"pin-project-lite",
- "socket2 0.5.4",
+ "socket2",
"windows-sys 0.48.0",
]
[[package]]
-name = "tokio-native-tls"
-version = "0.3.1"
+name = "tokio-rustls"
+version = "0.24.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2"
+checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081"
dependencies = [
- "native-tls",
+ "rustls",
"tokio",
]
[[package]]
name = "tokio-util"
-version = "0.7.9"
+version = "0.7.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1d68074620f57a0b21594d9735eb2e98ab38b17f80d3fcb189fca266771ca60d"
+checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15"
dependencies = [
"bytes",
"futures-core",
@@ -2322,11 +2246,10 @@ checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52"
[[package]]
name = "tracing"
-version = "0.1.37"
+version = "0.1.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8"
+checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef"
dependencies = [
- "cfg-if 1.0.0",
"pin-project-lite",
"tracing-attributes",
"tracing-core",
@@ -2334,20 +2257,20 @@ dependencies = [
[[package]]
name = "tracing-attributes"
-version = "0.1.26"
+version = "0.1.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab"
+checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
dependencies = [
- "proc-macro2 1.0.67",
- "quote 1.0.33",
- "syn 2.0.37",
+ "proc-macro2 1.0.78",
+ "quote 1.0.35",
+ "syn 2.0.52",
]
[[package]]
name = "tracing-core"
-version = "0.1.31"
+version = "0.1.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a"
+checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54"
dependencies = [
"once_cell",
"valuable",
@@ -2355,20 +2278,20 @@ dependencies = [
[[package]]
name = "tracing-log"
-version = "0.1.3"
+version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922"
+checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3"
dependencies = [
- "lazy_static",
"log",
+ "once_cell",
"tracing-core",
]
[[package]]
name = "tracing-subscriber"
-version = "0.3.17"
+version = "0.3.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77"
+checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b"
dependencies = [
"matchers",
"nu-ansi-term",
@@ -2384,49 +2307,29 @@ dependencies = [
[[package]]
name = "tracy-client"
-version = "0.13.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "42ebfe7a24c18b5ba86d8920c124b41b942352f863fbe0c84d3d63428fa1860f"
-dependencies = [
- "loom",
- "once_cell",
- "tracy-client-sys 0.17.1",
-]
-
-[[package]]
-name = "tracy-client"
-version = "0.16.3"
+version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "03684af8fb393cc7903210d868e4cb9f5c1e156737be38f52c4217fb21b86bf6"
+checksum = "59fb931a64ff88984f86d3e9bcd1ae8843aa7fe44dd0f8097527bc172351741d"
dependencies = [
"loom",
"once_cell",
- "tracy-client-sys 0.21.2",
+ "tracy-client-sys",
]
[[package]]
name = "tracy-client-sys"
-version = "0.17.1"
+version = "0.22.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "178d021455e83078bb38c00b70046b95117ef0a0312cbef925f426d833d11c79"
-dependencies = [
- "cc",
-]
-
-[[package]]
-name = "tracy-client-sys"
-version = "0.21.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2cb915ea3af048554640d76dd6f1492589a6401a41a30d789b983c1ec280455a"
+checksum = "9d104d610dfa9dd154535102cc9c6164ae1fa37842bc2d9e83f9ac82b0ae0882"
dependencies = [
"cc",
]
[[package]]
name = "try-lock"
-version = "0.2.4"
+version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed"
+checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
[[package]]
name = "typenum"
@@ -2442,9 +2345,9 @@ checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9"
[[package]]
name = "unicode-bidi"
-version = "0.3.13"
+version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460"
+checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75"
[[package]]
name = "unicode-ident"
@@ -2454,9 +2357,9 @@ checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "unicode-normalization"
-version = "0.1.22"
+version = "0.1.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921"
+checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5"
dependencies = [
"tinyvec",
]
@@ -2473,11 +2376,17 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
+[[package]]
+name = "untrusted"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
+
[[package]]
name = "url"
-version = "2.4.1"
+version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5"
+checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633"
dependencies = [
"form_urlencoded",
"idna",
@@ -2486,9 +2395,9 @@ dependencies = [
[[package]]
name = "uuid"
-version = "1.4.1"
+version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d"
+checksum = "f00cc9702ca12d3c81455259621e676d0f7251cec66a21e98fe2e9a37db93b2a"
dependencies = [
"getrandom",
"serde",
@@ -2500,12 +2409,6 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
-[[package]]
-name = "vcpkg"
-version = "0.2.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
-
[[package]]
name = "version_check"
version = "0.9.4"
@@ -2534,9 +2437,9 @@ dependencies = [
[[package]]
name = "walkdir"
-version = "2.4.0"
+version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee"
+checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b"
dependencies = [
"same-file",
"winapi-util",
@@ -2559,9 +2462,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "wasm-bindgen"
-version = "0.2.87"
+version = "0.2.92"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342"
+checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8"
dependencies = [
"cfg-if 1.0.0",
"wasm-bindgen-macro",
@@ -2569,24 +2472,24 @@ dependencies = [
[[package]]
name = "wasm-bindgen-backend"
-version = "0.2.87"
+version = "0.2.92"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd"
+checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da"
dependencies = [
"bumpalo",
"log",
"once_cell",
- "proc-macro2 1.0.67",
- "quote 1.0.33",
- "syn 2.0.37",
+ "proc-macro2 1.0.78",
+ "quote 1.0.35",
+ "syn 2.0.52",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-futures"
-version = "0.4.37"
+version = "0.4.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03"
+checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0"
dependencies = [
"cfg-if 1.0.0",
"js-sys",
@@ -2596,43 +2499,49 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro"
-version = "0.2.87"
+version = "0.2.92"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d"
+checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726"
dependencies = [
- "quote 1.0.33",
+ "quote 1.0.35",
"wasm-bindgen-macro-support",
]
[[package]]
name = "wasm-bindgen-macro-support"
-version = "0.2.87"
+version = "0.2.92"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b"
+checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
dependencies = [
- "proc-macro2 1.0.67",
- "quote 1.0.33",
- "syn 2.0.37",
+ "proc-macro2 1.0.78",
+ "quote 1.0.35",
+ "syn 2.0.52",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
-version = "0.2.87"
+version = "0.2.92"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1"
+checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96"
[[package]]
name = "web-sys"
-version = "0.3.64"
+version = "0.3.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b"
+checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef"
dependencies = [
"js-sys",
"wasm-bindgen",
]
+[[package]]
+name = "webpki-roots"
+version = "0.25.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1"
+
[[package]]
name = "winapi"
version = "0.2.8"
@@ -2685,15 +2594,6 @@ dependencies = [
"windows-targets 0.48.5",
]
-[[package]]
-name = "windows-sys"
-version = "0.45.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
-dependencies = [
- "windows-targets 0.42.2",
-]
-
[[package]]
name = "windows-sys"
version = "0.48.0"
@@ -2704,18 +2604,12 @@ dependencies = [
]
[[package]]
-name = "windows-targets"
-version = "0.42.2"
+name = "windows-sys"
+version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
+checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [
- "windows_aarch64_gnullvm 0.42.2",
- "windows_aarch64_msvc 0.42.2",
- "windows_i686_gnu 0.42.2",
- "windows_i686_msvc 0.42.2",
- "windows_x86_64_gnu 0.42.2",
- "windows_x86_64_gnullvm 0.42.2",
- "windows_x86_64_msvc 0.42.2",
+ "windows-targets 0.52.4",
]
[[package]]
@@ -2734,10 +2628,19 @@ dependencies = [
]
[[package]]
-name = "windows_aarch64_gnullvm"
-version = "0.42.2"
+name = "windows-targets"
+version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
+checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b"
+dependencies = [
+ "windows_aarch64_gnullvm 0.52.4",
+ "windows_aarch64_msvc 0.52.4",
+ "windows_i686_gnu 0.52.4",
+ "windows_i686_msvc 0.52.4",
+ "windows_x86_64_gnu 0.52.4",
+ "windows_x86_64_gnullvm 0.52.4",
+ "windows_x86_64_msvc 0.52.4",
+]
[[package]]
name = "windows_aarch64_gnullvm"
@@ -2746,10 +2649,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
[[package]]
-name = "windows_aarch64_msvc"
-version = "0.42.2"
+name = "windows_aarch64_gnullvm"
+version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
+checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9"
[[package]]
name = "windows_aarch64_msvc"
@@ -2758,10 +2661,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
[[package]]
-name = "windows_i686_gnu"
-version = "0.42.2"
+name = "windows_aarch64_msvc"
+version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
+checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675"
[[package]]
name = "windows_i686_gnu"
@@ -2770,10 +2673,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
[[package]]
-name = "windows_i686_msvc"
-version = "0.42.2"
+name = "windows_i686_gnu"
+version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
+checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3"
[[package]]
name = "windows_i686_msvc"
@@ -2782,10 +2685,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
[[package]]
-name = "windows_x86_64_gnu"
-version = "0.42.2"
+name = "windows_i686_msvc"
+version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
+checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02"
[[package]]
name = "windows_x86_64_gnu"
@@ -2794,10 +2697,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
[[package]]
-name = "windows_x86_64_gnullvm"
-version = "0.42.2"
+name = "windows_x86_64_gnu"
+version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
+checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03"
[[package]]
name = "windows_x86_64_gnullvm"
@@ -2806,10 +2709,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
[[package]]
-name = "windows_x86_64_msvc"
-version = "0.42.2"
+name = "windows_x86_64_gnullvm"
+version = "0.52.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
+checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177"
[[package]]
name = "windows_x86_64_msvc"
@@ -2817,6 +2720,12 @@ version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.52.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8"
+
[[package]]
name = "winreg"
version = "0.6.2"
diff --git a/Cargo.toml b/Cargo.toml
index 0b5ae9e68..a35ccd942 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -26,7 +26,9 @@ default = []
# Enable this feature to live-reload assets from the web UI.
dev_live_assets = []
-profile-with-tracy = ["profiling/profile-with-tracy", "tracy-client"]
+# Run Rojo with this feature to open a Tracy session.
+# Currently uses protocol v63, last supported in Tracy 0.9.1.
+profile-with-tracy = ["profiling/profile-with-tracy"]
[workspace]
members = ["crates/*"]
@@ -40,7 +42,7 @@ name = "build"
harness = false
[dependencies]
-memofs = { version = "0.2.0", path = "crates/memofs" }
+memofs = { version = "0.3.0", path = "crates/memofs" }
# These dependencies can be uncommented when working on rbx-dom simultaneously
# rbx_binary = { path = "../rbx-dom/rbx_binary" }
@@ -55,61 +57,60 @@ rbx_reflection = "4.5.0"
rbx_reflection_database = "0.2.10"
rbx_xml = "0.13.3"
-anyhow = "1.0.44"
-backtrace = "0.3.61"
+anyhow = "1.0.80"
+backtrace = "0.3.69"
bincode = "1.3.3"
-crossbeam-channel = "0.5.1"
-csv = "1.1.6"
-env_logger = "0.9.0"
-fs-err = "2.6.0"
-futures = "0.3.17"
-globset = "0.4.8"
+crossbeam-channel = "0.5.12"
+csv = "1.3.0"
+env_logger = "0.9.3"
+fs-err = "2.11.0"
+futures = "0.3.30"
+globset = "0.4.14"
humantime = "2.1.0"
-hyper = { version = "0.14.13", features = ["server", "tcp", "http1"] }
+hyper = { version = "0.14.28", features = ["server", "tcp", "http1"] }
jod-thread = "0.1.2"
-log = "0.4.14"
+log = "0.4.21"
maplit = "1.0.2"
-num_cpus = "1.15.0"
-opener = "0.5.0"
-rayon = "1.7.0"
-reqwest = { version = "0.11.10", features = [
+num_cpus = "1.16.0"
+opener = "0.5.2"
+rayon = "1.9.0"
+reqwest = { version = "0.11.24", default-features = false, features = [
"blocking",
"json",
- "native-tls-vendored",
+ "rustls-tls",
] }
ritz = "0.1.0"
roblox_install = "1.0.0"
-serde = { version = "1.0.130", features = ["derive", "rc"] }
-serde_json = "1.0.68"
-toml = "0.5.9"
-termcolor = "1.1.2"
-thiserror = "1.0.30"
-tokio = { version = "1.12.0", features = ["rt", "rt-multi-thread"] }
-uuid = { version = "1.0.0", features = ["v4", "serde"] }
-clap = { version = "3.1.18", features = ["derive"] }
-profiling = "1.0.6"
-tracy-client = { version = "0.13.2", optional = true }
+serde = { version = "1.0.197", features = ["derive", "rc"] }
+serde_json = "1.0.114"
+toml = "0.5.11"
+termcolor = "1.4.1"
+thiserror = "1.0.57"
+tokio = { version = "1.36.0", features = ["rt", "rt-multi-thread"] }
+uuid = { version = "1.7.0", features = ["v4", "serde"] }
+clap = { version = "3.2.25", features = ["derive"] }
+profiling = "1.0.15"
[target.'cfg(windows)'.dependencies]
winreg = "0.10.1"
[build-dependencies]
-memofs = { version = "0.2.0", path = "crates/memofs" }
+memofs = { version = "0.3.0", path = "crates/memofs" }
-embed-resource = "1.6.4"
-anyhow = "1.0.44"
+embed-resource = "1.8.0"
+anyhow = "1.0.80"
bincode = "1.3.3"
-fs-err = "2.6.0"
+fs-err = "2.11.0"
maplit = "1.0.2"
-semver = "1.0.19"
+semver = "1.0.22"
[dev-dependencies]
rojo-insta-ext = { path = "crates/rojo-insta-ext" }
-criterion = "0.3.5"
-insta = { version = "1.8.0", features = ["redactions", "yaml"] }
-paste = "1.0.5"
-pretty_assertions = "1.2.1"
-serde_yaml = "0.8.21"
-tempfile = "3.2.0"
-walkdir = "2.3.2"
+criterion = "0.3.6"
+insta = { version = "1.36.1", features = ["redactions", "yaml"] }
+paste = "1.0.14"
+pretty_assertions = "1.4.0"
+serde_yaml = "0.8.26"
+tempfile = "3.10.1"
+walkdir = "2.5.0"
diff --git a/README.md b/README.md
index bbdeba30a..bb4effcf9 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
-
+
@@ -43,4 +43,4 @@ Pull requests are welcome!
Rojo supports Rust 1.70.0 and newer. The minimum supported version of Rust is based on the latest versions of the dependencies that Rojo has.
## License
-Rojo is available under the terms of the Mozilla Public License, Version 2.0. See [LICENSE.txt](LICENSE.txt) for details.
\ No newline at end of file
+Rojo is available under the terms of the Mozilla Public License, Version 2.0. See [LICENSE.txt](LICENSE.txt) for details.
diff --git a/assets/icon-32.png b/assets/brand_images/icon-32.png
similarity index 100%
rename from assets/icon-32.png
rename to assets/brand_images/icon-32.png
diff --git a/assets/icon-link-32.png b/assets/brand_images/icon-link-32.png
similarity index 100%
rename from assets/icon-link-32.png
rename to assets/brand_images/icon-link-32.png
diff --git a/assets/icon-warn-32.png b/assets/brand_images/icon-warn-32.png
similarity index 100%
rename from assets/icon-warn-32.png
rename to assets/brand_images/icon-warn-32.png
diff --git a/assets/logo-512.png b/assets/brand_images/logo-512.png
similarity index 100%
rename from assets/logo-512.png
rename to assets/brand_images/logo-512.png
diff --git a/assets/images/back.png b/assets/images/icons/back.png
similarity index 100%
rename from assets/images/back.png
rename to assets/images/icons/back.png
diff --git a/assets/images/back.svg b/assets/images/icons/back.svg
similarity index 100%
rename from assets/images/back.svg
rename to assets/images/icons/back.svg
diff --git a/assets/images/close.png b/assets/images/icons/close.png
similarity index 100%
rename from assets/images/close.png
rename to assets/images/icons/close.png
diff --git a/assets/images/close.svg b/assets/images/icons/close.svg
similarity index 100%
rename from assets/images/close.svg
rename to assets/images/icons/close.svg
diff --git a/assets/images/icons/debug.png b/assets/images/icons/debug.png
new file mode 100644
index 000000000..b2217f0cc
Binary files /dev/null and b/assets/images/icons/debug.png differ
diff --git a/assets/images/icons/expand.png b/assets/images/icons/expand.png
new file mode 100644
index 000000000..fcf561dcd
Binary files /dev/null and b/assets/images/icons/expand.png differ
diff --git a/assets/images/icons/reset.png b/assets/images/icons/reset.png
new file mode 100644
index 000000000..802e430a1
Binary files /dev/null and b/assets/images/icons/reset.png differ
diff --git a/assets/images/icons/warning.png b/assets/images/icons/warning.png
new file mode 100644
index 000000000..79d457df0
Binary files /dev/null and b/assets/images/icons/warning.png differ
diff --git a/assets/round-rect-4px-radius.png b/assets/images/round-rect-4px-radius.png
similarity index 100%
rename from assets/round-rect-4px-radius.png
rename to assets/images/round-rect-4px-radius.png
diff --git a/assets/images/syncsuccess.png b/assets/images/syncsuccess.png
new file mode 100644
index 000000000..74958cc13
Binary files /dev/null and b/assets/images/syncsuccess.png differ
diff --git a/assets/images/syncwarning.png b/assets/images/syncwarning.png
new file mode 100644
index 000000000..eafb93d36
Binary files /dev/null and b/assets/images/syncwarning.png differ
diff --git a/crates/memofs/CHANGELOG.md b/crates/memofs/CHANGELOG.md
index d678f8c9d..44c3aa507 100644
--- a/crates/memofs/CHANGELOG.md
+++ b/crates/memofs/CHANGELOG.md
@@ -1,6 +1,8 @@
# memofs Changelog
## Unreleased Changes
+
+## 0.3.0 (2024-03-15)
* Changed `StdBackend` file watching component to use minimal recursive watches. [#830]
* Added `Vfs::read_to_string` and `Vfs::read_to_string_lf_normalized` [#854]
diff --git a/crates/memofs/Cargo.toml b/crates/memofs/Cargo.toml
index 5cf5a7334..57633ae4f 100644
--- a/crates/memofs/Cargo.toml
+++ b/crates/memofs/Cargo.toml
@@ -1,7 +1,7 @@
[package]
name = "memofs"
description = "Virtual filesystem with configurable backends."
-version = "0.2.0"
+version = "0.3.0"
authors = ["Lucien Greathouse "]
edition = "2018"
readme = "README.md"
@@ -11,7 +11,7 @@ homepage = "https://github.com/rojo-rbx/rojo/tree/master/memofs"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
-crossbeam-channel = "0.5.1"
-fs-err = "2.3.0"
-notify = "4.0.15"
-serde = { version = "1.0", features = ["derive"] }
+crossbeam-channel = "0.5.12"
+fs-err = "2.11.0"
+notify = "4.0.17"
+serde = { version = "1.0.197", features = ["derive"] }
diff --git a/crates/memofs/src/lib.rs b/crates/memofs/src/lib.rs
index 6d41c853b..7a348ff60 100644
--- a/crates/memofs/src/lib.rs
+++ b/crates/memofs/src/lib.rs
@@ -300,7 +300,7 @@ impl Vfs {
let path = path.as_ref();
let contents = self.inner.lock().unwrap().read_to_string(path)?;
- Ok(contents.lines().collect::>().join("\n").into())
+ Ok(contents.replace("\r\n", "\n").into())
}
/// Write a file to the VFS and the underlying backend.
@@ -473,3 +473,23 @@ impl VfsLock<'_> {
self.inner.commit_event(event)
}
}
+
+#[cfg(test)]
+mod test {
+ use crate::{InMemoryFs, Vfs, VfsSnapshot};
+
+ /// https://github.com/rojo-rbx/rojo/issues/899
+ #[test]
+ fn read_to_string_lf_normalized_keeps_trailing_newline() {
+ let mut imfs = InMemoryFs::new();
+ imfs.load_snapshot("test", VfsSnapshot::file("bar\r\nfoo\r\n\r\n"))
+ .unwrap();
+
+ let vfs = Vfs::new(imfs);
+
+ assert_eq!(
+ vfs.read_to_string_lf_normalized("test").unwrap().as_str(),
+ "bar\nfoo\n\n"
+ );
+ }
+}
diff --git a/crates/rojo-insta-ext/Cargo.toml b/crates/rojo-insta-ext/Cargo.toml
index 4471c4acc..55a864991 100644
--- a/crates/rojo-insta-ext/Cargo.toml
+++ b/crates/rojo-insta-ext/Cargo.toml
@@ -6,5 +6,5 @@ edition = "2018"
publish = false
[dependencies]
-serde = "1.0.99"
-serde_yaml = "0.8.9"
+serde = "1.0.197"
+serde_yaml = "0.8.26"
diff --git a/plugin/rbx_dom_lua/EncodedValue.lua b/plugin/rbx_dom_lua/EncodedValue.lua
index e9dd0edd4..f2e9e3434 100644
--- a/plugin/rbx_dom_lua/EncodedValue.lua
+++ b/plugin/rbx_dom_lua/EncodedValue.lua
@@ -493,9 +493,32 @@ types = {
},
}
+types.OptionalCFrame = {
+ fromPod = function(pod)
+ if pod == nil then
+ return nil
+ else
+ return types.CFrame.fromPod(pod)
+ end
+ end,
+
+ toPod = function(roblox)
+ if roblox == nil then
+ return nil
+ else
+ return types.CFrame.toPod(roblox)
+ end
+ end,
+}
+
function EncodedValue.decode(encodedValue)
local ty, value = next(encodedValue)
+ if ty == nil then
+ -- If the encoded pair is empty, assume it is an unoccupied optional value
+ return true, nil
+ end
+
local typeImpl = types[ty]
if typeImpl == nil then
return false, "Couldn't decode value " .. tostring(ty)
diff --git a/plugin/rbx_dom_lua/allValues.json b/plugin/rbx_dom_lua/allValues.json
index b233ab25b..9b07d7bf0 100644
--- a/plugin/rbx_dom_lua/allValues.json
+++ b/plugin/rbx_dom_lua/allValues.json
@@ -370,6 +370,41 @@
},
"ty": "NumberSequence"
},
+ "OptionalCFrame-None": {
+ "value": {
+ "OptionalCFrame": null
+ },
+ "ty": "OptionalCFrame"
+ },
+ "OptionalCFrame-Some": {
+ "value": {
+ "OptionalCFrame": {
+ "position": [
+ 0.0,
+ 0.0,
+ 0.0
+ ],
+ "orientation": [
+ [
+ 1.0,
+ 0.0,
+ 0.0
+ ],
+ [
+ 0.0,
+ 1.0,
+ 0.0
+ ],
+ [
+ 0.0,
+ 0.0,
+ 1.0
+ ]
+ ]
+ }
+ },
+ "ty": "OptionalCFrame"
+ },
"PhysicalProperties-Custom": {
"value": {
"PhysicalProperties": {
diff --git a/plugin/rbx_dom_lua/customProperties.lua b/plugin/rbx_dom_lua/customProperties.lua
index 072db9ef0..f115f7c82 100644
--- a/plugin/rbx_dom_lua/customProperties.lua
+++ b/plugin/rbx_dom_lua/customProperties.lua
@@ -111,6 +111,18 @@ return {
return true, instance:ScaleTo(value)
end,
},
+ WorldPivotData = {
+ read = function(instance)
+ return true, instance:GetPivot()
+ end,
+ write = function(instance, _, value)
+ if value == nil then
+ return true, nil
+ else
+ return true, instance:PivotTo(value)
+ end
+ end,
+ },
},
Terrain = {
MaterialColors = {
diff --git a/plugin/rbx_dom_lua/database.json b/plugin/rbx_dom_lua/database.json
index 81424b27e..34be08b46 100644
--- a/plugin/rbx_dom_lua/database.json
+++ b/plugin/rbx_dom_lua/database.json
@@ -1,9 +1,9 @@
{
"Version": [
0,
- 607,
+ 612,
0,
- 6070550
+ 6120532
],
"Classes": {
"Accessory": {
@@ -345,6 +345,17 @@
}
}
},
+ "ActivityHistoryService": {
+ "Name": "ActivityHistoryService",
+ "Tags": [
+ "NotCreatable",
+ "NotReplicated",
+ "Service"
+ ],
+ "Superclass": "Instance",
+ "Properties": {},
+ "DefaultProperties": {}
+ },
"Actor": {
"Name": "Actor",
"Tags": [],
@@ -11172,10 +11183,12 @@
"DataType": {
"Value": "CFrame"
},
- "Tags": [],
+ "Tags": [
+ "Hidden"
+ ],
"Kind": {
"Canonical": {
- "Serialization": "Serializes"
+ "Serialization": "DoesNotSerialize"
}
}
},
@@ -11185,10 +11198,12 @@
"DataType": {
"Value": "Int32"
},
- "Tags": [],
+ "Tags": [
+ "Hidden"
+ ],
"Kind": {
"Canonical": {
- "Serialization": "Serializes"
+ "Serialization": "DoesNotSerialize"
}
}
},
@@ -11198,10 +11213,12 @@
"DataType": {
"Value": "String"
},
- "Tags": [],
+ "Tags": [
+ "Hidden"
+ ],
"Kind": {
"Canonical": {
- "Serialization": "Serializes"
+ "Serialization": "DoesNotSerialize"
}
}
},
@@ -11211,22 +11228,38 @@
"DataType": {
"Value": "Int32"
},
- "Tags": [],
+ "Tags": [
+ "Hidden"
+ ],
"Kind": {
"Canonical": {
- "Serialization": "Serializes"
+ "Serialization": "DoesNotSerialize"
+ }
+ }
+ },
+ "IsIdle": {
+ "Name": "IsIdle",
+ "Scriptability": "ReadWrite",
+ "DataType": {
+ "Value": "Bool"
+ },
+ "Tags": [
+ "Hidden"
+ ],
+ "Kind": {
+ "Canonical": {
+ "Serialization": "DoesNotSerialize"
}
}
},
"Status": {
"Name": "Status",
- "Scriptability": "None",
+ "Scriptability": "ReadWrite",
"DataType": {
"Enum": "CollaboratorStatus"
},
"Tags": [
- "Hidden",
- "NotScriptable"
+ "Hidden"
],
"Kind": {
"Canonical": {
@@ -11240,10 +11273,12 @@
"DataType": {
"Value": "Int64"
},
- "Tags": [],
+ "Tags": [
+ "Hidden"
+ ],
"Kind": {
"Canonical": {
- "Serialization": "Serializes"
+ "Serialization": "DoesNotSerialize"
}
}
},
@@ -11253,10 +11288,12 @@
"DataType": {
"Value": "String"
},
- "Tags": [],
+ "Tags": [
+ "Hidden"
+ ],
"Kind": {
"Canonical": {
- "Serialization": "Serializes"
+ "Serialization": "DoesNotSerialize"
}
}
}
@@ -12224,6 +12261,19 @@
"Serialization": "Serializes"
}
}
+ },
+ "UpDirection": {
+ "Name": "UpDirection",
+ "Scriptability": "ReadWrite",
+ "DataType": {
+ "Value": "Vector3"
+ },
+ "Tags": [],
+ "Kind": {
+ "Canonical": {
+ "Serialization": "Serializes"
+ }
+ }
}
},
"DefaultProperties": {
@@ -12261,6 +12311,13 @@
},
"Tags": {
"Tags": []
+ },
+ "UpDirection": {
+ "Vector3": [
+ 0.0,
+ 1.0,
+ 0.0
+ ]
}
}
},
@@ -13286,7 +13343,9 @@
"DataType": {
"Value": "Bool"
},
- "Tags": [],
+ "Tags": [
+ "Deprecated"
+ ],
"Kind": {
"Canonical": {
"Serialization": "Serializes"
@@ -15878,6 +15937,19 @@
}
}
},
+ "PermissionPolicy": {
+ "Name": "PermissionPolicy",
+ "Scriptability": "ReadWrite",
+ "DataType": {
+ "Enum": "DragDetectorPermissionPolicy"
+ },
+ "Tags": [],
+ "Kind": {
+ "Canonical": {
+ "Serialization": "Serializes"
+ }
+ }
+ },
"PhysicalDragClickedPart": {
"Name": "PhysicalDragClickedPart",
"Scriptability": "None",
@@ -16168,10 +16240,13 @@
"Orientation": {
"Vector3": [
-0.0,
- 180.0,
+ 179.99998,
90.0
]
},
+ "PermissionPolicy": {
+ "Enum": 1
+ },
"ResponseStyle": {
"Enum": 1
},
@@ -22285,7 +22360,9 @@
"DataType": {
"Value": "Bool"
},
- "Tags": [],
+ "Tags": [
+ "Deprecated"
+ ],
"Kind": {
"Canonical": {
"Serialization": "Serializes"
@@ -31232,7 +31309,7 @@
},
"WorldPivotData": {
"Name": "WorldPivotData",
- "Scriptability": "None",
+ "Scriptability": "Custom",
"DataType": {
"Value": "OptionalCFrame"
},
@@ -33071,7 +33148,7 @@
},
"SerializedDefaultAttributes": {
"Name": "SerializedDefaultAttributes",
- "Scriptability": "Read",
+ "Scriptability": "None",
"DataType": {
"Value": "BinaryString"
},
@@ -35022,6 +35099,19 @@
"Serialization": "Serializes"
}
}
+ },
+ "ZIndex": {
+ "Name": "ZIndex",
+ "Scriptability": "None",
+ "DataType": {
+ "Value": "Int32"
+ },
+ "Tags": [],
+ "Kind": {
+ "Canonical": {
+ "Serialization": "Serializes"
+ }
+ }
}
},
"DefaultProperties": {}
@@ -35734,6 +35824,58 @@
}
}
},
+ "DrawConstraintsNetForce": {
+ "Name": "DrawConstraintsNetForce",
+ "Scriptability": "None",
+ "DataType": {
+ "Value": "Bool"
+ },
+ "Tags": [],
+ "Kind": {
+ "Canonical": {
+ "Serialization": "Serializes"
+ }
+ }
+ },
+ "DrawContactsNetForce": {
+ "Name": "DrawContactsNetForce",
+ "Scriptability": "None",
+ "DataType": {
+ "Value": "Bool"
+ },
+ "Tags": [],
+ "Kind": {
+ "Canonical": {
+ "Serialization": "Serializes"
+ }
+ }
+ },
+ "DrawTotalNetForce": {
+ "Name": "DrawTotalNetForce",
+ "Scriptability": "None",
+ "DataType": {
+ "Value": "Bool"
+ },
+ "Tags": [],
+ "Kind": {
+ "Canonical": {
+ "Serialization": "Serializes"
+ }
+ }
+ },
+ "EnableForceVisualizationSmoothing": {
+ "Name": "EnableForceVisualizationSmoothing",
+ "Scriptability": "None",
+ "DataType": {
+ "Value": "Bool"
+ },
+ "Tags": [],
+ "Kind": {
+ "Canonical": {
+ "Serialization": "Serializes"
+ }
+ }
+ },
"FluidForceDrawScale": {
"Name": "FluidForceDrawScale",
"Scriptability": "None",
@@ -35776,6 +35918,19 @@
}
}
},
+ "ForceVisualizationSmoothingSteps": {
+ "Name": "ForceVisualizationSmoothingSteps",
+ "Scriptability": "None",
+ "DataType": {
+ "Value": "Int32"
+ },
+ "Tags": [],
+ "Kind": {
+ "Canonical": {
+ "Serialization": "Serializes"
+ }
+ }
+ },
"IsInterpolationThrottleShown": {
"Name": "IsInterpolationThrottleShown",
"Scriptability": "ReadWrite",
@@ -35893,6 +36048,19 @@
}
}
},
+ "TorqueDrawScale": {
+ "Name": "TorqueDrawScale",
+ "Scriptability": "None",
+ "DataType": {
+ "Value": "Float32"
+ },
+ "Tags": [],
+ "Kind": {
+ "Canonical": {
+ "Serialization": "Serializes"
+ }
+ }
+ },
"UseCSGv2": {
"Name": "UseCSGv2",
"Scriptability": "ReadWrite",
@@ -38337,6 +38505,17 @@
}
}
},
+ "ProjectFolderService": {
+ "Name": "ProjectFolderService",
+ "Tags": [
+ "NotCreatable",
+ "NotReplicated",
+ "Service"
+ ],
+ "Superclass": "Instance",
+ "Properties": {},
+ "DefaultProperties": {}
+ },
"ProximityPrompt": {
"Name": "ProximityPrompt",
"Tags": [],
@@ -40859,6 +41038,19 @@
}
}
},
+ "PreferredUploadId": {
+ "Name": "PreferredUploadId",
+ "Scriptability": "ReadWrite",
+ "DataType": {
+ "Value": "Int64"
+ },
+ "Tags": [],
+ "Kind": {
+ "Canonical": {
+ "Serialization": "Serializes"
+ }
+ }
+ },
"RestPose": {
"Name": "RestPose",
"Scriptability": "ReadWrite",
@@ -44505,7 +44697,9 @@
"DataType": {
"Value": "Bool"
},
- "Tags": [],
+ "Tags": [
+ "Deprecated"
+ ],
"Kind": {
"Canonical": {
"Serialization": "Serializes"
@@ -46931,21 +47125,6 @@
}
}
},
- "AnimationCompositorMode": {
- "Name": "AnimationCompositorMode",
- "Scriptability": "ReadWrite",
- "DataType": {
- "Enum": "AnimationCompositorMode"
- },
- "Tags": [
- "NotBrowsable"
- ],
- "Kind": {
- "Canonical": {
- "Serialization": "Serializes"
- }
- }
- },
"AutoJumpEnabled": {
"Name": "AutoJumpEnabled",
"Scriptability": "ReadWrite",
@@ -47488,21 +47667,6 @@
}
}
},
- "HumanoidStateMachineMode": {
- "Name": "HumanoidStateMachineMode",
- "Scriptability": "ReadWrite",
- "DataType": {
- "Enum": "HumanoidStateMachineMode"
- },
- "Tags": [
- "NotBrowsable"
- ],
- "Kind": {
- "Canonical": {
- "Serialization": "Serializes"
- }
- }
- },
"LoadCharacterAppearance": {
"Name": "LoadCharacterAppearance",
"Scriptability": "ReadWrite",
@@ -47594,9 +47758,6 @@
"AllowCustomAnimations": {
"Bool": true
},
- "AnimationCompositorMode": {
- "Enum": 0
- },
"Attributes": {
"Attributes": {}
},
@@ -47729,9 +47890,6 @@
"HealthDisplayDistance": {
"Float32": 100.0
},
- "HumanoidStateMachineMode": {
- "Enum": 0
- },
"LoadCharacterAppearance": {
"Bool": true
},
@@ -48619,6 +48777,136 @@
}
}
},
+ "DraggerActiveColor": {
+ "Name": "DraggerActiveColor",
+ "Scriptability": "None",
+ "DataType": {
+ "Value": "Color3"
+ },
+ "Tags": [],
+ "Kind": {
+ "Canonical": {
+ "Serialization": "Serializes"
+ }
+ }
+ },
+ "DraggerMajorGridIncrement": {
+ "Name": "DraggerMajorGridIncrement",
+ "Scriptability": "None",
+ "DataType": {
+ "Value": "Int32"
+ },
+ "Tags": [],
+ "Kind": {
+ "Canonical": {
+ "Serialization": "Serializes"
+ }
+ }
+ },
+ "DraggerMaxSoftSnaps": {
+ "Name": "DraggerMaxSoftSnaps",
+ "Scriptability": "None",
+ "DataType": {
+ "Value": "Int32"
+ },
+ "Tags": [],
+ "Kind": {
+ "Canonical": {
+ "Serialization": "Serializes"
+ }
+ }
+ },
+ "DraggerPassiveColor": {
+ "Name": "DraggerPassiveColor",
+ "Scriptability": "None",
+ "DataType": {
+ "Value": "Color3"
+ },
+ "Tags": [],
+ "Kind": {
+ "Canonical": {
+ "Serialization": "Serializes"
+ }
+ }
+ },
+ "DraggerShowHoverRuler": {
+ "Name": "DraggerShowHoverRuler",
+ "Scriptability": "None",
+ "DataType": {
+ "Value": "Bool"
+ },
+ "Tags": [],
+ "Kind": {
+ "Canonical": {
+ "Serialization": "Serializes"
+ }
+ }
+ },
+ "DraggerShowMeasurement": {
+ "Name": "DraggerShowMeasurement",
+ "Scriptability": "None",
+ "DataType": {
+ "Value": "Bool"
+ },
+ "Tags": [],
+ "Kind": {
+ "Canonical": {
+ "Serialization": "Serializes"
+ }
+ }
+ },
+ "DraggerShowTargetSnap": {
+ "Name": "DraggerShowTargetSnap",
+ "Scriptability": "None",
+ "DataType": {
+ "Value": "Bool"
+ },
+ "Tags": [],
+ "Kind": {
+ "Canonical": {
+ "Serialization": "Serializes"
+ }
+ }
+ },
+ "DraggerSoftSnapMarginFactor": {
+ "Name": "DraggerSoftSnapMarginFactor",
+ "Scriptability": "None",
+ "DataType": {
+ "Value": "Float32"
+ },
+ "Tags": [],
+ "Kind": {
+ "Canonical": {
+ "Serialization": "Serializes"
+ }
+ }
+ },
+ "DraggerSummonMarginFactor": {
+ "Name": "DraggerSummonMarginFactor",
+ "Scriptability": "None",
+ "DataType": {
+ "Value": "Float32"
+ },
+ "Tags": [],
+ "Kind": {
+ "Canonical": {
+ "Serialization": "Serializes"
+ }
+ }
+ },
+ "DraggerTiltRotateDuration": {
+ "Name": "DraggerTiltRotateDuration",
+ "Scriptability": "None",
+ "DataType": {
+ "Value": "Float32"
+ },
+ "Tags": [],
+ "Kind": {
+ "Canonical": {
+ "Serialization": "Serializes"
+ }
+ }
+ },
"Enable Autocomplete": {
"Name": "Enable Autocomplete",
"Scriptability": "ReadWrite",
@@ -55907,6 +56195,17 @@
"Properties": {},
"DefaultProperties": {}
},
+ "TextureGenerationService": {
+ "Name": "TextureGenerationService",
+ "Tags": [
+ "NotCreatable",
+ "NotReplicated",
+ "Service"
+ ],
+ "Superclass": "Instance",
+ "Properties": {},
+ "DefaultProperties": {}
+ },
"ThirdPartyUserService": {
"Name": "ThirdPartyUserService",
"Tags": [
@@ -59590,6 +59889,22 @@
}
}
},
+ "ChatTranslationLocale": {
+ "Name": "ChatTranslationLocale",
+ "Scriptability": "None",
+ "DataType": {
+ "Value": "String"
+ },
+ "Tags": [
+ "Hidden",
+ "NotReplicated"
+ ],
+ "Kind": {
+ "Canonical": {
+ "Serialization": "Serializes"
+ }
+ }
+ },
"ChatTranslationToggleEnabled": {
"Name": "ChatTranslationToggleEnabled",
"Scriptability": "None",
@@ -59724,6 +60039,22 @@
}
}
},
+ "FramerateCap": {
+ "Name": "FramerateCap",
+ "Scriptability": "None",
+ "DataType": {
+ "Value": "Int32"
+ },
+ "Tags": [
+ "Hidden",
+ "NotReplicated"
+ ],
+ "Kind": {
+ "Canonical": {
+ "Serialization": "Serializes"
+ }
+ }
+ },
"Fullscreen": {
"Name": "Fullscreen",
"Scriptability": "None",
@@ -61068,6 +61399,7 @@
"VRService": {
"Name": "VRService",
"Tags": [
+ "NotBrowsable",
"NotCreatable",
"Service"
],
@@ -61084,7 +61416,22 @@
],
"Kind": {
"Canonical": {
- "Serialization": "DoesNotSerialize"
+ "Serialization": "Serializes"
+ }
+ }
+ },
+ "AvatarGestures": {
+ "Name": "AvatarGestures",
+ "Scriptability": "ReadWrite",
+ "DataType": {
+ "Value": "Bool"
+ },
+ "Tags": [
+ "NotBrowsable"
+ ],
+ "Kind": {
+ "Canonical": {
+ "Serialization": "Serializes"
}
}
},
@@ -61111,10 +61458,12 @@
"DataType": {
"Value": "Bool"
},
- "Tags": [],
+ "Tags": [
+ "NotReplicated"
+ ],
"Kind": {
"Canonical": {
- "Serialization": "DoesNotSerialize"
+ "Serialization": "Serializes"
}
}
},
@@ -61124,7 +61473,9 @@
"DataType": {
"Enum": "UserCFrame"
},
- "Tags": [],
+ "Tags": [
+ "NotReplicated"
+ ],
"Kind": {
"Canonical": {
"Serialization": "DoesNotSerialize"
@@ -61283,12 +61634,21 @@
"Attributes": {
"Attributes": {}
},
+ "AutomaticScaling": {
+ "Enum": 0
+ },
+ "AvatarGestures": {
+ "Bool": false
+ },
"Capabilities": {
"SecurityCapabilities": 0
},
"DefinesCapabilities": {
"Bool": false
},
+ "FadeOutViewOnCollision": {
+ "Bool": true
+ },
"SourceAssetId": {
"Int64": -1
},
@@ -62839,16 +63199,6 @@
"Properties": {},
"DefaultProperties": {}
},
- "VisibilityService": {
- "Name": "VisibilityService",
- "Tags": [
- "NotCreatable",
- "Service"
- ],
- "Superclass": "Instance",
- "Properties": {},
- "DefaultProperties": {}
- },
"Visit": {
"Name": "Visit",
"Tags": [
@@ -62933,9 +63283,7 @@
"DataType": {
"Enum": "AudioApiRollout"
},
- "Tags": [
- "NotBrowsable"
- ],
+ "Tags": [],
"Kind": {
"Canonical": {
"Serialization": "Serializes"
@@ -65214,14 +65562,6 @@
"Timeout": 10
}
},
- "AnimationCompositorMode": {
- "name": "AnimationCompositorMode",
- "items": {
- "Default": 0,
- "Disabled": 2,
- "Enabled": 1
- }
- },
"AnimationPriority": {
"name": "AnimationPriority",
"items": {
@@ -65835,10 +66175,10 @@
"CollaboratorStatus": {
"name": "CollaboratorStatus",
"items": {
- "Editing3D": 0,
- "None": 3,
- "PrivateScripting": 2,
- "Scripting": 1
+ "Editing3D": 1,
+ "None": 0,
+ "PrivateScripting": 3,
+ "Scripting": 2
}
},
"CollisionFidelity": {
@@ -66307,6 +66647,14 @@
"TranslateViewPlane": 4
}
},
+ "DragDetectorPermissionPolicy": {
+ "name": "DragDetectorPermissionPolicy",
+ "items": {
+ "Everybody": 1,
+ "Nobody": 0,
+ "Scriptable": 2
+ }
+ },
"DragDetectorResponseStyle": {
"name": "DragDetectorResponseStyle",
"items": {
@@ -66810,15 +67158,6 @@
"R6": 0
}
},
- "HumanoidStateMachineMode": {
- "name": "HumanoidStateMachineMode",
- "items": {
- "Default": 0,
- "Legacy": 1,
- "LuaStateMachine": 3,
- "NoStateMachine": 2
- }
- },
"HumanoidStateType": {
"name": "HumanoidStateType",
"items": {
@@ -67469,6 +67808,16 @@
"PersistentPerPlayer": 3
}
},
+ "ModerationStatus": {
+ "name": "ModerationStatus",
+ "items": {
+ "Invalid": 5,
+ "NotApplicable": 4,
+ "NotReviewed": 3,
+ "ReviewedApproved": 1,
+ "ReviewedRejected": 2
+ }
+ },
"ModifierKey": {
"name": "ModifierKey",
"items": {
diff --git a/plugin/src/App/Components/ClassIcon.lua b/plugin/src/App/Components/ClassIcon.lua
new file mode 100644
index 000000000..c3e46e0d2
--- /dev/null
+++ b/plugin/src/App/Components/ClassIcon.lua
@@ -0,0 +1,126 @@
+local StudioService = game:GetService("StudioService")
+local AssetService = game:GetService("AssetService")
+
+local Rojo = script:FindFirstAncestor("Rojo")
+local Plugin = Rojo.Plugin
+local Packages = Rojo.Packages
+
+local Roact = require(Packages.Roact)
+
+local e = Roact.createElement
+
+local EditableImage = require(Plugin.App.Components.EditableImage)
+
+local imageCache = {}
+local function getImageSizeAndPixels(image)
+ if not imageCache[image] then
+ local editableImage = AssetService:CreateEditableImageAsync(image)
+ imageCache[image] = {
+ Size = editableImage.Size,
+ Pixels = editableImage:ReadPixels(Vector2.zero, editableImage.Size),
+ }
+ end
+
+ return imageCache[image].Size, table.clone(imageCache[image].Pixels)
+end
+
+local function getRecoloredClassIcon(className, color)
+ local iconProps = StudioService:GetClassIcon(className)
+
+ if iconProps and color then
+ local success, editableImageSize, editableImagePixels = pcall(function()
+ local size, pixels = getImageSizeAndPixels(iconProps.Image)
+
+ local minVal, maxVal = math.huge, -math.huge
+ for i = 1, #pixels, 4 do
+ if pixels[i + 3] == 0 then
+ continue
+ end
+ local pixelVal = math.max(pixels[i], pixels[i + 1], pixels[i + 2])
+
+ minVal = math.min(minVal, pixelVal)
+ maxVal = math.max(maxVal, pixelVal)
+ end
+
+ local hue, sat, val = color:ToHSV()
+ for i = 1, #pixels, 4 do
+ if pixels[i + 3] == 0 then
+ continue
+ end
+
+ local pixelVal = math.max(pixels[i], pixels[i + 1], pixels[i + 2])
+ local newVal = val
+ if minVal < maxVal then
+ -- Remap minVal - maxVal to val*0.9 - val
+ newVal = val * (0.9 + 0.1 * (pixelVal - minVal) / (maxVal - minVal))
+ end
+
+ local newPixelColor = Color3.fromHSV(hue, sat, newVal)
+ pixels[i], pixels[i + 1], pixels[i + 2] = newPixelColor.R, newPixelColor.G, newPixelColor.B
+ end
+ return size, pixels
+ end)
+ if success then
+ iconProps.EditableImagePixels = editableImagePixels
+ iconProps.EditableImageSize = editableImageSize
+ end
+ end
+
+ return iconProps
+end
+
+local ClassIcon = Roact.PureComponent:extend("ClassIcon")
+
+function ClassIcon:init()
+ self.state = {
+ iconProps = nil,
+ }
+end
+
+function ClassIcon:updateIcon()
+ local props = self.props
+ local iconProps = getRecoloredClassIcon(props.className, props.color)
+ self:setState({
+ iconProps = iconProps,
+ })
+end
+
+function ClassIcon:didMount()
+ self:updateIcon()
+end
+
+function ClassIcon:didUpdate(lastProps)
+ if lastProps.className ~= self.props.className or lastProps.color ~= self.props.color then
+ self:updateIcon()
+ end
+end
+
+function ClassIcon:render()
+ local iconProps = self.state.iconProps
+ if not iconProps then
+ return nil
+ end
+
+ return e(
+ "ImageLabel",
+ {
+ Size = self.props.size,
+ Position = self.props.position,
+ LayoutOrder = self.props.layoutOrder,
+ AnchorPoint = self.props.anchorPoint,
+ ImageTransparency = self.props.transparency,
+ Image = iconProps.Image,
+ ImageRectOffset = iconProps.ImageRectOffset,
+ ImageRectSize = iconProps.ImageRectSize,
+ BackgroundTransparency = 1,
+ },
+ if iconProps.EditableImagePixels
+ then e(EditableImage, {
+ size = iconProps.EditableImageSize,
+ pixels = iconProps.EditableImagePixels,
+ })
+ else nil
+ )
+end
+
+return ClassIcon
diff --git a/plugin/src/App/Components/EditableImage.lua b/plugin/src/App/Components/EditableImage.lua
new file mode 100644
index 000000000..501a37eee
--- /dev/null
+++ b/plugin/src/App/Components/EditableImage.lua
@@ -0,0 +1,41 @@
+local Rojo = script:FindFirstAncestor("Rojo")
+local Packages = Rojo.Packages
+
+local Roact = require(Packages.Roact)
+
+local e = Roact.createElement
+
+local EditableImage = Roact.PureComponent:extend("EditableImage")
+
+function EditableImage:init()
+ self.ref = Roact.createRef()
+end
+
+function EditableImage:writePixels()
+ local image = self.ref.current
+ if not image then
+ return
+ end
+ if not self.props.pixels then
+ return
+ end
+
+ image:WritePixels(Vector2.zero, self.props.size, self.props.pixels)
+end
+
+function EditableImage:render()
+ return e("EditableImage", {
+ Size = self.props.size,
+ [Roact.Ref] = self.ref,
+ })
+end
+
+function EditableImage:didMount()
+ self:writePixels()
+end
+
+function EditableImage:didUpdate()
+ self:writePixels()
+end
+
+return EditableImage
diff --git a/plugin/src/App/Components/PatchVisualizer/ChangeList.lua b/plugin/src/App/Components/PatchVisualizer/ChangeList.lua
index ce01b8010..2f10d4587 100644
--- a/plugin/src/App/Components/PatchVisualizer/ChangeList.lua
+++ b/plugin/src/App/Components/PatchVisualizer/ChangeList.lua
@@ -155,7 +155,7 @@ function ChangeList:render()
local headerRow = changes[1]
local headers = e("Frame", {
- Size = UDim2.new(1, 0, 0, 30),
+ Size = UDim2.new(1, 0, 0, 24),
BackgroundTransparency = rowTransparency,
BackgroundColor3 = theme.Diff.Row,
LayoutOrder = 0,
@@ -214,7 +214,7 @@ function ChangeList:render()
local isWarning = metadata.isWarning
rows[row] = e("Frame", {
- Size = UDim2.new(1, 0, 0, 30),
+ Size = UDim2.new(1, 0, 0, 24),
BackgroundTransparency = row % 2 ~= 0 and rowTransparency or 1,
BackgroundColor3 = theme.Diff.Row,
BorderSizePixel = 0,
@@ -269,8 +269,8 @@ function ChangeList:render()
}, {
Headers = headers,
Values = e(ScrollingFrame, {
- size = UDim2.new(1, 0, 1, -30),
- position = UDim2.new(0, 0, 0, 30),
+ size = UDim2.new(1, 0, 1, -24),
+ position = UDim2.new(0, 0, 0, 24),
contentSize = self.contentSize,
transparency = props.transparency,
}, rows),
diff --git a/plugin/src/App/Components/PatchVisualizer/DomLabel.lua b/plugin/src/App/Components/PatchVisualizer/DomLabel.lua
index 41ec0b8e9..a842dcbc5 100644
--- a/plugin/src/App/Components/PatchVisualizer/DomLabel.lua
+++ b/plugin/src/App/Components/PatchVisualizer/DomLabel.lua
@@ -1,5 +1,4 @@
local SelectionService = game:GetService("Selection")
-local StudioService = game:GetService("StudioService")
local Rojo = script:FindFirstAncestor("Rojo")
local Plugin = Rojo.Plugin
@@ -15,7 +14,8 @@ local bindingUtil = require(Plugin.App.bindingUtil)
local e = Roact.createElement
local ChangeList = require(script.Parent.ChangeList)
-local Tooltip = require(script.Parent.Parent.Tooltip)
+local Tooltip = require(Plugin.App.Components.Tooltip)
+local ClassIcon = require(Plugin.App.Components.ClassIcon)
local Expansion = Roact.Component:extend("Expansion")
@@ -28,8 +28,8 @@ function Expansion:render()
return e("Frame", {
BackgroundTransparency = 1,
- Size = UDim2.new(1, -props.indent, 1, -30),
- Position = UDim2.new(0, props.indent, 0, 30),
+ Size = UDim2.new(1, -props.indent, 1, -24),
+ Position = UDim2.new(0, props.indent, 0, 24),
}, {
ChangeList = e(ChangeList, {
changes = props.changeList,
@@ -44,7 +44,7 @@ local DomLabel = Roact.Component:extend("DomLabel")
function DomLabel:init()
local initHeight = self.props.elementHeight:getValue()
- self.expanded = initHeight > 30
+ self.expanded = initHeight > 24
self.motor = Flipper.SingleMotor.new(initHeight)
self.binding = bindingUtil.fromMotor(self.motor)
@@ -53,7 +53,7 @@ function DomLabel:init()
renderExpansion = self.expanded,
})
self.motor:onStep(function(value)
- local renderExpansion = value > 30
+ local renderExpansion = value > 24
self.props.setElementHeight(value)
if self.props.updateEvent then
@@ -81,7 +81,7 @@ function DomLabel:didUpdate(prevProps)
then
-- Close the expansion when the domlabel is changed to a different thing
self.expanded = false
- self.motor:setGoal(Flipper.Spring.new(30, {
+ self.motor:setGoal(Flipper.Spring.new(24, {
frequency = 5,
dampingRatio = 1,
}))
@@ -90,17 +90,49 @@ end
function DomLabel:render()
local props = self.props
+ local depth = props.depth or 1
return Theme.with(function(theme)
- local iconProps = StudioService:GetClassIcon(props.className)
- local indent = (props.depth or 0) * 20 + 25
+ local color = if props.isWarning
+ then theme.Diff.Warning
+ elseif props.patchType then theme.Diff[props.patchType]
+ else theme.TextColor
+
+ local indent = (depth - 1) * 12 + 15
-- Line guides help indent depth remain readable
local lineGuides = {}
- for i = 1, props.depth or 0 do
- lineGuides["Line_" .. i] = e("Frame", {
- Size = UDim2.new(0, 2, 1, 2),
- Position = UDim2.new(0, (20 * i) + 15, 0, -1),
+ for i = 2, depth do
+ if props.depthsComplete[i] then
+ continue
+ end
+ if props.isFinalChild and i == depth then
+ -- This line stops halfway down to merge with our connector for the right angle
+ lineGuides["Line_" .. i] = e("Frame", {
+ Size = UDim2.new(0, 2, 0, 15),
+ Position = UDim2.new(0, (12 * (i - 1)) + 6, 0, -1),
+ BorderSizePixel = 0,
+ BackgroundTransparency = props.transparency,
+ BackgroundColor3 = theme.BorderedContainer.BorderColor,
+ })
+ else
+ -- All other lines go all the way
+ -- with the exception of the final element, which stops halfway down
+ lineGuides["Line_" .. i] = e("Frame", {
+ Size = UDim2.new(0, 2, 1, if props.isFinalElement then -9 else 2),
+ Position = UDim2.new(0, (12 * (i - 1)) + 6, 0, -1),
+ BorderSizePixel = 0,
+ BackgroundTransparency = props.transparency,
+ BackgroundColor3 = theme.BorderedContainer.BorderColor,
+ })
+ end
+ end
+
+ if depth ~= 1 then
+ lineGuides["Connector"] = e("Frame", {
+ Size = UDim2.new(0, 8, 0, 2),
+ Position = UDim2.new(0, 2 + (12 * props.depth), 0, 12),
+ AnchorPoint = Vector2.xAxis,
BorderSizePixel = 0,
BackgroundTransparency = props.transparency,
BackgroundColor3 = theme.BorderedContainer.BorderColor,
@@ -109,9 +141,8 @@ function DomLabel:render()
return e("Frame", {
ClipsDescendants = true,
- BackgroundColor3 = if props.patchType then theme.Diff[props.patchType] else nil,
- BorderSizePixel = 0,
- BackgroundTransparency = props.patchType and props.transparency or 1,
+ BackgroundTransparency = if props.elementIndex % 2 == 0 then 0.985 else 1,
+ BackgroundColor3 = theme.Diff.Row,
Size = self.binding:map(function(expand)
return UDim2.new(1, 0, 0, expand)
end),
@@ -141,8 +172,8 @@ function DomLabel:render()
if props.changeList then
self.expanded = not self.expanded
- local goalHeight = 30
- + (if self.expanded then math.clamp(#props.changeList * 30, 30, 30 * 6) else 0)
+ local goalHeight = 24
+ + (if self.expanded then math.clamp(#props.changeList * 24, 24, 24 * 6) else 0)
self.motor:setGoal(Flipper.Spring.new(goalHeight, {
frequency = 5,
dampingRatio = 1,
@@ -174,40 +205,74 @@ function DomLabel:render()
DiffIcon = if props.patchType
then e("ImageLabel", {
Image = Assets.Images.Diff[props.patchType],
- ImageColor3 = theme.AddressEntry.PlaceholderColor,
+ ImageColor3 = color,
ImageTransparency = props.transparency,
BackgroundTransparency = 1,
- Size = UDim2.new(0, 20, 0, 20),
- Position = UDim2.new(0, 0, 0, 15),
+ Size = UDim2.new(0, 14, 0, 14),
+ Position = UDim2.new(0, 0, 0, 12),
AnchorPoint = Vector2.new(0, 0.5),
})
else nil,
- ClassIcon = e("ImageLabel", {
- Image = iconProps.Image,
- ImageTransparency = props.transparency,
- ImageRectOffset = iconProps.ImageRectOffset,
- ImageRectSize = iconProps.ImageRectSize,
- BackgroundTransparency = 1,
- Size = UDim2.new(0, 20, 0, 20),
- Position = UDim2.new(0, indent, 0, 15),
- AnchorPoint = Vector2.new(0, 0.5),
+ ClassIcon = e(ClassIcon, {
+ className = props.className,
+ color = color,
+ transparency = props.transparency,
+ size = UDim2.new(0, 16, 0, 16),
+ position = UDim2.new(0, indent + 2, 0, 12),
+ anchorPoint = Vector2.new(0, 0.5),
}),
InstanceName = e("TextLabel", {
- Text = (if props.isWarning then "âš " else "") .. props.name .. (props.hint and string.format(
- ' %s',
- theme.AddressEntry.PlaceholderColor:ToHex(),
- props.hint
- ) or ""),
+ Text = (if props.isWarning then "âš " else "") .. props.name,
RichText = true,
BackgroundTransparency = 1,
- Font = Enum.Font.GothamMedium,
+ Font = if props.patchType then Enum.Font.GothamBold else Enum.Font.GothamMedium,
TextSize = 14,
- TextColor3 = if props.isWarning then theme.Diff.Warning else theme.TextColor,
+ TextColor3 = color,
TextXAlignment = Enum.TextXAlignment.Left,
TextTransparency = props.transparency,
TextTruncate = Enum.TextTruncate.AtEnd,
- Size = UDim2.new(1, -indent - 50, 0, 30),
- Position = UDim2.new(0, indent + 30, 0, 0),
+ Size = UDim2.new(1, -indent - 50, 0, 24),
+ Position = UDim2.new(0, indent + 22, 0, 0),
+ }),
+ ChangeInfo = e("Frame", {
+ BackgroundTransparency = 1,
+ Size = UDim2.new(1, -indent - 80, 0, 24),
+ Position = UDim2.new(1, -2, 0, 0),
+ AnchorPoint = Vector2.new(1, 0),
+ }, {
+ Layout = e("UIListLayout", {
+ FillDirection = Enum.FillDirection.Horizontal,
+ HorizontalAlignment = Enum.HorizontalAlignment.Right,
+ VerticalAlignment = Enum.VerticalAlignment.Center,
+ SortOrder = Enum.SortOrder.LayoutOrder,
+ Padding = UDim.new(0, 4),
+ }),
+ Edits = if props.changeInfo and props.changeInfo.edits
+ then e("TextLabel", {
+ Text = props.changeInfo.edits .. if props.changeInfo.failed then "," else "",
+ BackgroundTransparency = 1,
+ Font = Enum.Font.Gotham,
+ TextSize = 14,
+ TextColor3 = theme.SubTextColor,
+ TextTransparency = props.transparency,
+ Size = UDim2.new(0, 0, 0, 16),
+ AutomaticSize = Enum.AutomaticSize.X,
+ LayoutOrder = 2,
+ })
+ else nil,
+ Failed = if props.changeInfo and props.changeInfo.failed
+ then e("TextLabel", {
+ Text = props.changeInfo.failed,
+ BackgroundTransparency = 1,
+ Font = Enum.Font.Gotham,
+ TextSize = 14,
+ TextColor3 = theme.Diff.Warning,
+ TextTransparency = props.transparency,
+ Size = UDim2.new(0, 0, 0, 16),
+ AutomaticSize = Enum.AutomaticSize.X,
+ LayoutOrder = 6,
+ })
+ else nil,
}),
LineGuides = e("Folder", nil, lineGuides),
})
diff --git a/plugin/src/App/Components/PatchVisualizer/init.lua b/plugin/src/App/Components/PatchVisualizer/init.lua
index 67a4d7b20..a87d499bb 100644
--- a/plugin/src/App/Components/PatchVisualizer/init.lua
+++ b/plugin/src/App/Components/PatchVisualizer/init.lua
@@ -8,8 +8,8 @@ local PatchTree = require(Plugin.PatchTree)
local PatchSet = require(Plugin.PatchSet)
local Theme = require(Plugin.App.Theme)
-local BorderedContainer = require(Plugin.App.Components.BorderedContainer)
local VirtualScroller = require(Plugin.App.Components.VirtualScroller)
+local BorderedContainer = require(Plugin.App.Components.BorderedContainer)
local e = Roact.createElement
@@ -55,34 +55,60 @@ function PatchVisualizer:render()
end
-- Recusively draw tree
- local scrollElements, elementHeights = {}, {}
+ local scrollElements, elementHeights, elementIndex = {}, {}, 0
if patchTree then
+ local elementTotal = patchTree:getCount()
+ local depthsComplete = {}
local function drawNode(node, depth)
- local elementHeight, setElementHeight = Roact.createBinding(30)
- table.insert(elementHeights, elementHeight)
- table.insert(
- scrollElements,
- e(DomLabel, {
- updateEvent = self.updateEvent,
- elementHeight = elementHeight,
- setElementHeight = setElementHeight,
- patchType = node.patchType,
- className = node.className,
- isWarning = node.isWarning,
- instance = node.instance,
- name = node.name,
- hint = node.hint,
- changeList = node.changeList,
- depth = depth,
- transparency = self.props.transparency,
- showStringDiff = self.props.showStringDiff,
- showTableDiff = self.props.showTableDiff,
- })
- )
+ elementIndex += 1
+
+ local parentNode = patchTree:getNode(node.parentId)
+ local isFinalChild = true
+ if parentNode then
+ for _id, sibling in parentNode.children do
+ if type(sibling) == "table" and sibling.name and sibling.name > node.name then
+ isFinalChild = false
+ break
+ end
+ end
+ end
+
+ local elementHeight, setElementHeight = Roact.createBinding(24)
+ elementHeights[elementIndex] = elementHeight
+ scrollElements[elementIndex] = e(DomLabel, {
+ transparency = self.props.transparency,
+ showStringDiff = self.props.showStringDiff,
+ showTableDiff = self.props.showTableDiff,
+ updateEvent = self.updateEvent,
+ elementHeight = elementHeight,
+ setElementHeight = setElementHeight,
+ elementIndex = elementIndex,
+ isFinalElement = elementIndex == elementTotal,
+ depth = depth,
+ depthsComplete = table.clone(depthsComplete),
+ hasChildren = (node.children ~= nil and next(node.children) ~= nil),
+ isFinalChild = isFinalChild,
+ patchType = node.patchType,
+ className = node.className,
+ isWarning = node.isWarning,
+ instance = node.instance,
+ name = node.name,
+ changeInfo = node.changeInfo,
+ changeList = node.changeList,
+ })
+
+ if isFinalChild then
+ depthsComplete[depth] = true
+ end
end
patchTree:forEach(function(node, depth)
+ depthsComplete[depth] = false
+ for i = depth + 1, #depthsComplete do
+ depthsComplete[i] = nil
+ end
+
drawNode(node, depth)
end)
end
@@ -92,6 +118,7 @@ function PatchVisualizer:render()
transparency = self.props.transparency,
size = self.props.size,
position = self.props.position,
+ anchorPoint = self.props.anchorPoint,
layoutOrder = self.props.layoutOrder,
}, {
CleanMerge = e("TextLabel", {
@@ -106,7 +133,8 @@ function PatchVisualizer:render()
}),
VirtualScroller = e(VirtualScroller, {
- size = UDim2.new(1, 0, 1, 0),
+ size = UDim2.new(1, 0, 1, -2),
+ position = UDim2.new(0, 0, 0, 2),
transparency = self.props.transparency,
count = #scrollElements,
updateEvent = self.updateEvent.Event,
diff --git a/plugin/src/App/Components/SlicedImage.lua b/plugin/src/App/Components/SlicedImage.lua
index 40279cc89..1dff9caa8 100644
--- a/plugin/src/App/Components/SlicedImage.lua
+++ b/plugin/src/App/Components/SlicedImage.lua
@@ -20,6 +20,7 @@ local function SlicedImage(props)
Size = props.size,
Position = props.position,
AnchorPoint = props.anchorPoint,
+ AutomaticSize = props.automaticSize,
ZIndex = props.zIndex,
LayoutOrder = props.layoutOrder,
diff --git a/plugin/src/App/Components/StringDiffVisualizer/init.lua b/plugin/src/App/Components/StringDiffVisualizer/init.lua
index 60eb49a35..e4203c21c 100644
--- a/plugin/src/App/Components/StringDiffVisualizer/init.lua
+++ b/plugin/src/App/Components/StringDiffVisualizer/init.lua
@@ -9,6 +9,7 @@ local Log = require(Packages.Log)
local Highlighter = require(Packages.Highlighter)
local StringDiff = require(script:FindFirstChild("StringDiff"))
+local Timer = require(Plugin.Timer)
local Theme = require(Plugin.App.Theme)
local CodeLabel = require(Plugin.App.Components.CodeLabel)
@@ -74,6 +75,7 @@ function StringDiffVisualizer:calculateContentSize()
end
function StringDiffVisualizer:calculateDiffLines()
+ Timer.start("StringDiffVisualizer:calculateDiffLines")
local oldString, newString = self.props.oldString, self.props.newString
-- Diff the two texts
@@ -133,6 +135,7 @@ function StringDiffVisualizer:calculateDiffLines()
end
end
+ Timer.stop()
return add, remove
end
diff --git a/plugin/src/App/Components/TableDiffVisualizer/Array.lua b/plugin/src/App/Components/TableDiffVisualizer/Array.lua
index 4fd56f3c7..febd07e97 100644
--- a/plugin/src/App/Components/TableDiffVisualizer/Array.lua
+++ b/plugin/src/App/Components/TableDiffVisualizer/Array.lua
@@ -4,6 +4,7 @@ local Packages = Rojo.Packages
local Roact = require(Packages.Roact)
+local Timer = require(Plugin.Timer)
local Assets = require(Plugin.Assets)
local Theme = require(Plugin.App.Theme)
@@ -21,6 +22,7 @@ function Array:init()
end
function Array:calculateDiff()
+ Timer.start("Array:calculateDiff")
--[[
Find the indexes that are added or removed from the array,
and display them side by side with gaps for the indexes that
@@ -63,6 +65,7 @@ function Array:calculateDiff()
j += 1
end
+ Timer.stop()
return diff
end
diff --git a/plugin/src/App/Components/TableDiffVisualizer/Dictionary.lua b/plugin/src/App/Components/TableDiffVisualizer/Dictionary.lua
index d0c32d963..033956c30 100644
--- a/plugin/src/App/Components/TableDiffVisualizer/Dictionary.lua
+++ b/plugin/src/App/Components/TableDiffVisualizer/Dictionary.lua
@@ -4,6 +4,7 @@ local Packages = Rojo.Packages
local Roact = require(Packages.Roact)
+local Timer = require(Plugin.Timer)
local Assets = require(Plugin.Assets)
local Theme = require(Plugin.App.Theme)
@@ -21,6 +22,7 @@ function Dictionary:init()
end
function Dictionary:calculateDiff()
+ Timer.start("Dictionary:calculateDiff")
local oldTable, newTable = self.props.oldTable or {}, self.props.newTable or {}
-- Diff the two tables and find the added keys, removed keys, and changed keys
@@ -59,6 +61,7 @@ function Dictionary:calculateDiff()
return a.key < b.key
end)
+ Timer.stop()
return diff
end
diff --git a/plugin/src/App/Components/Tag.lua b/plugin/src/App/Components/Tag.lua
new file mode 100644
index 000000000..9fed3d33f
--- /dev/null
+++ b/plugin/src/App/Components/Tag.lua
@@ -0,0 +1,56 @@
+local Rojo = script:FindFirstAncestor("Rojo")
+local Plugin = Rojo.Plugin
+local Packages = Rojo.Packages
+
+local Roact = require(Packages.Roact)
+
+local Assets = require(Plugin.Assets)
+
+local SlicedImage = require(Plugin.App.Components.SlicedImage)
+
+local e = Roact.createElement
+
+return function(props)
+ return e(SlicedImage, {
+ slice = Assets.Slices.RoundedBackground,
+ color = props.color,
+ transparency = props.transparency:map(function(transparency)
+ return 0.9 + (0.1 * transparency)
+ end),
+ layoutOrder = props.layoutOrder,
+ position = props.position,
+ anchorPoint = props.anchorPoint,
+ size = UDim2.new(0, 0, 0, 16),
+ automaticSize = Enum.AutomaticSize.X,
+ }, {
+ Padding = e("UIPadding", {
+ PaddingLeft = UDim.new(0, 4),
+ PaddingRight = UDim.new(0, 4),
+ PaddingTop = UDim.new(0, 2),
+ PaddingBottom = UDim.new(0, 2),
+ }),
+ Icon = if props.icon
+ then e("ImageLabel", {
+ Size = UDim2.new(0, 12, 0, 12),
+ Position = UDim2.new(0, 0, 0.5, 0),
+ AnchorPoint = Vector2.new(0, 0.5),
+ Image = props.icon,
+ BackgroundTransparency = 1,
+ ImageColor3 = props.color,
+ ImageTransparency = props.transparency,
+ })
+ else nil,
+ Text = e("TextLabel", {
+ Text = props.text,
+ Font = Enum.Font.GothamMedium,
+ TextSize = 12,
+ TextColor3 = props.color,
+ TextXAlignment = Enum.TextXAlignment.Center,
+ TextTransparency = props.transparency,
+ Size = UDim2.new(0, 0, 1, 0),
+ Position = UDim2.new(0, if props.icon then 15 else 0, 0, 0),
+ AutomaticSize = Enum.AutomaticSize.X,
+ BackgroundTransparency = 1,
+ }),
+ })
+end
diff --git a/plugin/src/App/Components/Tooltip.lua b/plugin/src/App/Components/Tooltip.lua
index 278220958..2ab7e19a5 100644
--- a/plugin/src/App/Components/Tooltip.lua
+++ b/plugin/src/App/Components/Tooltip.lua
@@ -163,7 +163,6 @@ local Trigger = Roact.Component:extend("TooltipTrigger")
function Trigger:init()
self.id = HttpService:GenerateGUID(false)
self.ref = Roact.createRef()
- self.mousePos = Vector2.zero
self.showingPopup = false
self.destroy = function()
@@ -195,18 +194,22 @@ end
function Trigger:isHovering()
local rbx = self.ref.current
if rbx then
- local pos = rbx.AbsolutePosition
- local size = rbx.AbsoluteSize
- local mousePos = self.mousePos
-
- return mousePos.X >= pos.X
- and mousePos.X <= pos.X + size.X
- and mousePos.Y >= pos.Y
- and mousePos.Y <= pos.Y + size.Y
+ return rbx.GuiState == Enum.GuiState.Hover
end
return false
end
+function Trigger:getMousePos()
+ local rbx = self.ref.current
+ if rbx then
+ local widget = rbx:FindFirstAncestorOfClass("DockWidgetPluginGui")
+ if widget then
+ return widget:GetRelativeMousePosition()
+ end
+ end
+ return Vector2.zero
+end
+
function Trigger:managePopup()
if self:isHovering() then
if self.showingPopup or self.showDelayThread then
@@ -217,7 +220,7 @@ function Trigger:managePopup()
self.showDelayThread = task.delay(DELAY, function()
self.props.context.addTip(self.id, {
Text = self.props.text,
- Position = self.mousePos,
+ Position = self:getMousePos(),
Trigger = self.ref,
})
self.showDelayThread = nil
@@ -234,13 +237,7 @@ function Trigger:managePopup()
end
function Trigger:render()
- local function recalculate(rbx)
- local widget = rbx:FindFirstAncestorOfClass("DockWidgetPluginGui")
- if not widget then
- return
- end
- self.mousePos = widget:GetRelativeMousePosition()
-
+ local function recalculate()
self:managePopup()
end
@@ -250,11 +247,9 @@ function Trigger:render()
ZIndex = self.props.zIndex or 100,
[Roact.Ref] = self.ref,
+ [Roact.Change.GuiState] = recalculate,
[Roact.Change.AbsolutePosition] = recalculate,
[Roact.Change.AbsoluteSize] = recalculate,
- [Roact.Event.MouseMoved] = recalculate,
- [Roact.Event.MouseLeave] = recalculate,
- [Roact.Event.MouseEnter] = recalculate,
})
end
diff --git a/plugin/src/App/Components/VirtualScroller.lua b/plugin/src/App/Components/VirtualScroller.lua
index 69bcf5f10..466da8a4f 100644
--- a/plugin/src/App/Components/VirtualScroller.lua
+++ b/plugin/src/App/Components/VirtualScroller.lua
@@ -131,8 +131,8 @@ function VirtualScroller:render()
Position = props.position,
AnchorPoint = props.anchorPoint,
BackgroundTransparency = props.backgroundTransparency or 1,
- BackgroundColor3 = props.backgroundColor3,
- BorderColor3 = props.borderColor3,
+ BackgroundColor3 = props.backgroundColor3 or theme.BorderedContainer.BackgroundColor,
+ BorderColor3 = props.borderColor3 or theme.BorderedContainer.BorderColor,
CanvasSize = self.totalCanvas:map(function(s)
return UDim2.fromOffset(0, s)
end),
diff --git a/plugin/src/App/StatusPages/Confirming.lua b/plugin/src/App/StatusPages/Confirming.lua
index d3b6baa2e..df8bf5b49 100644
--- a/plugin/src/App/StatusPages/Confirming.lua
+++ b/plugin/src/App/StatusPages/Confirming.lua
@@ -4,10 +4,11 @@ local Packages = Rojo.Packages
local Roact = require(Packages.Roact)
+local Timer = require(Plugin.Timer)
+local PatchTree = require(Plugin.PatchTree)
local Settings = require(Plugin.Settings)
local Theme = require(Plugin.App.Theme)
local TextButton = require(Plugin.App.Components.TextButton)
-local Header = require(Plugin.App.Components.Header)
local StudioPluginGui = require(Plugin.App.Components.Studio.StudioPluginGui)
local Tooltip = require(Plugin.App.Components.Tooltip)
local PatchVisualizer = require(Plugin.App.Components.PatchVisualizer)
@@ -23,6 +24,7 @@ function ConfirmingPage:init()
self.containerSize, self.setContainerSize = Roact.createBinding(Vector2.new(0, 0))
self:setState({
+ patchTree = nil,
showingStringDiff = false,
oldString = "",
newString = "",
@@ -30,22 +32,38 @@ function ConfirmingPage:init()
oldTable = {},
newTable = {},
})
+
+ if self.props.confirmData and self.props.confirmData.patch and self.props.confirmData.instanceMap then
+ self:buildPatchTree()
+ end
+end
+
+function ConfirmingPage:didUpdate(prevProps)
+ if prevProps.confirmData ~= self.props.confirmData then
+ self:buildPatchTree()
+ end
+end
+
+function ConfirmingPage:buildPatchTree()
+ Timer.start("ConfirmingPage:buildPatchTree")
+ self:setState({
+ patchTree = PatchTree.build(
+ self.props.confirmData.patch,
+ self.props.confirmData.instanceMap,
+ { "Property", "Current", "Incoming" }
+ ),
+ })
+ Timer.stop()
end
function ConfirmingPage:render()
return Theme.with(function(theme)
local pageContent = Roact.createFragment({
- Header = e(Header, {
- transparency = self.props.transparency,
- layoutOrder = 1,
- }),
-
Title = e("TextLabel", {
Text = string.format(
"Sync changes for project '%s':",
self.props.confirmData.serverInfo.projectName or "UNKNOWN"
),
- LayoutOrder = 2,
Font = Enum.Font.Gotham,
LineHeight = 1.2,
TextSize = 14,
@@ -57,13 +75,11 @@ function ConfirmingPage:render()
}),
PatchVisualizer = e(PatchVisualizer, {
- size = UDim2.new(1, 0, 1, -150),
+ size = UDim2.new(1, 0, 1, -100),
transparency = self.props.transparency,
layoutOrder = 3,
- changeListHeaders = { "Property", "Current", "Incoming" },
- patch = self.props.confirmData.patch,
- instanceMap = self.props.confirmData.instanceMap,
+ patchTree = self.state.patchTree,
showStringDiff = function(oldString: string, newString: string)
self:setState({
@@ -132,6 +148,11 @@ function ConfirmingPage:render()
}),
}),
+ Padding = e("UIPadding", {
+ PaddingLeft = UDim.new(0, 8),
+ PaddingRight = UDim.new(0, 8),
+ }),
+
Layout = e("UIListLayout", {
HorizontalAlignment = Enum.HorizontalAlignment.Center,
VerticalAlignment = Enum.VerticalAlignment.Center,
@@ -140,11 +161,6 @@ function ConfirmingPage:render()
Padding = UDim.new(0, 10),
}),
- Padding = e("UIPadding", {
- PaddingLeft = UDim.new(0, 20),
- PaddingRight = UDim.new(0, 20),
- }),
-
StringDiff = e(StudioPluginGui, {
id = "Rojo_ConfirmingStringDiff",
title = "String diff",
diff --git a/plugin/src/App/StatusPages/Connected.lua b/plugin/src/App/StatusPages/Connected.lua
index d8055b3f3..3f84d15f4 100644
--- a/plugin/src/App/StatusPages/Connected.lua
+++ b/plugin/src/App/StatusPages/Connected.lua
@@ -3,9 +3,7 @@ local Plugin = Rojo.Plugin
local Packages = Rojo.Packages
local Roact = require(Packages.Roact)
-local Flipper = require(Packages.Flipper)
-local bindingUtil = require(Plugin.App.bindingUtil)
local Theme = require(Plugin.App.Theme)
local Assets = require(Plugin.Assets)
local PatchSet = require(Plugin.PatchSet)
@@ -23,28 +21,20 @@ local TableDiffVisualizer = require(Plugin.App.Components.TableDiffVisualizer)
local e = Roact.createElement
local AGE_UNITS = {
- { 31556909, "year" },
- { 2629743, "month" },
- { 604800, "week" },
- { 86400, "day" },
- { 3600, "hour" },
- {
- 60,
- "minute",
- },
+ { 31556909, "y" },
+ { 2629743, "mon" },
+ { 604800, "w" },
+ { 86400, "d" },
+ { 3600, "h" },
+ { 60, "m" },
}
function timeSinceText(elapsed: number): string
- if elapsed < 3 then
- return "just now"
- end
-
- local ageText = string.format("%d seconds ago", elapsed)
+ local ageText = string.format("%ds", elapsed)
for _, UnitData in ipairs(AGE_UNITS) do
local UnitSeconds, UnitName = UnitData[1], UnitData[2]
if elapsed > UnitSeconds then
- local c = math.floor(elapsed / UnitSeconds)
- ageText = string.format("%d %s%s ago", c, UnitName, c > 1 and "s" or "")
+ ageText = elapsed // UnitSeconds .. UnitName
break
end
end
@@ -52,49 +42,179 @@ function timeSinceText(elapsed: number): string
return ageText
end
-local ChangesDrawer = Roact.Component:extend("ChangesDrawer")
+local ChangesViewer = Roact.Component:extend("ChangesViewer")
-function ChangesDrawer:init()
+function ChangesViewer:init()
-- Hold onto the serve session during the lifecycle of this component
-- so that it can still render during the fade out after disconnecting
self.serveSession = self.props.serveSession
end
-function ChangesDrawer:render()
- if self.props.rendered == false or self.serveSession == nil then
+function ChangesViewer:render()
+ if self.props.rendered == false or self.serveSession == nil or self.props.patchData == nil then
return nil
end
+ local unapplied = PatchSet.countChanges(self.props.patchData.unapplied)
+ local applied = PatchSet.countChanges(self.props.patchData.patch) - unapplied
+
return Theme.with(function(theme)
- return e(BorderedContainer, {
- transparency = self.props.transparency,
- size = self.props.height:map(function(y)
- return UDim2.new(1, 0, y, -220 * y)
- end),
- position = UDim2.new(0, 0, 1, 0),
- anchorPoint = Vector2.new(0, 1),
- layoutOrder = self.props.layoutOrder,
- }, {
- Close = e(IconButton, {
- icon = Assets.Images.Icons.Close,
- iconSize = 24,
- color = theme.ConnectionDetails.DisconnectColor,
- transparency = self.props.transparency,
+ return Roact.createFragment({
+ Navbar = e("Frame", {
+ Size = UDim2.new(1, 0, 0, 40),
+ BackgroundTransparency = 1,
+ }, {
+ Close = e(IconButton, {
+ icon = Assets.Images.Icons.Close,
+ iconSize = 24,
+ color = theme.Settings.Navbar.BackButtonColor,
+ transparency = self.props.transparency,
- position = UDim2.new(1, 0, 0, 0),
- anchorPoint = Vector2.new(1, 0),
+ position = UDim2.new(0, 0, 0.5, 0),
+ anchorPoint = Vector2.new(0, 0.5),
- onClick = self.props.onClose,
- }, {
- Tip = e(Tooltip.Trigger, {
- text = "Close the patch visualizer",
+ onClick = self.props.onBack,
+ }, {
+ Tip = e(Tooltip.Trigger, {
+ text = "Close",
+ }),
+ }),
+
+ Title = e("TextLabel", {
+ Text = "Sync",
+ Font = Enum.Font.GothamMedium,
+ TextSize = 17,
+ TextXAlignment = Enum.TextXAlignment.Left,
+ TextColor3 = theme.TextColor,
+ TextTransparency = self.props.transparency,
+ Size = UDim2.new(1, -40, 0, 20),
+ Position = UDim2.new(0, 40, 0, 0),
+ BackgroundTransparency = 1,
+ }),
+
+ Subtitle = e("TextLabel", {
+ Text = DateTime.fromUnixTimestamp(self.props.patchData.timestamp):FormatLocalTime("LTS", "en-us"),
+ TextXAlignment = Enum.TextXAlignment.Left,
+ Font = Enum.Font.Gotham,
+ TextSize = 15,
+ TextColor3 = theme.SubTextColor,
+ TextTruncate = Enum.TextTruncate.AtEnd,
+ TextTransparency = self.props.transparency,
+ Size = UDim2.new(1, -40, 0, 16),
+ Position = UDim2.new(0, 40, 0, 20),
+ BackgroundTransparency = 1,
+ }),
+
+ Info = e("Frame", {
+ BackgroundTransparency = 1,
+ Size = UDim2.new(0, 10, 0, 24),
+ AutomaticSize = Enum.AutomaticSize.X,
+ Position = UDim2.new(1, -5, 0.5, 0),
+ AnchorPoint = Vector2.new(1, 0.5),
+ }, {
+ Tooltip = e(Tooltip.Trigger, {
+ text = `{applied} changes applied`
+ .. (if unapplied > 0 then `, {unapplied} changes failed` else ""),
+ }),
+ Content = e("Frame", {
+ BackgroundTransparency = 1,
+ Size = UDim2.new(0, 0, 1, 0),
+ AutomaticSize = Enum.AutomaticSize.X,
+ }, {
+ Layout = e("UIListLayout", {
+ FillDirection = Enum.FillDirection.Horizontal,
+ HorizontalAlignment = Enum.HorizontalAlignment.Right,
+ VerticalAlignment = Enum.VerticalAlignment.Center,
+ SortOrder = Enum.SortOrder.LayoutOrder,
+ Padding = UDim.new(0, 4),
+ }),
+
+ StatusIcon = e("ImageLabel", {
+ BackgroundTransparency = 1,
+ Image = if unapplied > 0
+ then Assets.Images.Icons.SyncWarning
+ else Assets.Images.Icons.SyncSuccess,
+ ImageColor3 = if unapplied > 0 then theme.Diff.Warning else theme.TextColor,
+ Size = UDim2.new(0, 24, 0, 24),
+ LayoutOrder = 10,
+ }),
+ StatusSpacer = e("Frame", {
+ BackgroundTransparency = 1,
+ Size = UDim2.new(0, 6, 0, 4),
+ LayoutOrder = 9,
+ }),
+ AppliedIcon = e("ImageLabel", {
+ BackgroundTransparency = 1,
+ Image = Assets.Images.Icons.Checkmark,
+ ImageColor3 = theme.TextColor,
+ Size = UDim2.new(0, 16, 0, 16),
+ LayoutOrder = 1,
+ }),
+ AppliedText = e("TextLabel", {
+ Text = applied,
+ Font = Enum.Font.Gotham,
+ TextSize = 15,
+ TextColor3 = theme.TextColor,
+ TextTransparency = self.props.transparency,
+ Size = UDim2.new(0, 0, 1, 0),
+ AutomaticSize = Enum.AutomaticSize.X,
+ BackgroundTransparency = 1,
+ LayoutOrder = 2,
+ }),
+ Warnings = if unapplied > 0
+ then Roact.createFragment({
+ WarningsSpacer = e("Frame", {
+ BackgroundTransparency = 1,
+ Size = UDim2.new(0, 4, 0, 4),
+ LayoutOrder = 3,
+ }),
+ UnappliedIcon = e("ImageLabel", {
+ BackgroundTransparency = 1,
+ Image = Assets.Images.Icons.Exclamation,
+ ImageColor3 = theme.Diff.Warning,
+ Size = UDim2.new(0, 4, 0, 16),
+ LayoutOrder = 4,
+ }),
+ UnappliedText = e("TextLabel", {
+ Text = unapplied,
+ Font = Enum.Font.Gotham,
+ TextSize = 15,
+ TextColor3 = theme.Diff.Warning,
+ TextTransparency = self.props.transparency,
+ Size = UDim2.new(0, 0, 1, 0),
+ AutomaticSize = Enum.AutomaticSize.X,
+ BackgroundTransparency = 1,
+ LayoutOrder = 5,
+ }),
+ })
+ else nil,
+ }),
+ }),
+
+ Divider = e("Frame", {
+ BackgroundColor3 = theme.Settings.DividerColor,
+ BackgroundTransparency = self.props.transparency,
+ Size = UDim2.new(1, 0, 0, 1),
+ Position = UDim2.new(0, 0, 1, 0),
+ BorderSizePixel = 0,
+ }, {
+ Gradient = e("UIGradient", {
+ Transparency = NumberSequence.new({
+ NumberSequenceKeypoint.new(0, 1),
+ NumberSequenceKeypoint.new(0.1, 0),
+ NumberSequenceKeypoint.new(0.9, 0),
+ NumberSequenceKeypoint.new(1, 1),
+ }),
+ }),
}),
}),
- PatchVisualizer = e(PatchVisualizer, {
- size = UDim2.new(1, 0, 1, 0),
+ Patch = e(PatchVisualizer, {
+ size = UDim2.new(1, -10, 1, -65),
+ position = UDim2.new(0, 5, 1, -5),
+ anchorPoint = Vector2.new(0, 1),
transparency = self.props.transparency,
- layoutOrder = 3,
+ layoutOrder = self.props.layoutOrder,
patchTree = self.props.patchTree,
@@ -167,20 +287,7 @@ function ConnectedPage:getChangeInfoText()
if patchData == nil then
return ""
end
-
- local elapsed = os.time() - patchData.timestamp
- local unapplied = PatchSet.countChanges(patchData.unapplied)
-
- return "Synced "
- .. timeSinceText(elapsed)
- .. (if unapplied > 0
- then string.format(
- ', but %d change%s failed to apply',
- unapplied,
- unapplied == 1 and "" or "s"
- )
- else "")
- .. ""
+ return timeSinceText(DateTime.now().UnixTimestamp - patchData.timestamp)
end
function ConnectedPage:startChangeInfoTextUpdater()
@@ -190,13 +297,9 @@ function ConnectedPage:startChangeInfoTextUpdater()
-- Start a new updater
self.changeInfoTextUpdater = task.defer(function()
while true do
- if self.state.hoveringChangeInfo then
- self.setChangeInfoText("" .. self:getChangeInfoText() .. "")
- else
- self.setChangeInfoText(self:getChangeInfoText())
- end
+ self.setChangeInfoText(self:getChangeInfoText())
- local elapsed = os.time() - self.props.patchData.timestamp
+ local elapsed = DateTime.now().UnixTimestamp - self.props.patchData.timestamp
local updateInterval = 1
-- Update timestamp text as frequently as currently needed
@@ -221,23 +324,6 @@ function ConnectedPage:stopChangeInfoTextUpdater()
end
function ConnectedPage:init()
- self.changeDrawerMotor = Flipper.SingleMotor.new(0)
- self.changeDrawerHeight = bindingUtil.fromMotor(self.changeDrawerMotor)
-
- self.changeDrawerMotor:onStep(function(value)
- local renderChanges = value > 0.05
-
- self:setState(function(state)
- if state.renderChanges == renderChanges then
- return nil
- end
-
- return {
- renderChanges = renderChanges,
- }
- end)
- end)
-
self:setState({
renderChanges = false,
hoveringChangeInfo = false,
@@ -266,6 +352,10 @@ function ConnectedPage:didUpdate(previousProps)
end
function ConnectedPage:render()
+ local syncWarning = self.props.patchData
+ and self.props.patchData.unapplied
+ and PatchSet.countChanges(self.props.patchData.unapplied) > 0
+
return Theme.with(function(theme)
return Roact.createFragment({
Padding = e("UIPadding", {
@@ -280,9 +370,88 @@ function ConnectedPage:render()
Padding = UDim.new(0, 10),
}),
- Header = e(Header, {
- transparency = self.props.transparency,
- layoutOrder = 1,
+ Heading = e("Frame", {
+ BackgroundTransparency = 1,
+ Size = UDim2.new(1, 0, 0, 32),
+ }, {
+ Header = e(Header, {
+ transparency = self.props.transparency,
+ }),
+
+ ChangeInfo = e("TextButton", {
+ Text = "",
+ Size = UDim2.new(0, 0, 1, 0),
+ AutomaticSize = Enum.AutomaticSize.X,
+ BackgroundColor3 = theme.BorderedContainer.BorderedColor,
+ BackgroundTransparency = if self.state.hoveringChangeInfo then 0.7 else 1,
+ BorderSizePixel = 0,
+ Position = UDim2.new(1, -5, 0.5, 0),
+ AnchorPoint = Vector2.new(1, 0.5),
+ [Roact.Event.MouseEnter] = function()
+ self:setState({
+ hoveringChangeInfo = true,
+ })
+ end,
+ [Roact.Event.MouseLeave] = function()
+ self:setState({
+ hoveringChangeInfo = false,
+ })
+ end,
+ [Roact.Event.Activated] = function()
+ self:setState(function(prevState)
+ prevState = prevState or {}
+ return {
+ renderChanges = not prevState.renderChanges,
+ }
+ end)
+ end,
+ }, {
+ Corner = e("UICorner", {
+ CornerRadius = UDim.new(0, 5),
+ }),
+ Tooltip = e(Tooltip.Trigger, {
+ text = if self.state.renderChanges then "Hide changes" else "View changes",
+ }),
+ Content = e("Frame", {
+ BackgroundTransparency = 1,
+ Size = UDim2.new(0, 0, 1, 0),
+ AutomaticSize = Enum.AutomaticSize.X,
+ }, {
+ Layout = e("UIListLayout", {
+ FillDirection = Enum.FillDirection.Horizontal,
+ HorizontalAlignment = Enum.HorizontalAlignment.Center,
+ VerticalAlignment = Enum.VerticalAlignment.Center,
+ SortOrder = Enum.SortOrder.LayoutOrder,
+ Padding = UDim.new(0, 5),
+ }),
+ Padding = e("UIPadding", {
+ PaddingLeft = UDim.new(0, 5),
+ PaddingRight = UDim.new(0, 5),
+ }),
+ Text = e("TextLabel", {
+ BackgroundTransparency = 1,
+ Text = self.changeInfoText,
+ Font = Enum.Font.Gotham,
+ TextSize = 15,
+ TextColor3 = if syncWarning then theme.Diff.Warning else theme.Header.VersionColor,
+ TextTransparency = self.props.transparency,
+ TextXAlignment = Enum.TextXAlignment.Right,
+ Size = UDim2.new(0, 0, 1, 0),
+ AutomaticSize = Enum.AutomaticSize.X,
+ LayoutOrder = 1,
+ }),
+ Icon = e("ImageLabel", {
+ BackgroundTransparency = 1,
+ Image = if syncWarning
+ then Assets.Images.Icons.SyncWarning
+ else Assets.Images.Icons.SyncSuccess,
+ ImageColor3 = if syncWarning then theme.Diff.Warning else theme.Header.VersionColor,
+ ImageTransparency = self.props.transparency,
+ Size = UDim2.new(0, 24, 0, 24),
+ LayoutOrder = 2,
+ }),
+ }),
+ }),
}),
ConnectionDetails = e(ConnectionDetails, {
@@ -332,86 +501,61 @@ function ConnectedPage:render()
}),
}),
- ChangeInfo = e("TextButton", {
- Text = self.changeInfoText,
- Font = Enum.Font.Gotham,
- TextSize = 14,
- TextWrapped = true,
- RichText = true,
- TextColor3 = theme.Header.VersionColor,
- TextXAlignment = Enum.TextXAlignment.Left,
- TextYAlignment = Enum.TextYAlignment.Top,
- TextTransparency = self.props.transparency,
-
- Size = UDim2.new(1, 0, 0, 28),
+ ChangesViewer = e(StudioPluginGui, {
+ id = "Rojo_ChangesViewer",
+ title = "View changes",
+ active = self.state.renderChanges,
+ isEphemeral = true,
- LayoutOrder = 4,
- BackgroundTransparency = 1,
+ initDockState = Enum.InitialDockState.Float,
+ overridePreviousState = true,
+ floatingSize = Vector2.new(400, 500),
+ minimumSize = Vector2.new(300, 300),
- [Roact.Event.MouseEnter] = function()
- self:setState({
- hoveringChangeInfo = true,
- })
- self.setChangeInfoText("" .. self:getChangeInfoText() .. "")
- end,
+ zIndexBehavior = Enum.ZIndexBehavior.Sibling,
- [Roact.Event.MouseLeave] = function()
+ onClose = function()
self:setState({
- hoveringChangeInfo = false,
+ renderChanges = false,
})
- self.setChangeInfoText(self:getChangeInfoText())
- end,
-
- [Roact.Event.Activated] = function()
- if self.state.renderChanges then
- self.changeDrawerMotor:setGoal(Flipper.Spring.new(0, {
- frequency = 4,
- dampingRatio = 1,
- }))
- else
- self.changeDrawerMotor:setGoal(Flipper.Spring.new(1, {
- frequency = 3,
- dampingRatio = 1,
- }))
- end
end,
}, {
- Tooltip = e(Tooltip.Trigger, {
- text = if self.state.renderChanges then "Hide the changes" else "View the changes",
+ TooltipsProvider = e(Tooltip.Provider, nil, {
+ Tooltips = e(Tooltip.Container, nil),
+ Content = e("Frame", {
+ Size = UDim2.fromScale(1, 1),
+ BackgroundTransparency = 1,
+ }, {
+ Changes = e(ChangesViewer, {
+ transparency = self.props.transparency,
+ rendered = self.state.renderChanges,
+ patchData = self.props.patchData,
+ patchTree = self.props.patchTree,
+ serveSession = self.props.serveSession,
+ showStringDiff = function(oldString: string, newString: string)
+ self:setState({
+ showingStringDiff = true,
+ oldString = oldString,
+ newString = newString,
+ })
+ end,
+ showTableDiff = function(oldTable: { [any]: any? }, newTable: { [any]: any? })
+ self:setState({
+ showingTableDiff = true,
+ oldTable = oldTable,
+ newTable = newTable,
+ })
+ end,
+ onBack = function()
+ self:setState({
+ renderChanges = false,
+ })
+ end,
+ }),
+ }),
}),
}),
- ChangesDrawer = e(ChangesDrawer, {
- rendered = self.state.renderChanges,
- transparency = self.props.transparency,
- patchTree = self.props.patchTree,
- serveSession = self.props.serveSession,
- height = self.changeDrawerHeight,
- layoutOrder = 5,
-
- showStringDiff = function(oldString: string, newString: string)
- self:setState({
- showingStringDiff = true,
- oldString = oldString,
- newString = newString,
- })
- end,
- showTableDiff = function(oldTable: { [any]: any? }, newTable: { [any]: any? })
- self:setState({
- showingTableDiff = true,
- oldTable = oldTable,
- newTable = newTable,
- })
- end,
-
- onClose = function()
- self.changeDrawerMotor:setGoal(Flipper.Spring.new(0, {
- frequency = 4,
- dampingRatio = 1,
- }))
- end,
- }),
-
StringDiff = e(StudioPluginGui, {
id = "Rojo_ConnectedStringDiff",
title = "String diff",
diff --git a/plugin/src/App/StatusPages/Settings/Setting.lua b/plugin/src/App/StatusPages/Settings/Setting.lua
index 86adb6fcb..00c75d86d 100644
--- a/plugin/src/App/StatusPages/Settings/Setting.lua
+++ b/plugin/src/App/StatusPages/Settings/Setting.lua
@@ -13,10 +13,23 @@ local Theme = require(Plugin.App.Theme)
local Checkbox = require(Plugin.App.Components.Checkbox)
local Dropdown = require(Plugin.App.Components.Dropdown)
local IconButton = require(Plugin.App.Components.IconButton)
+local Tag = require(Plugin.App.Components.Tag)
local e = Roact.createElement
local DIVIDER_FADE_SIZE = 0.1
+local TAG_TYPES = {
+ unstable = {
+ text = "UNSTABLE",
+ icon = Assets.Images.Icons.Warning,
+ color = { "Settings", "Setting", "UnstableColor" },
+ },
+ debug = {
+ text = "DEBUG",
+ icon = Assets.Images.Icons.Debug,
+ color = { "Settings", "Setting", "DebugColor" },
+ },
+}
local function getTextBounds(text, textSize, font, lineHeight, bounds)
local textBounds = TextService:GetTextSize(text, textSize, font, bounds)
@@ -27,6 +40,17 @@ local function getTextBounds(text, textSize, font, lineHeight, bounds)
return Vector2.new(textBounds.X, lineHeightAbsolute * lineCount - (lineHeightAbsolute - textSize))
end
+local function getThemeColorFromPath(theme, path)
+ local color = theme
+ for _, key in path do
+ if color[key] == nil then
+ return theme.BrandColor
+ end
+ color = color[key]
+ end
+ return color
+end
+
local Setting = Roact.Component:extend("Setting")
function Setting:init()
@@ -51,11 +75,11 @@ end
function Setting:render()
return Theme.with(function(theme)
- theme = theme.Settings
+ local settingsTheme = theme.Settings
return e("Frame", {
Size = self.contentSize:map(function(value)
- return UDim2.new(1, 0, 0, 20 + value.Y + 20)
+ return UDim2.new(1, 0, 0, value.Y + 20)
end),
LayoutOrder = self.props.layoutOrder,
ZIndex = -self.props.layoutOrder,
@@ -106,7 +130,7 @@ function Setting:render()
then e(IconButton, {
icon = Assets.Images.Icons.Reset,
iconSize = 24,
- color = theme.BackButtonColor,
+ color = settingsTheme.BackButtonColor,
transparency = self.props.transparency,
visible = self.props.showReset,
layoutOrder = -1,
@@ -120,29 +144,49 @@ function Setting:render()
Size = UDim2.new(1, 0, 1, 0),
BackgroundTransparency = 1,
}, {
- Name = e("TextLabel", {
- Text = (if self.props.experimental then 'âš ' else "")
- .. self.props.name,
- Font = Enum.Font.GothamBold,
- TextSize = 17,
- TextColor3 = theme.Setting.NameColor,
- TextXAlignment = Enum.TextXAlignment.Left,
- TextTransparency = self.props.transparency,
- RichText = true,
-
- Size = UDim2.new(1, 0, 0, 17),
-
- LayoutOrder = 1,
+ Heading = e("Frame", {
+ Size = UDim2.new(1, 0, 0, 16),
BackgroundTransparency = 1,
+ }, {
+ Layout = e("UIListLayout", {
+ VerticalAlignment = Enum.VerticalAlignment.Center,
+ FillDirection = Enum.FillDirection.Horizontal,
+ SortOrder = Enum.SortOrder.LayoutOrder,
+ Padding = UDim.new(0, 5),
+ }),
+ Tag = if self.props.tag and TAG_TYPES[self.props.tag]
+ then e(Tag, {
+ layoutOrder = 1,
+ transparency = self.props.transparency,
+ text = TAG_TYPES[self.props.tag].text,
+ icon = TAG_TYPES[self.props.tag].icon,
+ color = getThemeColorFromPath(theme, TAG_TYPES[self.props.tag].color),
+ })
+ else nil,
+ Name = e("TextLabel", {
+ Text = self.props.name,
+ Font = Enum.Font.GothamBold,
+ TextSize = 16,
+ TextColor3 = if self.props.tag and TAG_TYPES[self.props.tag]
+ then getThemeColorFromPath(theme, TAG_TYPES[self.props.tag].color)
+ else settingsTheme.Setting.NameColor,
+ TextXAlignment = Enum.TextXAlignment.Left,
+ TextTransparency = self.props.transparency,
+ RichText = true,
+
+ Size = UDim2.new(1, 0, 0, 16),
+
+ LayoutOrder = 2,
+ BackgroundTransparency = 1,
+ }),
}),
Description = e("TextLabel", {
- Text = (if self.props.experimental then '[Experimental] ' else "")
- .. self.props.description,
+ Text = self.props.description,
Font = Enum.Font.Gotham,
LineHeight = 1.2,
TextSize = 14,
- TextColor3 = theme.Setting.DescriptionColor,
+ TextColor3 = settingsTheme.Setting.DescriptionColor,
TextXAlignment = Enum.TextXAlignment.Left,
TextTransparency = self.props.transparency,
TextWrapped = true,
@@ -152,11 +196,9 @@ function Setting:render()
containerSize = self.containerSize,
inputSize = self.inputSize,
}):map(function(values)
- local desc = (if self.props.experimental then "[Experimental] " else "")
- .. self.props.description
local offset = values.inputSize.X + 5
local textBounds = getTextBounds(
- desc,
+ self.props.description,
14,
Enum.Font.Gotham,
1.2,
@@ -165,7 +207,7 @@ function Setting:render()
return UDim2.new(1, -offset, 0, textBounds.Y)
end),
- LayoutOrder = 2,
+ LayoutOrder = 3,
BackgroundTransparency = 1,
}),
@@ -173,21 +215,16 @@ function Setting:render()
VerticalAlignment = Enum.VerticalAlignment.Center,
FillDirection = Enum.FillDirection.Vertical,
SortOrder = Enum.SortOrder.LayoutOrder,
- Padding = UDim.new(0, 6),
+ Padding = UDim.new(0, 5),
[Roact.Change.AbsoluteContentSize] = function(object)
self.setContentSize(object.AbsoluteContentSize)
end,
}),
-
- Padding = e("UIPadding", {
- PaddingTop = UDim.new(0, 20),
- PaddingBottom = UDim.new(0, 20),
- }),
}),
Divider = e("Frame", {
- BackgroundColor3 = theme.DividerColor,
+ BackgroundColor3 = settingsTheme.DividerColor,
BackgroundTransparency = self.props.transparency,
Size = UDim2.new(1, 0, 0, 1),
BorderSizePixel = 0,
diff --git a/plugin/src/App/StatusPages/Settings/init.lua b/plugin/src/App/StatusPages/Settings/init.lua
index a33eb1b54..70f835084 100644
--- a/plugin/src/App/StatusPages/Settings/init.lua
+++ b/plugin/src/App/StatusPages/Settings/init.lua
@@ -26,7 +26,7 @@ local function invertTbl(tbl)
end
local invertedLevels = invertTbl(Log.Level)
-local confirmationBehaviors = { "Initial", "Always", "Large Changes", "Unlisted PlaceId" }
+local confirmationBehaviors = { "Initial", "Always", "Large Changes", "Unlisted PlaceId", "Never" }
local function Navbar(props)
return Theme.with(function(theme)
@@ -84,148 +84,160 @@ function SettingsPage:render()
return Theme.with(function(theme)
theme = theme.Settings
- return e(ScrollingFrame, {
- size = UDim2.new(1, 0, 1, 0),
- contentSize = self.contentSize,
- transparency = self.props.transparency,
- }, {
+ return Roact.createFragment({
Navbar = e(Navbar, {
onBack = self.props.onBack,
transparency = self.props.transparency,
layoutOrder = layoutIncrement(),
}),
-
- ShowNotifications = e(Setting, {
- id = "showNotifications",
- name = "Show Notifications",
- description = "Popup notifications in viewport",
+ Content = e(ScrollingFrame, {
+ size = UDim2.new(1, 0, 1, -47),
+ position = UDim2.new(0, 0, 0, 47),
+ contentSize = self.contentSize,
transparency = self.props.transparency,
- layoutOrder = layoutIncrement(),
- }),
+ }, {
+ ShowNotifications = e(Setting, {
+ id = "showNotifications",
+ name = "Show Notifications",
+ description = "Popup notifications in viewport",
+ transparency = self.props.transparency,
+ layoutOrder = layoutIncrement(),
+ }),
- SyncReminder = e(Setting, {
- id = "syncReminder",
- name = "Sync Reminder",
- description = "Notify to sync when opening a place that has previously been synced",
- transparency = self.props.transparency,
- visible = Settings:getBinding("showNotifications"),
- layoutOrder = layoutIncrement(),
- }),
+ SyncReminder = e(Setting, {
+ id = "syncReminder",
+ name = "Sync Reminder",
+ description = "Notify to sync when opening a place that has previously been synced",
+ transparency = self.props.transparency,
+ visible = Settings:getBinding("showNotifications"),
+ layoutOrder = layoutIncrement(),
+ }),
- ConfirmationBehavior = e(Setting, {
- id = "confirmationBehavior",
- name = "Confirmation Behavior",
- description = "When to prompt for confirmation before syncing",
- transparency = self.props.transparency,
- layoutOrder = layoutIncrement(),
+ ConfirmationBehavior = e(Setting, {
+ id = "confirmationBehavior",
+ name = "Confirmation Behavior",
+ description = "When to prompt for confirmation before syncing",
+ transparency = self.props.transparency,
+ layoutOrder = layoutIncrement(),
- options = confirmationBehaviors,
- }),
+ options = confirmationBehaviors,
+ }),
- LargeChangesConfirmationThreshold = e(Setting, {
- id = "largeChangesConfirmationThreshold",
- name = "Confirmation Threshold",
- description = "How many modified instances to be considered a large change",
- transparency = self.props.transparency,
- layoutOrder = layoutIncrement(),
- visible = Settings:getBinding("confirmationBehavior"):map(function(value)
- return value == "Large Changes"
- end),
- input = e(TextInput, {
- size = UDim2.new(0, 40, 0, 28),
- text = Settings:getBinding("largeChangesConfirmationThreshold"):map(function(value)
- return tostring(value)
+ LargeChangesConfirmationThreshold = e(Setting, {
+ id = "largeChangesConfirmationThreshold",
+ name = "Confirmation Threshold",
+ description = "How many modified instances to be considered a large change",
+ transparency = self.props.transparency,
+ layoutOrder = layoutIncrement(),
+ visible = Settings:getBinding("confirmationBehavior"):map(function(value)
+ return value == "Large Changes"
end),
+ input = e(TextInput, {
+ size = UDim2.new(0, 40, 0, 28),
+ text = Settings:getBinding("largeChangesConfirmationThreshold"):map(function(value)
+ return tostring(value)
+ end),
+ transparency = self.props.transparency,
+ enabled = true,
+ onEntered = function(text)
+ local number = tonumber(string.match(text, "%d+"))
+ if number then
+ Settings:set("largeChangesConfirmationThreshold", math.clamp(number, 1, 999))
+ else
+ -- Force text back to last valid value
+ Settings:set(
+ "largeChangesConfirmationThreshold",
+ Settings:get("largeChangesConfirmationThreshold")
+ )
+ end
+ end,
+ }),
+ }),
+
+ PlaySounds = e(Setting, {
+ id = "playSounds",
+ name = "Play Sounds",
+ description = "Toggle sound effects",
transparency = self.props.transparency,
- enabled = true,
- onEntered = function(text)
- local number = tonumber(string.match(text, "%d+"))
- if number then
- Settings:set("largeChangesConfirmationThreshold", math.clamp(number, 1, 999))
- else
- -- Force text back to last valid value
- Settings:set(
- "largeChangesConfirmationThreshold",
- Settings:get("largeChangesConfirmationThreshold")
- )
- end
- end,
+ layoutOrder = layoutIncrement(),
}),
- }),
- PlaySounds = e(Setting, {
- id = "playSounds",
- name = "Play Sounds",
- description = "Toggle sound effects",
- transparency = self.props.transparency,
- layoutOrder = layoutIncrement(),
- }),
+ AutoConnectPlaytestServer = e(Setting, {
+ id = "autoConnectPlaytestServer",
+ name = "Auto Connect Playtest Server",
+ description = "Automatically connect game server to Rojo when playtesting while connected in Edit",
+ tag = "unstable",
+ transparency = self.props.transparency,
+ layoutOrder = layoutIncrement(),
+ }),
- AutoConnectPlaytestServer = e(Setting, {
- id = "autoConnectPlaytestServer",
- name = "Auto Connect Playtest Server",
- description = "Automatically connect game server to Rojo when playtesting while connected in Edit",
- experimental = true,
- transparency = self.props.transparency,
- layoutOrder = layoutIncrement(),
- }),
+ OpenScriptsExternally = e(Setting, {
+ id = "openScriptsExternally",
+ name = "Open Scripts Externally",
+ description = "Attempt to open scripts in an external editor",
+ tag = "unstable",
+ transparency = self.props.transparency,
+ layoutOrder = layoutIncrement(),
+ }),
- OpenScriptsExternally = e(Setting, {
- id = "openScriptsExternally",
- name = "Open Scripts Externally",
- description = "Attempt to open scripts in an external editor",
- locked = self.props.syncActive,
- experimental = true,
- transparency = self.props.transparency,
- layoutOrder = layoutIncrement(),
- }),
+ TwoWaySync = e(Setting, {
+ id = "twoWaySync",
+ name = "Two-Way Sync",
+ description = "Editing files in Studio will sync them into the filesystem",
+ locked = self.props.syncActive,
+ tag = "unstable",
+ transparency = self.props.transparency,
+ layoutOrder = layoutIncrement(),
+ }),
- TwoWaySync = e(Setting, {
- id = "twoWaySync",
- name = "Two-Way Sync",
- description = "Editing files in Studio will sync them into the filesystem",
- locked = self.props.syncActive,
- experimental = true,
- transparency = self.props.transparency,
- layoutOrder = layoutIncrement(),
- }),
+ LogLevel = e(Setting, {
+ id = "logLevel",
+ name = "Log Level",
+ description = "Plugin output verbosity level",
+ tag = "debug",
+ transparency = self.props.transparency,
+ layoutOrder = layoutIncrement(),
- LogLevel = e(Setting, {
- id = "logLevel",
- name = "Log Level",
- description = "Plugin output verbosity level",
- transparency = self.props.transparency,
- layoutOrder = layoutIncrement(),
+ options = invertedLevels,
+ showReset = Settings:getBinding("logLevel"):map(function(value)
+ return value ~= "Info"
+ end),
+ onReset = function()
+ Settings:set("logLevel", "Info")
+ end,
+ }),
- options = invertedLevels,
- showReset = Settings:getBinding("logLevel"):map(function(value)
- return value ~= "Info"
- end),
- onReset = function()
- Settings:set("logLevel", "Info")
- end,
- }),
+ TypecheckingEnabled = e(Setting, {
+ id = "typecheckingEnabled",
+ name = "Typechecking",
+ description = "Toggle typechecking on the API surface",
+ tag = "debug",
+ transparency = self.props.transparency,
+ layoutOrder = layoutIncrement(),
+ }),
- TypecheckingEnabled = e(Setting, {
- id = "typecheckingEnabled",
- name = "Typechecking",
- description = "Toggle typechecking on the API surface",
- transparency = self.props.transparency,
- layoutOrder = layoutIncrement(),
- }),
+ TimingLogsEnabled = e(Setting, {
+ id = "timingLogsEnabled",
+ name = "Timing Logs",
+ description = "Toggle logging timing of internal actions for benchmarking Rojo performance",
+ tag = "debug",
+ transparency = self.props.transparency,
+ layoutOrder = layoutIncrement(),
+ }),
- Layout = e("UIListLayout", {
- FillDirection = Enum.FillDirection.Vertical,
- SortOrder = Enum.SortOrder.LayoutOrder,
+ Layout = e("UIListLayout", {
+ FillDirection = Enum.FillDirection.Vertical,
+ SortOrder = Enum.SortOrder.LayoutOrder,
- [Roact.Change.AbsoluteContentSize] = function(object)
- self.setContentSize(object.AbsoluteContentSize)
- end,
- }),
+ [Roact.Change.AbsoluteContentSize] = function(object)
+ self.setContentSize(object.AbsoluteContentSize)
+ end,
+ }),
- Padding = e("UIPadding", {
- PaddingLeft = UDim.new(0, 20),
- PaddingRight = UDim.new(0, 20),
+ Padding = e("UIPadding", {
+ PaddingLeft = UDim.new(0, 20),
+ PaddingRight = UDim.new(0, 20),
+ }),
}),
})
end)
diff --git a/plugin/src/App/Theme.lua b/plugin/src/App/Theme.lua
index f1e9c3971..42d619425 100644
--- a/plugin/src/App/Theme.lua
+++ b/plugin/src/App/Theme.lua
@@ -32,9 +32,13 @@ local StudioProvider = Roact.Component:extend("StudioProvider")
function StudioProvider:updateTheme()
local studioTheme = getStudio().Theme
+ local isDark = studioTheme.Name == "Dark"
+
local theme = strict(studioTheme.Name .. "Theme", {
+ BrandColor = BRAND_COLOR,
BackgroundColor = studioTheme:GetColor(Enum.StudioStyleGuideColor.MainBackground),
TextColor = studioTheme:GetColor(Enum.StudioStyleGuideColor.MainText),
+ SubTextColor = studioTheme:GetColor(Enum.StudioStyleGuideColor.SubText),
Button = {
Solid = {
-- Solid uses brand theming, not Studio theming.
@@ -139,9 +143,10 @@ function StudioProvider:updateTheme()
BackgroundColor = studioTheme:GetColor(Enum.StudioStyleGuideColor.InputFieldBackground),
},
Diff = {
- Add = studioTheme:GetColor(Enum.StudioStyleGuideColor.DiffTextAdditionBackground),
- Remove = studioTheme:GetColor(Enum.StudioStyleGuideColor.DiffTextDeletionBackground),
- Edit = studioTheme:GetColor(Enum.StudioStyleGuideColor.DiffLineNumSeparatorBackground),
+ -- Studio doesn't have good colors since their diffs use backgrounds, not text
+ Add = if isDark then Color3.fromRGB(143, 227, 154) else Color3.fromRGB(41, 164, 45),
+ Remove = if isDark then Color3.fromRGB(242, 125, 125) else Color3.fromRGB(150, 29, 29),
+ Edit = if isDark then Color3.fromRGB(120, 154, 248) else Color3.fromRGB(0, 70, 160),
Row = studioTheme:GetColor(Enum.StudioStyleGuideColor.BrightText),
Warning = studioTheme:GetColor(Enum.StudioStyleGuideColor.WarningText),
},
@@ -162,6 +167,8 @@ function StudioProvider:updateTheme()
Setting = {
NameColor = studioTheme:GetColor(Enum.StudioStyleGuideColor.BrightText),
DescriptionColor = studioTheme:GetColor(Enum.StudioStyleGuideColor.MainText),
+ UnstableColor = studioTheme:GetColor(Enum.StudioStyleGuideColor.WarningText),
+ DebugColor = studioTheme:GetColor(Enum.StudioStyleGuideColor.InfoText),
},
},
Header = {
diff --git a/plugin/src/App/init.lua b/plugin/src/App/init.lua
index ecb807f05..bd21765d0 100644
--- a/plugin/src/App/init.lua
+++ b/plugin/src/App/init.lua
@@ -425,11 +425,6 @@ function App:startSession()
local host, port = self:getHostAndPort()
- local sessionOptions = {
- openScriptsExternally = Settings:get("openScriptsExternally"),
- twoWaySync = Settings:get("twoWaySync"),
- }
-
local baseUrl = if string.find(host, "^https?://")
then string.format("%s:%s", host, port)
else string.format("http://%s:%s", host, port)
@@ -437,8 +432,7 @@ function App:startSession()
local serveSession = ServeSession.new({
apiContext = apiContext,
- openScriptsExternally = sessionOptions.openScriptsExternally,
- twoWaySync = sessionOptions.twoWaySync,
+ twoWaySync = Settings:get("twoWaySync"),
})
self.cleanupPrecommit = serveSession.__reconciler:hookPrecommit(function(patch, instanceMap)
@@ -457,7 +451,7 @@ function App:startSession()
end)
serveSession:hookPostcommit(function(patch, _instanceMap, unapplied)
- local now = os.time()
+ local now = DateTime.now().UnixTimestamp
local old = self.state.patchData
if PatchSet.isEmpty(patch) then
@@ -582,6 +576,9 @@ function App:startSession()
return "Accept"
end
end
+ elseif confirmationBehavior == "Never" then
+ Log.trace("Accepting patch without confirmation because behavior is set to Never")
+ return "Accept"
end
-- The datamodel name gets overwritten by Studio, making confirmation of it intrusive
diff --git a/plugin/src/Assets.lua b/plugin/src/Assets.lua
index dbc60a166..e48c1217e 100644
--- a/plugin/src/Assets.lua
+++ b/plugin/src/Assets.lua
@@ -25,6 +25,12 @@ local Assets = {
Back = "rbxassetid://6017213752",
Reset = "rbxassetid://10142422327",
Expand = "rbxassetid://12045401097",
+ Warning = "rbxassetid://16571019891",
+ Debug = "rbxassetid://16588411361",
+ Checkmark = "rbxassetid://16571012729",
+ Exclamation = "rbxassetid://16571172190",
+ SyncSuccess = "rbxassetid://16565035221",
+ SyncWarning = "rbxassetid://16565325171",
},
Diff = {
Add = "rbxassetid://10434145835",
diff --git a/plugin/src/Config.lua b/plugin/src/Config.lua
index 0238b2cb6..5567efca2 100644
--- a/plugin/src/Config.lua
+++ b/plugin/src/Config.lua
@@ -3,7 +3,8 @@ local strict = require(script.Parent.strict)
local isDevBuild = script.Parent.Parent:FindFirstChild("ROJO_DEV_BUILD") ~= nil
local Version = script.Parent.Parent.Version
-local major, minor, patch, metadata = Version.Value:match("^(%d+)%.(%d+)%.(%d+)(.*)$")
+local trimmedVersionValue = Version.Value:gsub("^%s+", ""):gsub("%s+$", "")
+local major, minor, patch, metadata = trimmedVersionValue:match("^(%d+)%.(%d+)%.(%d+)(.*)$")
local realVersion = { major, minor, patch, metadata }
for i = 1, 3 do
diff --git a/plugin/src/InstanceMap.lua b/plugin/src/InstanceMap.lua
index b035d423c..76754fef5 100644
--- a/plugin/src/InstanceMap.lua
+++ b/plugin/src/InstanceMap.lua
@@ -112,9 +112,12 @@ end
function InstanceMap:destroyInstance(instance)
local id = self.fromInstances[instance]
-
local descendants = instance:GetDescendants()
- instance:Destroy()
+
+ -- Because the user might want to Undo this change, we cannot use Destroy
+ -- since that locks that parent and prevents ChangeHistoryService from
+ -- ever bringing it back. Instead, we parent to nil.
+ instance.Parent = nil
-- After the instance is successfully destroyed,
-- we can remove all the id mappings
diff --git a/plugin/src/PatchSet.lua b/plugin/src/PatchSet.lua
index abbac0cbb..064def36c 100644
--- a/plugin/src/PatchSet.lua
+++ b/plugin/src/PatchSet.lua
@@ -211,9 +211,11 @@ end
function PatchSet.countChanges(patch)
local count = 0
- for _ in patch.added do
- -- Adding an instance is 1 change
- count += 1
+ for _, add in patch.added do
+ -- Adding an instance is 1 change per property
+ for _ in add.Properties do
+ count += 1
+ end
end
for _ in patch.removed do
-- Removing an instance is 1 change
diff --git a/plugin/src/PatchTree.lua b/plugin/src/PatchTree.lua
index e469e2112..c1c5f91ca 100644
--- a/plugin/src/PatchTree.lua
+++ b/plugin/src/PatchTree.lua
@@ -11,6 +11,7 @@ local Packages = Rojo.Packages
local Log = require(Packages.Log)
+local Timer = require(Plugin.Timer)
local Types = require(Plugin.Types)
local decodeValue = require(Plugin.Reconciler.decodeValue)
local getProperty = require(Plugin.Reconciler.getProperty)
@@ -78,6 +79,15 @@ function Tree.new()
return setmetatable(tree, Tree)
end
+-- Iterates over all nodes and counts them up
+function Tree:getCount()
+ local count = 0
+ self:forEach(function()
+ count += 1
+ end)
+ return count
+end
+
-- Iterates over all sub-nodes, depth first
-- node is where to start from, defaults to root
-- depth is used for recursion but can be used to set the starting depth
@@ -122,6 +132,7 @@ end
-- props must contain id, and cannot contain children or parentId
-- other than those three, it can hold anything
function Tree:addNode(parent, props)
+ Timer.start("Tree:addNode")
assert(props.id, "props must contain id")
parent = parent or "ROOT"
@@ -132,6 +143,7 @@ function Tree:addNode(parent, props)
for k, v in props do
node[k] = v
end
+ Timer.stop()
return node
end
@@ -142,18 +154,21 @@ function Tree:addNode(parent, props)
local parentNode = self:getNode(parent)
if not parentNode then
Log.warn("Failed to create node since parent doesnt exist: {}, {}", parent, props)
+ Timer.stop()
return
end
parentNode.children[node.id] = node
self.idToNode[node.id] = node
+ Timer.stop()
return node
end
-- Given a list of ancestor ids in descending order, builds the nodes for them
-- using the patch and instanceMap info
function Tree:buildAncestryNodes(previousId: string?, ancestryIds: { string }, patch, instanceMap)
+ Timer.start("Tree:buildAncestryNodes")
-- Build nodes for ancestry by going up the tree
previousId = previousId or "ROOT"
@@ -171,6 +186,8 @@ function Tree:buildAncestryNodes(previousId: string?, ancestryIds: { string }, p
})
previousId = ancestorId
end
+
+ Timer.stop()
end
local PatchTree = {}
@@ -178,10 +195,12 @@ local PatchTree = {}
-- Builds a new tree from a patch and instanceMap
-- uses changeListHeaders in node.changeList
function PatchTree.build(patch, instanceMap, changeListHeaders)
+ Timer.start("PatchTree.build")
local tree = Tree.new()
local knownAncestors = {}
+ Timer.start("patch.updated")
for _, change in patch.updated do
local instance = instanceMap.fromIds[change.id]
if not instance then
@@ -209,15 +228,14 @@ function PatchTree.build(patch, instanceMap, changeListHeaders)
tree:buildAncestryNodes(previousId, ancestryIds, patch, instanceMap)
-- Gather detail text
- local changeList, hint = nil, nil
+ local changeList, changeInfo = nil, nil
if next(change.changedProperties) or change.changedName then
changeList = {}
- local hintBuffer, i = {}, 0
+ local changeIndex = 0
local function addProp(prop: string, current: any?, incoming: any?, metadata: any?)
- i += 1
- hintBuffer[i] = prop
- changeList[i] = { prop, current, incoming, metadata }
+ changeIndex += 1
+ changeList[changeIndex] = { prop, current, incoming, metadata }
end
-- Gather the changes
@@ -237,19 +255,9 @@ function PatchTree.build(patch, instanceMap, changeListHeaders)
)
end
- -- Finalize detail values
-
- -- Trim hint to top 3
- table.sort(hintBuffer)
- if #hintBuffer > 3 then
- hintBuffer = {
- hintBuffer[1],
- hintBuffer[2],
- hintBuffer[3],
- i - 3 .. " more",
- }
- end
- hint = table.concat(hintBuffer, ", ")
+ changeInfo = {
+ edits = changeIndex,
+ }
-- Sort changes and add header
table.sort(changeList, function(a, b)
@@ -265,11 +273,13 @@ function PatchTree.build(patch, instanceMap, changeListHeaders)
className = instance.ClassName,
name = instance.Name,
instance = instance,
- hint = hint,
+ changeInfo = changeInfo,
changeList = changeList,
})
end
+ Timer.stop()
+ Timer.start("patch.removed")
for _, idOrInstance in patch.removed do
local instance = if Types.RbxId(idOrInstance) then instanceMap.fromIds[idOrInstance] else idOrInstance
if not instance then
@@ -311,7 +321,9 @@ function PatchTree.build(patch, instanceMap, changeListHeaders)
instance = instance,
})
end
+ Timer.stop()
+ Timer.start("patch.added")
for id, change in patch.added do
-- Gather ancestors from existing DOM or future additions
local ancestryIds = {}
@@ -346,36 +358,24 @@ function PatchTree.build(patch, instanceMap, changeListHeaders)
tree:buildAncestryNodes(previousId, ancestryIds, patch, instanceMap)
-- Gather detail text
- local changeList, hint = nil, nil
+ local changeList, changeInfo = nil, nil
if next(change.Properties) then
changeList = {}
- local hintBuffer, i = {}, 0
- for prop, incoming in change.Properties do
- i += 1
- hintBuffer[i] = prop
+ local changeIndex = 0
+ local function addProp(prop: string, incoming: any)
+ changeIndex += 1
+ changeList[changeIndex] = { prop, "N/A", incoming }
+ end
+ for prop, incoming in change.Properties do
local success, incomingValue = decodeValue(incoming, instanceMap)
- if success then
- table.insert(changeList, { prop, "N/A", incomingValue })
- else
- table.insert(changeList, { prop, "N/A", select(2, next(incoming)) })
- end
+ addProp(prop, if success then incomingValue else select(2, next(incoming)))
end
- -- Finalize detail values
-
- -- Trim hint to top 3
- table.sort(hintBuffer)
- if #hintBuffer > 3 then
- hintBuffer = {
- hintBuffer[1],
- hintBuffer[2],
- hintBuffer[3],
- i - 3 .. " more",
- }
- end
- hint = table.concat(hintBuffer, ", ")
+ changeInfo = {
+ edits = changeIndex,
+ }
-- Sort changes and add header
table.sort(changeList, function(a, b)
@@ -390,40 +390,32 @@ function PatchTree.build(patch, instanceMap, changeListHeaders)
patchType = "Add",
className = change.ClassName,
name = change.Name,
- hint = hint,
+ changeInfo = changeInfo,
changeList = changeList,
instance = instanceMap.fromIds[id],
})
end
+ Timer.stop()
+ Timer.stop()
return tree
end
--- Creates a deep copy of a tree for immutability purposes in Roact
-function PatchTree.clone(tree)
- if not tree then
- return
- end
-
- local newTree = Tree.new()
- tree:forEach(function(node)
- newTree:addNode(node.parentId, table.clone(node))
- end)
-
- return newTree
-end
-
-- Updates the metadata of a tree with the unapplied patch and currently existing instances
-- Builds a new tree from the data if one isn't provided
-- Always returns a new tree for immutability purposes in Roact
function PatchTree.updateMetadata(tree, patch, instanceMap, unappliedPatch)
+ Timer.start("PatchTree.updateMetadata")
if tree then
- tree = PatchTree.clone(tree)
+ -- A shallow copy is enough for our purposes here since we really only need a new top-level object
+ -- for immutable comparison checks in Roact
+ tree = table.clone(tree)
else
tree = PatchTree.build(patch, instanceMap)
end
-- Update isWarning metadata
+ Timer.start("isWarning")
for _, failedChange in unappliedPatch.updated do
local node = tree:getNode(failedChange.id)
if not node then
@@ -436,6 +428,8 @@ function PatchTree.updateMetadata(tree, patch, instanceMap, unappliedPatch)
if not node.changeList then
continue
end
+
+ local warnings = 0
for _, change in node.changeList do
local property = change[1]
local propertyFailedToApply = if property == "Name"
@@ -446,6 +440,8 @@ function PatchTree.updateMetadata(tree, patch, instanceMap, unappliedPatch)
-- This change didn't fail, no need to mark
continue
end
+
+ warnings += 1
if change[4] == nil then
change[4] = { isWarning = true }
else
@@ -453,6 +449,11 @@ function PatchTree.updateMetadata(tree, patch, instanceMap, unappliedPatch)
end
Log.trace(" Marked property as warning: {}.{}", node.name, property)
end
+
+ node.changeInfo = {
+ edits = (node.changeInfo.edits or (#node.changeList - 1)) - warnings,
+ failed = if warnings > 0 then warnings else nil,
+ }
end
for failedAdditionId in unappliedPatch.added do
local node = tree:getNode(failedAdditionId)
@@ -466,6 +467,7 @@ function PatchTree.updateMetadata(tree, patch, instanceMap, unappliedPatch)
if not node.changeList then
continue
end
+
for _, change in node.changeList do
-- Failed addition means that all properties failed to be added
if change[4] == nil then
@@ -475,6 +477,10 @@ function PatchTree.updateMetadata(tree, patch, instanceMap, unappliedPatch)
end
Log.trace(" Marked property as warning: {}.{}", node.name, change[1])
end
+
+ node.changeInfo = {
+ failed = node.changeInfo.edits or (#node.changeList - 1),
+ }
end
for _, failedRemovalIdOrInstance in unappliedPatch.removed do
local failedRemovalId = if Types.RbxId(failedRemovalIdOrInstance)
@@ -492,8 +498,10 @@ function PatchTree.updateMetadata(tree, patch, instanceMap, unappliedPatch)
node.isWarning = true
Log.trace("Marked node as warning: {} {}", node.id, node.name)
end
+ Timer.stop()
-- Update if instances exist
+ Timer.start("instanceAncestry")
tree:forEach(function(node)
if node.instance then
if node.instance.Parent == nil and node.instance ~= game then
@@ -509,7 +517,9 @@ function PatchTree.updateMetadata(tree, patch, instanceMap, unappliedPatch)
end
end
end)
+ Timer.stop()
+ Timer.stop()
return tree
end
diff --git a/plugin/src/Reconciler/applyPatch.lua b/plugin/src/Reconciler/applyPatch.lua
index 5ee6ed5e4..05e7412a8 100644
--- a/plugin/src/Reconciler/applyPatch.lua
+++ b/plugin/src/Reconciler/applyPatch.lua
@@ -20,6 +20,11 @@ local setProperty = require(script.Parent.setProperty)
local function applyPatch(instanceMap, patch)
local patchTimestamp = DateTime.now():FormatLocalTime("LTS", "en-us")
+ local historyRecording = ChangeHistoryService:TryBeginRecording("Rojo: Patch " .. patchTimestamp)
+ if not historyRecording then
+ -- There can only be one recording at a time
+ Log.debug("Failed to begin history recording for " .. patchTimestamp .. ". Another recording is in progress.")
+ end
-- Tracks any portions of the patch that could not be applied to the DOM.
local unappliedPatch = PatchSet.newEmpty()
@@ -62,6 +67,9 @@ local function applyPatch(instanceMap, patch)
if parentInstance == nil then
-- This would be peculiar. If you create an instance with no
-- parent, were you supposed to create it at all?
+ if historyRecording then
+ ChangeHistoryService:FinishRecording(historyRecording, Enum.FinishRecordingOperation.Commit)
+ end
invariant(
"Cannot add an instance from a patch that has no parent.\nInstance {} with parent {}.\nState: {:#?}",
id,
@@ -164,10 +172,14 @@ local function applyPatch(instanceMap, patch)
end
-- See you later, original instance.
- --
+
+ -- Because the user might want to Undo this change, we cannot use Destroy
+ -- since that locks that parent and prevents ChangeHistoryService from
+ -- ever bringing it back. Instead, we parent to nil.
+
-- TODO: Can this fail? Some kinds of instance may not appreciate
- -- being destroyed, like services.
- instance:Destroy()
+ -- being reparented, like services.
+ instance.Parent = nil
-- This completes your rebuilding a plane mid-flight safety
-- instruction. Please sit back, relax, and enjoy your flight.
@@ -214,7 +226,9 @@ local function applyPatch(instanceMap, patch)
end
end
- ChangeHistoryService:SetWaypoint("Rojo: Patch " .. patchTimestamp)
+ if historyRecording then
+ ChangeHistoryService:FinishRecording(historyRecording, Enum.FinishRecordingOperation.Commit)
+ end
return unappliedPatch
end
diff --git a/plugin/src/Reconciler/applyPatch.spec.lua b/plugin/src/Reconciler/applyPatch.spec.lua
index c561db751..b44e3eda6 100644
--- a/plugin/src/Reconciler/applyPatch.spec.lua
+++ b/plugin/src/Reconciler/applyPatch.spec.lua
@@ -4,25 +4,41 @@ return function()
local InstanceMap = require(script.Parent.Parent.InstanceMap)
local PatchSet = require(script.Parent.Parent.PatchSet)
- local dummy = Instance.new("Folder")
- local function wasDestroyed(instance)
+ local container = Instance.new("Folder")
+
+ local tempContainer = Instance.new("Folder")
+ local function wasRemoved(instance)
-- If an instance was destroyed, its parent property is locked.
- local ok = pcall(function()
+ -- If an instance was removed, its parent property is nil.
+ -- We need to ensure we only remove, so that ChangeHistoryService can still Undo.
+
+ local isParentUnlocked = pcall(function()
local oldParent = instance.Parent
- instance.Parent = dummy
+ instance.Parent = tempContainer
instance.Parent = oldParent
end)
- return not ok
+ return instance.Parent == nil and isParentUnlocked
end
+ beforeEach(function()
+ container:ClearAllChildren()
+ end)
+
+ afterAll(function()
+ container:Destroy()
+ tempContainer:Destroy()
+ end)
+
it("should return an empty patch if given an empty patch", function()
local patch = applyPatch(InstanceMap.new(), PatchSet.newEmpty())
assert(PatchSet.isEmpty(patch), "expected remaining patch to be empty")
end)
- it("should destroy instances listed for remove", function()
+ it("should remove instances listed for remove", function()
local root = Instance.new("Folder")
+ root.Name = "ROOT"
+ root.Parent = container
local child = Instance.new("Folder")
child.Name = "Child"
@@ -38,14 +54,16 @@ return function()
local unapplied = applyPatch(instanceMap, patch)
assert(PatchSet.isEmpty(unapplied), "expected remaining patch to be empty")
- assert(not wasDestroyed(root), "expected root to be left alone")
- assert(wasDestroyed(child), "expected child to be destroyed")
+ assert(not wasRemoved(root), "expected root to be left alone")
+ assert(wasRemoved(child), "expected child to be removed")
instanceMap:stop()
end)
- it("should destroy IDs listed for remove", function()
+ it("should remove IDs listed for remove", function()
local root = Instance.new("Folder")
+ root.Name = "ROOT"
+ root.Parent = container
local child = Instance.new("Folder")
child.Name = "Child"
@@ -62,8 +80,8 @@ return function()
assert(PatchSet.isEmpty(unapplied), "expected remaining patch to be empty")
expect(instanceMap:size()).to.equal(1)
- assert(not wasDestroyed(root), "expected root to be left alone")
- assert(wasDestroyed(child), "expected child to be destroyed")
+ assert(not wasRemoved(root), "expected root to be left alone")
+ assert(wasRemoved(child), "expected child to be removed")
instanceMap:stop()
end)
@@ -73,6 +91,8 @@ return function()
-- tests on reify, not here.
local root = Instance.new("Folder")
+ root.Name = "ROOT"
+ root.Parent = container
local instanceMap = InstanceMap.new()
instanceMap:insert("ROOT", root)
@@ -113,6 +133,8 @@ return function()
it("should return unapplied additions when instances cannot be created", function()
local root = Instance.new("Folder")
+ root.Name = "ROOT"
+ root.Parent = container
local instanceMap = InstanceMap.new()
instanceMap:insert("ROOT", root)
@@ -159,6 +181,7 @@ return function()
it("should recreate instances when changedClassName is set, preserving children", function()
local root = Instance.new("Folder")
root.Name = "Initial Root Name"
+ root.Parent = container
local child = Instance.new("Folder")
child.Name = "Child"
diff --git a/plugin/src/Reconciler/init.lua b/plugin/src/Reconciler/init.lua
index 129457827..df7cd92f4 100644
--- a/plugin/src/Reconciler/init.lua
+++ b/plugin/src/Reconciler/init.lua
@@ -3,9 +3,14 @@
and mutating the Roblox DOM.
]]
-local Packages = script.Parent.Parent.Packages
+local Rojo = script:FindFirstAncestor("Rojo")
+local Plugin = Rojo.Plugin
+local Packages = Rojo.Packages
+
local Log = require(Packages.Log)
+local Timer = require(Plugin.Timer)
+
local applyPatch = require(script.applyPatch)
local hydrate = require(script.hydrate)
local diff = require(script.diff)
@@ -57,31 +62,55 @@ function Reconciler:hookPostcommit(callback: (patch: any, instanceMap: any, unap
end
function Reconciler:applyPatch(patch)
+ Timer.start("Reconciler:applyPatch")
+
+ Timer.start("precommitCallbacks")
+ -- Precommit callbacks must be serial in order to obey the contract that
+ -- they execute before commit
for _, callback in self.__precommitCallbacks do
local success, err = pcall(callback, patch, self.__instanceMap)
if not success then
Log.warn("Precommit hook errored: {}", err)
end
end
+ Timer.stop()
+ Timer.start("apply")
local unappliedPatch = applyPatch(self.__instanceMap, patch)
+ Timer.stop()
+ Timer.start("postcommitCallbacks")
+ -- Postcommit callbacks can be called with spawn since regardless of firing order, they are
+ -- guaranteed to be called after the commit
for _, callback in self.__postcommitCallbacks do
- local success, err = pcall(callback, patch, self.__instanceMap, unappliedPatch)
- if not success then
- Log.warn("Postcommit hook errored: {}", err)
- end
+ task.spawn(function()
+ local success, err = pcall(callback, patch, self.__instanceMap, unappliedPatch)
+ if not success then
+ Log.warn("Postcommit hook errored: {}", err)
+ end
+ end)
end
+ Timer.stop()
+
+ Timer.stop()
return unappliedPatch
end
function Reconciler:hydrate(virtualInstances, rootId, rootInstance)
- return hydrate(self.__instanceMap, virtualInstances, rootId, rootInstance)
+ Timer.start("Reconciler:hydrate")
+ local result = hydrate(self.__instanceMap, virtualInstances, rootId, rootInstance)
+ Timer.stop()
+
+ return result
end
function Reconciler:diff(virtualInstances, rootId)
- return diff(self.__instanceMap, virtualInstances, rootId)
+ Timer.start("Reconciler:diff")
+ local success, result = diff(self.__instanceMap, virtualInstances, rootId)
+ Timer.stop()
+
+ return success, result
end
return Reconciler
diff --git a/plugin/src/ServeSession.lua b/plugin/src/ServeSession.lua
index 82d8fd42f..bb844d062 100644
--- a/plugin/src/ServeSession.lua
+++ b/plugin/src/ServeSession.lua
@@ -13,6 +13,7 @@ local InstanceMap = require(script.Parent.InstanceMap)
local PatchSet = require(script.Parent.PatchSet)
local Reconciler = require(script.Parent.Reconciler)
local strict = require(script.Parent.strict)
+local Settings = require(script.Parent.Settings)
local Status = strict("Session.Status", {
NotStarted = "NotStarted",
@@ -50,7 +51,6 @@ ServeSession.Status = Status
local validateServeOptions = t.strictInterface({
apiContext = t.table,
- openScriptsExternally = t.boolean,
twoWaySync = t.boolean,
})
@@ -89,7 +89,6 @@ function ServeSession.new(options)
self = {
__status = Status.NotStarted,
__apiContext = options.apiContext,
- __openScriptsExternally = options.openScriptsExternally,
__twoWaySync = options.twoWaySync,
__reconciler = reconciler,
__instanceMap = instanceMap,
@@ -170,7 +169,7 @@ function ServeSession:__applyGameAndPlaceId(serverInfo)
end
function ServeSession:__onActiveScriptChanged(activeScript)
- if not self.__openScriptsExternally then
+ if not Settings:get("openScriptsExternally") then
Log.trace("Not opening script {} because feature not enabled.", activeScript)
return
diff --git a/plugin/src/Settings.lua b/plugin/src/Settings.lua
index b5be22a76..67f13ba21 100644
--- a/plugin/src/Settings.lua
+++ b/plugin/src/Settings.lua
@@ -20,6 +20,7 @@ local defaultSettings = {
playSounds = true,
typecheckingEnabled = false,
logLevel = "Info",
+ timingLogsEnabled = false,
priorEndpoints = {},
}
diff --git a/plugin/src/Timer.lua b/plugin/src/Timer.lua
new file mode 100644
index 000000000..9a5bbbd02
--- /dev/null
+++ b/plugin/src/Timer.lua
@@ -0,0 +1,57 @@
+local Settings = require(script.Parent.Settings)
+
+local clock = os.clock
+
+local Timer = {
+ _entries = {},
+}
+
+function Timer._start(label)
+ local start = clock()
+ if not label then
+ error("[Rojo-Timer] Timer.start: label is required", 2)
+ return
+ end
+
+ table.insert(Timer._entries, { label, start })
+end
+
+function Timer._stop()
+ local stop = clock()
+
+ local entry = table.remove(Timer._entries)
+ if not entry then
+ error("[Rojo-Timer] Timer.stop: no label to stop", 2)
+ return
+ end
+
+ local label = entry[1]
+ if #Timer._entries > 0 then
+ local priorLabels = {}
+ for _, priorEntry in ipairs(Timer._entries) do
+ table.insert(priorLabels, priorEntry[1])
+ end
+ label = table.concat(priorLabels, "/") .. "/" .. label
+ end
+
+ local start = entry[2]
+ local duration = stop - start
+ print(string.format("[Rojo-Timer] %s took %.3f ms", label, duration * 1000))
+end
+
+-- Replace functions with no-op if not in debug mode
+local function no_op() end
+local function setFunctions(enabled)
+ if enabled then
+ Timer.start = Timer._start
+ Timer.stop = Timer._stop
+ else
+ Timer.start = no_op
+ Timer.stop = no_op
+ end
+end
+
+Settings:onChanged("timingLogsEnabled", setFunctions)
+setFunctions(Settings:get("timingLogsEnabled"))
+
+return Timer
diff --git a/rojo-test/build-test-snapshots/end_to_end__tests__build__no_name_default_project.snap b/rojo-test/build-test-snapshots/end_to_end__tests__build__no_name_default_project.snap
new file mode 100644
index 000000000..fbbd49116
--- /dev/null
+++ b/rojo-test/build-test-snapshots/end_to_end__tests__build__no_name_default_project.snap
@@ -0,0 +1,22 @@
+---
+source: tests/tests/build.rs
+expression: contents
+---
+
+ -
+
+ top-level
+
+
-
+
+ second-level
+
+
-
+
+ third-level
+ 1337
+
+
+
+
+
diff --git a/rojo-test/build-test-snapshots/end_to_end__tests__build__no_name_project.snap b/rojo-test/build-test-snapshots/end_to_end__tests__build__no_name_project.snap
new file mode 100644
index 000000000..588979334
--- /dev/null
+++ b/rojo-test/build-test-snapshots/end_to_end__tests__build__no_name_project.snap
@@ -0,0 +1,22 @@
+---
+source: tests/tests/build.rs
+expression: contents
+---
+
+ -
+
+ no_name_project
+
+
-
+
+ second-level
+
+
-
+
+ bool_value
+ true
+
+
+
+
+
diff --git a/rojo-test/build-test-snapshots/end_to_end__tests__build__no_name_top_level_project.snap b/rojo-test/build-test-snapshots/end_to_end__tests__build__no_name_top_level_project.snap
new file mode 100644
index 000000000..2f2e3d6ad
--- /dev/null
+++ b/rojo-test/build-test-snapshots/end_to_end__tests__build__no_name_top_level_project.snap
@@ -0,0 +1,13 @@
+---
+source: tests/tests/build.rs
+assertion_line: 107
+expression: contents
+---
+
+ -
+
+ no_name_top_level_project
+ If this isn't named `no_name_top_level_project`, something went wrong!
+
+
+
diff --git a/rojo-test/build-tests/no_name_default_project/default.project.json b/rojo-test/build-tests/no_name_default_project/default.project.json
new file mode 100644
index 000000000..1c2a1400d
--- /dev/null
+++ b/rojo-test/build-tests/no_name_default_project/default.project.json
@@ -0,0 +1,9 @@
+{
+ "name": "top-level",
+ "tree": {
+ "$className": "Folder",
+ "second-level": {
+ "$path": "src"
+ }
+ }
+}
\ No newline at end of file
diff --git a/rojo-test/build-tests/no_name_default_project/src/third-level/default.project.json b/rojo-test/build-tests/no_name_default_project/src/third-level/default.project.json
new file mode 100644
index 000000000..e7b87be1c
--- /dev/null
+++ b/rojo-test/build-tests/no_name_default_project/src/third-level/default.project.json
@@ -0,0 +1,8 @@
+{
+ "tree": {
+ "$className": "IntValue",
+ "$properties": {
+ "Value": 1337
+ }
+ }
+}
\ No newline at end of file
diff --git a/rojo-test/build-tests/no_name_project/default.project.json b/rojo-test/build-tests/no_name_project/default.project.json
new file mode 100644
index 000000000..93ef2e8ce
--- /dev/null
+++ b/rojo-test/build-tests/no_name_project/default.project.json
@@ -0,0 +1,9 @@
+{
+ "name": "no_name_project",
+ "tree": {
+ "$className": "Folder",
+ "second-level": {
+ "$path": "src"
+ }
+ }
+}
\ No newline at end of file
diff --git a/rojo-test/build-tests/no_name_project/src/bool_value.project.json b/rojo-test/build-tests/no_name_project/src/bool_value.project.json
new file mode 100644
index 000000000..6be58a3ce
--- /dev/null
+++ b/rojo-test/build-tests/no_name_project/src/bool_value.project.json
@@ -0,0 +1,8 @@
+{
+ "tree": {
+ "$className": "BoolValue",
+ "$properties": {
+ "Value": true
+ }
+ }
+}
\ No newline at end of file
diff --git a/rojo-test/build-tests/no_name_top_level_project/default.project.json b/rojo-test/build-tests/no_name_top_level_project/default.project.json
new file mode 100644
index 000000000..845ae3725
--- /dev/null
+++ b/rojo-test/build-tests/no_name_top_level_project/default.project.json
@@ -0,0 +1,8 @@
+{
+ "tree": {
+ "$className": "StringValue",
+ "$properties": {
+ "Value": "If this isn't named `no_name_top_level_project`, something went wrong!"
+ }
+ }
+}
\ No newline at end of file
diff --git a/rojo-test/serve-test-snapshots/end_to_end__tests__serve__no_name_default_project_all.snap b/rojo-test/serve-test-snapshots/end_to_end__tests__serve__no_name_default_project_all.snap
new file mode 100644
index 000000000..a8179a919
--- /dev/null
+++ b/rojo-test/serve-test-snapshots/end_to_end__tests__serve__no_name_default_project_all.snap
@@ -0,0 +1,39 @@
+---
+source: tests/tests/serve.rs
+expression: "read_response.intern_and_redact(&mut redactions, root_id)"
+---
+instances:
+ id-2:
+ Children:
+ - id-3
+ ClassName: Folder
+ Id: id-2
+ Metadata:
+ ignoreUnknownInstances: true
+ Name: top-level
+ Parent: "00000000000000000000000000000000"
+ Properties: {}
+ id-3:
+ Children:
+ - id-4
+ ClassName: Folder
+ Id: id-3
+ Metadata:
+ ignoreUnknownInstances: false
+ Name: second-level
+ Parent: id-2
+ Properties: {}
+ id-4:
+ Children: []
+ ClassName: IntValue
+ Id: id-4
+ Metadata:
+ ignoreUnknownInstances: true
+ Name: third-level
+ Parent: id-3
+ Properties:
+ Value:
+ Int64: 1337
+messageCursor: 0
+sessionId: id-1
+
diff --git a/rojo-test/serve-test-snapshots/end_to_end__tests__serve__no_name_default_project_info.snap b/rojo-test/serve-test-snapshots/end_to_end__tests__serve__no_name_default_project_info.snap
new file mode 100644
index 000000000..954ba6229
--- /dev/null
+++ b/rojo-test/serve-test-snapshots/end_to_end__tests__serve__no_name_default_project_info.snap
@@ -0,0 +1,14 @@
+---
+source: tests/tests/serve.rs
+assertion_line: 316
+expression: redactions.redacted_yaml(info)
+---
+expectedPlaceIds: ~
+gameId: ~
+placeId: ~
+projectName: top-level
+protocolVersion: 4
+rootInstanceId: id-2
+serverVersion: "[server-version]"
+sessionId: id-1
+
diff --git a/rojo-test/serve-test-snapshots/end_to_end__tests__serve__no_name_project_all.snap b/rojo-test/serve-test-snapshots/end_to_end__tests__serve__no_name_project_all.snap
new file mode 100644
index 000000000..1b398a928
--- /dev/null
+++ b/rojo-test/serve-test-snapshots/end_to_end__tests__serve__no_name_project_all.snap
@@ -0,0 +1,40 @@
+---
+source: tests/tests/serve.rs
+assertion_line: 338
+expression: "read_response.intern_and_redact(&mut redactions, root_id)"
+---
+instances:
+ id-2:
+ Children:
+ - id-3
+ ClassName: Folder
+ Id: id-2
+ Metadata:
+ ignoreUnknownInstances: true
+ Name: no_name_project
+ Parent: "00000000000000000000000000000000"
+ Properties: {}
+ id-3:
+ Children:
+ - id-4
+ ClassName: Folder
+ Id: id-3
+ Metadata:
+ ignoreUnknownInstances: false
+ Name: second-level
+ Parent: id-2
+ Properties: {}
+ id-4:
+ Children: []
+ ClassName: BoolValue
+ Id: id-4
+ Metadata:
+ ignoreUnknownInstances: true
+ Name: bool_value
+ Parent: id-3
+ Properties:
+ Value:
+ Bool: true
+messageCursor: 0
+sessionId: id-1
+
diff --git a/rojo-test/serve-test-snapshots/end_to_end__tests__serve__no_name_project_info.snap b/rojo-test/serve-test-snapshots/end_to_end__tests__serve__no_name_project_info.snap
new file mode 100644
index 000000000..d9772de1c
--- /dev/null
+++ b/rojo-test/serve-test-snapshots/end_to_end__tests__serve__no_name_project_info.snap
@@ -0,0 +1,14 @@
+---
+source: tests/tests/serve.rs
+assertion_line: 335
+expression: redactions.redacted_yaml(info)
+---
+expectedPlaceIds: ~
+gameId: ~
+placeId: ~
+projectName: no_name_project
+protocolVersion: 4
+rootInstanceId: id-2
+serverVersion: "[server-version]"
+sessionId: id-1
+
diff --git a/rojo-test/serve-test-snapshots/end_to_end__tests__serve__no_name_top_level_project_all.snap b/rojo-test/serve-test-snapshots/end_to_end__tests__serve__no_name_top_level_project_all.snap
new file mode 100644
index 000000000..ea52fe4bf
--- /dev/null
+++ b/rojo-test/serve-test-snapshots/end_to_end__tests__serve__no_name_top_level_project_all.snap
@@ -0,0 +1,20 @@
+---
+source: tests/tests/serve.rs
+assertion_line: 357
+expression: "read_response.intern_and_redact(&mut redactions, root_id)"
+---
+instances:
+ id-2:
+ Children: []
+ ClassName: StringValue
+ Id: id-2
+ Metadata:
+ ignoreUnknownInstances: true
+ Name: no_name_top_level_project
+ Parent: "00000000000000000000000000000000"
+ Properties:
+ Value:
+ String: "If this isn't named `no_name_top_level_project`, something went wrong!"
+messageCursor: 0
+sessionId: id-1
+
diff --git a/rojo-test/serve-test-snapshots/end_to_end__tests__serve__no_name_top_level_project_info.snap b/rojo-test/serve-test-snapshots/end_to_end__tests__serve__no_name_top_level_project_info.snap
new file mode 100644
index 000000000..3ad79c37e
--- /dev/null
+++ b/rojo-test/serve-test-snapshots/end_to_end__tests__serve__no_name_top_level_project_info.snap
@@ -0,0 +1,14 @@
+---
+source: tests/tests/serve.rs
+assertion_line: 351
+expression: redactions.redacted_yaml(info)
+---
+expectedPlaceIds: ~
+gameId: ~
+placeId: ~
+projectName: no_name_top_level_project
+protocolVersion: 4
+rootInstanceId: id-2
+serverVersion: "[server-version]"
+sessionId: id-1
+
diff --git a/rojo-test/serve-tests/no_name_default_project/default.project.json b/rojo-test/serve-tests/no_name_default_project/default.project.json
new file mode 100644
index 000000000..1c2a1400d
--- /dev/null
+++ b/rojo-test/serve-tests/no_name_default_project/default.project.json
@@ -0,0 +1,9 @@
+{
+ "name": "top-level",
+ "tree": {
+ "$className": "Folder",
+ "second-level": {
+ "$path": "src"
+ }
+ }
+}
\ No newline at end of file
diff --git a/rojo-test/serve-tests/no_name_default_project/src/third-level/default.project.json b/rojo-test/serve-tests/no_name_default_project/src/third-level/default.project.json
new file mode 100644
index 000000000..e7b87be1c
--- /dev/null
+++ b/rojo-test/serve-tests/no_name_default_project/src/third-level/default.project.json
@@ -0,0 +1,8 @@
+{
+ "tree": {
+ "$className": "IntValue",
+ "$properties": {
+ "Value": 1337
+ }
+ }
+}
\ No newline at end of file
diff --git a/rojo-test/serve-tests/no_name_project/default.project.json b/rojo-test/serve-tests/no_name_project/default.project.json
new file mode 100644
index 000000000..93ef2e8ce
--- /dev/null
+++ b/rojo-test/serve-tests/no_name_project/default.project.json
@@ -0,0 +1,9 @@
+{
+ "name": "no_name_project",
+ "tree": {
+ "$className": "Folder",
+ "second-level": {
+ "$path": "src"
+ }
+ }
+}
\ No newline at end of file
diff --git a/rojo-test/serve-tests/no_name_project/src/bool_value.project.json b/rojo-test/serve-tests/no_name_project/src/bool_value.project.json
new file mode 100644
index 000000000..6be58a3ce
--- /dev/null
+++ b/rojo-test/serve-tests/no_name_project/src/bool_value.project.json
@@ -0,0 +1,8 @@
+{
+ "tree": {
+ "$className": "BoolValue",
+ "$properties": {
+ "Value": true
+ }
+ }
+}
\ No newline at end of file
diff --git a/rojo-test/serve-tests/no_name_top_level_project/default.project.json b/rojo-test/serve-tests/no_name_top_level_project/default.project.json
new file mode 100644
index 000000000..845ae3725
--- /dev/null
+++ b/rojo-test/serve-tests/no_name_top_level_project/default.project.json
@@ -0,0 +1,8 @@
+{
+ "tree": {
+ "$className": "StringValue",
+ "$properties": {
+ "Value": "If this isn't named `no_name_top_level_project`, something went wrong!"
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main.rs b/src/main.rs
index 5bb9bc6c2..4e0fb507f 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -7,7 +7,7 @@ use librojo::cli::Options;
fn main() {
#[cfg(feature = "profile-with-tracy")]
- tracy_client::Client::start();
+ profiling::tracy_client::Client::start();
panic::set_hook(Box::new(|panic_info| {
// PanicInfo's payload is usually a &'static str or String.
diff --git a/src/project.rs b/src/project.rs
index f09917025..6e503dd63 100644
--- a/src/project.rs
+++ b/src/project.rs
@@ -39,7 +39,7 @@ enum Error {
#[serde(deny_unknown_fields, rename_all = "camelCase")]
pub struct Project {
/// The name of the top-level instance described by the project.
- pub name: String,
+ pub name: Option,
/// The tree of instances described by this project. Projects always
/// describe at least one instance.
diff --git a/src/serve_session.rs b/src/serve_session.rs
index 85ae77934..dbc841d74 100644
--- a/src/serve_session.rs
+++ b/src/serve_session.rs
@@ -110,7 +110,7 @@ impl ServeSession {
log::debug!("Loading project file from {}", project_path.display());
- let root_project = match vfs.read(&project_path).with_not_found()? {
+ let mut root_project = match vfs.read(&project_path).with_not_found()? {
Some(contents) => Project::load_from_slice(&contents, &project_path)?,
None => {
return Err(ServeSessionError::NoProjectFound {
@@ -118,6 +118,35 @@ impl ServeSession {
});
}
};
+ if root_project.name.is_none() {
+ if let Some(file_name) = project_path.file_name().and_then(|s| s.to_str()) {
+ if file_name == "default.project.json" {
+ let folder_name = project_path
+ .parent()
+ .and_then(Path::file_name)
+ .and_then(|s| s.to_str());
+ if let Some(folder_name) = folder_name {
+ root_project.name = Some(folder_name.to_string());
+ } else {
+ return Err(ServeSessionError::FolderNameInvalid {
+ path: project_path.to_path_buf(),
+ });
+ }
+ } else if let Some(trimmed) = file_name.strip_suffix(".project.json") {
+ root_project.name = Some(trimmed.to_string());
+ } else {
+ return Err(ServeSessionError::ProjectNameInvalid {
+ path: project_path.to_path_buf(),
+ });
+ }
+ } else {
+ return Err(ServeSessionError::ProjectNameInvalid {
+ path: project_path.to_path_buf(),
+ });
+ }
+ }
+ // Rebind it to make it no longer mutable
+ let root_project = root_project;
let mut tree = RojoTree::new(InstanceSnapshot::new());
@@ -190,7 +219,10 @@ impl ServeSession {
}
pub fn project_name(&self) -> &str {
- &self.root_project.name
+ self.root_project
+ .name
+ .as_ref()
+ .expect("all top-level projects must have their name set")
}
pub fn project_port(&self) -> Option {
@@ -231,6 +263,14 @@ pub enum ServeSessionError {
)]
NoProjectFound { path: PathBuf },
+ #[error("The folder for the provided project cannot be used as a project name: {}\n\
+ Consider setting the `name` field on this project.", .path.display())]
+ FolderNameInvalid { path: PathBuf },
+
+ #[error("The file name of the provided project cannot be used as a project name: {}.\n\
+ Consider setting the `name` field on this project.", .path.display())]
+ ProjectNameInvalid { path: PathBuf },
+
#[error(transparent)]
Io {
#[from]
diff --git a/src/snapshot_middleware/mod.rs b/src/snapshot_middleware/mod.rs
index 30ea57061..1c95154ef 100644
--- a/src/snapshot_middleware/mod.rs
+++ b/src/snapshot_middleware/mod.rs
@@ -66,7 +66,13 @@ pub fn snapshot_from_vfs(
for rule in default_sync_rules() {
if rule.matches(&init_path) {
return match rule.middleware {
- Middleware::Project => snapshot_project(context, vfs, &init_path),
+ Middleware::Project => {
+ let name = init_path
+ .parent()
+ .and_then(Path::file_name)
+ .and_then(|s| s.to_str()).expect("default.project.json should be inside a folder with a unicode name");
+ snapshot_project(context, vfs, &init_path, name)
+ }
Middleware::ModuleScript => {
snapshot_lua_init(context, vfs, &init_path, ScriptType::Module)
@@ -218,9 +224,7 @@ impl Middleware {
Self::ServerScript => snapshot_lua(context, vfs, path, name, ScriptType::Server),
Self::ClientScript => snapshot_lua(context, vfs, path, name, ScriptType::Client),
Self::ModuleScript => snapshot_lua(context, vfs, path, name, ScriptType::Module),
- // At the moment, snapshot_project does not use `name` so we
- // don't provide it.
- Self::Project => snapshot_project(context, vfs, path),
+ Self::Project => snapshot_project(context, vfs, path, name),
Self::Rbxm => snapshot_rbxm(context, vfs, path, name),
Self::Rbxmx => snapshot_rbxmx(context, vfs, path, name),
Self::Toml => snapshot_toml(context, vfs, path, name),
@@ -280,8 +284,7 @@ fn default_sync_rules() -> &'static [SyncRule] {
sync_rule!("*.client.lua", ClientScript, ".client.lua"),
sync_rule!("*.client.luau", ClientScript, ".client.luau"),
sync_rule!("*.{lua,luau}", ModuleScript),
- // Project middleware doesn't use the file name.
- sync_rule!("*.project.json", Project),
+ sync_rule!("*.project.json", Project, ".project.json"),
sync_rule!("*.model.json", JsonModel, ".model.json"),
sync_rule!("*.json", Json, ".json", "*.meta.json"),
sync_rule!("*.toml", Toml),
diff --git a/src/snapshot_middleware/project.rs b/src/snapshot_middleware/project.rs
index e5d279517..53e65251b 100644
--- a/src/snapshot_middleware/project.rs
+++ b/src/snapshot_middleware/project.rs
@@ -20,9 +20,11 @@ pub fn snapshot_project(
context: &InstanceContext,
vfs: &Vfs,
path: &Path,
+ name: &str,
) -> anyhow::Result