Explorar o código

Refact(All): (WIP) Cleanup workflow and add Windows Features. (#468)

* use var_os instead of var

* combine both var calls

* Add logic to remove cmd windows.

* fix build.rs

* modify for clippy.

* expose handle and refactor commands.

* add author name

* revert command changes

* little refactor

* add loopback to wix template

* fix custom command
Tensor-Programming %!s(int64=5) %!d(string=hai) anos
pai
achega
6f12a34e6f

+ 17 - 9
cli/tauri-bundler/src/bundle/settings.rs

@@ -238,7 +238,7 @@ impl Settings {
     let tauri_config = super::tauri_config::get();
     let merged_bundle_settings = match tauri_config {
       Ok(config) => merge_settings(bundle_settings, config.tauri.bundle),
-      Err(_) => bundle_settings
+      Err(_) => bundle_settings,
     };
 
     Ok(Settings {
@@ -591,17 +591,16 @@ fn add_external_bin(bundle_settings: BundleSettings) -> crate::Result<BundleSett
 }
 
 fn options_value<T>(first: Option<T>, second: Option<T>) -> Option<T> {
-  if first.is_some() {
+  if let Some(_) = first {
     first
-  }
-  else {
+  } else {
     second
   }
 }
 
 fn merge_settings(
   bundle_settings: BundleSettings,
-  config: crate::bundle::tauri_config::BundleConfig
+  config: crate::bundle::tauri_config::BundleConfig,
 ) -> BundleSettings {
   BundleSettings {
     name: options_value(config.name, bundle_settings.name),
@@ -616,9 +615,15 @@ fn merge_settings(
     script: options_value(config.script, bundle_settings.script),
     deb_depends: options_value(config.deb.depends, bundle_settings.deb_depends),
     osx_frameworks: options_value(config.osx.frameworks, bundle_settings.osx_frameworks),
-    osx_minimum_system_version: options_value(config.osx.minimum_system_version, bundle_settings.osx_minimum_system_version),
+    osx_minimum_system_version: options_value(
+      config.osx.minimum_system_version,
+      bundle_settings.osx_minimum_system_version,
+    ),
     external_bin: options_value(config.external_bin, bundle_settings.external_bin),
-    exception_domain: options_value(config.osx.exception_domain, bundle_settings.exception_domain),
+    exception_domain: options_value(
+      config.osx.exception_domain,
+      bundle_settings.exception_domain,
+    ),
     ..bundle_settings
   }
 }
@@ -629,7 +634,7 @@ pub struct ResourcePaths<'a> {
   walk_iter: Option<walkdir::IntoIter>,
   allow_walk: bool,
   current_pattern: Option<String>,
-  current_pattern_is_valid: bool
+  current_pattern_is_valid: bool,
 }
 
 impl<'a> ResourcePaths<'a> {
@@ -686,7 +691,10 @@ impl<'a> Iterator for ResourcePaths<'a> {
         } else {
           if let Some(current_path) = &self.current_pattern {
             if !self.current_pattern_is_valid {
-              return Some(Err(crate::Error::from(format!("Path matching '{}' not found", current_path))));
+              return Some(Err(crate::Error::from(format!(
+                "Path matching '{}' not found",
+                current_path
+              ))));
             }
           }
         }

+ 8 - 1
cli/tauri-bundler/src/bundle/templates/main.wxs

@@ -9,7 +9,6 @@
 <?endif?>
 
 <Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
-
     <Product
             Id="*"
             Name="{{{product_name}}}"
@@ -126,5 +125,13 @@
         </Feature>
 
         <SetProperty Id="ARPINSTALLLOCATION" Value="[APPLICATIONFOLDER]" After="CostFinalize"/>
+
+        <InstallExecuteSequence>
+            <Custom Action='LoopBackCmd' After='InstallFiles'/>
+        </InstallExecuteSequence>
     </Product>
+
+    <Fragment>
+        <CustomAction Id="LoopBackCmd" Directory="ApplicationProgramsFolder" Execute="commit" Impersonate="no" ExeCommand="cmd.exe /c &quot;CheckNetIsolation.exe LoopbackExempt -a -n=&quot;Microsoft.Win32WebViewHost_cw5n1h2txyewy&quot;&quot;" Return="ignore" />
+    </Fragment>
 </Wix>

+ 1 - 1
cli/tauri-bundler/src/main.rs

@@ -75,7 +75,7 @@ fn run() -> crate::Result<()> {
     .setting(AppSettings::SubcommandRequired)
     .subcommand(
       SubCommand::with_name("tauri-bundler")
-        .author("George Burton <burtonageo@gmail.com>, Lucas Fernandes Gonçalves Nogueira <lucas@quasar.dev>, Daniel Thompson-Yvetot <denjell@sfosc.org>")
+        .author("George Burton <burtonageo@gmail.com>, Lucas Fernandes Gonçalves Nogueira <lucas@quasar.dev>, Daniel Thompson-Yvetot <denjell@sfosc.org>, Tensor Programming <tensordeveloper@gmail.com>")
         .about("Bundle Rust executables into OS bundles")
         .setting(AppSettings::DisableVersion)
         .setting(AppSettings::UnifiedHelpMessage)

+ 49 - 2
tauri-api/src/command.rs

@@ -1,7 +1,14 @@
 use std::process::{Child, Command, Stdio};
 
+#[cfg(windows)]
+use std::os::windows::process::CommandExt;
+
+#[cfg(windows)]
+const CREATE_NO_WINDOW: u32 = 0x08000000;
+
 use tauri_utils::platform;
 
+#[cfg(not(windows))]
 pub fn get_output(cmd: String, args: Vec<String>, stdout: Stdio) -> crate::Result<String> {
   Command::new(cmd)
     .args(args)
@@ -17,6 +24,23 @@ pub fn get_output(cmd: String, args: Vec<String>, stdout: Stdio) -> crate::Resul
     })
 }
 
+#[cfg(windows)]
+pub fn get_output(cmd: String, args: Vec<String>, stdout: Stdio) -> crate::Result<String> {
+  Command::new(cmd)
+    .args(args)
+    .stdout(stdout)
+    .creation_flags(CREATE_NO_WINDOW)
+    .output()
+    .map_err(|err| crate::Error::with_chain(err, "Command: get output failed"))
+    .and_then(|output| {
+      if output.status.success() {
+        Ok(String::from_utf8_lossy(&output.stdout).to_string())
+      } else {
+        Err(crate::ErrorKind::Command(String::from_utf8_lossy(&output.stderr).to_string()).into())
+      }
+    })
+}
+
 pub fn format_command(path: String, command: String) -> String {
   if cfg!(windows) {
     format!("{}/./{}.exe", path, command)
@@ -32,16 +56,39 @@ pub fn relative_command(command: String) -> crate::Result<String> {
   }
 }
 
+#[cfg(not(windows))]
 pub fn command_path(command: String) -> crate::Result<String> {
   match std::env::current_exe()?.parent() {
-    #[cfg(not(windows))]
     Some(exe_dir) => Ok(format!("{}/{}", exe_dir.display().to_string(), command)),
-    #[cfg(windows)]
+    None => Err(crate::ErrorKind::Command("Could not evaluate executable dir".to_string()).into()),
+  }
+}
+
+#[cfg(windows)]
+pub fn command_path(command: String) -> crate::Result<String> {
+  match std::env::current_exe()?.parent() {
     Some(exe_dir) => Ok(format!("{}/{}.exe", exe_dir.display().to_string(), command)),
     None => Err(crate::ErrorKind::Command("Could not evaluate executable dir".to_string()).into()),
   }
 }
 
+#[cfg(windows)]
+pub fn spawn_relative_command(
+  command: String,
+  args: Vec<String>,
+  stdout: Stdio,
+) -> crate::Result<Child> {
+  let cmd = relative_command(command)?;
+  Ok(
+    Command::new(cmd)
+      .args(args)
+      .creation_flags(CREATE_NO_WINDOW)
+      .stdout(stdout)
+      .spawn()?,
+  )
+}
+
+#[cfg(not(windows))]
 pub fn spawn_relative_command(
   command: String,
   args: Vec<String>,

+ 19 - 11
tauri/build.rs

@@ -1,22 +1,30 @@
 #[cfg(not(feature = "dev-server"))]
 pub fn main() {
-  println!(
-    "cargo:rerun-if-changed={}",
-    std::env::var("TAURI_DIST_DIR").expect("Unable to read dist directory")
-  );
-  match std::env::var("TAURI_DIST_DIR") {
-    Ok(dist_path) => {
-      let inlined_assets = match std::env::var("TAURI_INLINED_ASSETS") {
-        Ok(assets) => assets.split('|').map(|s| s.to_string()).collect(),
-        Err(_) => Vec::new(),
+  match std::env::var_os("TAURI_DIST_DIR") {
+    Some(dist_path) => {
+      let dist_path_string = dist_path.into_string().unwrap();
+
+      println!("cargo:rerun-if-changed={}", dist_path_string);
+
+      let inlined_assets = match std::env::var_os("TAURI_INLINED_ASSETS") {
+        Some(assets) => assets
+          .into_string()
+          .unwrap()
+          .split('|')
+          .map(|s| s.to_string())
+          .collect(),
+        None => Vec::new(),
       };
       // include assets
       tauri_includedir_codegen::start("ASSETS")
-        .dir(dist_path, tauri_includedir_codegen::Compression::None)
+        .dir(
+          dist_path_string,
+          tauri_includedir_codegen::Compression::None,
+        )
         .build("data.rs", inlined_assets)
         .expect("failed to build data.rs")
     }
-    Err(e) => panic!("Build error: Couldn't find ENV: {}", e),
+    None => println!("Build error: Couldn't find ENV: TAURI_DIST_DIR"),
   }
 }
 

+ 12 - 10
tauri/src/endpoints.rs

@@ -1,8 +1,8 @@
 mod cmd;
 
-use web_view::WebView;
 #[cfg(not(any(feature = "dev-server", feature = "embedded-server")))]
-use std::path::{PathBuf};
+use std::path::PathBuf;
+use web_view::WebView;
 
 #[allow(unused_variables)]
 pub(crate) fn handle<T: 'static>(webview: &mut WebView<'_, T>, arg: &str) -> crate::Result<bool> {
@@ -203,13 +203,11 @@ fn load_asset<T: 'static>(
   crate::execute_promise(
     webview,
     move || {
-      let mut path = PathBuf::from(
-        if asset.starts_with('/') {
-          asset.replacen("/", "", 1)
-        } else {
-          asset.clone()
-        }
-      );
+      let mut path = PathBuf::from(if asset.starts_with('/') {
+        asset.replacen("/", "", 1)
+      } else {
+        asset.clone()
+      });
       let mut read_asset;
       loop {
         read_asset = crate::assets::ASSETS.get(&format!(
@@ -221,7 +219,11 @@ fn load_asset<T: 'static>(
           match path.iter().next() {
             Some(component) => {
               let first_component = component.to_str().expect("failed to read path component");
-              path = PathBuf::from(path.to_string_lossy().replacen(format!("{}/", first_component).as_str(), "", 1));
+              path = PathBuf::from(path.to_string_lossy().replacen(
+                format!("{}/", first_component).as_str(),
+                "",
+                1,
+              ));
             }
             None => {
               return Err(format!("Asset '{}' not found", asset).into());

+ 2 - 2
tauri/src/lib.rs

@@ -24,8 +24,8 @@ use std::process::Stdio;
 use error_chain::error_chain;
 use threadpool::ThreadPool;
 
-pub use app::*;
-pub use web_view::{WebView, Handle};
+pub use web_view::Handle;
+use web_view::WebView;
 
 pub use app::*;
 pub use tauri_api as api;