Parcourir la source

Merge branch '1.x' into dev

Lucas Nogueira il y a 1 an
Parent
commit
a9b87c057d
50 fichiers modifiés avec 697 ajouts et 303 suppressions
  1. 5 0
      .changes/api-module-resolution-node.md
  2. 5 0
      .changes/arboard.md
  3. 5 0
      .changes/config-f64-deserialize.md
  4. 5 0
      .changes/dialog-window-forward-slash.md
  5. 0 5
      .changes/nsis-german.md
  6. 2 2
      .github/workflows/test-cli-rs.yml
  7. 6 0
      core/tauri-macros/CHANGELOG.md
  8. 2 1
      core/tauri-macros/Cargo.toml
  9. 50 0
      core/tauri-macros/src/command/wrapper.rs
  10. 6 0
      core/tauri-runtime-wry/CHANGELOG.md
  11. 2 0
      core/tauri-runtime-wry/Cargo.toml
  12. 107 11
      core/tauri-runtime-wry/src/lib.rs
  13. 6 0
      core/tauri-utils/CHANGELOG.md
  14. 7 0
      core/tauri-utils/src/assets.rs
  15. 1 1
      core/tauri-utils/src/config.rs
  16. 17 0
      core/tauri/CHANGELOG.md
  17. 6 0
      core/tauri/Cargo.toml
  18. 19 15
      core/tauri/src/app.rs
  19. 4 0
      core/tauri/src/command.rs
  20. 2 0
      core/tauri/src/event/mod.rs
  21. 13 0
      core/tauri/src/lib.rs
  22. 1 1
      core/tauri/src/manager/mod.rs
  23. 45 21
      core/tauri/src/plugin.rs
  24. 9 1
      core/tauri/src/test/mod.rs
  25. 10 0
      core/tauri/src/window/mod.rs
  26. 0 0
      examples/api/dist/assets/index.css
  27. 0 0
      examples/api/dist/assets/index.js
  28. 22 67
      examples/api/src-tauri/Cargo.lock
  29. 6 3
      renovate.json
  30. 28 2
      tooling/api/CHANGELOG.md
  31. 9 6
      tooling/api/src/mocks.ts
  32. 7 0
      tooling/api/yarn.lock
  33. 22 0
      tooling/bundler/CHANGELOG.md
  34. 1 1
      tooling/bundler/Cargo.toml
  35. 14 8
      tooling/bundler/src/bundle/common.rs
  36. 4 32
      tooling/bundler/src/bundle/windows/msi/wix.rs
  37. 48 38
      tooling/bundler/src/bundle/windows/nsis.rs
  38. 23 16
      tooling/bundler/src/bundle/windows/templates/installer.nsi
  39. 51 3
      tooling/bundler/src/bundle/windows/util.rs
  40. 28 0
      tooling/cli/CHANGELOG.md
  41. 30 52
      tooling/cli/Cargo.lock
  42. 1 1
      tooling/cli/Cargo.toml
  43. 2 2
      tooling/cli/metadata.json
  44. 28 0
      tooling/cli/node/CHANGELOG.md
  45. 3 3
      tooling/cli/node/Cargo.toml
  46. 1 1
      tooling/cli/node/test/jest/fixtures/app/src-tauri/Cargo.toml
  47. 1 1
      tooling/cli/src/build.rs
  48. 3 1
      tooling/cli/src/dev.rs
  49. 16 0
      tooling/cli/src/helpers/updater_signature.rs
  50. 14 8
      tooling/cli/src/lib.rs

+ 5 - 0
.changes/api-module-resolution-node.md

@@ -0,0 +1,5 @@
+---
+"@tauri-apps/api": "patch:bug"
+---
+
+Fix a regression where typescript could not find types when using `"moduleResolution": "node"` 

+ 5 - 0
.changes/arboard.md

@@ -0,0 +1,5 @@
+---
+"tauri-runtime-wry": patch:bug
+---
+
+Use `arboard` instead of `tao` clipboard implementation to prevent a crash.

+ 5 - 0
.changes/config-f64-deserialize.md

@@ -0,0 +1,5 @@
+---
+'tauri-utils': 'patch:bug'
+---
+
+Fix compile error when parsing config that includes float values.

+ 5 - 0
.changes/dialog-window-forward-slash.md

@@ -0,0 +1,5 @@
+---
+'tauri': 'patch:bug'
+---
+
+On Windows, fix `open` dialog `defaultPath`, when invoked from JS, not working if the path uses forward slash (`/`)

+ 0 - 5
.changes/nsis-german.md

@@ -1,5 +0,0 @@
----
-'tauri-bundler': 'patch:enhance'
----
-
-Added German language support to the NSIS bundler.

+ 2 - 2
.github/workflows/test-cli-rs.yml

@@ -66,5 +66,5 @@ jobs:
         with:
           workspaces: tooling/cli
 
-      - name: build CLI
-        run: cargo build --manifest-path ./tooling/cli/Cargo.toml ${{ matrix.platform.args }}
+      - name: test CLI
+        run: cargo test --manifest-path ./tooling/cli/Cargo.toml ${{ matrix.platform.args }}

+ 6 - 0
core/tauri-macros/CHANGELOG.md

@@ -112,6 +112,12 @@
 - First mobile alpha release!
   - [fa3a1098](https://www.github.com/tauri-apps/tauri/commit/fa3a10988a03aed1b66fb17d893b1a9adb90f7cd) feat(ci): prepare 2.0.0-alpha.0 ([#5786](https://www.github.com/tauri-apps/tauri/pull/5786)) on 2022-12-08
 
+## \[1.4.2]
+
+### Enhancements
+
+- [`5e05236b`](https://www.github.com/tauri-apps/tauri/commit/5e05236b4987346697c7caae0567d3c50714c198)([#8289](https://www.github.com/tauri-apps/tauri/pull/8289)) Added tracing for window startup, plugins, `Window::eval`, events, IPC, updater and custom protocol request handlers behind the `tracing` feature flag.
+
 ## \[1.4.1]
 
 ### Dependencies

+ 2 - 1
core/tauri-macros/Cargo.toml

@@ -16,7 +16,7 @@ rust-version = { workspace = true }
 proc-macro = true
 
 [dependencies]
-proc-macro2 = "1"
+proc-macro2 = { version = "1", features = [ "span-locations" ] }
 quote = "1"
 syn = { version = "2", features = [ "full" ] }
 heck = "0.4"
@@ -29,3 +29,4 @@ compression = [ "tauri-codegen/compression" ]
 isolation = [ "tauri-codegen/isolation" ]
 config-json5 = [ "tauri-codegen/config-json5", "tauri-utils/config-json5" ]
 config-toml = [ "tauri-codegen/config-toml", "tauri-utils/config-toml" ]
+tracing = [ ]

+ 50 - 0
core/tauri-macros/src/command/wrapper.rs

@@ -214,6 +214,32 @@ pub fn wrapper(attributes: TokenStream, item: TokenStream) -> TokenStream {
 
   let root = attrs.root;
 
+  let kind = match attrs.execution_context {
+    ExecutionContext::Async if function.sig.asyncness.is_none() => "sync_threadpool",
+    ExecutionContext::Async => "async",
+    ExecutionContext::Blocking => "sync",
+  };
+
+  let loc = function.span().start();
+  let line = loc.line;
+  let col = loc.column;
+
+  let maybe_span = if cfg!(feature = "tracing") {
+    quote!({
+      let _span = tracing::debug_span!(
+        "ipc::request::handler",
+        cmd = #message.command(),
+        kind = #kind,
+        loc.line = #line,
+        loc.col = #col,
+        is_internal = false,
+      )
+      .entered();
+    })
+  } else {
+    quote!()
+  };
+
   // Rely on rust 2018 edition to allow importing a macro from a path.
   quote!(
     #async_command_check
@@ -231,6 +257,8 @@ pub fn wrapper(attributes: TokenStream, item: TokenStream) -> TokenStream {
           #[allow(unused_variables)]
           let #root::ipc::Invoke { message: #message, resolver: #resolver } = $invoke;
 
+          #maybe_span
+
           #body
       }};
     }
@@ -254,6 +282,21 @@ fn body_async(
 ) -> syn::Result<TokenStream2> {
   let Invoke { message, resolver } = invoke;
   parse_args(function, message, attributes).map(|args| {
+    #[cfg(feature = "tracing")]
+    quote! {
+      use tracing::Instrument;
+
+      let span = tracing::debug_span!("ipc::request::run");
+      #resolver.respond_async_serialized(async move {
+        let result = $path(#(#args?),*);
+        let kind = (&result).async_kind();
+        kind.future(result).await
+      }
+      .instrument(span));
+      return true;
+    }
+
+    #[cfg(not(feature = "tracing"))]
     quote! {
       #resolver.respond_async_serialized(async move {
         let result = $path(#(#args?),*);
@@ -284,7 +327,14 @@ fn body_blocking(
     Err(err) => { #resolver.invoke_error(err); return true },
   });
 
+  let maybe_span = if cfg!(feature = "tracing") {
+    quote!(let _span = tracing::debug_span!("ipc::request::run").entered();)
+  } else {
+    quote!()
+  };
+
   Ok(quote! {
+    #maybe_span
     let result = $path(#(match #args #match_body),*);
     let kind = (&result).blocking_kind();
     kind.block(result, #resolver);

+ 6 - 0
core/tauri-runtime-wry/CHANGELOG.md

@@ -160,6 +160,12 @@
 - Support `with_webview` for Android platform alowing execution of JNI code in context.
   - [8ea87e9c](https://www.github.com/tauri-apps/tauri/commit/8ea87e9c9ca8ba4c7017c8281f78aacd08f45785) feat(android): with_webview access for jni execution ([#5148](https://www.github.com/tauri-apps/tauri/pull/5148)) on 2022-09-08
 
+## \[0.14.2]
+
+### Enhancements
+
+- [`5e05236b`](https://www.github.com/tauri-apps/tauri/commit/5e05236b4987346697c7caae0567d3c50714c198)([#8289](https://www.github.com/tauri-apps/tauri/pull/8289)) Added tracing for window startup, plugins, `Window::eval`, events, IPC, updater and custom protocol request handlers behind the `tracing` feature flag.
+
 ## \[0.14.1]
 
 ### Enhancements

+ 2 - 0
core/tauri-runtime-wry/Cargo.toml

@@ -19,6 +19,7 @@ tauri-runtime = { version = "1.0.0-alpha.7", path = "../tauri-runtime" }
 tauri-utils = { version = "2.0.0-alpha.12", path = "../tauri-utils" }
 raw-window-handle = "0.5"
 http = "0.2"
+tracing = { version = "0.1", optional = true }
 
 [target."cfg(windows)".dependencies]
 webview2-com = "0.28"
@@ -47,3 +48,4 @@ macos-private-api = [
 ]
 objc-exception = [ "wry/objc-exception" ]
 linux-protocol-body = [ "wry/linux-body", "webkit2gtk/v2_40" ]
+tracing = [ "dep:tracing" ]

+ 107 - 11
core/tauri-runtime-wry/src/lib.rs

@@ -239,21 +239,39 @@ impl<T: UserEvent> Context<T> {
   }
 }
 
-#[derive(Clone)]
+#[cfg(feature = "tracing")]
+#[derive(Debug, Clone, Default)]
+pub struct ActiveTraceSpanStore(Rc<RefCell<Vec<ActiveTracingSpan>>>);
+
+#[cfg(feature = "tracing")]
+impl ActiveTraceSpanStore {
+  pub fn remove_window_draw(&self, window_id: WindowId) {
+    let mut store = self.0.borrow_mut();
+    if let Some(index) = store
+      .iter()
+      .position(|t| matches!(t, ActiveTracingSpan::WindowDraw { id, span: _ } if id == &window_id))
+    {
+      store.remove(index);
+    }
+  }
+}
+
+#[cfg(feature = "tracing")]
+#[derive(Debug)]
+pub enum ActiveTracingSpan {
+  WindowDraw {
+    id: WindowId,
+    span: tracing::span::EnteredSpan,
+  },
+}
+
+#[derive(Debug, Clone)]
 pub struct DispatcherMainThreadContext<T: UserEvent> {
   pub window_target: EventLoopWindowTarget<Message<T>>,
   pub web_context: WebContextStore,
   pub windows: Rc<RefCell<HashMap<WebviewId, WindowWrapper>>>,
-}
-
-impl<T: UserEvent> std::fmt::Debug for DispatcherMainThreadContext<T> {
-  fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-    f.debug_struct("DispatcherMainThreadContext")
-      .field("window_target", &self.window_target)
-      .field("web_context", &self.web_context)
-      .field("windows", &self.windows)
-      .finish()
-  }
+  #[cfg(feature = "tracing")]
+  pub active_tracing_spans: ActiveTraceSpanStore,
 }
 
 // SAFETY: we ensure this type is only used on the main thread.
@@ -1051,7 +1069,10 @@ pub enum WindowMessage {
 
 #[derive(Debug, Clone)]
 pub enum WebviewMessage {
+  #[cfg(not(feature = "tracing"))]
   EvaluateScript(String),
+  #[cfg(feature = "tracing")]
+  EvaluateScript(String, Sender<()>, tracing::Span),
   #[allow(dead_code)]
   WebviewEvent(WebviewEvent),
   Print,
@@ -1560,6 +1581,21 @@ impl<T: UserEvent> Dispatch<T> for WryDispatcher<T> {
     )
   }
 
+  #[cfg(feature = "tracing")]
+  fn eval_script<S: Into<String>>(&self, script: S) -> Result<()> {
+    // use a channel so the EvaluateScript task uses the current span as parent
+    let (tx, rx) = channel();
+    getter!(
+      self,
+      rx,
+      Message::Webview(
+        self.window_id,
+        WebviewMessage::EvaluateScript(script.into(), tx, tracing::Span::current()),
+      )
+    )
+  }
+
+  #[cfg(not(feature = "tracing"))]
   fn eval_script<S: Into<String>>(&self, script: S) -> Result<()> {
     send_user_message(
       &self.context,
@@ -1867,6 +1903,8 @@ impl<T: UserEvent> Wry<T> {
         window_target: event_loop.deref().clone(),
         web_context,
         windows,
+        #[cfg(feature = "tracing")]
+        active_tracing_spans: Default::default(),
       },
       plugins: Default::default(),
       next_window_id: Default::default(),
@@ -2009,6 +2047,9 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
     let web_context = &self.context.main_thread.web_context;
     let plugins = self.context.plugins.clone();
 
+    #[cfg(feature = "tracing")]
+    let active_tracing_spans = self.context.main_thread.active_tracing_spans.clone();
+
     let mut iteration = RunIteration::default();
 
     let proxy = self.event_loop.create_proxy();
@@ -2031,6 +2072,8 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
               callback: &mut callback,
               webview_id_map: webview_id_map.clone(),
               windows: windows.clone(),
+              #[cfg(feature = "tracing")]
+              active_tracing_spans: active_tracing_spans.clone(),
             },
             web_context,
           );
@@ -2047,6 +2090,8 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
             callback: &mut callback,
             windows: windows.clone(),
             webview_id_map: webview_id_map.clone(),
+            #[cfg(feature = "tracing")]
+            active_tracing_spans: active_tracing_spans.clone(),
           },
           web_context,
         );
@@ -2061,6 +2106,8 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
     let web_context = self.context.main_thread.web_context;
     let plugins = self.context.plugins.clone();
 
+    #[cfg(feature = "tracing")]
+    let active_tracing_spans = self.context.main_thread.active_tracing_spans.clone();
     let proxy = self.event_loop.create_proxy();
 
     self.event_loop.run(move |event, event_loop, control_flow| {
@@ -2074,6 +2121,8 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
             callback: &mut callback,
             webview_id_map: webview_id_map.clone(),
             windows: windows.clone(),
+            #[cfg(feature = "tracing")]
+            active_tracing_spans: active_tracing_spans.clone(),
           },
           &web_context,
         );
@@ -2089,6 +2138,8 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
           callback: &mut callback,
           webview_id_map: webview_id_map.clone(),
           windows: windows.clone(),
+          #[cfg(feature = "tracing")]
+          active_tracing_spans: active_tracing_spans.clone(),
         },
         &web_context,
       );
@@ -2100,6 +2151,8 @@ pub struct EventLoopIterationContext<'a, T: UserEvent> {
   pub callback: &'a mut (dyn FnMut(RunEvent<T>) + 'static),
   pub webview_id_map: WebviewIdStore,
   pub windows: Rc<RefCell<HashMap<WebviewId, WindowWrapper>>>,
+  #[cfg(feature = "tracing")]
+  pub active_tracing_spans: ActiveTraceSpanStore,
 }
 
 struct UserMessageContext {
@@ -2374,6 +2427,19 @@ fn handle_user_message<T: UserEvent>(
       }
     }
     Message::Webview(id, webview_message) => match webview_message {
+      #[cfg(feature = "tracing")]
+      WebviewMessage::EvaluateScript(script, tx, span) => {
+        let _span = span.entered();
+        if let Some(WindowHandle::Webview { inner: webview, .. }) =
+          windows.borrow().get(&id).and_then(|w| w.inner.as_ref())
+        {
+          if let Err(e) = webview.evaluate_script(&script) {
+            debug_eprintln!("{}", e);
+          }
+        }
+        tx.send(()).unwrap();
+      }
+      #[cfg(not(feature = "tracing"))]
       WebviewMessage::EvaluateScript(script) => {
         if let Some(WindowHandle::Webview { inner: webview, .. }) =
           windows.borrow().get(&id).and_then(|w| w.inner.as_ref())
@@ -2441,6 +2507,8 @@ fn handle_event_loop<T: UserEvent>(
     callback,
     webview_id_map,
     windows,
+    #[cfg(feature = "tracing")]
+    active_tracing_spans,
   } = context;
   if *control_flow != ControlFlow::Exit {
     *control_flow = ControlFlow::Wait;
@@ -2463,6 +2531,11 @@ fn handle_event_loop<T: UserEvent>(
       callback(RunEvent::Exit);
     }
 
+    #[cfg(feature = "tracing")]
+    Event::RedrawRequested(id) => {
+      active_tracing_spans.remove_window_draw(id);
+    }
+
     Event::UserEvent(Message::Webview(id, WebviewMessage::WebviewEvent(event))) => {
       if let Some(event) = WindowEventWrapper::from(&event).0 {
         let windows = windows.borrow();
@@ -2650,6 +2723,14 @@ fn create_webview<T: UserEvent, F: Fn(RawWindow) + Send + 'static>(
     ..
   } = pending;
 
+  #[cfg(feature = "tracing")]
+  let _webview_create_span = tracing::debug_span!("wry::webview::create").entered();
+  #[cfg(feature = "tracing")]
+  let window_draw_span = tracing::debug_span!("wry::window::draw").entered();
+  #[cfg(feature = "tracing")]
+  let window_create_span =
+    tracing::debug_span!(parent: &window_draw_span, "wry::window::create").entered();
+
   let window_event_listeners = WindowEventListeners::default();
 
   #[cfg(windows)]
@@ -2678,6 +2759,21 @@ fn create_webview<T: UserEvent, F: Fn(RawWindow) + Send + 'static>(
   let focused = window_builder.inner.window.focused;
   let window = window_builder.inner.build(event_loop).unwrap();
 
+  #[cfg(feature = "tracing")]
+  {
+    drop(window_create_span);
+
+    context
+      .main_thread
+      .active_tracing_spans
+      .0
+      .borrow_mut()
+      .push(ActiveTracingSpan::WindowDraw {
+        id: window.id(),
+        span: window_draw_span,
+      });
+  }
+
   context.webview_id_map.insert(window.id(), window_id);
 
   if window_builder.center {

+ 6 - 0
core/tauri-utils/CHANGELOG.md

@@ -112,6 +112,12 @@
 - First mobile alpha release!
   - [fa3a1098](https://www.github.com/tauri-apps/tauri/commit/fa3a10988a03aed1b66fb17d893b1a9adb90f7cd) feat(ci): prepare 2.0.0-alpha.0 ([#5786](https://www.github.com/tauri-apps/tauri/pull/5786)) on 2022-12-08
 
+## \[1.5.3]
+
+### New Features
+
+- [`b3e53e72`](https://www.github.com/tauri-apps/tauri/commit/b3e53e7243311a2659b7569dddc20c56ac9f9d8e)([#8288](https://www.github.com/tauri-apps/tauri/pull/8288)) Added `Assets::iter` to iterate on all embedded assets.
+
 ## \[1.5.0]
 
 ### New Features

+ 7 - 0
core/tauri-utils/src/assets.rs

@@ -109,6 +109,9 @@ pub trait Assets: Send + Sync + 'static {
   /// Get the content of the passed [`AssetKey`].
   fn get(&self, key: &AssetKey) -> Option<Cow<'_, [u8]>>;
 
+  /// Iterator for the assets.
+  fn iter(&self) -> Box<dyn Iterator<Item = (&&str, &&[u8])> + '_>;
+
   /// Gets the hashes for the CSP tag of the HTML on the given path.
   fn csp_hashes(&self, html_path: &AssetKey) -> Box<dyn Iterator<Item = CspHash<'_>> + '_>;
 }
@@ -163,6 +166,10 @@ impl Assets for EmbeddedAssets {
       .map(|a| Cow::Owned(a.to_vec()))
   }
 
+  fn iter(&self) -> Box<dyn Iterator<Item = (&&str, &&[u8])> + '_> {
+    Box::new(self.assets.into_iter())
+  }
+
   fn csp_hashes(&self, html_path: &AssetKey) -> Box<dyn Iterator<Item = CspHash<'_>> + '_> {
     Box::new(
       self

+ 1 - 1
core/tauri-utils/src/config.rs

@@ -2200,7 +2200,7 @@ mod build {
     } else if num.is_f64() {
       // guaranteed f64
       let num = num.as_f64().unwrap();
-      quote! { #prefix::Number(#num.into()) }
+      quote! { #prefix::Number(::serde_json::Number::from_f64(#num).unwrap(/* safe to unwrap, guaranteed f64 */)) }
     } else {
       // invalid number
       quote! { #prefix::Null }

+ 17 - 0
core/tauri/CHANGELOG.md

@@ -419,6 +419,23 @@
 - Export types required by the `mobile_entry_point` macro.
   - [98904863](https://www.github.com/tauri-apps/tauri/commit/9890486321c9c79ccfb7c547fafee85b5c3ffa71) feat(core): add `mobile_entry_point` macro ([#4983](https://www.github.com/tauri-apps/tauri/pull/4983)) on 2022-08-21
 
+## \[1.5.3]
+
+### Enhancements
+
+- [`b3e53e72`](https://www.github.com/tauri-apps/tauri/commit/b3e53e7243311a2659b7569dddc20c56ac9f9d8e)([#8288](https://www.github.com/tauri-apps/tauri/pull/8288)) Added `AssetResolver::iter` to iterate on all embedded assets.
+- [`5e05236b`](https://www.github.com/tauri-apps/tauri/commit/5e05236b4987346697c7caae0567d3c50714c198)([#8289](https://www.github.com/tauri-apps/tauri/pull/8289)) Added tracing for window startup, plugins, `Window::eval`, events, IPC, updater and custom protocol request handlers behind the `tracing` feature flag.
+
+### Bug Fixes
+
+- [`2ba88563`](https://www.github.com/tauri-apps/tauri/commit/2ba8856343e284ed022f28cff6d16db15ad4645f)([#8095](https://www.github.com/tauri-apps/tauri/pull/8095)) Fix docs.rs build for `x86_64-apple-darwin`.
+- [`4b6a602a`](https://www.github.com/tauri-apps/tauri/commit/4b6a602a89b36f24d34d6ccd8e3c9b7ce202c9eb)([#8234](https://www.github.com/tauri-apps/tauri/pull/8234)) Escape path of the updater msi to avoid crashing on installers with spaces.
+
+### Dependencies
+
+- Upgraded to `tauri-runtime-wry@0.14.2`
+- Upgraded to `tauri-macros@1.4.2`
+
 ## \[1.5.2]
 
 ### Bug Fixes

+ 6 - 0
core/tauri/Cargo.toml

@@ -70,6 +70,7 @@ infer = { version = "0.15", optional = true }
 png = { version = "0.17", optional = true }
 ico = { version = "0.3.0", optional = true }
 http-range = { version = "0.1.5", optional = true }
+tracing = { version = "0.1", optional = true }
 
 [target."cfg(any(target_os = \"linux\", target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"openbsd\", target_os = \"netbsd\", target_os = \"windows\", target_os = \"macos\"))".dependencies]
 muda = { version = "0.11", default-features = false, features = [ "serde" ] }
@@ -130,6 +131,11 @@ default = [
   "muda/common-controls-v6"
 ]
 tray-icon = [ "dep:tray-icon" ]
+tracing = [
+  "dep:tracing",
+  "tauri-macros/tracing",
+  "tauri-runtime-wry/tracing"
+]
 test = [ ]
 compression = [ "tauri-macros/compression", "tauri-utils/compression" ]
 wry = [ "tauri-runtime-wry" ]

+ 19 - 15
core/tauri/src/app.rs

@@ -250,6 +250,11 @@ impl<R: Runtime> AssetResolver<R> {
   pub fn get(&self, path: String) -> Option<Asset> {
     self.manager.get_asset(path).ok()
   }
+
+  /// Iterate on all assets.
+  pub fn iter(&self) -> Box<dyn Iterator<Item = (&&str, &&[u8])> + '_> {
+    self.manager.assets.iter()
+  }
 }
 
 /// A handle to the currently running application.
@@ -341,20 +346,14 @@ impl<R: Runtime> AppHandle<R> {
   ///     Ok(())
   ///   });
   /// ```
-  pub fn plugin<P: Plugin<R> + 'static>(&self, mut plugin: P) -> crate::Result<()> {
-    plugin
-      .initialize(
-        self,
-        self
-          .config()
-          .plugins
-          .0
-          .get(plugin.name())
-          .cloned()
-          .unwrap_or_default(),
-      )
-      .map_err(|e| crate::Error::PluginInitialization(plugin.name().to_string(), e.to_string()))?;
-    self.manager().plugins.lock().unwrap().register(plugin);
+  #[cfg_attr(feature = "tracing", tracing::instrument(name = "app::plugin::register", skip(plugin), fields(name = plugin.name())))]
+  pub fn plugin<P: Plugin<R> + 'static>(&self, plugin: P) -> crate::Result<()> {
+    let mut plugin = Box::new(plugin) as Box<dyn Plugin<R>>;
+
+    let mut store = self.manager().plugins.lock().unwrap();
+    store.initialize(&mut plugin, self, &self.config().plugins)?;
+    store.register(plugin);
+
     Ok(())
   }
 
@@ -922,6 +921,7 @@ impl<R: Runtime> App<R> {
   /// }
   /// ```
   #[cfg(desktop)]
+  #[cfg_attr(feature = "tracing", tracing::instrument(name = "app::run_iteration"))]
   pub fn run_iteration(&mut self) -> crate::runtime::RunIteration {
     let manager = self.manager.clone();
     let app_handle = self.handle().clone();
@@ -1161,7 +1161,7 @@ impl<R: Runtime> Builder<R> {
   /// ```
   #[must_use]
   pub fn plugin<P: Plugin<R> + 'static>(mut self, plugin: P) -> Self {
-    self.plugins.register(plugin);
+    self.plugins.register(Box::new(plugin));
     self
   }
 
@@ -1447,6 +1447,10 @@ impl<R: Runtime> Builder<R> {
 
   /// Builds the application.
   #[allow(clippy::type_complexity)]
+  #[cfg_attr(
+    feature = "tracing",
+    tracing::instrument(name = "app::build", skip_all)
+  )]
   pub fn build<A: Assets>(mut self, context: Context<A>) -> crate::Result<App<R>> {
     #[cfg(target_os = "macos")]
     if self.menu.is_none() && self.enable_macos_default_menu {

+ 4 - 0
core/tauri/src/command.rs

@@ -55,6 +55,8 @@ impl<'de, D: Deserialize<'de>, R: Runtime> CommandArg<'de, R> for D {
   fn from_command(command: CommandItem<'de, R>) -> Result<D, InvokeError> {
     let name = command.name;
     let arg = command.key;
+    #[cfg(feature = "tracing")]
+    let _span = tracing::trace_span!("ipc::request::deserialize_arg", arg = arg).entered();
     Self::deserialize(command).map_err(|e| crate::Error::InvalidArgs(name, arg, e).into())
   }
 }
@@ -178,6 +180,8 @@ pub mod private {
   };
   use futures_util::{FutureExt, TryFutureExt};
   use std::future::Future;
+  #[cfg(feature = "tracing")]
+  pub use tracing;
 
   // ===== impl IpcResponse =====
 

+ 2 - 0
core/tauri/src/event/mod.rs

@@ -43,6 +43,8 @@ impl EmitArgs {
     source_window_label: Option<&str>,
     payload: S,
   ) -> crate::Result<Self> {
+    #[cfg(feature = "tracing")]
+    let _span = tracing::debug_span!("window::emit::serialize").entered();
     Ok(EmitArgs {
       event_name: event.into(),
       event: serde_json::to_string(event)?,

+ 13 - 0
core/tauri/src/lib.rs

@@ -13,6 +13,7 @@
 //! The following are a list of [Cargo features](https://doc.rust-lang.org/stable/cargo/reference/manifest.html#the-features-section) that can be enabled or disabled:
 //!
 //! - **wry** *(enabled by default)*: Enables the [wry](https://github.com/tauri-apps/wry) runtime. Only disable it if you want a custom runtime.
+//! - **tracing**: Enables [`tracing`](https://docs.rs/tracing/latest/tracing) for window startup, plugins, `Window::eval`, events, IPC, updater and custom protocol request handlers.
 //! - **test**: Enables the [`test`] module exposing unit test helpers.
 //! - **objc-exception**: Wrap each msg_send! in a @try/@catch and panics if an exception is caught, preventing Objective-C from unwinding into Rust.
 //! - **linux-ipc-protocol**: Use custom protocol for faster IPC on Linux. Requires webkit2gtk v2.40 or above.
@@ -642,6 +643,10 @@ pub trait Manager<R: Runtime>: sealed::ManagerBase<R> {
   ///   app.emit("synchronized", ());
   /// }
   /// ```
+  #[cfg_attr(
+    feature = "tracing",
+    tracing::instrument("app::emit", skip(self, payload))
+  )]
   fn emit<S: Serialize + Clone>(&self, event: &str, payload: S) -> Result<()> {
     self.manager().emit(event, None, payload)
   }
@@ -663,6 +668,10 @@ pub trait Manager<R: Runtime>: sealed::ManagerBase<R> {
   ///   }
   /// }
   /// ```
+  #[cfg_attr(
+    feature = "tracing",
+    tracing::instrument("app::emit::to", skip(self, payload))
+  )]
   fn emit_to<S: Serialize + Clone>(&self, label: &str, event: &str, payload: S) -> Result<()> {
     self
       .manager()
@@ -686,6 +695,10 @@ pub trait Manager<R: Runtime>: sealed::ManagerBase<R> {
   ///   }
   /// }
   /// ```
+  #[cfg_attr(
+    feature = "tracing",
+    tracing::instrument("app::emit::filter", skip(self, payload, filter))
+  )]
   fn emit_filter<S, F>(&self, event: &str, payload: S, filter: F) -> Result<()>
   where
     S: Serialize + Clone,

+ 1 - 1
core/tauri/src/manager/mod.rs

@@ -430,7 +430,7 @@ impl<R: Runtime> AppManager<R> {
       .plugins
       .lock()
       .expect("poisoned plugin store")
-      .initialize(app, &self.config.plugins)
+      .initialize_all(app, &self.config.plugins)
   }
 
   pub fn config(&self) -> &Config {

+ 45 - 21
core/tauri/src/plugin.rs

@@ -6,12 +6,11 @@
 
 use crate::{
   app::UriSchemeResponder,
-  error::Error,
   ipc::{Invoke, InvokeHandler},
   manager::window::UriSchemeProtocol,
   utils::config::PluginConfig,
   window::PageLoadPayload,
-  AppHandle, RunEvent, Runtime, Window,
+  AppHandle, Error, RunEvent, Runtime, Window,
 };
 use serde::de::DeserializeOwned;
 use serde_json::Value as JsonValue;
@@ -692,11 +691,11 @@ impl<R: Runtime> PluginStore<R> {
   /// Adds a plugin to the store.
   ///
   /// Returns `true` if a plugin with the same name is already in the store.
-  pub fn register<P: Plugin<R> + 'static>(&mut self, plugin: P) -> bool {
+  pub fn register(&mut self, plugin: Box<dyn Plugin<R>>) -> bool {
     let len = self.store.len();
     self.store.retain(|p| p.name() != plugin.name());
     let result = len != self.store.len();
-    self.store.push(Box::new(plugin));
+    self.store.push(plugin);
     result
   }
 
@@ -707,20 +706,26 @@ impl<R: Runtime> PluginStore<R> {
     len != self.store.len()
   }
 
-  /// Initializes all plugins in the store.
+  /// Initializes the given plugin.
   pub(crate) fn initialize(
+    &self,
+    plugin: &mut Box<dyn Plugin<R>>,
+    app: &AppHandle<R>,
+    config: &PluginConfig,
+  ) -> crate::Result<()> {
+    initialize(plugin, app, config)
+  }
+
+  /// Initializes all plugins in the store.
+  pub(crate) fn initialize_all(
     &mut self,
     app: &AppHandle<R>,
     config: &PluginConfig,
   ) -> crate::Result<()> {
-    self.store.iter_mut().try_for_each(|plugin| {
-      plugin
-        .initialize(
-          app,
-          config.0.get(plugin.name()).cloned().unwrap_or_default(),
-        )
-        .map_err(|e| Error::PluginInitialization(plugin.name().to_string(), e.to_string()))
-    })
+    self
+      .store
+      .iter_mut()
+      .try_for_each(|plugin| initialize(plugin, app, config))
   }
 
   /// Generates an initialization script from all plugins in the store.
@@ -736,10 +741,11 @@ impl<R: Runtime> PluginStore<R> {
 
   /// Runs the created hook for all plugins in the store.
   pub(crate) fn created(&mut self, window: Window<R>) {
-    self
-      .store
-      .iter_mut()
-      .for_each(|plugin| plugin.created(window.clone()))
+    self.store.iter_mut().for_each(|plugin| {
+      #[cfg(feature = "tracing")]
+      let _span = tracing::trace_span!("plugin::hooks::created", name = plugin.name()).entered();
+      plugin.created(window.clone())
+    })
   }
 
   pub(crate) fn on_navigation(&mut self, window: &Window<R>, url: &Url) -> bool {
@@ -753,10 +759,12 @@ impl<R: Runtime> PluginStore<R> {
 
   /// Runs the on_page_load hook for all plugins in the store.
   pub(crate) fn on_page_load(&mut self, window: &Window<R>, payload: &PageLoadPayload<'_>) {
-    self
-      .store
-      .iter_mut()
-      .for_each(|plugin| plugin.on_page_load(window, payload))
+    self.store.iter_mut().for_each(|plugin| {
+      #[cfg(feature = "tracing")]
+      let _span =
+        tracing::trace_span!("plugin::hooks::on_page_load", name = plugin.name()).entered();
+      plugin.on_page_load(window, payload)
+    })
   }
 
   /// Runs the on_event hook for all plugins in the store.
@@ -773,6 +781,8 @@ impl<R: Runtime> PluginStore<R> {
   pub(crate) fn extend_api(&mut self, plugin: &str, invoke: Invoke<R>) -> bool {
     for p in self.store.iter_mut() {
       if p.name() == plugin {
+        #[cfg(feature = "tracing")]
+        let _span = tracing::trace_span!("plugin::hooks::ipc", name = plugin).entered();
         return p.extend_api(invoke);
       }
     }
@@ -780,3 +790,17 @@ impl<R: Runtime> PluginStore<R> {
     true
   }
 }
+
+#[cfg_attr(feature = "tracing", tracing::instrument(name = "plugin::hooks::initialize", skip(plugin, app), fields(name = plugin.name())))]
+fn initialize<R: Runtime>(
+  plugin: &mut Box<dyn Plugin<R>>,
+  app: &AppHandle<R>,
+  config: &PluginConfig,
+) -> crate::Result<()> {
+  plugin
+    .initialize(
+      app,
+      config.0.get(plugin.name()).cloned().unwrap_or_default(),
+    )
+    .map_err(|e| Error::PluginInitialization(plugin.name().to_string(), e.to_string()))
+}

+ 9 - 1
core/tauri/src/test/mod.rs

@@ -27,6 +27,8 @@
 //! }
 //!
 //! fn main() {
+//!     // Use `tauri::Builder::default()` to use the default runtime rather than the `MockRuntime`;
+//!     // let app = create_app(tauri::Builder::default());
 //!     let app = create_app(mock_builder());
 //!     let window = tauri::WindowBuilder::new(&app, "main", Default::default())
 //!         .build()
@@ -52,7 +54,7 @@ mod mock_runtime;
 pub use mock_runtime::*;
 use serde::Serialize;
 
-use std::{borrow::Cow, fmt::Debug};
+use std::{borrow::Cow, collections::HashMap, fmt::Debug};
 
 use crate::{
   ipc::{InvokeBody, InvokeError, InvokeResponse},
@@ -66,6 +68,7 @@ use tauri_utils::{
 
 /// An empty [`Assets`] implementation.
 pub struct NoopAsset {
+  assets: HashMap<&'static str, &'static [u8]>,
   csp_hashes: Vec<CspHash<'static>>,
 }
 
@@ -74,6 +77,10 @@ impl Assets for NoopAsset {
     None
   }
 
+  fn iter(&self) -> Box<dyn Iterator<Item = (&&str, &&[u8])> + '_> {
+    Box::new(self.assets.iter())
+  }
+
   fn csp_hashes(&self, html_path: &AssetKey) -> Box<dyn Iterator<Item = CspHash<'_>> + '_> {
     Box::new(self.csp_hashes.iter().copied())
   }
@@ -82,6 +89,7 @@ impl Assets for NoopAsset {
 /// Creates a new empty [`Assets`] implementation.
 pub fn noop_assets() -> NoopAsset {
   NoopAsset {
+    assets: Default::default(),
     csp_hashes: Default::default(),
   }
 }

+ 10 - 0
core/tauri/src/window/mod.rs

@@ -434,6 +434,7 @@ impl<'a, R: Runtime> WindowBuilder<'a, R> {
   }
 
   /// Creates a new webview window.
+  #[cfg_attr(feature = "tracing", tracing::instrument(name = "window::create"))]
   pub fn build(mut self) -> crate::Result<Window<R>> {
     let mut pending = PendingWindow::new(
       self.window_builder.clone(),
@@ -1032,6 +1033,10 @@ impl<R: Runtime> PartialEq for Window<R> {
 }
 
 impl<R: Runtime> Manager<R> for Window<R> {
+  #[cfg_attr(
+    feature = "tracing",
+    tracing::instrument("window::emit", skip(self, payload))
+  )]
   fn emit<S: Serialize + Clone>(&self, event: &str, payload: S) -> crate::Result<()> {
     self.manager().emit(event, Some(self.label()), payload)?;
     Ok(())
@@ -1048,6 +1053,10 @@ impl<R: Runtime> Manager<R> for Window<R> {
       .emit_filter(event, Some(self.label()), payload, |w| label == w.label())
   }
 
+  #[cfg_attr(
+    feature = "tracing",
+    tracing::instrument("window::emit::filter", skip(self, payload, filter))
+  )]
   fn emit_filter<S, F>(&self, event: &str, payload: S, filter: F) -> crate::Result<()>
   where
     S: Serialize + Clone,
@@ -1058,6 +1067,7 @@ impl<R: Runtime> Manager<R> for Window<R> {
       .emit_filter(event, Some(self.label()), payload, filter)
   }
 }
+
 impl<R: Runtime> ManagerBase<R> for Window<R> {
   fn manager(&self) -> &AppManager<R> {
     &self.manager

Fichier diff supprimé car celui-ci est trop grand
+ 0 - 0
examples/api/dist/assets/index.css


Fichier diff supprimé car celui-ci est trop grand
+ 0 - 0
examples/api/dist/assets/index.js


+ 22 - 67
examples/api/src-tauri/Cargo.lock

@@ -625,22 +625,6 @@ version = "0.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961"
 
-[[package]]
-name = "cocoa"
-version = "0.24.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f425db7937052c684daec3bd6375c8abe2d146dca4b8b143d6db777c39138f3a"
-dependencies = [
- "bitflags 1.3.2",
- "block",
- "cocoa-foundation",
- "core-foundation",
- "core-graphics 0.22.3",
- "foreign-types 0.3.2",
- "libc",
- "objc",
-]
-
 [[package]]
 name = "cocoa"
 version = "0.25.0"
@@ -651,8 +635,8 @@ dependencies = [
  "block",
  "cocoa-foundation",
  "core-foundation",
- "core-graphics 0.23.1",
- "foreign-types 0.5.0",
+ "core-graphics",
+ "foreign-types",
  "libc",
  "objc",
 ]
@@ -724,19 +708,6 @@ version = "0.8.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa"
 
-[[package]]
-name = "core-graphics"
-version = "0.22.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2581bbab3b8ffc6fcbd550bf46c355135d16e9ff2a6ea032ad6b9bf1d7efe4fb"
-dependencies = [
- "bitflags 1.3.2",
- "core-foundation",
- "core-graphics-types",
- "foreign-types 0.3.2",
- "libc",
-]
-
 [[package]]
 name = "core-graphics"
 version = "0.23.1"
@@ -746,7 +717,7 @@ dependencies = [
  "bitflags 1.3.2",
  "core-foundation",
  "core-graphics-types",
- "foreign-types 0.5.0",
+ "foreign-types",
  "libc",
 ]
 
@@ -1124,15 +1095,6 @@ 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 0.1.1",
-]
-
 [[package]]
 name = "foreign-types"
 version = "0.5.0"
@@ -1140,7 +1102,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965"
 dependencies = [
  "foreign-types-macros",
- "foreign-types-shared 0.3.1",
+ "foreign-types-shared",
 ]
 
 [[package]]
@@ -1154,12 +1116,6 @@ dependencies = [
  "syn 2.0.38",
 ]
 
-[[package]]
-name = "foreign-types-shared"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
-
 [[package]]
 name = "foreign-types-shared"
 version = "0.3.1"
@@ -2155,7 +2111,7 @@ version = "0.11.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "b564d551449738387fb4541aef5fbfceaa81b2b732f2534c1c7c89dc7d673eaa"
 dependencies = [
- "cocoa 0.25.0",
+ "cocoa",
  "crossbeam-channel",
  "gtk",
  "keyboard-types",
@@ -3408,9 +3364,9 @@ checksum = "3c0dff18fed076d29cb5779e918ef4b8a5dbb756204e4a027794f0bce233d949"
 dependencies = [
  "bitflags 1.3.2",
  "cc",
- "cocoa 0.25.0",
+ "cocoa",
  "core-foundation",
- "core-graphics 0.23.1",
+ "core-graphics",
  "crossbeam-channel",
  "dispatch",
  "gdkwayland-sys",
@@ -3460,11 +3416,11 @@ checksum = "14c39fd04924ca3a864207c66fc2cd7d22d7c016007f9ce846cbb9326331930a"
 
 [[package]]
 name = "tauri"
-version = "2.0.0-alpha.18"
+version = "2.0.0-alpha.20"
 dependencies = [
  "anyhow",
  "bytes",
- "cocoa 0.25.0",
+ "cocoa",
  "dirs-next",
  "embed_plist",
  "futures-util",
@@ -3482,7 +3438,6 @@ dependencies = [
  "mime",
  "muda",
  "objc",
- "once_cell",
  "percent-encoding",
  "png",
  "raw-window-handle",
@@ -3511,7 +3466,7 @@ dependencies = [
 
 [[package]]
 name = "tauri-build"
-version = "2.0.0-alpha.12"
+version = "2.0.0-alpha.13"
 dependencies = [
  "anyhow",
  "cargo_toml",
@@ -3532,7 +3487,7 @@ dependencies = [
 
 [[package]]
 name = "tauri-codegen"
-version = "2.0.0-alpha.11"
+version = "2.0.0-alpha.12"
 dependencies = [
  "base64",
  "brotli",
@@ -3556,7 +3511,7 @@ dependencies = [
 
 [[package]]
 name = "tauri-macros"
-version = "2.0.0-alpha.11"
+version = "2.0.0-alpha.12"
 dependencies = [
  "heck",
  "proc-macro2",
@@ -3592,7 +3547,7 @@ dependencies = [
 
 [[package]]
 name = "tauri-runtime"
-version = "1.0.0-alpha.5"
+version = "1.0.0-alpha.7"
 dependencies = [
  "gtk",
  "http",
@@ -3608,9 +3563,9 @@ dependencies = [
 
 [[package]]
 name = "tauri-runtime-wry"
-version = "1.0.0-alpha.6"
+version = "1.0.0-alpha.8"
 dependencies = [
- "cocoa 0.24.1",
+ "cocoa",
  "gtk",
  "http",
  "jni",
@@ -3627,7 +3582,7 @@ dependencies = [
 
 [[package]]
 name = "tauri-utils"
-version = "2.0.0-alpha.11"
+version = "2.0.0-alpha.12"
 dependencies = [
  "aes-gcm",
  "brotli",
@@ -3944,8 +3899,8 @@ version = "0.11.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "5375d350db4ccd3c783a4c683be535e70df5c62b07a824e7bcd6d43ef6d74181"
 dependencies = [
- "cocoa 0.25.0",
- "core-graphics 0.23.1",
+ "cocoa",
+ "core-graphics",
  "crossbeam-channel",
  "dirs-next",
  "libappindicator",
@@ -4340,7 +4295,7 @@ version = "0.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "67ff424735b1ac21293b0492b069394b0a189c8a463fb015a16dea7c2e221c08"
 dependencies = [
- "cocoa 0.25.0",
+ "cocoa",
  "objc",
  "raw-window-handle",
  "windows-sys 0.48.0",
@@ -4352,7 +4307,7 @@ version = "0.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "5931735e675b972fada30c7a402915d4d827aa5ef6c929c133d640c4b785e963"
 dependencies = [
- "cocoa 0.25.0",
+ "cocoa",
  "objc",
  "raw-window-handle",
  "windows-sys 0.48.0",
@@ -4664,8 +4619,8 @@ dependencies = [
  "base64",
  "block",
  "cfg_aliases",
- "cocoa 0.25.0",
- "core-graphics 0.23.1",
+ "cocoa",
+ "core-graphics",
  "crossbeam-channel",
  "dunce",
  "gdkx11",

+ 6 - 3
renovate.json

@@ -22,7 +22,8 @@
       "lockFileMaintenance": {
         "enabled": true
       },
-      "rebaseConflictedPrs": false
+      "rebaseConflictedPrs": false,
+      "ignoreDeps": ["cargo_toml", "toml"]
     },
     {
       "enabled": true,
@@ -33,7 +34,8 @@
       "lockFileMaintenance": {
         "enabled": true
       },
-      "rebaseConflictedPrs": false
+      "rebaseConflictedPrs": false,
+      "ignoreDeps": ["cargo_toml"]
     },
     {
       "enabled": true,
@@ -78,7 +80,8 @@
         "enabled": true
       },
       "rebaseConflictedPrs": false,
-      "matchManagers": ["cargo"]
+      "matchManagers": ["cargo"],
+      "ignoreDeps": ["minisign"]
     },
     {
       "enabled": true,

+ 28 - 2
tooling/api/CHANGELOG.md

@@ -128,6 +128,13 @@
 - First mobile alpha release!
   - [fa3a1098](https://www.github.com/tauri-apps/tauri/commit/fa3a10988a03aed1b66fb17d893b1a9adb90f7cd) feat(ci): prepare 2.0.0-alpha.0 ([#5786](https://www.github.com/tauri-apps/tauri/pull/5786)) on 2022-12-08
 
+## \[1.5.2]
+
+### Bug Fixes
+
+- [`50462702`](https://www.github.com/tauri-apps/tauri/commit/504627027303ef5a0e855aab2abea64c6964223b)([#8267](https://www.github.com/tauri-apps/tauri/pull/8267)) Add top-level `main`, `module` and `types` fields in `package.json` to be compliant with typescripts's `"moduleResolution": "node"`
+- [`14544e4b`](https://www.github.com/tauri-apps/tauri/commit/14544e4b87269c06c89fed3647d80f492e0a1d34)([#8219](https://www.github.com/tauri-apps/tauri/pull/8219)) Avoid crashing in `clearMocks`
+
 ## \[1.5.1]
 
 ### New Features
@@ -159,7 +166,7 @@
 
 ## \[1.3.0]
 
-- Return correct type for ` event.payload  ` in `onResized` and `onMoved` window event handlers.
+- Return correct type for `event.payload` in `onResized` and `onMoved` window event handlers.
   - [0b46637e](https://www.github.com/tauri-apps/tauri/commit/0b46637ebaba54403afa32a1cb466f09df2db999) fix(api): construct correct object for onResized and onMoved, closes [#6507](https://www.github.com/tauri-apps/tauri/pull/6507) ([#6509](https://www.github.com/tauri-apps/tauri/pull/6509)) on 2023-04-03
 - Added the `WindowOptions::contentProtected` option and `WebviewWindow#setContentProtected` to change it at runtime.
   - [4ab5545b](https://www.github.com/tauri-apps/tauri/commit/4ab5545b7a831c549f3c65e74de487ede3ab7ce5) feat: add content protection api, closes [#5132](https://www.github.com/tauri-apps/tauri/pull/5132) ([#5513](https://www.github.com/tauri-apps/tauri/pull/5513)) on 2022-12-13
@@ -296,65 +303,84 @@
 ## \[1.0.0-rc.0]
 
 - Add `fileDropEnabled` property to `WindowOptions` so you can now disable it when creating windows from js.
+
   - [1bfc32a3](https://www.github.com/tauri-apps/tauri/commit/1bfc32a3b2f31b962ce8a5c611b60cb008360923) fix(api.js): add `fileDropEnabled` to `WindowOptions`, closes [#2968](https://www.github.com/tauri-apps/tauri/pull/2968) ([#2989](https://www.github.com/tauri-apps/tauri/pull/2989)) on 2021-12-09
 
 - Add `logDir` function to the `path` module to access the suggested log directory.
   Add `BaseDirectory.Log` to the `fs` module.
+
   - [acbb3ae7](https://www.github.com/tauri-apps/tauri/commit/acbb3ae7bb0165846b9456aea103269f027fc548) feat: add Log directory ([#2736](https://www.github.com/tauri-apps/tauri/pull/2736)) on 2021-10-16
   - [62c7a8ad](https://www.github.com/tauri-apps/tauri/commit/62c7a8ad30fd3031b8679960590e5ef3eef8e4da) chore(covector): prepare for `rc` release ([#3376](https://www.github.com/tauri-apps/tauri/pull/3376)) on 2022-02-10
 
 - Expose `ask`, `message` and `confirm` APIs on the dialog module.
+
   - [e98c1af4](https://www.github.com/tauri-apps/tauri/commit/e98c1af44279a5ff6c8a6f0a506ecc219c9f77af) feat(core): expose message dialog APIs, fix window.confirm, implement HasRawWindowHandle for Window, closes [#2535](https://www.github.com/tauri-apps/tauri/pull/2535) ([#2700](https://www.github.com/tauri-apps/tauri/pull/2700)) on 2021-10-02
 
 - Event `emit` now automatically serialize non-string types.
+
   - [06000996](https://www.github.com/tauri-apps/tauri/commit/060009969627890fa9018e2f1105bad13299394c) feat(api): support unknown types for event emit payload, closes [#2929](https://www.github.com/tauri-apps/tauri/pull/2929) ([#2964](https://www.github.com/tauri-apps/tauri/pull/2964)) on 2022-01-07
 
 - Fix `http.fetch` throwing error if the response is successful but the body is empty.
+
   - [50c63900](https://www.github.com/tauri-apps/tauri/commit/50c63900c7313064037e2ceb798a6432fcd1bcda) fix(api.js): fix `http.fetch` throwing error if response body is empty, closes [#2831](https://www.github.com/tauri-apps/tauri/pull/2831) ([#3008](https://www.github.com/tauri-apps/tauri/pull/3008)) on 2021-12-09
 
 - Add `title` option to file open/save dialogs.
+
   - [e1d6a6e6](https://www.github.com/tauri-apps/tauri/commit/e1d6a6e6445637723e2331ca799a662e720e15a8) Create api-file-dialog-title.md ([#3235](https://www.github.com/tauri-apps/tauri/pull/3235)) on 2022-01-16
   - [62c7a8ad](https://www.github.com/tauri-apps/tauri/commit/62c7a8ad30fd3031b8679960590e5ef3eef8e4da) chore(covector): prepare for `rc` release ([#3376](https://www.github.com/tauri-apps/tauri/pull/3376)) on 2022-02-10
 
 - Fix `os.platform` returning `macos` and `windows` instead of `darwin` and `win32`.
+
   - [3924c3d8](https://www.github.com/tauri-apps/tauri/commit/3924c3d85365df30b376a1ec6c2d933460d66af0) fix(api.js): fix `os.platform` return on macos and windows, closes [#2698](https://www.github.com/tauri-apps/tauri/pull/2698) ([#2699](https://www.github.com/tauri-apps/tauri/pull/2699)) on 2021-10-02
 
 - The `formatCallback` helper function now returns a number instead of a string.
+
   - [a48b8b18](https://www.github.com/tauri-apps/tauri/commit/a48b8b18d428bcc404d489daa690bbefe1f57311) feat(core): validate callbacks and event names \[TRI-038] \[TRI-020] ([#21](https://www.github.com/tauri-apps/tauri/pull/21)) on 2022-01-09
 
 - Added `rawHeaders` to `http > Response`.
+
   - [b7a2345b](https://www.github.com/tauri-apps/tauri/commit/b7a2345b06ca0306988b4ba3d3deadd449e65af9) feat(core): add raw headers to HTTP API, closes [#2695](https://www.github.com/tauri-apps/tauri/pull/2695) ([#3053](https://www.github.com/tauri-apps/tauri/pull/3053)) on 2022-01-07
 
 - Removed the `currentDir` API from the `path` module.
+
   - [a08509c6](https://www.github.com/tauri-apps/tauri/commit/a08509c641f43695e25944a2dd47697b18cd83e2) fix(api): remove `currentDir` API from the `path` module on 2022-02-04
 
 - Remove `.ts` files on the published package.
+
   - [0f321ac0](https://www.github.com/tauri-apps/tauri/commit/0f321ac08d56412edd5bc9d166201fbc95d887d8) fix(api): do not ship TS files, closes [#2598](https://www.github.com/tauri-apps/tauri/pull/2598) ([#2645](https://www.github.com/tauri-apps/tauri/pull/2645)) on 2021-09-23
 
 - **Breaking change:** Replaces all usages of `number[]` with `Uint8Array` to be closer aligned with the wider JS ecosystem.
+
   - [9b19a805](https://www.github.com/tauri-apps/tauri/commit/9b19a805aa8efa64b22f2dfef193a144b8e0cee3) fix(api.js) Replace `number[]`with `Uint8Array`. fixes [#3306](https://www.github.com/tauri-apps/tauri/pull/3306) ([#3305](https://www.github.com/tauri-apps/tauri/pull/3305)) on 2022-02-05
 
 - `WindowManager` methods `innerPosition` `outerPosition` now correctly return instance of `PhysicalPosition`.
   `WindowManager` methods `innerSize` `outerSize` now correctly return instance of `PhysicalSize`.
+
   - [cc8b1468](https://www.github.com/tauri-apps/tauri/commit/cc8b1468c821df53ceb771061c919409a9c80978) Fix(api): Window size and position returning wrong class (fix: [#2599](https://www.github.com/tauri-apps/tauri/pull/2599)) ([#2621](https://www.github.com/tauri-apps/tauri/pull/2621)) on 2021-09-22
 
 - Change the `event` field of the `Event` interface to type `EventName` instead of `string`.
+
   - [b5d9bcb4](https://www.github.com/tauri-apps/tauri/commit/b5d9bcb402380abc86ae1fa1a77c629af2275f9d) Consistent event name usage ([#3228](https://www.github.com/tauri-apps/tauri/pull/3228)) on 2022-01-15
   - [62c7a8ad](https://www.github.com/tauri-apps/tauri/commit/62c7a8ad30fd3031b8679960590e5ef3eef8e4da) chore(covector): prepare for `rc` release ([#3376](https://www.github.com/tauri-apps/tauri/pull/3376)) on 2022-02-10
 
 - Now `resolve()`, `join()` and `normalize()` from the `path` module, won't throw errors if the path doesn't exist, which matches NodeJS behavior.
+
   - [fe381a0b](https://www.github.com/tauri-apps/tauri/commit/fe381a0bde86ebf4014007f6e21af4c1a9e58cef) fix: `join` no longer cares if path doesn't exist, closes [#2499](https://www.github.com/tauri-apps/tauri/pull/2499) ([#2548](https://www.github.com/tauri-apps/tauri/pull/2548)) on 2021-09-21
 
 - Fixes the dialog `defaultPath` usage on Linux.
+
   - [2212bd5d](https://www.github.com/tauri-apps/tauri/commit/2212bd5d75146f5a2df27cc2157a057642f626da) fix: dialog default path on Linux, closes [#3091](https://www.github.com/tauri-apps/tauri/pull/3091) ([#3123](https://www.github.com/tauri-apps/tauri/pull/3123)) on 2021-12-27
 
 - Fixes `window.label` property returning null instead of the actual label.
+
   - [f5109e0c](https://www.github.com/tauri-apps/tauri/commit/f5109e0c962e3d25404995194968bade1be33b16) fix(api): window label null instead of actual value, closes [#3295](https://www.github.com/tauri-apps/tauri/pull/3295) ([#3332](https://www.github.com/tauri-apps/tauri/pull/3332)) on 2022-02-04
 
 - Remove the `BaseDirectory::Current` enum variant for security reasons.
+
   - [696dca58](https://www.github.com/tauri-apps/tauri/commit/696dca58a9f8ee127a1cf857eb848e09f5845d18) refactor(core): remove `BaseDirectory::Current` variant on 2022-01-26
 
 - Change `WindowLabel` type to `string`.
+
   - [f68603ae](https://www.github.com/tauri-apps/tauri/commit/f68603aee4e16500dff9e385b217f5dd8b1b39e8) chore(docs): simplify event system documentation on 2021-09-27
 
 - When building Universal macOS Binaries through the virtual target `universal-apple-darwin`:
@@ -423,7 +449,7 @@
 ## \[1.0.0-beta.3]
 
 - Export `Response` and `ResponseType` as value instead of type.
-  - [394b6e05](https://www.github.com/tauri-apps/tauri/commit/394b6e0572e7a0a92e103e462a7f603f7d569319) fix(api): http  `ResponseType` export type error ([#2065](https://www.github.com/tauri-apps/tauri/pull/2065)) on 2021-06-24
+  - [394b6e05](https://www.github.com/tauri-apps/tauri/commit/394b6e0572e7a0a92e103e462a7f603f7d569319) fix(api): http `ResponseType` export type error ([#2065](https://www.github.com/tauri-apps/tauri/pull/2065)) on 2021-06-24
 
 ## \[1.0.0-beta.2]
 

+ 9 - 6
tooling/api/src/mocks.ts

@@ -196,10 +196,13 @@ export function clearMocks(): void {
     return
   }
 
-  // @ts-expect-error "The operand of a 'delete' operator must be optional' does not matter in this case
-  delete window.__TAURI_INTERNALS__.convertFileSrc
-  // @ts-expect-error "The operand of a 'delete' operator must be optional' does not matter in this case
-  delete window.__TAURI_INTERNALS__.ipc
-  // @ts-expect-error "The operand of a 'delete' operator must be optional' does not matter in this case
-  delete window.__TAURI_INTERNALS__.metadata
+  if (window.__TAURI_INTERNALS__?.convertFileSrc)
+    // @ts-expect-error "The operand of a 'delete' operator must be optional' does not matter in this case
+    delete window.__TAURI_INTERNALS__.convertFileSrc
+  if (window.__TAURI_INTERNALS__?.ipc)
+    // @ts-expect-error "The operand of a 'delete' operator must be optional' does not matter in this case
+    delete window.__TAURI_INTERNALS__.ipc
+  if (window.__TAURI_INTERNALS__?.metadata)
+    // @ts-expect-error "The operand of a 'delete' operator must be optional' does not matter in this case
+    delete window.__TAURI_INTERNALS__.metadata
 }

+ 7 - 0
tooling/api/yarn.lock

@@ -1245,6 +1245,13 @@ is-typed-array@^1.1.10, is-typed-array@^1.1.12, is-typed-array@^1.1.9:
   dependencies:
     which-typed-array "^1.1.11"
 
+is-typed-array@^1.1.12:
+  version "1.1.12"
+  resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.12.tgz#d0bab5686ef4a76f7a73097b95470ab199c57d4a"
+  integrity sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==
+  dependencies:
+    which-typed-array "^1.1.11"
+
 is-weakref@^1.0.2:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2"

+ 22 - 0
tooling/bundler/CHANGELOG.md

@@ -103,6 +103,28 @@
 - First mobile alpha release!
   - [fa3a1098](https://www.github.com/tauri-apps/tauri/commit/fa3a10988a03aed1b66fb17d893b1a9adb90f7cd) feat(ci): prepare 2.0.0-alpha.0 ([#5786](https://www.github.com/tauri-apps/tauri/pull/5786)) on 2022-12-08
 
+## \[1.4.7]
+
+### Bug Fixes
+
+- [`777ddf43`](https://www.github.com/tauri-apps/tauri/commit/777ddf434a966966dc8918322c1ec9ee3f822ee2)([#8376](https://www.github.com/tauri-apps/tauri/pull/8376)) Unset `NSISDIR` and `NSISCONFDIR` when running `makensis.exe` so it doesn't conflict with NSIS installed by the user.
+- [`5ff9d459`](https://www.github.com/tauri-apps/tauri/commit/5ff9d4592a6dd8fc93165012ef367d78ea06e4ce)([#8390](https://www.github.com/tauri-apps/tauri/pull/8390)) NSIS perUser installers will now only check if the app is running on the current user.
+
+## \[1.4.6]
+
+### Bug Fixes
+
+- [`1d5aa38a`](https://www.github.com/tauri-apps/tauri/commit/1d5aa38ae418ea31f593590b6d32cf04d3bfd8c1)([#8162](https://www.github.com/tauri-apps/tauri/pull/8162)) Fixes errors on command output, occuring when the output stream contains an invalid UTF-8 character, or ends with a multi-bytes UTF-8 character.
+- [`977a39f4`](https://www.github.com/tauri-apps/tauri/commit/977a39f4f7fb5e47492b51df931643b1af4f92b0)([#8292](https://www.github.com/tauri-apps/tauri/pull/8292)) Migrate the WebView2 offline installer to use shorturl provided by Microsoft.
+- [`f26d9f08`](https://www.github.com/tauri-apps/tauri/commit/f26d9f0884f63f61b9f4d4fac15e6b251163793e)([#8263](https://www.github.com/tauri-apps/tauri/pull/8263)) Fixes an issue in the NSIS installer which caused the uninstallation to leave empty folders on the system if the `resources` feature was used.
+- [`92bc7d0e`](https://www.github.com/tauri-apps/tauri/commit/92bc7d0e16157434330a1bcf1eefda6f0f1e5f85)([#8233](https://www.github.com/tauri-apps/tauri/pull/8233)) Fixes an issue in the NSIS installer which caused the installation to take much longer than expected when many `resources` were added to the bundle.
+
+## \[1.4.5]
+
+### Enhancements
+
+- [`cfe6fa6c`](https://www.github.com/tauri-apps/tauri/commit/cfe6fa6c91a8cc177d4665ba04dad32ba545159d)([#8061](https://www.github.com/tauri-apps/tauri/pull/8061)) Added German language support to the NSIS bundler.
+
 ## \[1.4.4]
 
 ### Enhancements

+ 1 - 1
tooling/bundler/Cargo.toml

@@ -27,7 +27,7 @@ serde = { version = "1.0", features = [ "derive" ] }
 strsim = "0.10.0"
 tar = "0.4.40"
 walkdir = "2"
-handlebars = "4.4"
+handlebars = "4.5"
 tempfile = "3.8.1"
 log = { version = "0.4.20", features = [ "kv_unstable" ] }
 dirs-next = "2.0"

+ 14 - 8
tooling/bundler/src/bundle/common.rs

@@ -164,11 +164,14 @@ impl CommandExt for Command {
       let mut lines = stdout_lines_.lock().unwrap();
       loop {
         line.clear();
-        if let Ok(0) = stdout.read_line(&mut line) {
-          break;
+        match stdout.read_line(&mut line) {
+          Ok(0) => break,
+          Ok(_) => {
+            debug!(action = "stdout"; "{}", line.trim_end());
+            lines.extend(line.as_bytes().to_vec());
+          }
+          Err(_) => (),
         }
-        debug!(action = "stdout"; "{}", &line[0..line.len() - 1]);
-        lines.extend(line.as_bytes().to_vec());
       }
     });
 
@@ -180,11 +183,14 @@ impl CommandExt for Command {
       let mut lines = stderr_lines_.lock().unwrap();
       loop {
         line.clear();
-        if let Ok(0) = stderr.read_line(&mut line) {
-          break;
+        match stderr.read_line(&mut line) {
+          Ok(0) => break,
+          Ok(_) => {
+            debug!(action = "stderr"; "{}", line.trim_end());
+            lines.extend(line.as_bytes().to_vec());
+          }
+          Err(_) => (),
         }
-        debug!(action = "stderr"; "{}", &line[0..line.len() - 1]);
-        lines.extend(line.as_bytes().to_vec());
       }
     });
 

+ 4 - 32
tooling/bundler/src/bundle/windows/msi/wix.rs

@@ -10,9 +10,8 @@ use crate::bundle::{
   windows::{
     sign::try_sign,
     util::{
-      download, download_and_verify, extract_zip, HashAlgorithm, WEBVIEW2_BOOTSTRAPPER_URL,
-      WEBVIEW2_X64_OFFLINE_INSTALLER_GUID, WEBVIEW2_X86_OFFLINE_INSTALLER_GUID,
-      WIX_OUTPUT_FOLDER_NAME, WIX_UPDATER_OUTPUT_FOLDER_NAME,
+      download_and_verify, download_webview2_bootstrapper, download_webview2_offline_installer,
+      extract_zip, HashAlgorithm, WIX_OUTPUT_FOLDER_NAME, WIX_UPDATER_OUTPUT_FOLDER_NAME,
     },
   },
 };
@@ -473,42 +472,15 @@ pub fn build_wix_app_installer(
       );
     }
     WebviewInstallMode::EmbedBootstrapper { silent: _ } => {
-      let webview2_bootstrapper_path = output_path.join("MicrosoftEdgeWebview2Setup.exe");
-      std::fs::write(
-        &webview2_bootstrapper_path,
-        download(WEBVIEW2_BOOTSTRAPPER_URL)?,
-      )?;
+      let webview2_bootstrapper_path = download_webview2_bootstrapper(&output_path)?;
       data.insert(
         "webview2_bootstrapper_path",
         to_json(webview2_bootstrapper_path),
       );
     }
     WebviewInstallMode::OfflineInstaller { silent: _ } => {
-      let guid = if arch == "x64" {
-        WEBVIEW2_X64_OFFLINE_INSTALLER_GUID
-      } else {
-        WEBVIEW2_X86_OFFLINE_INSTALLER_GUID
-      };
-      let offline_installer_path = dirs_next::cache_dir()
-        .unwrap()
-        .join("tauri")
-        .join("Webview2OfflineInstaller")
-        .join(guid)
-        .join(arch);
-      create_dir_all(&offline_installer_path)?;
       let webview2_installer_path =
-        offline_installer_path.join("MicrosoftEdgeWebView2RuntimeInstaller.exe");
-      if !webview2_installer_path.exists() {
-        std::fs::write(
-          &webview2_installer_path,
-          download(
-            &format!("https://msedge.sf.dl.delivery.mp.microsoft.com/filestreamingservice/files/{}/MicrosoftEdgeWebView2RuntimeInstaller{}.exe",
-              guid,
-              arch.to_uppercase(),
-            ),
-          )?,
-        )?;
-      }
+        download_webview2_offline_installer(&output_path.join(arch), arch)?;
       data.insert("webview2_installer_path", to_json(webview2_installer_path));
     }
   }

+ 48 - 38
tooling/bundler/src/bundle/windows/nsis.rs

@@ -8,9 +8,9 @@ use crate::{
   bundle::{
     common::CommandExt,
     windows::util::{
-      download, download_and_verify, extract_zip, HashAlgorithm, NSIS_OUTPUT_FOLDER_NAME,
-      NSIS_UPDATER_OUTPUT_FOLDER_NAME, WEBVIEW2_BOOTSTRAPPER_URL,
-      WEBVIEW2_X64_OFFLINE_INSTALLER_GUID, WEBVIEW2_X86_OFFLINE_INSTALLER_GUID,
+      download, download_and_verify, download_webview2_bootstrapper,
+      download_webview2_offline_installer, extract_zip, HashAlgorithm, NSIS_OUTPUT_FOLDER_NAME,
+      NSIS_UPDATER_OUTPUT_FOLDER_NAME,
     },
   },
   Settings,
@@ -37,8 +37,8 @@ const NSIS_URL: &str =
 const NSIS_SHA1: &str = "057e83c7d82462ec394af76c87d06733605543d4";
 const NSIS_APPLICATIONID_URL: &str = "https://github.com/tauri-apps/binary-releases/releases/download/nsis-plugins-v0/NSIS-ApplicationID.zip";
 const NSIS_TAURI_UTILS: &str =
-  "https://github.com/tauri-apps/nsis-tauri-utils/releases/download/nsis_tauri_utils-v0.2.1/nsis_tauri_utils.dll";
-const NSIS_TAURI_UTILS_SHA1: &str = "53A7CFAEB6A4A9653D6D5FBFF02A3C3B8720130A";
+  "https://github.com/tauri-apps/nsis-tauri-utils/releases/download/nsis_tauri_utils-v0.2.2/nsis_tauri_utils.dll";
+const NSIS_TAURI_UTILS_SHA1: &str = "16DF1D1A5B4D5DF3859447279C55BE36D4109DFB";
 
 #[cfg(target_os = "windows")]
 const NSIS_REQUIRED_FILES: &[&str] = &[
@@ -290,23 +290,38 @@ fn build_nsis_app_installer(
     .iter()
     .find(|bin| bin.main())
     .ok_or_else(|| anyhow::anyhow!("Failed to get main binary"))?;
+  let main_binary_path = settings.binary_path(main_binary).with_extension("exe");
   data.insert(
     "main_binary_name",
     to_json(main_binary.name().replace(".exe", "")),
   );
-  data.insert(
-    "main_binary_path",
-    to_json(settings.binary_path(main_binary).with_extension("exe")),
-  );
+  data.insert("main_binary_path", to_json(&main_binary_path));
 
   let out_file = "nsis-output.exe";
   data.insert("out_file", to_json(out_file));
 
   let resources = generate_resource_data(settings)?;
-  data.insert("resources", to_json(resources));
+  let resources_dirs =
+    std::collections::HashSet::<PathBuf>::from_iter(resources.values().map(|r| r.0.to_owned()));
+
+  let mut resources_ancestors = resources_dirs
+    .iter()
+    .flat_map(|p| p.ancestors())
+    .collect::<Vec<_>>();
+  resources_ancestors.sort_unstable();
+  resources_ancestors.dedup();
+  resources_ancestors.sort_by_key(|p| std::cmp::Reverse(p.components().count()));
+  resources_ancestors.pop(); // Last one is always ""
+
+  data.insert("resources_ancestors", to_json(resources_ancestors));
+  data.insert("resources_dirs", to_json(resources_dirs));
+  data.insert("resources", to_json(&resources));
 
   let binaries = generate_binaries_data(settings)?;
-  data.insert("binaries", to_json(binaries));
+  data.insert("binaries", to_json(&binaries));
+
+  let estimated_size = generate_estimated_size(&main_binary_path, &binaries, &resources)?;
+  data.insert("estimated_size", to_json(estimated_size));
 
   if let Some(file_associations) = &settings.file_associations() {
     data.insert("file_associations", to_json(file_associations));
@@ -359,40 +374,15 @@ fn build_nsis_app_installer(
 
   match webview2_install_mode {
     WebviewInstallMode::EmbedBootstrapper { silent: _ } => {
-      let webview2_bootstrapper_path = tauri_tools_path.join("MicrosoftEdgeWebview2Setup.exe");
-      std::fs::write(
-        &webview2_bootstrapper_path,
-        download(WEBVIEW2_BOOTSTRAPPER_URL)?,
-      )?;
+      let webview2_bootstrapper_path = download_webview2_bootstrapper(tauri_tools_path)?;
       data.insert(
         "webview2_bootstrapper_path",
         to_json(webview2_bootstrapper_path),
       );
     }
     WebviewInstallMode::OfflineInstaller { silent: _ } => {
-      let guid = if arch == "x64" {
-        WEBVIEW2_X64_OFFLINE_INSTALLER_GUID
-      } else {
-        WEBVIEW2_X86_OFFLINE_INSTALLER_GUID
-      };
-      let offline_installer_path = tauri_tools_path
-        .join("Webview2OfflineInstaller")
-        .join(guid)
-        .join(arch);
-      create_dir_all(&offline_installer_path)?;
       let webview2_installer_path =
-        offline_installer_path.join("MicrosoftEdgeWebView2RuntimeInstaller.exe");
-      if !webview2_installer_path.exists() {
-        std::fs::write(
-          &webview2_installer_path,
-          download(
-            &format!("https://msedge.sf.dl.delivery.mp.microsoft.com/filestreamingservice/files/{}/MicrosoftEdgeWebView2RuntimeInstaller{}.exe",
-              guid,
-              arch.to_uppercase(),
-            ),
-          )?,
-        )?;
-      }
+        download_webview2_offline_installer(&tauri_tools_path.join(arch), arch)?;
       data.insert("webview2_installer_path", to_json(webview2_installer_path));
     }
     _ => {}
@@ -479,6 +469,8 @@ fn build_nsis_app_installer(
       _ => "-V4",
     })
     .arg(installer_nsi_path)
+    .env_remove("NSISDIR")
+    .env_remove("NSISCONFDIR")
     .current_dir(output_path)
     .piped()
     .context("error running makensis.exe")?;
@@ -600,6 +592,24 @@ fn generate_binaries_data(settings: &Settings) -> crate::Result<BinariesMap> {
   Ok(binaries)
 }
 
+fn generate_estimated_size(
+  main: &Path,
+  binaries: &BinariesMap,
+  resources: &ResourcesMap,
+) -> crate::Result<String> {
+  use std::fs::metadata;
+
+  let mut size = metadata(main)?.len();
+
+  for k in binaries.keys().chain(resources.keys()) {
+    size += metadata(k)?.len();
+  }
+
+  size /= 1000;
+
+  Ok(format!("{size:#08x}"))
+}
+
 fn get_lang_data(
   lang: &str,
   custom_lang_files: Option<&HashMap<String, PathBuf>>,

+ 23 - 16
tooling/bundler/src/bundle/windows/templates/installer.nsi

@@ -41,6 +41,7 @@ ${StrLoc}
 !define UNINSTKEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCTNAME}"
 !define MANUPRODUCTKEY "Software\${MANUFACTURER}\${PRODUCTNAME}"
 !define UNINSTALLERSIGNCOMMAND "{{uninstaller_sign_cmd}}"
+!define ESTIMATEDSIZE "{{estimated_size}}"
 
 Name "${PRODUCTNAME}"
 BrandingText "${COPYRIGHT}"
@@ -493,13 +494,21 @@ Section WebView2
 SectionEnd
 
 !macro CheckIfAppIsRunning
-  nsis_tauri_utils::FindProcess "${MAINBINARYNAME}.exe"
+  !if "${INSTALLMODE}" == "currentUser"
+    nsis_tauri_utils::FindProcessCurrentUser "${MAINBINARYNAME}.exe"
+  !else
+    nsis_tauri_utils::FindProcess "${MAINBINARYNAME}.exe"
+  !endif
   Pop $R0
   ${If} $R0 = 0
       IfSilent kill 0
       ${IfThen} $PassiveMode != 1 ${|} MessageBox MB_OKCANCEL "$(appRunningOkKill)" IDOK kill IDCANCEL cancel ${|}
       kill:
-        nsis_tauri_utils::KillProcess "${MAINBINARYNAME}.exe"
+        !if "${INSTALLMODE}" == "currentUser"
+          nsis_tauri_utils::KillProcessCurrentUser "${MAINBINARYNAME}.exe"
+        !else
+          nsis_tauri_utils::KillProcess "${MAINBINARYNAME}.exe"
+        !endif
         Pop $R0
         Sleep 500
         ${If} $R0 = 0
@@ -523,31 +532,25 @@ SectionEnd
   app_check_done:
 !macroend
 
-Var AppSize
 Section Install
   SetOutPath $INSTDIR
-  StrCpy $AppSize 0
 
   !insertmacro CheckIfAppIsRunning
 
   ; Copy main executable
   File "${MAINBINARYSRCPATH}"
-  ${GetSize} "$INSTDIR" "/M=${MAINBINARYNAME}.exe /S=0B" $0 $1 $2
-  IntOp $AppSize $AppSize + $0
 
   ; Copy resources
+  {{#each resources_dirs}}
+    CreateDirectory "$INSTDIR\\{{this}}"
+  {{/each}}
   {{#each resources}}
-    CreateDirectory "$INSTDIR\\{{this.[0]}}"
     File /a "/oname={{this.[1]}}" "{{@key}}"
-    ${GetSize} "$INSTDIR" "/M={{this.[1]}} /S=0B" $0 $1 $2
-    IntOp $AppSize $AppSize + $0
   {{/each}}
 
   ; Copy external binaries
   {{#each binaries}}
     File /a "/oname={{this}}" "{{@key}}"
-    ${GetSize} "$INSTDIR" "/M={{this}} /S=0B" $0 $1 $2
-    IntOp $AppSize $AppSize + $0
   {{/each}}
 
   ; Create file associations
@@ -578,9 +581,7 @@ Section Install
   WriteRegStr SHCTX "${UNINSTKEY}" "UninstallString" "$\"$INSTDIR\uninstall.exe$\""
   WriteRegDWORD SHCTX "${UNINSTKEY}" "NoModify" "1"
   WriteRegDWORD SHCTX "${UNINSTKEY}" "NoRepair" "1"
-  IntOp $AppSize $AppSize / 1000
-  IntFmt $AppSize "0x%08X" $AppSize
-  WriteRegDWORD SHCTX "${UNINSTKEY}" "EstimatedSize" "$AppSize"
+  WriteRegDWORD SHCTX "${UNINSTKEY}" "EstimatedSize" "${ESTIMATEDSIZE}"
 
   ; Create start menu shortcut (GUI)
   !insertmacro MUI_STARTMENU_WRITE_BEGIN Application
@@ -637,7 +638,6 @@ Section Uninstall
   ; Delete resources
   {{#each resources}}
     Delete "$INSTDIR\\{{this.[1]}}"
-    RMDir "$INSTDIR\\{{this.[0]}}"
   {{/each}}
 
   ; Delete external binaries
@@ -655,7 +655,14 @@ Section Uninstall
   ; Delete uninstaller
   Delete "$INSTDIR\uninstall.exe"
 
-  RMDir "$INSTDIR"
+  ${If} $DeleteAppDataCheckboxState == 1
+    RMDir /R /REBOOTOK "$INSTDIR"
+  ${Else}
+    {{#each resources_ancestors}}
+    RMDir /REBOOTOK "$INSTDIR\\{{this}}"
+    {{/each}}
+    RMDir "$INSTDIR"
+  ${EndIf}
 
   ; Remove start menu shortcut
   !insertmacro MUI_STARTMENU_GETFOLDER Application $AppStartMenuFolder

+ 51 - 3
tooling/bundler/src/bundle/windows/util.rs

@@ -5,7 +5,7 @@
 use std::{
   fs::{create_dir_all, File},
   io::{Cursor, Read, Write},
-  path::Path,
+  path::{Path, PathBuf},
 };
 
 use log::info;
@@ -13,13 +13,61 @@ use sha2::Digest;
 use zip::ZipArchive;
 
 pub const WEBVIEW2_BOOTSTRAPPER_URL: &str = "https://go.microsoft.com/fwlink/p/?LinkId=2124703";
-pub const WEBVIEW2_X86_OFFLINE_INSTALLER_GUID: &str = "2c122012-898d-4a69-9ab6-aa50bbe81031";
-pub const WEBVIEW2_X64_OFFLINE_INSTALLER_GUID: &str = "0af26c79-02f0-4f06-a12d-116bc05ca860";
+pub const WEBVIEW2_OFFLINE_INSTALLER_X86_URL: &str =
+  "https://go.microsoft.com/fwlink/?linkid=2099617";
+pub const WEBVIEW2_OFFLINE_INSTALLER_X64_URL: &str =
+  "https://go.microsoft.com/fwlink/?linkid=2124701";
+pub const WEBVIEW2_URL_PREFIX: &str =
+  "https://msedge.sf.dl.delivery.mp.microsoft.com/filestreamingservice/files/";
 pub const NSIS_OUTPUT_FOLDER_NAME: &str = "nsis";
 pub const NSIS_UPDATER_OUTPUT_FOLDER_NAME: &str = "nsis-updater";
 pub const WIX_OUTPUT_FOLDER_NAME: &str = "msi";
 pub const WIX_UPDATER_OUTPUT_FOLDER_NAME: &str = "msi-updater";
 
+pub fn webview2_guid_path(url: &str) -> crate::Result<(String, String)> {
+  let agent = ureq::AgentBuilder::new().try_proxy_from_env(true).build();
+  let response = agent.head(url).call().map_err(Box::new)?;
+  let final_url = response.get_url();
+  let remaining_url = final_url.strip_prefix(WEBVIEW2_URL_PREFIX).ok_or_else(|| {
+    anyhow::anyhow!(
+      "WebView2 URL prefix mismatch. Expected `{}`, found `{}`.",
+      WEBVIEW2_URL_PREFIX,
+      final_url
+    )
+  })?;
+  let (guid, filename) = remaining_url.split_once('/').ok_or_else(|| {
+    anyhow::anyhow!(
+      "WebView2 URL format mismatch. Expected `<GUID>/<FILENAME>`, found `{}`.",
+      remaining_url
+    )
+  })?;
+  Ok((guid.into(), filename.into()))
+}
+
+pub fn download_webview2_bootstrapper(base_path: &Path) -> crate::Result<PathBuf> {
+  let file_path = base_path.join("MicrosoftEdgeWebview2Setup.exe");
+  if !file_path.exists() {
+    std::fs::write(&file_path, download(WEBVIEW2_BOOTSTRAPPER_URL)?)?;
+  }
+  Ok(file_path)
+}
+
+pub fn download_webview2_offline_installer(base_path: &Path, arch: &str) -> crate::Result<PathBuf> {
+  let url = if arch == "x64" {
+    WEBVIEW2_OFFLINE_INSTALLER_X64_URL
+  } else {
+    WEBVIEW2_OFFLINE_INSTALLER_X86_URL
+  };
+  let (guid, filename) = webview2_guid_path(url)?;
+  let dir_path = base_path.join(guid);
+  let file_path = dir_path.join(filename);
+  if !file_path.exists() {
+    create_dir_all(dir_path)?;
+    std::fs::write(&file_path, download(url)?)?;
+  }
+  Ok(file_path)
+}
+
 pub fn download(url: &str) -> crate::Result<Vec<u8>> {
   info!(action = "Downloading"; "{}", url);
 

+ 28 - 0
tooling/cli/CHANGELOG.md

@@ -305,6 +305,34 @@
 - First mobile alpha release!
   - [fa3a1098](https://www.github.com/tauri-apps/tauri/commit/fa3a10988a03aed1b66fb17d893b1a9adb90f7cd) feat(ci): prepare 2.0.0-alpha.0 ([#5786](https://www.github.com/tauri-apps/tauri/pull/5786)) on 2022-12-08
 
+## \[1.5.8]
+
+### Dependencies
+
+- Upgraded to `tauri-bundler@1.4.7`
+
+## \[1.5.7]
+
+### Bug Fixes
+
+- [`1d5aa38a`](https://www.github.com/tauri-apps/tauri/commit/1d5aa38ae418ea31f593590b6d32cf04d3bfd8c1)([#8162](https://www.github.com/tauri-apps/tauri/pull/8162)) Fixes errors on command output, occuring when the output stream contains an invalid UTF-8 character, or ends with a multi-bytes UTF-8 character.
+- [`f26d9f08`](https://www.github.com/tauri-apps/tauri/commit/f26d9f0884f63f61b9f4d4fac15e6b251163793e)([#8263](https://www.github.com/tauri-apps/tauri/pull/8263)) Fixes an issue in the NSIS installer which caused the uninstallation to leave empty folders on the system if the `resources` feature was used.
+- [`92bc7d0e`](https://www.github.com/tauri-apps/tauri/commit/92bc7d0e16157434330a1bcf1eefda6f0f1e5f85)([#8233](https://www.github.com/tauri-apps/tauri/pull/8233)) Fixes an issue in the NSIS installer which caused the installation to take much longer than expected when many `resources` were added to the bundle.
+
+### Dependencies
+
+- Upgraded to `tauri-bundler@1.4.6`
+
+## \[1.5.6]
+
+### Bug Fixes
+
+- [`5264e41d`](https://www.github.com/tauri-apps/tauri/commit/5264e41db3763e4c2eb0c3c21bd423fb7bece3e2)([#8082](https://www.github.com/tauri-apps/tauri/pull/8082)) Downgraded `rust-minisign` to `0.7.3` to fix signing updater bundles with empty passwords.
+
+### Dependencies
+
+- Upgraded to `tauri-bundler@1.4.5`
+
 ## \[1.5.5]
 
 ### Enhancements

+ 30 - 52
tooling/cli/Cargo.lock

@@ -577,9 +577,9 @@ dependencies = [
 
 [[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",
@@ -587,9 +587,9 @@ 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 = "core2"
@@ -793,9 +793,9 @@ checksum = "7762d17f1241643615821a8455a0b2c3e803784b058693d990b11f2dce25a0ca"
 
 [[package]]
 name = "data-encoding"
-version = "2.4.0"
+version = "2.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308"
+checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5"
 
 [[package]]
 name = "data-url"
@@ -1133,9 +1133,9 @@ 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",
 ]
@@ -1327,9 +1327,9 @@ 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 = "glob"
@@ -1339,15 +1339,15 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
 
 [[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",
+ "regex-syntax",
 ]
 
 [[package]]
@@ -1561,9 +1561,9 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
 
 [[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",
@@ -1571,17 +1571,16 @@ dependencies = [
 
 [[package]]
 name = "ignore"
-version = "0.4.20"
+version = "0.4.21"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dbe7873dab538a9a44ad79ede1faf5f30d49f9a5c883ddbab48bce81b64b7492"
+checksum = "747ad1b4ae841a78e8aba0d63adbfbeaea26b517b63705d47856b73015d27060"
 dependencies = [
+ "crossbeam-deque",
  "globset",
- "lazy_static",
  "log",
  "memchr",
- "regex",
+ "regex-automata",
  "same-file",
- "thread_local",
  "walkdir",
  "winapi-util",
 ]
@@ -2625,9 +2624,9 @@ dependencies = [
 
 [[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"
@@ -2933,9 +2932,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068"
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.69"
+version = "1.0.70"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da"
+checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b"
 dependencies = [
  "unicode-ident",
 ]
@@ -4110,7 +4109,7 @@ dependencies = [
  "thiserror",
  "tokio",
  "toml 0.8.8",
- "toml_edit 0.20.7",
+ "toml_edit",
  "unicode-width",
  "ureq",
  "url",
@@ -4281,16 +4280,6 @@ dependencies = [
  "syn 2.0.39",
 ]
 
-[[package]]
-name = "thread_local"
-version = "1.1.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152"
-dependencies = [
- "cfg-if",
- "once_cell",
-]
-
 [[package]]
 name = "tiff"
 version = "0.9.0"
@@ -4457,7 +4446,7 @@ dependencies = [
  "serde",
  "serde_spanned",
  "toml_datetime",
- "toml_edit 0.21.0",
+ "toml_edit",
 ]
 
 [[package]]
@@ -4469,17 +4458,6 @@ dependencies = [
  "serde",
 ]
 
-[[package]]
-name = "toml_edit"
-version = "0.20.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81"
-dependencies = [
- "indexmap 2.1.0",
- "toml_datetime",
- "winnow",
-]
-
 [[package]]
 name = "toml_edit"
 version = "0.21.0"
@@ -4718,9 +4696,9 @@ dependencies = [
 
 [[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",
@@ -4988,9 +4966,9 @@ dependencies = [
 
 [[package]]
 name = "webpki-roots"
-version = "0.25.2"
+version = "0.25.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc"
+checksum = "1778a42e8b3b90bff8d0f5032bf22250792889a5cdc752aa0020c84abe3aaf10"
 
 [[package]]
 name = "weezl"

+ 1 - 1
tooling/cli/Cargo.toml

@@ -57,7 +57,7 @@ notify = "6.1"
 notify-debouncer-mini = "0.4"
 shared_child = "1.0"
 duct = "0.13"
-toml_edit = "0.20"
+toml_edit = "0.21"
 json-patch = "1.2"
 tauri-utils = { version = "2.0.0-alpha.12", path = "../../core/tauri-utils", features = [ "isolation", "schema", "config-json5", "config-toml" ] }
 tauri-utils-v1 = { version = "1", package = "tauri-utils", features = [ "isolation", "schema", "config-json5", "config-toml" ] }

+ 2 - 2
tooling/cli/metadata.json

@@ -1,8 +1,8 @@
 {
   "cli.js": {
-    "version": "1.5.5",
+    "version": "1.5.8",
     "node": ">= 10.0.0"
   },
-  "tauri": "1.5.2",
+  "tauri": "1.5.3",
   "tauri-build": "1.5.0"
 }

+ 28 - 0
tooling/cli/node/CHANGELOG.md

@@ -288,6 +288,34 @@
 - First mobile alpha release!
   - [fa3a1098](https://www.github.com/tauri-apps/tauri/commit/fa3a10988a03aed1b66fb17d893b1a9adb90f7cd) feat(ci): prepare 2.0.0-alpha.0 ([#5786](https://www.github.com/tauri-apps/tauri/pull/5786)) on 2022-12-08
 
+## \[1.5.8]
+
+### Dependencies
+
+- Upgraded to `tauri-cli@1.5.8`
+
+## \[1.5.7]
+
+### Bug Fixes
+
+- [`1d5aa38a`](https://www.github.com/tauri-apps/tauri/commit/1d5aa38ae418ea31f593590b6d32cf04d3bfd8c1)([#8162](https://www.github.com/tauri-apps/tauri/pull/8162)) Fixes errors on command output, occuring when the output stream contains an invalid UTF-8 character, or ends with a multi-bytes UTF-8 character.
+- [`f26d9f08`](https://www.github.com/tauri-apps/tauri/commit/f26d9f0884f63f61b9f4d4fac15e6b251163793e)([#8263](https://www.github.com/tauri-apps/tauri/pull/8263)) Fixes an issue in the NSIS installer which caused the uninstallation to leave empty folders on the system if the `resources` feature was used.
+- [`92bc7d0e`](https://www.github.com/tauri-apps/tauri/commit/92bc7d0e16157434330a1bcf1eefda6f0f1e5f85)([#8233](https://www.github.com/tauri-apps/tauri/pull/8233)) Fixes an issue in the NSIS installer which caused the installation to take much longer than expected when many `resources` were added to the bundle.
+
+### Dependencies
+
+- Upgraded to `tauri-cli@1.5.7`
+
+## \[1.5.6]
+
+### Bug Fixes
+
+- [`5264e41d`](https://www.github.com/tauri-apps/tauri/commit/5264e41db3763e4c2eb0c3c21bd423fb7bece3e2)([#8082](https://www.github.com/tauri-apps/tauri/pull/8082)) Downgraded `rust-minisign` to `0.7.3` to fix signing updater bundles with empty passwords.
+
+### Dependencies
+
+- Upgraded to `tauri-cli@1.5.6`
+
 ## \[1.5.5]
 
 ### Enhancements

+ 3 - 3
tooling/cli/node/Cargo.toml

@@ -8,13 +8,13 @@ crate-type = ["cdylib"]
 
 [dependencies]
 # Default enable napi4 feature, see https://nodejs.org/api/n-api.html#node-api-version-matrix
-napi = { version = "2.13", default-features = false, features = ["napi4"] }
-napi-derive = "2.13"
+napi = { version = "2.14", default-features = false, features = ["napi4"] }
+napi-derive = "2.14"
 tauri-cli = { path = "..", default-features = false }
 log = "0.4.20"
 
 [build-dependencies]
-napi-build = "2.0"
+napi-build = "2.1"
 
 [features]
 default = ["tauri-cli/default"]

+ 1 - 1
tooling/cli/node/test/jest/fixtures/app/src-tauri/Cargo.toml

@@ -24,7 +24,7 @@ icon = [
 tauri-build = { path = "../../../../../../../../core/tauri-build", features = [] }
 
 [dependencies]
-serde_json = "1.0.107"
+serde_json = "1.0.108"
 serde = "1.0"
 serde_derive = "1.0"
 tauri = { path = "../../../../../../../../core/tauri", features = ["api-all"] }

+ 1 - 1
tooling/cli/src/build.rs

@@ -58,7 +58,7 @@ pub struct Options {
   /// JSON string or path to JSON file to merge with tauri.conf.json
   #[clap(short, long)]
   pub config: Option<String>,
-  /// Command line arguments passed to the runner
+  /// Command line arguments passed to the runner. Use `--` to explicitly mark the start of the arguments.
   pub args: Vec<String>,
   /// Skip prompting for values
   #[clap(long)]

+ 3 - 1
tooling/cli/src/dev.rs

@@ -63,7 +63,9 @@ pub struct Options {
   /// Run the code in release mode
   #[clap(long = "release")]
   pub release_mode: bool,
-  /// Command line arguments passed to the runner. Arguments after `--` are passed to the application.
+  /// Command line arguments passed to the runner.
+  /// Use `--` to explicitly mark the start of the arguments. Arguments after a second `--` are passed to the application
+  /// e.g. `tauri dev -- [runnerArgs] -- [appArgs]`.
   pub args: Vec<String>,
   /// Skip waiting for the frontend dev server to start before building the tauri application.
   #[clap(long, env = "TAURI_CLI_NO_DEV_SERVER_WAIT")]

+ 16 - 0
tooling/cli/src/helpers/updater_signature.rs

@@ -165,3 +165,19 @@ where
     .map_err(|e| minisign::PError::new(minisign::ErrorKind::Io, e))?;
   Ok(BufReader::new(file))
 }
+
+#[cfg(test)]
+mod tests {
+  const PRIVATE_KEY: &str = "dW50cnVzdGVkIGNvbW1lbnQ6IHJzaWduIGVuY3J5cHRlZCBzZWNyZXQga2V5ClJXUlRZMEl5dkpDN09RZm5GeVAzc2RuYlNzWVVJelJRQnNIV2JUcGVXZUplWXZXYXpqUUFBQkFBQUFBQUFBQUFBQUlBQUFBQTZrN2RnWGh5dURxSzZiL1ZQSDdNcktiaHRxczQwMXdQelRHbjRNcGVlY1BLMTBxR2dpa3I3dDE1UTVDRDE4MXR4WlQwa1BQaXdxKy9UU2J2QmVSNXhOQWFDeG1GSVllbUNpTGJQRkhhTnROR3I5RmdUZi90OGtvaGhJS1ZTcjdZU0NyYzhQWlQ5cGM9Cg==";
+
+  // we use minisign=0.7.3 to prevent a breaking change
+  #[test]
+  fn empty_password_is_valid() {
+    let path = std::env::temp_dir().join("minisign-password-text.txt");
+    std::fs::write(&path, b"TAURI").expect("failed to write test file");
+
+    let secret_key =
+      super::secret_key(PRIVATE_KEY.into(), Some("".into())).expect("failed to resolve secret key");
+    super::sign_file(&secret_key, &path).expect("failed to sign file");
+  }
+}

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

@@ -278,11 +278,14 @@ impl CommandExt for Command {
       let mut lines = stdout_lines_.lock().unwrap();
       loop {
         line.clear();
-        if let Ok(0) = stdout.read_line(&mut line) {
-          break;
+        match stdout.read_line(&mut line) {
+          Ok(0) => break,
+          Ok(_) => {
+            debug!(action = "stdout"; "{}", line.trim_end());
+            lines.extend(line.as_bytes().to_vec());
+          }
+          Err(_) => (),
         }
-        debug!(action = "stdout"; "{}", &line[0..line.len() - 1]);
-        lines.extend(line.as_bytes().to_vec());
       }
     });
 
@@ -294,11 +297,14 @@ impl CommandExt for Command {
       let mut lines = stderr_lines_.lock().unwrap();
       loop {
         line.clear();
-        if let Ok(0) = stderr.read_line(&mut line) {
-          break;
+        match stderr.read_line(&mut line) {
+          Ok(0) => break,
+          Ok(_) => {
+            debug!(action = "stderr"; "{}", line.trim_end());
+            lines.extend(line.as_bytes().to_vec());
+          }
+          Err(_) => (),
         }
-        debug!(action = "stderr"; "{}", &line[0..line.len() - 1]);
-        lines.extend(line.as_bytes().to_vec());
       }
     });
 

Certains fichiers n'ont pas été affichés car il y a eu trop de fichiers modifiés dans ce diff