浏览代码

fix(cli): warn about bundling updater target without appropriate targets, closes #7181 (#7189)

* fix(cli): warn about bundling updater target without appropriate targets, closes #7181

* change tags

* cleanup

---------

Co-authored-by: Lucas Nogueira <lucas@tauri.studio>
Amr Bashir 2 年之前
父节点
当前提交
d75c1b829b

+ 6 - 0
.changes/cli-updater-only.md

@@ -0,0 +1,6 @@
+---
+'tauri-cli': 'patch:enhance'
+'@tauri-apps/cli': 'patch:enhance'
+---
+
+Print a useful error when `updater` bundle target is specified without an updater-enabled target.

+ 1 - 0
core/tauri-utils/Cargo.toml

@@ -36,6 +36,7 @@ walkdir = { version = "2", optional = true }
 memchr = "2"
 semver = "1"
 infer = "0.12"
+dunce = "1"
 
 [target."cfg(target_os = \"linux\")".dependencies]
 heck = "0.4"

+ 2 - 4
core/tauri-utils/src/lib.rs

@@ -298,11 +298,9 @@ macro_rules! debug_eprintln {
   };
 }
 
-/// Reconstructs a path from its components using the platform separator then converts it to String
+/// Reconstructs a path from its components using the platform separator then converts it to String and removes UNC prefixes on Windows if it exists.
 pub fn display_path<P: AsRef<Path>>(p: P) -> String {
-  p.as_ref()
-    .components()
-    .collect::<PathBuf>()
+  dunce::simplified(&p.as_ref().components().collect::<PathBuf>())
     .display()
     .to_string()
 }

+ 1 - 32
examples/api/src-tauri/Cargo.lock

@@ -259,24 +259,6 @@ version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "debc29dde2e69f9e47506b525f639ed42300fc014a3e007832592448fa8e4599"
 
-[[package]]
-name = "attohttpc"
-version = "0.22.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1fcf00bc6d5abb29b5f97e3c61a90b6d3caa12f3faf897d4a3e3607c050a35a7"
-dependencies = [
- "flate2",
- "http",
- "log",
- "mime",
- "multipart",
- "native-tls",
- "serde",
- "serde_json",
- "serde_urlencoded",
- "url",
-]
-
 [[package]]
 name = "atty"
 version = "0.2.14"
@@ -2139,19 +2121,6 @@ dependencies = [
  "syn 1.0.107",
 ]
 
-[[package]]
-name = "multipart"
-version = "0.18.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "00dec633863867f29cb39df64a397cdf4a6354708ddd7759f70c7fb51c5f9182"
-dependencies = [
- "log",
- "mime",
- "mime_guess",
- "rand 0.8.5",
- "tempfile",
-]
-
 [[package]]
 name = "native-tls"
 version = "0.2.11"
@@ -3609,7 +3578,6 @@ name = "tauri"
 version = "1.3.0"
 dependencies = [
  "anyhow",
- "attohttpc",
  "base64 0.21.0",
  "bytes",
  "clap",
@@ -3764,6 +3732,7 @@ dependencies = [
  "aes-gcm",
  "brotli",
  "ctor",
+ "dunce",
  "getrandom 0.2.8",
  "glob",
  "heck 0.4.0",

+ 45 - 19
tooling/bundler/src/bundle.rs

@@ -43,8 +43,12 @@ pub struct Bundle {
 /// Bundles the project.
 /// Returns the list of paths where the bundles can be found.
 pub fn bundle_project(settings: Settings) -> crate::Result<Vec<Bundle>> {
-  let mut bundles: Vec<Bundle> = Vec::new();
   let package_types = settings.package_types()?;
+  if package_types.is_empty() {
+    return Ok(Vec::new());
+  }
+
+  let mut bundles: Vec<Bundle> = Vec::new();
 
   let target_os = settings
     .target()
@@ -93,9 +97,23 @@ pub fn bundle_project(settings: Settings) -> crate::Result<Vec<Bundle>> {
       PackageType::AppImage => linux::appimage::bundle_project(&settings)?,
 
       // updater is dependant of multiple bundle, we send our bundles to prevent rebuilding
-      PackageType::Updater => updater_bundle::bundle_project(&settings, &bundles)?,
+      PackageType::Updater => {
+        if !package_types.iter().any(|p| {
+          matches!(
+            p,
+            PackageType::AppImage
+              | PackageType::MacOsBundle
+              | PackageType::Nsis
+              | PackageType::WindowsMsi
+          )
+        }) {
+          warn!("The updater bundle target exists but couldn't find any updater-enabled target, so the updater artifacts won't be generated. Please add one of these targets as well: app, appimage, msi, nsis");
+          continue;
+        }
+        updater_bundle::bundle_project(&settings, &bundles)?
+      }
       _ => {
-        warn!("ignoring {:?}", package_type);
+        warn!("ignoring {}", package_type.short_name());
         continue;
       }
     };
@@ -133,26 +151,34 @@ pub fn bundle_project(settings: Settings) -> crate::Result<Vec<Bundle>> {
     }
   }
 
-  let pluralised = if bundles.len() == 1 {
-    "bundle"
-  } else {
-    "bundles"
-  };
-
-  let mut printable_paths = String::new();
-  for bundle in &bundles {
-    for path in &bundle.bundle_paths {
-      let mut note = "";
-      if bundle.package_type == crate::PackageType::Updater {
-        note = " (updater)";
+  if !bundles.is_empty() {
+    let bundles_wo_updater = bundles
+      .iter()
+      .filter(|b| b.package_type != PackageType::Updater)
+      .collect::<Vec<_>>();
+    let pluralised = if bundles_wo_updater.len() == 1 {
+      "bundle"
+    } else {
+      "bundles"
+    };
+
+    let mut printable_paths = String::new();
+    for bundle in &bundles {
+      for path in &bundle.bundle_paths {
+        let mut note = "";
+        if bundle.package_type == crate::PackageType::Updater {
+          note = " (updater)";
+        }
+        writeln!(printable_paths, "        {}{}", display_path(path), note).unwrap();
       }
-      writeln!(printable_paths, "        {}{}", display_path(path), note).unwrap();
     }
-  }
 
-  info!(action = "Finished"; "{} {} at:\n{}", bundles.len(), pluralised, printable_paths);
+    info!(action = "Finished"; "{} {} at:\n{}", bundles_wo_updater.len(), pluralised, printable_paths);
 
-  Ok(bundles)
+    Ok(bundles)
+  } else {
+    Err(anyhow::anyhow!("No bundles were built").into())
+  }
 }
 
 /// Check to see if there are icons in the settings struct

+ 33 - 53
tooling/bundler/src/bundle/updater_bundle.rs

@@ -5,12 +5,6 @@
 
 use super::common;
 
-#[cfg(target_os = "macos")]
-use super::macos::app;
-
-#[cfg(target_os = "linux")]
-use super::linux::appimage;
-
 use crate::{
   bundle::{
     windows::{
@@ -47,9 +41,9 @@ pub fn bundle_project(settings: &Settings, bundles: &[Bundle]) -> crate::Result<
   }
 
   #[cfg(target_os = "macos")]
-  return bundle_update_macos(settings, bundles);
+  return bundle_update_macos(bundles);
   #[cfg(target_os = "linux")]
-  return bundle_update_linux(settings, bundles);
+  return bundle_update_linux(bundles);
 
   #[cfg(not(any(target_os = "macos", target_os = "linux")))]
   {
@@ -61,11 +55,11 @@ pub fn bundle_project(settings: &Settings, bundles: &[Bundle]) -> crate::Result<
 // Create simple update-macos.tar.gz
 // This is the Mac OS App packaged
 #[cfg(target_os = "macos")]
-fn bundle_update_macos(settings: &Settings, bundles: &[Bundle]) -> crate::Result<Vec<PathBuf>> {
+fn bundle_update_macos(bundles: &[Bundle]) -> crate::Result<Vec<PathBuf>> {
   use std::ffi::OsStr;
 
   // find our .app or rebuild our bundle
-  let bundle_path = match bundles
+  if let Some(source_path) = bundles
     .iter()
     .filter(|bundle| bundle.package_type == crate::PackageType::MacOsBundle)
     .find_map(|bundle| {
@@ -73,30 +67,23 @@ fn bundle_update_macos(settings: &Settings, bundles: &[Bundle]) -> crate::Result
         .bundle_paths
         .iter()
         .find(|path| path.extension() == Some(OsStr::new("app")))
-    }) {
-    Some(path) => vec![path.clone()],
-    None => app::bundle_project(settings)?,
-  };
-
-  // we expect our .app to be on bundle_path[0]
-  if bundle_path.is_empty() {
-    return Err(crate::Error::UnableToFindProject);
-  }
-
-  let source_path = &bundle_path[0];
-
-  // add .tar.gz to our path
-  let osx_archived = format!("{}.tar.gz", source_path.display());
-  let osx_archived_path = PathBuf::from(&osx_archived);
+    })
+  {
+    // add .tar.gz to our path
+    let osx_archived = format!("{}.tar.gz", source_path.display());
+    let osx_archived_path = PathBuf::from(&osx_archived);
 
-  // Create our gzip file (need to send parent)
-  // as we walk the source directory (source isnt added)
-  create_tar(source_path, &osx_archived_path)
-    .with_context(|| "Failed to tar.gz update directory")?;
+    // Create our gzip file (need to send parent)
+    // as we walk the source directory (source isnt added)
+    create_tar(source_path, &osx_archived_path)
+      .with_context(|| "Failed to tar.gz update directory")?;
 
-  info!(action = "Bundling"; "{} ({})", osx_archived, display_path(&osx_archived_path));
+    info!(action = "Bundling"; "{} ({})", osx_archived, display_path(&osx_archived_path));
 
-  Ok(vec![osx_archived_path])
+    Ok(vec![osx_archived_path])
+  } else {
+    Err(crate::Error::UnableToFindProject)
+  }
 }
 
 // Create simple update-linux_<arch>.tar.gz
@@ -104,11 +91,11 @@ fn bundle_update_macos(settings: &Settings, bundles: &[Bundle]) -> crate::Result
 // Right now in linux we hot replace the bin and request a restart
 // No assets are replaced
 #[cfg(target_os = "linux")]
-fn bundle_update_linux(settings: &Settings, bundles: &[Bundle]) -> crate::Result<Vec<PathBuf>> {
+fn bundle_update_linux(bundles: &[Bundle]) -> crate::Result<Vec<PathBuf>> {
   use std::ffi::OsStr;
 
   // build our app actually we support only appimage on linux
-  let bundle_path = match bundles
+  if let Some(source_path) = bundles
     .iter()
     .filter(|bundle| bundle.package_type == crate::PackageType::AppImage)
     .find_map(|bundle| {
@@ -116,29 +103,22 @@ fn bundle_update_linux(settings: &Settings, bundles: &[Bundle]) -> crate::Result
         .bundle_paths
         .iter()
         .find(|path| path.extension() == Some(OsStr::new("AppImage")))
-    }) {
-    Some(path) => vec![path.clone()],
-    None => appimage::bundle_project(settings)?,
-  };
-
-  // we expect our .app to be on bundle[0]
-  if bundle_path.is_empty() {
-    return Err(crate::Error::UnableToFindProject);
-  }
-
-  let source_path = &bundle_path[0];
-
-  // add .tar.gz to our path
-  let appimage_archived = format!("{}.tar.gz", source_path.display());
-  let appimage_archived_path = PathBuf::from(&appimage_archived);
+    })
+  {
+    // add .tar.gz to our path
+    let appimage_archived = format!("{}.tar.gz", source_path.display());
+    let appimage_archived_path = PathBuf::from(&appimage_archived);
 
-  // Create our gzip file
-  create_tar(source_path, &appimage_archived_path)
-    .with_context(|| "Failed to tar.gz update directory")?;
+    // Create our gzip file
+    create_tar(source_path, &appimage_archived_path)
+      .with_context(|| "Failed to tar.gz update directory")?;
 
-  info!(action = "Bundling"; "{} ({})", appimage_archived, display_path(&appimage_archived_path));
+    info!(action = "Bundling"; "{} ({})", appimage_archived, display_path(&appimage_archived_path));
 
-  Ok(vec![appimage_archived_path])
+    Ok(vec![appimage_archived_path])
+  } else {
+    Err(crate::Error::UnableToFindProject)
+  }
 }
 
 // Create simple update-win_<arch>.zip

+ 5 - 3
tooling/cli/Cargo.lock

@@ -3435,6 +3435,7 @@ version = "1.3.0"
 dependencies = [
  "aes-gcm",
  "ctor 0.1.26",
+ "dunce",
  "getrandom 0.2.9",
  "glob",
  "heck",
@@ -3460,15 +3461,16 @@ dependencies = [
 
 [[package]]
 name = "tempfile"
-version = "3.5.0"
+version = "3.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998"
+checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6"
 dependencies = [
+ "autocfg",
  "cfg-if",
  "fastrand",
  "redox_syscall 0.3.5",
  "rustix",
- "windows-sys 0.45.0",
+ "windows-sys 0.48.0",
 ]
 
 [[package]]

+ 16 - 15
tooling/cli/src/build.rs

@@ -382,21 +382,22 @@ fn run_hook(name: &str, hook: HookCommand, interface: &AppInterface, debug: bool
 }
 
 fn print_signed_updater_archive(output_paths: &[PathBuf]) -> crate::Result<()> {
-  let pluralised = if output_paths.len() == 1 {
-    "updater archive"
-  } else {
-    "updater archives"
-  };
-  let msg = format!("{} {} at:", output_paths.len(), pluralised);
-  info!("{}", msg);
-  for path in output_paths {
-    #[cfg(unix)]
-    info!("        {}", path.display());
-    #[cfg(windows)]
-    info!(
-      "        {}",
-      tauri_utils::display_path(path).replacen(r"\\?\", "", 1)
-    );
+  use std::fmt::Write;
+  if !output_paths.is_empty() {
+    let pluralised = if output_paths.len() == 1 {
+      "updater signature"
+    } else {
+      "updater signatures"
+    };
+    let mut printable_paths = String::new();
+    for path in output_paths {
+      writeln!(
+        printable_paths,
+        "        {}",
+        tauri_utils::display_path(path)
+      )?;
+    }
+    info!( action = "Finished"; "{} {} at:\n{}", output_paths.len(), pluralised, printable_paths);
   }
   Ok(())
 }