瀏覽代碼

chore(deps) Update Tauri CLI (1.x) (#8229)

* chore(deps) Update Tauri CLI

* fix build

* fix msrv

* update lockfile

* revert api test

* lint

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Lucas Nogueira <lucas@tauri.studio>
renovate[bot] 1 年之前
父節點
當前提交
60f7443ce0

+ 2 - 2
core/tauri-utils/src/html.rs

@@ -265,7 +265,7 @@ pub fn inline_isolation(document: &mut NodeRef, dir: &Path) {
     let src = {
       let attributes = script.attributes.borrow();
       attributes
-        .get(LocalName::from("src"))
+        .get("src")
         .expect("script with src attribute has no src value")
         .to_string()
     };
@@ -282,7 +282,7 @@ pub fn inline_isolation(document: &mut NodeRef, dir: &Path) {
     script.as_node().append(NodeRef::new_text(file));
 
     let mut attributes = script.attributes.borrow_mut();
-    attributes.remove(LocalName::from("src"));
+    attributes.remove("src");
   }
 }
 

+ 40 - 70
examples/api/src-tauri/Cargo.lock

@@ -405,6 +405,12 @@ version = "0.21.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
 
+[[package]]
+name = "base64"
+version = "0.22.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
+
 [[package]]
 name = "bitflags"
 version = "1.3.2"
@@ -450,9 +456,9 @@ dependencies = [
 
 [[package]]
 name = "brotli"
-version = "3.4.0"
+version = "6.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "516074a47ef4bce09577a3b379392300159ce5b1ba2e501ff1c819950066100f"
+checksum = "74f7971dbd9326d58187408ab83117d8ac1bb9c17b085fdacd1cf2f598719b6b"
 dependencies = [
  "alloc-no-stdlib",
  "alloc-stdlib",
@@ -461,9 +467,9 @@ dependencies = [
 
 [[package]]
 name = "brotli-decompressor"
-version = "2.5.1"
+version = "4.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4e2e4afe60d7dd600fdd3de8d0f08c2b7ec039712e3b6137ff98b7004e82de4f"
+checksum = "9a45bd2e4095a8b518033b128020dd4a55aab1c0a381ba4404a472630f4bc362"
 dependencies = [
  "alloc-no-stdlib",
  "alloc-stdlib",
@@ -1267,6 +1273,15 @@ dependencies = [
  "miniz_oxide",
 ]
 
+[[package]]
+name = "fluent-uri"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "17c704e9dbe1ddd863da1e6ff3567795087b1eb201ce80d8fa81162e1516500d"
+dependencies = [
+ "bitflags 1.3.2",
+]
+
 [[package]]
 name = "fnv"
 version = "1.0.7"
@@ -1953,16 +1968,6 @@ dependencies = [
  "cc",
 ]
 
-[[package]]
-name = "ico"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "031530fe562d8c8d71c0635013d6d155bbfe8ba0aa4b4d2d24ce8af6b71047bd"
-dependencies = [
- "byteorder",
- "png",
-]
-
 [[package]]
 name = "ico"
 version = "0.3.0"
@@ -2041,15 +2046,6 @@ dependencies = [
  "serde",
 ]
 
-[[package]]
-name = "infer"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f178e61cdbfe084aa75a2f4f7a25a5bb09701a47ae1753608f194b15783c937a"
-dependencies = [
- "cfb",
-]
-
 [[package]]
 name = "infer"
 version = "0.13.0"
@@ -2180,14 +2176,25 @@ dependencies = [
 
 [[package]]
 name = "json-patch"
-version = "1.2.0"
+version = "2.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "55ff1e1486799e3f64129f8ccad108b38290df9cd7015cd31bed17239f0789d6"
+checksum = "5b1fb8864823fad91877e6caea0baca82e49e8db50f8e5c9f9a453e27d3330fc"
 dependencies = [
+ "jsonptr",
  "serde",
  "serde_json",
  "thiserror",
- "treediff",
+]
+
+[[package]]
+name = "jsonptr"
+version = "0.4.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1c6e529149475ca0b2820835d3dce8fcc41c6b943ca608d32f35b449255e4627"
+dependencies = [
+ "fluent-uri",
+ "serde",
+ "serde_json",
 ]
 
 [[package]]
@@ -3887,15 +3894,11 @@ checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160"
 
 [[package]]
 name = "sys-locale"
-version = "0.2.4"
+version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f8a11bd9c338fdba09f7881ab41551932ad42e405f61d01e8406baea71c07aee"
+checksum = "e801cf239ecd6ccd71f03d270d67dd53d13e90aab208bf4b8fe4ad957ea949b0"
 dependencies = [
- "js-sys",
  "libc",
- "wasm-bindgen",
- "web-sys",
- "windows-sys 0.45.0",
 ]
 
 [[package]]
@@ -4027,7 +4030,7 @@ name = "tauri"
 version = "1.7.1"
 dependencies = [
  "anyhow",
- "base64 0.21.7",
+ "base64 0.22.1",
  "bytes",
  "clap",
  "cocoa 0.24.1",
@@ -4043,10 +4046,10 @@ dependencies = [
  "gtk",
  "heck 0.5.0",
  "http",
- "ico 0.2.0",
+ "ico",
  "ignore",
  "indexmap 1.9.3",
- "infer 0.9.0",
+ "infer",
  "minisign-verify",
  "nix",
  "notify-rust",
@@ -4113,7 +4116,7 @@ version = "1.4.4"
 dependencies = [
  "base64 0.21.7",
  "brotli",
- "ico 0.3.0",
+ "ico",
  "json-patch",
  "plist",
  "png",
@@ -4193,7 +4196,7 @@ dependencies = [
  "glob",
  "heck 0.5.0",
  "html5ever",
- "infer 0.13.0",
+ "infer",
  "json-patch",
  "kuchikiki",
  "log",
@@ -4565,15 +4568,6 @@ dependencies = [
  "petgraph",
 ]
 
-[[package]]
-name = "treediff"
-version = "4.0.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4d127780145176e2b5d16611cc25a900150e86e9fd79d3bde6ff3a37359c9cb5"
-dependencies = [
- "serde_json",
-]
-
 [[package]]
 name = "try-lock"
 version = "0.2.5"
@@ -5168,15 +5162,6 @@ dependencies = [
  "windows_x86_64_msvc 0.42.2",
 ]
 
-[[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"
@@ -5195,21 +5180,6 @@ dependencies = [
  "windows-targets 0.52.0",
 ]
 
-[[package]]
-name = "windows-targets"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
-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",
-]
-
 [[package]]
 name = "windows-targets"
 version = "0.48.5"

+ 112 - 266
tooling/cli/Cargo.lock

@@ -222,19 +222,20 @@ dependencies = [
 
 [[package]]
 name = "axum"
-version = "0.6.20"
+version = "0.7.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf"
+checksum = "3a6c9af12842a67734c9a2e355436e5d03b22383ed60cf13cd0c18fbfe3dcbcf"
 dependencies = [
  "async-trait",
  "axum-core",
  "base64 0.21.7",
- "bitflags 1.3.2",
  "bytes",
  "futures-util",
  "http",
  "http-body",
+ "http-body-util",
  "hyper",
+ "hyper-util",
  "itoa 1.0.11",
  "matchit",
  "memchr",
@@ -247,29 +248,34 @@ dependencies = [
  "serde_path_to_error",
  "serde_urlencoded",
  "sha1",
- "sync_wrapper",
+ "sync_wrapper 1.0.1",
  "tokio",
  "tokio-tungstenite",
  "tower",
  "tower-layer",
  "tower-service",
+ "tracing",
 ]
 
 [[package]]
 name = "axum-core"
-version = "0.3.4"
+version = "0.4.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c"
+checksum = "a15c63fd72d41492dc4f497196f5da1fb04fb7529e631d73630d1b491e47a2e3"
 dependencies = [
  "async-trait",
  "bytes",
  "futures-util",
  "http",
  "http-body",
+ "http-body-util",
  "mime",
+ "pin-project-lite",
  "rustversion",
+ "sync_wrapper 0.1.2",
  "tower-layer",
  "tower-service",
+ "tracing",
 ]
 
 [[package]]
@@ -487,9 +493,9 @@ dependencies = [
 
 [[package]]
 name = "cc"
-version = "1.1.7"
+version = "1.1.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "26a5c3fd7bfa1ce3897a3a3501d362b2d87b7f2583ebcb4a949ec25911025cbc"
+checksum = "504bdec147f2cc13c8b57ed9401fd8a147cc66b67ad5cb241394244f2c947549"
 dependencies = [
  "jobserver",
  "libc",
@@ -564,9 +570,9 @@ dependencies = [
 
 [[package]]
 name = "clap"
-version = "4.4.18"
+version = "4.5.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e578d6ec4194633722ccf9544794b71b1385c3c027efe0c55db226fc880865c"
+checksum = "c937d4061031a6d0c8da4b9a4f98a172fc2976dfb1c19213a9cf7d0d3c837e36"
 dependencies = [
  "clap_builder",
  "clap_derive",
@@ -574,32 +580,32 @@ dependencies = [
 
 [[package]]
 name = "clap_builder"
-version = "4.4.18"
+version = "4.5.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4df4df40ec50c46000231c914968278b1eb05098cf8f1b3a518a95030e71d1c7"
+checksum = "85379ba512b21a328adf887e85f7742d12e96eb31f3ef077df4ffc26b506ffed"
 dependencies = [
  "anstream",
  "anstyle",
  "clap_lex",
- "strsim 0.10.0",
+ "strsim 0.11.1",
 ]
 
 [[package]]
 name = "clap_complete"
-version = "4.4.10"
+version = "4.5.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "abb745187d7f4d76267b37485a65e0149edd0e91a4cfcdd3f27524ad86cee9f3"
+checksum = "aa3c596da3cf0983427b0df0dba359df9182c13bd5b519b585a482b0c351f4e8"
 dependencies = [
  "clap",
 ]
 
 [[package]]
 name = "clap_derive"
-version = "4.4.7"
+version = "4.5.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442"
+checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0"
 dependencies = [
- "heck 0.4.1",
+ "heck",
  "proc-macro2",
  "quote",
  "syn 2.0.72",
@@ -607,9 +613,9 @@ dependencies = [
 
 [[package]]
 name = "clap_lex"
-version = "0.6.0"
+version = "0.7.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1"
+checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97"
 
 [[package]]
 name = "color_quant"
@@ -1181,15 +1187,6 @@ version = "0.3.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
 
-[[package]]
-name = "encoding_rs"
-version = "0.8.34"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59"
-dependencies = [
- "cfg-if",
-]
-
 [[package]]
 name = "enum-display-derive"
 version = "0.1.1"
@@ -1212,17 +1209,27 @@ dependencies = [
  "syn 2.0.72",
 ]
 
+[[package]]
+name = "env_filter"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4f2c92ceda6ceec50f43169f9ee8424fe2db276791afde7b2cd8bc084cb376ab"
+dependencies = [
+ "log",
+ "regex",
+]
+
 [[package]]
 name = "env_logger"
-version = "0.10.2"
+version = "0.11.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580"
+checksum = "e13fa619b91fb2381732789fc5de83b45675e882f66623b7d8cb4f643017018d"
 dependencies = [
+ "anstream",
+ "anstyle",
+ "env_filter",
  "humantime",
- "is-terminal",
  "log",
- "regex",
- "termcolor",
 ]
 
 [[package]]
@@ -1269,12 +1276,13 @@ dependencies = [
 
 [[package]]
 name = "fancy-regex"
-version = "0.11.0"
+version = "0.13.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b95f7c0680e4142284cf8b22c14a476e87d61b004a3a0861872b32ef7ead40a2"
+checksum = "531e46835a22af56d1e3b66f04844bed63158bc094a628bec1d321d9b4c44bf2"
 dependencies = [
  "bit-set",
- "regex",
+ "regex-automata",
+ "regex-syntax",
 ]
 
 [[package]]
@@ -1380,9 +1388,9 @@ dependencies = [
 
 [[package]]
 name = "fraction"
-version = "0.13.1"
+version = "0.15.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3027ae1df8d41b4bed2241c8fdad4acc1e7af60c8e17743534b545e77182d678"
+checksum = "0f158e3ff0a1b334408dc9fb811cd99b446986f4d8b741bb08f9df1604085ae7"
 dependencies = [
  "lazy_static",
  "num",
@@ -1422,12 +1430,6 @@ version = "0.3.30"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d"
 
-[[package]]
-name = "futures-io"
-version = "0.3.30"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1"
-
 [[package]]
 name = "futures-sink"
 version = "0.3.30"
@@ -1447,10 +1449,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48"
 dependencies = [
  "futures-core",
- "futures-io",
  "futures-sink",
  "futures-task",
- "memchr",
  "pin-project-lite",
  "pin-utils",
  "slab",
@@ -1556,25 +1556,6 @@ dependencies = [
  "subtle",
 ]
 
-[[package]]
-name = "h2"
-version = "0.3.26"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8"
-dependencies = [
- "bytes",
- "fnv",
- "futures-core",
- "futures-sink",
- "futures-util",
- "http",
- "indexmap 2.3.0",
- "slab",
- "tokio",
- "tokio-util",
- "tracing",
-]
-
 [[package]]
 name = "half"
 version = "2.4.1"
@@ -1611,12 +1592,6 @@ version = "0.14.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
 
-[[package]]
-name = "heck"
-version = "0.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
-
 [[package]]
 name = "heck"
 version = "0.5.0"
@@ -1669,9 +1644,9 @@ dependencies = [
 
 [[package]]
 name = "http"
-version = "0.2.12"
+version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1"
+checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258"
 dependencies = [
  "bytes",
  "fnv",
@@ -1680,12 +1655,24 @@ dependencies = [
 
 [[package]]
 name = "http-body"
-version = "0.4.6"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184"
+dependencies = [
+ "bytes",
+ "http",
+]
+
+[[package]]
+name = "http-body-util"
+version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2"
+checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f"
 dependencies = [
  "bytes",
+ "futures-util",
  "http",
+ "http-body",
  "pin-project-lite",
 ]
 
@@ -1709,26 +1696,36 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
 
 [[package]]
 name = "hyper"
-version = "0.14.30"
+version = "1.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9"
+checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05"
 dependencies = [
  "bytes",
  "futures-channel",
- "futures-core",
  "futures-util",
- "h2",
  "http",
  "http-body",
  "httparse",
  "httpdate",
  "itoa 1.0.11",
  "pin-project-lite",
- "socket2",
+ "smallvec",
+ "tokio",
+]
+
+[[package]]
+name = "hyper-util"
+version = "0.1.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cde7055719c54e36e95e8719f95883f22072a48ede39db7fc17a4e1d5281e9b9"
+dependencies = [
+ "bytes",
+ "futures-util",
+ "http",
+ "http-body",
+ "hyper",
+ "pin-project-lite",
  "tokio",
- "tower-service",
- "tracing",
- "want",
 ]
 
 [[package]]
@@ -1795,19 +1792,6 @@ dependencies = [
  "winapi-util",
 ]
 
-[[package]]
-name = "image"
-version = "0.24.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5690139d2f55868e080017335e4b94cb7414274c74f1669c84fb5feba2c9f69d"
-dependencies = [
- "bytemuck",
- "byteorder",
- "color_quant",
- "num-traits",
- "png",
-]
-
 [[package]]
 name = "image"
 version = "0.25.2"
@@ -1937,23 +1921,6 @@ dependencies = [
  "syn 2.0.72",
 ]
 
-[[package]]
-name = "ipnet"
-version = "2.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3"
-
-[[package]]
-name = "is-terminal"
-version = "0.4.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b"
-dependencies = [
- "hermit-abi",
- "libc",
- "windows-sys 0.52.0",
-]
-
 [[package]]
 name = "is_terminal_polyfill"
 version = "1.70.1"
@@ -1977,18 +1944,18 @@ checksum = "a598c1abae8e3456ebda517868b254b6bc2a9bb6501ffd5b9d0875bf332e048b"
 
 [[package]]
 name = "itertools"
-version = "0.11.0"
+version = "0.12.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57"
+checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569"
 dependencies = [
  "either",
 ]
 
 [[package]]
 name = "itertools"
-version = "0.12.1"
+version = "0.13.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569"
+checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186"
 dependencies = [
  "either",
 ]
@@ -2065,15 +2032,14 @@ dependencies = [
 
 [[package]]
 name = "jsonschema"
-version = "0.17.1"
+version = "0.18.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2a071f4f7efc9a9118dfb627a0a94ef247986e1ab8606a4c806ae2b3aa3b6978"
+checksum = "ec0afd06142c9bcb03f4a8787c77897a87b6be9c4918f1946c33caa714c27578"
 dependencies = [
  "ahash",
  "anyhow",
- "base64 0.21.7",
+ "base64 0.22.1",
  "bytecount",
- "clap",
  "fancy-regex",
  "fraction",
  "getrandom 0.2.15",
@@ -2085,7 +2051,6 @@ dependencies = [
  "parking_lot",
  "percent-encoding",
  "regex",
- "reqwest",
  "serde",
  "serde_json",
  "time",
@@ -2188,7 +2153,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4"
 dependencies = [
  "cfg-if",
- "windows-targets 0.48.5",
+ "windows-targets 0.52.6",
 ]
 
 [[package]]
@@ -3512,42 +3477,6 @@ version = "0.8.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b"
 
-[[package]]
-name = "reqwest"
-version = "0.11.27"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62"
-dependencies = [
- "base64 0.21.7",
- "bytes",
- "encoding_rs",
- "futures-core",
- "futures-util",
- "h2",
- "http",
- "http-body",
- "hyper",
- "ipnet",
- "js-sys",
- "log",
- "mime",
- "once_cell",
- "percent-encoding",
- "pin-project-lite",
- "serde",
- "serde_json",
- "serde_urlencoded",
- "sync_wrapper",
- "system-configuration",
- "tokio",
- "tower-service",
- "url",
- "wasm-bindgen",
- "wasm-bindgen-futures",
- "web-sys",
- "winreg",
-]
-
 [[package]]
 name = "rfc6979"
 version = "0.4.0"
@@ -3868,9 +3797,9 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b"
 
 [[package]]
 name = "serde"
-version = "1.0.204"
+version = "1.0.205"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12"
+checksum = "e33aedb1a7135da52b7c21791455563facbbcc43d0f0f66165b42c21b3dfb150"
 dependencies = [
  "serde_derive",
 ]
@@ -3887,9 +3816,9 @@ dependencies = [
 
 [[package]]
 name = "serde_derive"
-version = "1.0.204"
+version = "1.0.205"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222"
+checksum = "692d6f5ac90220161d6774db30c662202721e64aed9058d2c394f451261420c1"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -4318,25 +4247,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160"
 
 [[package]]
-name = "system-configuration"
-version = "0.5.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7"
-dependencies = [
- "bitflags 1.3.2",
- "core-foundation",
- "system-configuration-sys",
-]
-
-[[package]]
-name = "system-configuration-sys"
-version = "0.5.0"
+name = "sync_wrapper"
+version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9"
-dependencies = [
- "core-foundation-sys",
- "libc",
-]
+checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394"
 
 [[package]]
 name = "system-deps"
@@ -4345,7 +4259,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a3e535eb8dded36d55ec13eddacd30dec501792ff23a0b1682c38601b8cf2349"
 dependencies = [
  "cfg-expr",
- "heck 0.5.0",
+ "heck",
  "pkg-config",
  "toml 0.8.19",
  "version-compare",
@@ -4379,9 +4293,9 @@ dependencies = [
  "flate2",
  "glob",
  "handlebars",
- "heck 0.5.0",
+ "heck",
  "hex",
- "image 0.25.2",
+ "image",
  "log",
  "md5",
  "native-tls",
@@ -4415,7 +4329,7 @@ version = "1.6.0"
 dependencies = [
  "anyhow",
  "axum",
- "base64 0.21.7",
+ "base64 0.22.1",
  "cc",
  "clap",
  "clap_complete",
@@ -4423,15 +4337,16 @@ dependencies = [
  "common-path",
  "ctrlc",
  "dialoguer",
+ "dunce",
  "env_logger",
  "glob",
  "handlebars",
- "heck 0.5.0",
+ "heck",
  "html5ever",
  "ignore",
- "image 0.24.9",
+ "image",
  "include_dir",
- "itertools 0.11.0",
+ "itertools 0.13.0",
  "json-patch",
  "jsonschema",
  "kuchikiki",
@@ -4454,7 +4369,7 @@ dependencies = [
  "tauri-utils",
  "tokio",
  "toml 0.8.19",
- "toml_edit 0.21.1",
+ "toml_edit 0.22.20",
  "unicode-width",
  "ureq",
  "url",
@@ -4492,7 +4407,7 @@ dependencies = [
  "dunce",
  "getrandom 0.2.15",
  "glob",
- "heck 0.5.0",
+ "heck",
  "html5ever",
  "infer",
  "json-patch",
@@ -4538,15 +4453,6 @@ dependencies = [
  "utf-8",
 ]
 
-[[package]]
-name = "termcolor"
-version = "1.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755"
-dependencies = [
- "winapi-util",
-]
-
 [[package]]
 name = "thin-slice"
 version = "0.1.1"
@@ -4659,9 +4565,9 @@ dependencies = [
 
 [[package]]
 name = "tokio-tungstenite"
-version = "0.20.1"
+version = "0.21.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c"
+checksum = "c83b561d025642014097b66e6c1bb422783339e0909e4429cde4749d1990bc38"
 dependencies = [
  "futures-util",
  "log",
@@ -4669,19 +4575,6 @@ dependencies = [
  "tungstenite",
 ]
 
-[[package]]
-name = "tokio-util"
-version = "0.7.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1"
-dependencies = [
- "bytes",
- "futures-core",
- "futures-sink",
- "pin-project-lite",
- "tokio",
-]
-
 [[package]]
 name = "toml"
 version = "0.7.8"
@@ -4800,17 +4693,11 @@ dependencies = [
  "once_cell",
 ]
 
-[[package]]
-name = "try-lock"
-version = "0.2.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
-
 [[package]]
 name = "tungstenite"
-version = "0.20.1"
+version = "0.21.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9e3dac10fd62eaf6617d3a904ae222845979aec67c615d1c842b4002c7666fb9"
+checksum = "9ef1a641ea34f399a848dea702823bbecfb4c486f911735368f1f137cb8257e1"
 dependencies = [
  "byteorder",
  "bytes",
@@ -4903,9 +4790,9 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
 
 [[package]]
 name = "ureq"
-version = "2.10.0"
+version = "2.10.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "72139d247e5f97a3eff96229a7ae85ead5328a39efe76f8bf5a06313d505b6ea"
+checksum = "b74fc6b57825be3373f7054754755f03ac3a8f5d70015ccad699ba2029956f4a"
 dependencies = [
  "base64 0.22.1",
  "flate2",
@@ -5028,15 +4915,6 @@ dependencies = [
  "winapi-util",
 ]
 
-[[package]]
-name = "want"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e"
-dependencies = [
- "try-lock",
-]
-
 [[package]]
 name = "wasi"
 version = "0.9.0+wasi-snapshot-preview1"
@@ -5074,18 +4952,6 @@ dependencies = [
  "wasm-bindgen-shared",
 ]
 
-[[package]]
-name = "wasm-bindgen-futures"
-version = "0.4.42"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0"
-dependencies = [
- "cfg-if",
- "js-sys",
- "wasm-bindgen",
- "web-sys",
-]
-
 [[package]]
 name = "wasm-bindgen-macro"
 version = "0.2.92"
@@ -5115,16 +4981,6 @@ version = "0.2.92"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96"
 
-[[package]]
-name = "web-sys"
-version = "0.3.69"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef"
-dependencies = [
- "js-sys",
- "wasm-bindgen",
-]
-
 [[package]]
 name = "webpki-roots"
 version = "0.26.3"
@@ -5385,16 +5241,6 @@ dependencies = [
  "memchr",
 ]
 
-[[package]]
-name = "winreg"
-version = "0.50.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1"
-dependencies = [
- "cfg-if",
- "windows-sys 0.48.0",
-]
-
 [[package]]
 name = "x25519-dalek"
 version = "2.0.1"

+ 8 - 7
tooling/cli/Cargo.toml

@@ -50,15 +50,15 @@ serde_json = "1.0"
 notify = "6.1"
 notify-debouncer-mini = "0.4"
 shared_child = "1.0"
-toml_edit = "0.21"
+toml_edit = "0.22"
 json-patch = "2"
 tauri-utils = { version = "1.6.0", path = "../../core/tauri-utils", features = [ "isolation", "schema", "config-json5", "config-toml" ] }
 toml = "0.8"
-jsonschema = "0.17"
+jsonschema = { version = "0.18", default-features = false }
 handlebars = "4.4"
 include_dir = "0.7"
 minisign = "=0.7.3"
-base64 = "0.21.5"
+base64 = "0.22.0"
 ureq = { version = "2.9.1", default-features = false, features = [ "gzip" ] }
 os_info = "3"
 semver = "1.0"
@@ -72,17 +72,18 @@ os_pipe = "1"
 ignore = "0.4"
 ctrlc = "3.4"
 log = { version = "0.4.21", features = [ "kv", "kv_std" ] }
-env_logger = "0.10.0"
+env_logger = "0.11.0"
 icns = { package = "tauri-icns", version = "0.1" }
-image = { version = "0.24", default-features = false, features = [ "ico" ] }
-axum = { version = "0.6.20", features = [ "ws" ] }
+image = { version = "0.25", default-features = false, features = [ "ico" ] }
+axum = { version = "0.7.0", features = [ "ws" ] }
 html5ever = "0.26"
 kuchiki = { package = "kuchikiki", version = "0.8" }
 tokio = { version = "1", features = [ "macros", "sync" ] }
 common-path = "1"
 serde-value = "0.7.0"
-itertools = "0.11"
+itertools = "0.13"
 glob = "0.3"
+dunce = "1"
 
 [target."cfg(windows)".dependencies]
 winapi = { version = "0.3", features = [ "handleapi", "processenv", "winbase", "wincon", "winnt" ] }

+ 4 - 4
tooling/cli/src/helpers/auto-reload.js

@@ -1,18 +1,18 @@
-// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
+// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
 // SPDX-License-Identifier: Apache-2.0
 // SPDX-License-Identifier: MIT
 
 // taken from https://github.com/thedodd/trunk/blob/5c799dc35f1f1d8f8d3d30c8723cbb761a9b6a08/src/autoreload.js
 
 ;(function () {
-  const url = 'ws:' + '//' + window.location.host + '/_tauri-cli/ws'
+  const reload_url = '{{reload_url}}'
+  const url = reload_url ? reload_url : window.location.href
   const poll_interval = 5000
   const reload_upon_connect = () => {
     window.setTimeout(() => {
       // when we successfully reconnect, we'll force a
       // reload (since we presumably lost connection to
-      // trunk due to it being killed, so it will have
-      // rebuilt on restart)
+      // tauri-cli due to it being killed)
       const ws = new WebSocket(url)
       ws.onopen = () => window.location.reload()
       ws.onclose = reload_upon_connect

+ 128 - 141
tooling/cli/src/helpers/web_dev_server.rs

@@ -3,126 +3,82 @@
 // SPDX-License-Identifier: MIT
 
 use axum::{
-  extract::{ws::WebSocket, WebSocketUpgrade},
-  http::{header::CONTENT_TYPE, StatusCode},
-  response::IntoResponse,
-  routing::get,
-  Router, Server,
+  extract::{ws, State, WebSocketUpgrade},
+  http::{header, StatusCode, Uri},
+  response::{IntoResponse, Response},
 };
 use html5ever::{namespace_url, ns, LocalName, QualName};
 use kuchiki::{traits::TendrilSink, NodeRef};
-use notify::RecursiveMode;
-use notify_debouncer_mini::new_debouncer;
 use std::{
   net::{Ipv4Addr, SocketAddr},
   path::{Path, PathBuf},
-  sync::{mpsc::sync_channel, Arc},
   thread,
   time::Duration,
 };
 use tauri_utils::mime_type::MimeType;
 use tokio::sync::broadcast::{channel, Sender};
 
-const AUTO_RELOAD_SCRIPT: &str = include_str!("./auto-reload.js");
+const RELOAD_SCRIPT: &str = include_str!("./auto-reload.js");
 
-struct State {
-  serve_dir: PathBuf,
+#[derive(Clone)]
+struct ServerState {
+  dir: PathBuf,
+  address: SocketAddr,
   tx: Sender<()>,
 }
 
-pub fn start_dev_server<P: AsRef<Path>>(path: P, port: Option<u16>) -> crate::Result<SocketAddr> {
-  let serve_dir = path.as_ref().to_path_buf();
+pub fn start_dev_server<P: AsRef<Path>>(dir: P, port: Option<u16>) -> crate::Result<SocketAddr> {
+  let dir = dir.as_ref();
+  let dir = dunce::canonicalize(dir)?;
+
+  // bind port and tcp listener
+  let auto_port = port.is_none();
+  let mut port = port.unwrap_or(1430);
+  let (tcp_listener, address) = loop {
+    let address = SocketAddr::new(Ipv4Addr::LOCALHOST.into(), port);
+    if let Ok(tcp) = std::net::TcpListener::bind(address) {
+      tcp.set_nonblocking(true)?;
+      break (tcp, address);
+    }
+
+    if !auto_port {
+      anyhow::bail!("Couldn't bind to {port} on localhost");
+    }
+
+    port += 1;
+  };
+
+  let (tx, _) = channel(1);
+
+  // watch dir for changes
+  let tx_c = tx.clone();
+  watch(dir.clone(), move || {
+    let _ = tx_c.send(());
+  });
 
-  let (server_url_tx, server_url_rx) = std::sync::mpsc::channel();
+  let state = ServerState { dir, tx, address };
 
+  // start router thread
   std::thread::spawn(move || {
     tokio::runtime::Builder::new_current_thread()
       .enable_io()
       .build()
-      .unwrap()
+      .expect("failed to start tokio runtime for builtin dev server")
       .block_on(async move {
-        let (tx, _) = channel(1);
-
-        let tokio_tx = tx.clone();
-        let serve_dir_ = serve_dir.clone();
-        thread::spawn(move || {
-          let (tx, rx) = sync_channel(1);
-          let mut watcher = new_debouncer(Duration::from_secs(1), move |r| {
-            if let Ok(events) = r {
-              tx.send(events).unwrap()
-            }
-          })
-          .unwrap();
-
-          watcher
-            .watcher()
-            .watch(&serve_dir_, RecursiveMode::Recursive)
-            .unwrap();
-
-          loop {
-            if rx.recv().is_ok() {
-              let _ = tokio_tx.send(());
-            }
-          }
-        });
-
-        let state = Arc::new(State { serve_dir, tx });
-        let state_ = state.clone();
-        let router = Router::new()
-          .fallback(move |uri| handler(uri, state_))
-          .route(
-            "/_tauri-cli/ws",
-            get(move |ws: WebSocketUpgrade| async move {
-              ws.on_upgrade(|socket| async move { ws_handler(socket, state).await })
-            }),
-          );
-
-        let mut auto_port = false;
-        let mut port = port.unwrap_or_else(|| {
-          std::env::var("TAURI_DEV_SERVER_PORT")
-            .unwrap_or_else(|_| {
-              auto_port = true;
-              "1430".to_string()
-            })
-            .parse()
-            .unwrap()
-        });
-
-        let (server, server_url) = loop {
-          let server_url = SocketAddr::new(Ipv4Addr::new(127, 0, 0, 1).into(), port);
-          let server = Server::try_bind(&server_url);
-
-          if !auto_port {
-            break (server, server_url);
-          }
-
-          if server.is_ok() {
-            break (server, server_url);
-          }
-
-          port += 1;
-        };
-
-        match server {
-          Ok(server) => {
-            server_url_tx.send(Ok(server_url)).unwrap();
-            server.serve(router.into_make_service()).await.unwrap();
-          }
-          Err(e) => {
-            server_url_tx
-              .send(Err(anyhow::anyhow!(
-                "failed to start development server on {server_url}: {e}"
-              )))
-              .unwrap();
-          }
-        }
+        let router = axum::Router::new()
+          .fallback(handler)
+          .route("/__tauri_cli", axum::routing::get(ws_handler))
+          .with_state(state);
+
+        axum::serve(tokio::net::TcpListener::from_std(tcp_listener)?, router).await
       })
+      .expect("builtin server errored");
   });
 
-  server_url_rx.recv().unwrap()
+  Ok(address)
 }
 
-async fn handler(uri: axum::http::Uri, state: Arc<State>) -> impl IntoResponse {
+async fn handler(uri: Uri, state: State<ServerState>) -> impl IntoResponse {
   // Frontend files should not contain query parameters. This seems to be how vite handles it.
   let uri = uri.path();
 
@@ -132,61 +88,92 @@ async fn handler(uri: axum::http::Uri, state: Arc<State>) -> impl IntoResponse {
     uri.strip_prefix('/').unwrap_or(uri)
   };
 
-  let file = std::fs::read(state.serve_dir.join(uri))
-    .or_else(|_| std::fs::read(state.serve_dir.join(format!("{}.html", &uri))))
-    .or_else(|_| std::fs::read(state.serve_dir.join(format!("{}/index.html", &uri))))
-    .or_else(|_| std::fs::read(state.serve_dir.join("index.html")));
+  let bytes = fs_read_scoped(state.dir.join(uri), &state.dir)
+    .or_else(|_| fs_read_scoped(state.dir.join(format!("{}.html", &uri)), &state.dir))
+    .or_else(|_| fs_read_scoped(state.dir.join(format!("{}/index.html", &uri)), &state.dir))
+    .or_else(|_| std::fs::read(state.dir.join("index.html")));
 
-  file
-    .map(|mut f| {
-      let mime_type = MimeType::parse_with_fallback(&f, uri, MimeType::OctetStream);
+  match bytes {
+    Ok(mut bytes) => {
+      let mime_type = MimeType::parse_with_fallback(&bytes, uri, MimeType::OctetStream);
       if mime_type == MimeType::Html.to_string() {
-        let mut document = kuchiki::parse_html().one(String::from_utf8_lossy(&f).into_owned());
-        fn with_html_head<F: FnOnce(&NodeRef)>(document: &mut NodeRef, f: F) {
-          if let Ok(ref node) = document.select_first("head") {
-            f(node.as_node())
-          } else {
-            let node = NodeRef::new_element(
-              QualName::new(None, ns!(html), LocalName::from("head")),
-              None,
-            );
-            f(&node);
-            document.prepend(node)
-          }
-        }
-
-        with_html_head(&mut document, |head| {
-          let script_el =
-            NodeRef::new_element(QualName::new(None, ns!(html), "script".into()), None);
-          script_el.append(NodeRef::new_text(AUTO_RELOAD_SCRIPT));
-          head.prepend(script_el);
-        });
-
-        f = tauri_utils::html::serialize_node(&document);
+        bytes = inject_address(bytes, &state.address);
       }
+      (StatusCode::OK, [(header::CONTENT_TYPE, mime_type)], bytes)
+    }
+    Err(_) => (
+      StatusCode::NOT_FOUND,
+      [(header::CONTENT_TYPE, "text/plain".into())],
+      vec![],
+    ),
+  }
+}
 
-      (StatusCode::OK, [(CONTENT_TYPE, mime_type)], f)
-    })
-    .unwrap_or_else(|_| {
-      (
-        StatusCode::NOT_FOUND,
-        [(CONTENT_TYPE, "text/plain".into())],
-        vec![],
-      )
-    })
+async fn ws_handler(ws: WebSocketUpgrade, state: State<ServerState>) -> Response {
+  ws.on_upgrade(move |mut ws| async move {
+    let mut rx = state.tx.subscribe();
+    while tokio::select! {
+        _ = ws.recv() => return,
+        fs_reload_event = rx.recv() => fs_reload_event.is_ok(),
+    } {
+      let msg = ws::Message::Text(r#"{"reload": true}"#.to_owned());
+      if ws.send(msg).await.is_err() {
+        break;
+      }
+    }
+  })
 }
 
-async fn ws_handler(mut ws: WebSocket, state: Arc<State>) {
-  let mut rx = state.tx.subscribe();
-  while tokio::select! {
-      _ = ws.recv() => return,
-      fs_reload_event = rx.recv() => fs_reload_event.is_ok(),
-  } {
-    let ws_send = ws.send(axum::extract::ws::Message::Text(
-      r#"{"reload": true}"#.to_owned(),
-    ));
-    if ws_send.await.is_err() {
-      break;
+fn inject_address(html_bytes: Vec<u8>, address: &SocketAddr) -> Vec<u8> {
+  fn with_html_head<F: FnOnce(&NodeRef)>(document: &mut NodeRef, f: F) {
+    if let Ok(ref node) = document.select_first("head") {
+      f(node.as_node())
+    } else {
+      let node = NodeRef::new_element(
+        QualName::new(None, ns!(html), LocalName::from("head")),
+        None,
+      );
+      f(&node);
+      document.prepend(node)
     }
   }
+
+  let mut document = kuchiki::parse_html().one(String::from_utf8_lossy(&html_bytes).into_owned());
+  with_html_head(&mut document, |head| {
+    let script = RELOAD_SCRIPT.replace("{{reload_url}}", &format!("ws://{address}/__tauri_cli"));
+    let script_el = NodeRef::new_element(QualName::new(None, ns!(html), "script".into()), None);
+    script_el.append(NodeRef::new_text(script));
+    head.prepend(script_el);
+  });
+
+  tauri_utils::html::serialize_node(&document)
+}
+
+fn fs_read_scoped(path: PathBuf, scope: &Path) -> crate::Result<Vec<u8>> {
+  let path = dunce::canonicalize(path)?;
+  if path.starts_with(scope) {
+    std::fs::read(path).map_err(Into::into)
+  } else {
+    anyhow::bail!("forbidden path")
+  }
+}
+
+fn watch<F: Fn() + Send + 'static>(dir: PathBuf, handler: F) {
+  thread::spawn(move || {
+    let (tx, rx) = std::sync::mpsc::channel();
+
+    let mut watcher = notify_debouncer_mini::new_debouncer(Duration::from_secs(1), tx)
+      .expect("failed to start builtin server fs watcher");
+
+    watcher
+      .watcher()
+      .watch(&dir, notify::RecursiveMode::Recursive)
+      .expect("builtin server failed to watch dir");
+
+    loop {
+      if rx.recv().is_ok() {
+        handler();
+      }
+    }
+  });
 }

+ 9 - 4
tooling/cli/src/icon.rs

@@ -20,7 +20,7 @@ use image::{
     png::{CompressionType, FilterType as PngFilterType, PngEncoder},
   },
   imageops::FilterType,
-  open, ColorType, DynamicImage, ImageEncoder,
+  open, DynamicImage, ExtendedColorType, ImageEncoder,
 };
 use serde::Deserialize;
 
@@ -168,13 +168,18 @@ fn ico(source: &DynamicImage, out_dir: &Path) -> Result<()> {
 
       write_png(image.as_bytes(), &mut buf, size)?;
 
-      frames.push(IcoFrame::with_encoded(buf, size, size, ColorType::Rgba8)?)
+      frames.push(IcoFrame::with_encoded(
+        buf,
+        size,
+        size,
+        ExtendedColorType::Rgba8,
+      )?)
     } else {
       frames.push(IcoFrame::as_png(
         image.as_bytes(),
         size,
         size,
-        ColorType::Rgba8,
+        ExtendedColorType::Rgba8,
       )?);
     }
   }
@@ -212,6 +217,6 @@ fn resize_and_save_png(source: &DynamicImage, size: u32, file_path: &Path) -> Re
 // Encode image data as png with compression.
 fn write_png<W: Write>(image_data: &[u8], w: W, size: u32) -> Result<()> {
   let encoder = PngEncoder::new_with_quality(w, CompressionType::Best, PngFilterType::Adaptive);
-  encoder.write_image(image_data, size, size, ColorType::Rgba8)?;
+  encoder.write_image(image_data, size, size, ExtendedColorType::Rgba8)?;
   Ok(())
 }

+ 10 - 8
tooling/cli/src/interface/rust/manifest.rs

@@ -10,7 +10,7 @@ use crate::helpers::{
 use anyhow::Context;
 use itertools::Itertools;
 use log::info;
-use toml_edit::{Array, Document, InlineTable, Item, TableLike, Value};
+use toml_edit::{Array, DocumentMut, InlineTable, Item, TableLike, Value};
 
 use std::{
   collections::{HashMap, HashSet},
@@ -22,7 +22,7 @@ use std::{
 
 #[derive(Default)]
 pub struct Manifest {
-  pub inner: Document,
+  pub inner: DocumentMut,
   pub tauri_features: HashSet<String>,
 }
 
@@ -84,15 +84,15 @@ fn get_enabled_features(list: &HashMap<String, Vec<String>>, feature: &str) -> V
   f
 }
 
-pub fn read_manifest(manifest_path: &Path) -> crate::Result<Document> {
+pub fn read_manifest(manifest_path: &Path) -> crate::Result<DocumentMut> {
   let mut manifest_str = String::new();
 
   let mut manifest_file = File::open(manifest_path)
     .with_context(|| format!("failed to open `{manifest_path:?}` file"))?;
   manifest_file.read_to_string(&mut manifest_str)?;
 
-  let manifest: Document = manifest_str
-    .parse::<Document>()
+  let manifest: DocumentMut = manifest_str
+    .parse::<DocumentMut>()
     .with_context(|| "failed to parse Cargo.toml")?;
 
   Ok(manifest)
@@ -109,7 +109,7 @@ fn toml_array(features: &HashSet<String>) -> Array {
 }
 
 fn find_dependency<'a>(
-  manifest: &'a mut Document,
+  manifest: &'a mut DocumentMut,
   name: &'a str,
   kind: DependencyKind,
 ) -> Vec<&'a mut Item> {
@@ -231,7 +231,7 @@ fn inject_features_table<D: TableLike, F: Fn(&str) -> bool>(
 }
 
 fn inject_features(
-  manifest: &mut Document,
+  manifest: &mut DocumentMut,
   dependencies: &mut Vec<DependencyAllowlist>,
 ) -> crate::Result<bool> {
   let mut persist = false;
@@ -335,7 +335,9 @@ mod tests {
   use std::collections::{HashMap, HashSet};
 
   fn inject_features(toml: &str, mut dependencies: Vec<DependencyAllowlist>) {
-    let mut manifest = toml.parse::<toml_edit::Document>().expect("invalid toml");
+    let mut manifest = toml
+      .parse::<toml_edit::DocumentMut>()
+      .expect("invalid toml");
 
     let mut expected = HashMap::new();
     for dep in &dependencies {

+ 8 - 12
tooling/cli/src/lib.rs

@@ -16,7 +16,7 @@ mod plugin;
 mod signer;
 
 use clap::{ArgAction, CommandFactory, FromArgMatches, Parser, Subcommand};
-use env_logger::fmt::Color;
+use env_logger::fmt::style::{AnsiColor, Style};
 use env_logger::Builder;
 use log::{debug, log_enabled, Level};
 use serde::Deserialize;
@@ -132,27 +132,23 @@ where
         let action = action.to_cow_str().unwrap();
         is_command_output = action == "stdout" || action == "stderr";
         if !is_command_output {
-          let mut action_style = f.style();
-          action_style.set_color(Color::Green).set_bold(true);
+          let style = Style::new().fg_color(Some(AnsiColor::Green.into())).bold();
 
-          write!(f, "{:>12} ", action_style.value(action))?;
+          write!(f, "    {style}{}{style:#} ", action)?;
         }
       } else {
-        let mut level_style = f.default_level_style(record.level());
-        level_style.set_bold(true);
-
+        let style = f.default_level_style(record.level()).bold();
         write!(
           f,
-          "{:>12} ",
-          level_style.value(prettyprint_level(record.level()))
+          "    {style}{}{style:#} ",
+          prettyprint_level(record.level())
         )?;
       }
 
       if !is_command_output && log_enabled!(Level::Debug) {
-        let mut target_style = f.style();
-        target_style.set_color(Color::Black);
+        let style = Style::new().fg_color(Some(AnsiColor::Black.into()));
 
-        write!(f, "[{}] ", target_style.value(record.target()))?;
+        write!(f, "[{style}{}{style:#}] ", record.target())?;
       }
 
       writeln!(f, "{}", record.args())