From f24f7e18f39cd1bb852cb0ed7efea69307972d05 Mon Sep 17 00:00:00 2001 From: Lucas Fernandes Nogueira Date: Fri, 3 Apr 2020 13:30:55 -0300 Subject: [PATCH] =?UTF-8?q?feat(tauri)=20bundle=20formats=20config=20on=20?= =?UTF-8?q?tauri.js,=20fix=20bundler=20appim=E2=80=A6=20(#537)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(tauri) bundle formats config on tauri.js, fix bundler appimage * fix(bundler) dmg chmod correctly --- cli/tauri-bundler/Cargo.toml | 9 +- cli/tauri-bundler/src/bundle.rs | 10 - .../src/bundle/appimage_bundle.rs | 34 +-- cli/tauri-bundler/src/bundle/deb_bundle.rs | 4 +- cli/tauri-bundler/src/bundle/dmg_bundle.rs | 2 +- cli/tauri-bundler/src/bundle/ios_bundle.rs | 224 ++++++++++-------- cli/tauri-bundler/src/bundle/osx_bundle.rs | 6 +- cli/tauri-bundler/src/bundle/settings.rs | 80 ++++--- cli/tauri-bundler/src/bundle/tauri_config.rs | 4 +- cli/tauri-bundler/src/main.rs | 1 + cli/tauri.js/src/runner.ts | 7 +- cli/tauri.js/src/template/defaultConfig.ts | 1 + cli/tauri.js/src/types/config.ts | 18 +- 13 files changed, 223 insertions(+), 177 deletions(-) diff --git a/cli/tauri-bundler/Cargo.toml b/cli/tauri-bundler/Cargo.toml index 29d3ef206..59f3f8f61 100644 --- a/cli/tauri-bundler/Cargo.toml +++ b/cli/tauri-bundler/Cargo.toml @@ -32,14 +32,14 @@ term = "0.6.1" toml = "0.5.6" uuid = { version = "0.8", features = ["v5"] } walkdir = "2" +lazy_static = { version = "1.4" } +handlebars = { version = "3.0" } [target.'cfg(target_os = "windows")'.dependencies] attohttpc = { version = "0.12.0" } regex = { version = "1" } [target.'cfg(not(target_os = "linux"))'.dependencies] -handlebars = { version = "3.0" } -lazy_static = { version = "1.4" } zip = { version = "0.5" } sha2 = { version = "0.8" } hex = { version = "0.4" } @@ -50,8 +50,3 @@ tempfile = "3" [[bin]] name = "cargo-tauri-bundler" path = "src/main.rs" - -[features] -appimage = [] -ios = [] -dmg = [] diff --git a/cli/tauri-bundler/src/bundle.rs b/cli/tauri-bundler/src/bundle.rs index 6d2b77916..e3767c1be 100644 --- a/cli/tauri-bundler/src/bundle.rs +++ b/cli/tauri-bundler/src/bundle.rs @@ -1,11 +1,8 @@ -#[cfg(feature = "appimage")] mod appimage_bundle; mod category; mod common; mod deb_bundle; -#[cfg(feature = "dmg")] mod dmg_bundle; -#[cfg(feature = "ios")] mod ios_bundle; #[cfg(target_os = "windows")] mod msi_bundle; @@ -28,19 +25,12 @@ pub fn bundle_project(settings: Settings) -> crate::Result> { for package_type in settings.package_types()? { paths.append(&mut match package_type { PackageType::OsxBundle => osx_bundle::bundle_project(&settings)?, - #[cfg(feature = "ios")] PackageType::IosBundle => ios_bundle::bundle_project(&settings)?, - // use dmg bundler - // PackageType::OsxBundle => dmg_bundle::bundle_project(&settings)?, #[cfg(target_os = "windows")] PackageType::WindowsMsi => msi_bundle::bundle_project(&settings)?, - // force appimage on linux - // PackageType::Deb => appimage_bundle::bundle_project(&settings)?, PackageType::Deb => deb_bundle::bundle_project(&settings)?, PackageType::Rpm => rpm_bundle::bundle_project(&settings)?, - #[cfg(feature = "appimage")] PackageType::AppImage => appimage_bundle::bundle_project(&settings)?, - #[cfg(feature = "dmg")] PackageType::Dmg => dmg_bundle::bundle_project(&settings)?, }); } diff --git a/cli/tauri-bundler/src/bundle/appimage_bundle.rs b/cli/tauri-bundler/src/bundle/appimage_bundle.rs index e08a6a7bc..64ff26ce2 100644 --- a/cli/tauri-bundler/src/bundle/appimage_bundle.rs +++ b/cli/tauri-bundler/src/bundle/appimage_bundle.rs @@ -40,20 +40,19 @@ pub fn bundle_project(settings: &Settings) -> crate::Result> { ); let base_dir = settings.project_out_directory().join("bundle/deb"); let package_dir = base_dir.join(&package_base_name); - if package_dir.exists() { - remove_dir_all(&package_dir) - .chain_err(|| format!("Failed to remove old {}", package_base_name))?; - } // generate deb_folder structure deb_bundle::generate_folders(settings, &package_dir)?; - let _app_dir_path = path_utils::create( - settings - .project_out_directory() - .join(format!("{}.AppDir", settings.binary_name())), - true, - ); + let output_path = settings.project_out_directory().join("bundle/appimage"); + if output_path.exists() { + remove_dir_all(&output_path) + .chain_err(|| format!("Failed to remove old {}", package_base_name))?; + } + std::fs::create_dir_all(output_path.clone())?; + let app_dir_path = output_path.join(format!("{}.AppDir", settings.binary_name())); + let appimage_path = output_path.join(format!("{}.AppImage", settings.binary_name())); + path_utils::create(app_dir_path.clone(), true)?; let upcase = settings.binary_name().to_uppercase(); @@ -67,27 +66,20 @@ pub fn bundle_project(settings: &Settings) -> crate::Result> { let temp = HANDLEBARS .render("appimage", &sh_map) .or_else(|e| Err(e.to_string()))?; - let output_path = settings.project_out_directory(); // create the shell script file in the target/ folder. let sh_file = output_path.join("build_appimage"); - common::print_bundling( - format!( - "{:?}", - &output_path.join(format!("{}.AppImage", settings.binary_name())) - ) - .as_str(), - )?; + common::print_bundling(format!("{:?}", &appimage_path).as_str())?; write(&sh_file, temp).or_else(|e| Err(e.to_string()))?; // chmod script for execution Command::new("chmod") .arg("777") .arg(&sh_file) - .current_dir(output_path) + .current_dir(output_path.clone()) .stdout(Stdio::piped()) .stderr(Stdio::piped()) - .spawn() + .output() .expect("Failed to chmod script"); // execute the shell script to build the appimage. @@ -98,5 +90,5 @@ pub fn bundle_project(settings: &Settings) -> crate::Result> { .spawn() .expect("Failed to execute shell script"); - Ok(vec![sh_file]) + Ok(vec![appimage_path]) } diff --git a/cli/tauri-bundler/src/bundle/deb_bundle.rs b/cli/tauri-bundler/src/bundle/deb_bundle.rs index 4c985b309..45c1fe8f4 100644 --- a/cli/tauri-bundler/src/bundle/deb_bundle.rs +++ b/cli/tauri-bundler/src/bundle/deb_bundle.rs @@ -23,7 +23,7 @@ use crate::{ResultExt, Settings}; use ar; use icns; -use image::png::{PngDecoder}; +use image::png::PngDecoder; use image::{self, GenericImageView, ImageDecoder}; use libflate::gzip; use md5; @@ -334,7 +334,7 @@ fn generate_icon_files(settings: &Settings, data_dir: &PathBuf) -> crate::Result let dest_path = get_dest_path(width, height, is_high_density); icon.write_to( &mut common::create_file(&dest_path)?, - image::ImageOutputFormat::Png + image::ImageOutputFormat::Png, )?; } } diff --git a/cli/tauri-bundler/src/bundle/dmg_bundle.rs b/cli/tauri-bundler/src/bundle/dmg_bundle.rs index 09535ff56..ad60dc6e7 100644 --- a/cli/tauri-bundler/src/bundle/dmg_bundle.rs +++ b/cli/tauri-bundler/src/bundle/dmg_bundle.rs @@ -68,7 +68,7 @@ pub fn bundle_project(settings: &Settings) -> crate::Result> { .current_dir(output_path) .stdout(Stdio::piped()) .stderr(Stdio::piped()) - .spawn() + .output() .expect("Failed to chmod script"); // execute the bundle script diff --git a/cli/tauri-bundler/src/bundle/ios_bundle.rs b/cli/tauri-bundler/src/bundle/ios_bundle.rs index 3ee45e584..7b4670b40 100644 --- a/cli/tauri-bundler/src/bundle/ios_bundle.rs +++ b/cli/tauri-bundler/src/bundle/ios_bundle.rs @@ -12,143 +12,175 @@ use super::common; use crate::{ResultExt, Settings}; use icns; -use image::png::{PNGDecoder, PNGEncoder}; +use image::png::PngDecoder; use image::{self, GenericImageView, ImageDecoder}; use std::collections::BTreeSet; -use std::convert::TryInto; use std::ffi::OsStr; use std::fs::{self, File}; use std::io::Write; use std::path::{Path, PathBuf}; - -pub fn bundle_project(settings: &Settings) -> ::Result> { +pub fn bundle_project(settings: &Settings) -> crate::Result> { common::print_warning("iOS bundle support is still experimental.")?; let app_bundle_name = format!("{}.app", settings.bundle_name()); common::print_bundling(&app_bundle_name)?; - let bundle_dir = settings.project_out_directory().join("bundle/ios").join(&app_bundle_name); + let bundle_dir = settings + .project_out_directory() + .join("bundle/ios") + .join(&app_bundle_name); if bundle_dir.exists() { - fs::remove_dir_all(&bundle_dir).chain_err(|| { - format!("Failed to remove old {}", app_bundle_name) - })?; + fs::remove_dir_all(&bundle_dir) + .chain_err(|| format!("Failed to remove old {}", app_bundle_name))?; } - fs::create_dir_all(&bundle_dir).chain_err(|| { - format!("Failed to create bundle directory at {:?}", bundle_dir) - })?; + fs::create_dir_all(&bundle_dir) + .chain_err(|| format!("Failed to create bundle directory at {:?}", bundle_dir))?; for src in settings.resource_files() { - let src = src?; - let dest = bundle_dir.join(common::resource_relpath(&src)); - common::copy_file(&src, &dest).chain_err(|| { - format!("Failed to copy resource file {:?}", src) - })?; + let src = src?; + let dest = bundle_dir.join(common::resource_relpath(&src)); + common::copy_file(&src, &dest) + .chain_err(|| format!("Failed to copy resource file {:?}", src))?; } - let icon_filenames = generate_icon_files(&bundle_dir, settings).chain_err(|| { - "Failed to create app icons" - })?; - generate_info_plist(&bundle_dir, settings, &icon_filenames).chain_err(|| { - "Failed to create Info.plist" - })?; + let icon_filenames = + generate_icon_files(&bundle_dir, settings).chain_err(|| "Failed to create app icons")?; + generate_info_plist(&bundle_dir, settings, &icon_filenames) + .chain_err(|| "Failed to create Info.plist")?; let bin_path = bundle_dir.join(&settings.bundle_name()); - common::copy_file(settings.binary_path(), &bin_path).chain_err(|| { - format!("Failed to copy binary from {:?}", settings.binary_path()) - })?; + common::copy_file(settings.binary_path(), &bin_path) + .chain_err(|| format!("Failed to copy binary from {:?}", settings.binary_path()))?; Ok(vec![bundle_dir]) } /// Generate the icon files and store them under the `bundle_dir`. -fn generate_icon_files(bundle_dir: &Path, settings: &Settings) -> ::Result> { +fn generate_icon_files(bundle_dir: &Path, settings: &Settings) -> crate::Result> { let mut filenames = Vec::new(); { - let mut get_dest_path = |width: u32, height: u32, is_retina: bool| { - let filename = format!("icon_{}x{}{}.png", - width, - height, - if is_retina { "@2x" } else { "" }); - let path = bundle_dir.join(&filename); - filenames.push(filename); - path - }; - let mut sizes = BTreeSet::new(); - // Prefer PNG files. - for icon_path in settings.icon_files() { - let icon_path = icon_path?; - if icon_path.extension() != Some(OsStr::new("png")) { - continue; - } - let mut decoder = PNGDecoder::new(File::open(&icon_path)?); - let (width, height) = decoder.dimensions()?; - let is_retina = common::is_retina(&icon_path); + let mut get_dest_path = |width: u32, height: u32, is_retina: bool| { + let filename = format!( + "icon_{}x{}{}.png", + width, + height, + if is_retina { "@2x" } else { "" } + ); + let path = bundle_dir.join(&filename); + filenames.push(filename); + path + }; + let mut sizes = BTreeSet::new(); + // Prefer PNG files. + for icon_path in settings.icon_files() { + let icon_path = icon_path?; + if icon_path.extension() != Some(OsStr::new("png")) { + continue; + } + let decoder = PngDecoder::new(File::open(&icon_path)?)?; + let width = decoder.dimensions().0; + let height = decoder.dimensions().1; + let is_retina = common::is_retina(&icon_path); + if !sizes.contains(&(width, height, is_retina)) { + sizes.insert((width, height, is_retina)); + let dest_path = get_dest_path(width, height, is_retina); + common::copy_file(&icon_path, &dest_path)?; + } + } + // Fall back to non-PNG files for any missing sizes. + for icon_path in settings.icon_files() { + let icon_path = icon_path?; + if icon_path.extension() == Some(OsStr::new("png")) { + continue; + } else if icon_path.extension() == Some(OsStr::new("icns")) { + let icon_family = icns::IconFamily::read(File::open(&icon_path)?)?; + for icon_type in icon_family.available_icons() { + let width = icon_type.screen_width(); + let height = icon_type.screen_height(); + let is_retina = icon_type.pixel_density() > 1; if !sizes.contains(&(width, height, is_retina)) { - sizes.insert((width, height, is_retina)); - let dest_path = get_dest_path(width, height, is_retina); - common::copy_file(&icon_path, &dest_path)?; - } - } - // Fall back to non-PNG files for any missing sizes. - for icon_path in settings.icon_files() { - let icon_path = icon_path?; - if icon_path.extension() == Some(OsStr::new("png")) { - continue; - } else if icon_path.extension() == Some(OsStr::new("icns")) { - let icon_family = icns::IconFamily::read(File::open(&icon_path)?)?; - for icon_type in icon_family.available_icons() { - let width = icon_type.screen_width(); - let height = icon_type.screen_height(); - let is_retina = icon_type.pixel_density() > 1; - if !sizes.contains(&(width, height, is_retina)) { - sizes.insert((width, height, is_retina)); - let dest_path = get_dest_path(width, height, is_retina); - let icon = icon_family.get_icon_with_type(icon_type)?; - icon.write_png(File::create(dest_path)?)?; - } - } - } else { - let icon = try!(image::open(&icon_path)); - let (width, height) = icon.dimensions(); - let is_retina = common::is_retina(&icon_path); - if !sizes.contains(&(width, height, is_retina)) { - sizes.insert((width, height, is_retina)); - let dest_path = get_dest_path(width, height, is_retina); - let encoder = PNGEncoder::new(common::create_file(&dest_path)?); - encoder.encode(&icon.raw_pixels(), width, height, icon.color())?; - } + sizes.insert((width, height, is_retina)); + let dest_path = get_dest_path(width, height, is_retina); + let icon = icon_family.get_icon_with_type(icon_type)?; + icon.write_png(File::create(dest_path)?)?; } + } + } else { + let icon = image::open(&icon_path)?; + let (width, height) = icon.dimensions(); + let is_retina = common::is_retina(&icon_path); + if !sizes.contains(&(width, height, is_retina)) { + sizes.insert((width, height, is_retina)); + let dest_path = get_dest_path(width, height, is_retina); + icon.write_to( + &mut common::create_file(&dest_path)?, + image::ImageOutputFormat::Png, + )?; + } } + } } Ok(filenames) } -fn generate_info_plist(bundle_dir: &Path, settings: &Settings, icon_filenames: &Vec) -> ::Result<()> { +fn generate_info_plist( + bundle_dir: &Path, + settings: &Settings, + icon_filenames: &Vec, +) -> crate::Result<()> { let file = &mut common::create_file(&bundle_dir.join("Info.plist"))?; - write!(file, - "\n\ + write!( + file, + "\n\ \n\ \n\ - \n")?; - - write!(file, " CFBundleIdentifier\n {}\n", settings.bundle_identifier())?; - write!(file, " CFBundleDisplayName\n {}\n", settings.bundle_name())?; - write!(file, " CFBundleName\n {}\n", settings.bundle_name())?; - write!(file, " CFBundleExecutable\n {}\n", settings.binary_name())?; - write!(file, " CFBundleVersion\n {}\n", settings.version_string())?; - write!(file, " CFBundleShortVersionString\n {}\n", settings.version_string())?; - write!(file, " CFBundleDevelopmentRegion\n en_US\n")?; + \n" + )?; + write!( + file, + " CFBundleIdentifier\n {}\n", + settings.bundle_identifier() + )?; + write!( + file, + " CFBundleDisplayName\n {}\n", + settings.bundle_name() + )?; + write!( + file, + " CFBundleName\n {}\n", + settings.bundle_name() + )?; + write!( + file, + " CFBundleExecutable\n {}\n", + settings.binary_name() + )?; + write!( + file, + " CFBundleVersion\n {}\n", + settings.version_string() + )?; + write!( + file, + " CFBundleShortVersionString\n {}\n", + settings.version_string() + )?; + write!( + file, + " CFBundleDevelopmentRegion\n en_US\n" + )?; if !icon_filenames.is_empty() { - write!(file, " CFBundleIconFiles\n \n")?; - for filename in icon_filenames { - write!(file, " {}\n", filename)?; - } - write!(file, " \n")?; + write!(file, " CFBundleIconFiles\n \n")?; + for filename in icon_filenames { + write!(file, " {}\n", filename)?; + } + write!(file, " \n")?; } write!(file, " LSRequiresIPhoneOS\n \n")?; write!(file, "\n\n")?; file.flush()?; Ok(()) -} \ No newline at end of file +} diff --git a/cli/tauri-bundler/src/bundle/osx_bundle.rs b/cli/tauri-bundler/src/bundle/osx_bundle.rs index 9402b8780..74818dc2d 100644 --- a/cli/tauri-bundler/src/bundle/osx_bundle.rs +++ b/cli/tauri-bundler/src/bundle/osx_bundle.rs @@ -375,7 +375,11 @@ fn create_icns_file( } for (icon, next_size_down, density) in images_to_resize { - let icon = icon.resize_exact(next_size_down, next_size_down, image::imageops::FilterType::Lanczos3); + let icon = icon.resize_exact( + next_size_down, + next_size_down, + image::imageops::FilterType::Lanczos3, + ); add_icon_to_family(icon, density, &mut family)?; } diff --git a/cli/tauri-bundler/src/bundle/settings.rs b/cli/tauri-bundler/src/bundle/settings.rs index 57113b834..3fcc1ec81 100644 --- a/cli/tauri-bundler/src/bundle/settings.rs +++ b/cli/tauri-bundler/src/bundle/settings.rs @@ -19,15 +19,12 @@ use std::path::{Path, PathBuf}; #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum PackageType { OsxBundle, - #[cfg(feature = "ios")] IosBundle, #[cfg(target_os = "windows")] WindowsMsi, Deb, Rpm, - #[cfg(feature = "appimage")] AppImage, - #[cfg(feature = "dmg")] Dmg, } @@ -36,15 +33,12 @@ impl PackageType { // Other types we may eventually want to support: apk match name { "deb" => Some(PackageType::Deb), - #[cfg(feature = "ios")] "ios" => Some(PackageType::IosBundle), #[cfg(target_os = "windows")] "msi" => Some(PackageType::WindowsMsi), "osx" => Some(PackageType::OsxBundle), "rpm" => Some(PackageType::Rpm), - #[cfg(feature = "appimage")] "appimage" => Some(PackageType::AppImage), - #[cfg(feature = "dmg")] "dmg" => Some(PackageType::Dmg), _ => None, } @@ -53,15 +47,12 @@ impl PackageType { pub fn short_name(&self) -> &'static str { match *self { PackageType::Deb => "deb", - #[cfg(feature = "ios")] PackageType::IosBundle => "ios", #[cfg(target_os = "windows")] PackageType::WindowsMsi => "msi", PackageType::OsxBundle => "osx", PackageType::Rpm => "rpm", - #[cfg(feature = "appimage")] PackageType::AppImage => "appimage", - #[cfg(feature = "dmg")] PackageType::Dmg => "dmg", } } @@ -73,14 +64,13 @@ impl PackageType { const ALL_PACKAGE_TYPES: &[PackageType] = &[ PackageType::Deb, - #[cfg(feature = "ios")] PackageType::IosBundle, #[cfg(target_os = "windows")] PackageType::WindowsMsi, PackageType::OsxBundle, PackageType::Rpm, - #[cfg(feature = "dmg")] PackageType::Dmg, + PackageType::AppImage, ]; #[derive(Clone, Debug)] @@ -143,7 +133,7 @@ struct CargoSettings { #[derive(Clone, Debug)] pub struct Settings { package: PackageSettings, - package_type: Option, // If `None`, use the default package type for this os + package_types: Option>, // If `None`, use the default package type for this os target: Option<(String, TargetInfo)>, features: Option>, project_out_directory: PathBuf, @@ -169,11 +159,19 @@ impl CargoSettings { impl Settings { pub fn new(current_dir: PathBuf, matches: &ArgMatches<'_>) -> crate::Result { - let package_type = match matches.value_of("format") { - Some(name) => match PackageType::from_short_name(name) { - Some(package_type) => Some(package_type), - None => bail!("Unsupported bundle format: {}", name), - }, + let package_types = match matches.values_of("format") { + Some(names) => { + let mut types = vec![]; + for name in names { + match PackageType::from_short_name(name) { + Some(package_type) => { + types.push(package_type); + } + None => bail!("Unsupported bundle format: {}", name), + } + } + Some(types) + } None => None, }; let build_artifact = if let Some(bin) = matches.value_of("bin") { @@ -248,7 +246,7 @@ impl Settings { Ok(Settings { package, - package_type, + package_types, target, features, build_artifact, @@ -350,29 +348,41 @@ impl Settings { &self.binary_path } - /// If a specific package type was specified by the command-line, returns - /// that package type; otherwise, if a target triple was specified by the + /// If a list of package types was specified by the command-line, returns + /// that list filtered by the current target's available targets; + /// otherwise, if a target triple was specified by the /// command-line, returns the native package type(s) for that target; /// otherwise, returns the native package type(s) for the host platform. /// Fails if the host/target's native package type is not supported. pub fn package_types(&self) -> crate::Result> { - if let Some(package_type) = self.package_type { - Ok(vec![package_type]) + let target_os = if let Some((_, ref info)) = self.target { + info.target_os() } else { - let target_os = if let Some((_, ref info)) = self.target { - info.target_os() - } else { - std::env::consts::OS - }; - match target_os { - "macos" => Ok(vec![PackageType::OsxBundle]), - #[cfg(feature = "ios")] - "ios" => Ok(vec![PackageType::IosBundle]), - "linux" => Ok(vec![PackageType::Deb]), // TODO: Do Rpm too, once it's implemented. - #[cfg(target_os = "windows")] - "windows" => Ok(vec![PackageType::WindowsMsi]), - os => bail!("Native {} bundles not yet supported.", os), + std::env::consts::OS + }; + let platform_types = match target_os { + "macos" => vec![PackageType::OsxBundle, PackageType::Dmg], + "ios" => vec![PackageType::IosBundle], + "linux" => vec![PackageType::Deb, PackageType::AppImage], + #[cfg(target_os = "windows")] + "windows" => vec![PackageType::WindowsMsi], + os => bail!("Native {} bundles not yet supported.", os), + }; + if let Some(package_types) = &self.package_types { + let mut types = vec![]; + for package_type in package_types { + let package_type = *package_type; + if platform_types + .clone() + .into_iter() + .any(|t| t == package_type) + { + types.push(package_type); + } } + Ok(types) + } else { + Ok(platform_types) } } diff --git a/cli/tauri-bundler/src/bundle/tauri_config.rs b/cli/tauri-bundler/src/bundle/tauri_config.rs index 28296f745..aafcd4aaf 100644 --- a/cli/tauri-bundler/src/bundle/tauri_config.rs +++ b/cli/tauri-bundler/src/bundle/tauri_config.rs @@ -1,5 +1,5 @@ -use serde::Deserialize; use super::category::AppCategory; +use serde::Deserialize; use std::path::PathBuf; use std::fs; @@ -67,4 +67,4 @@ pub fn get() -> crate::Result { None => Err(crate::Error::from("Couldn't get tauri config; please specify the TAURI_CONFIG or TAURI_DIR environment variables")) } } -} \ No newline at end of file +} diff --git a/cli/tauri-bundler/src/main.rs b/cli/tauri-bundler/src/main.rs index 5bfc01889..17a13494c 100644 --- a/cli/tauri-bundler/src/main.rs +++ b/cli/tauri-bundler/src/main.rs @@ -97,6 +97,7 @@ fn run() -> crate::Result<()> { .long("format") .value_name("FORMAT") .possible_values(&all_formats) + .multiple(true) .help("Which bundle format to produce"), ) .arg( diff --git a/cli/tauri.js/src/runner.ts b/cli/tauri.js/src/runner.ts index 9da20baeb..d230a8357 100644 --- a/cli/tauri.js/src/runner.ts +++ b/cli/tauri.js/src/runner.ts @@ -164,7 +164,12 @@ class Runner { cargoArgs: [ cfg.tauri.bundle.active ? 'tauri-bundler' : 'build', '--features', - ...features + ...features, + ...( + cfg.tauri.bundle.active && Array.isArray(cfg.tauri.bundle.targets) && cfg.tauri.bundle.targets.length + ? ['--format'].concat(cfg.tauri.bundle.targets) + : [] + ) ] .concat(cfg.ctx.debug ? [] : ['--release']) .concat(target ? ['--target', target] : []) diff --git a/cli/tauri.js/src/template/defaultConfig.ts b/cli/tauri.js/src/template/defaultConfig.ts index c6372d00e..b49b6635e 100644 --- a/cli/tauri.js/src/template/defaultConfig.ts +++ b/cli/tauri.js/src/template/defaultConfig.ts @@ -12,6 +12,7 @@ export default { }, bundle: { active: true, + targets: 'all', // or an array of targets identifier: 'com.tauri.dev', icon: ['icons/32x32.png', 'icons/128x128.png', 'icons/128x128@2x.png', 'icons/icon.icns', 'icons/icon.ico'], resources: [], diff --git a/cli/tauri.js/src/types/config.ts b/cli/tauri.js/src/types/config.ts index c52380f2c..8c0c5d7bb 100644 --- a/cli/tauri.js/src/types/config.ts +++ b/cli/tauri.js/src/types/config.ts @@ -16,7 +16,6 @@ export interface TauriConfig { targetName: string exitOnPanic?: boolean } - bundle: {} tauri: { inlinedAssets: string[] devPath: string @@ -25,6 +24,23 @@ export interface TauriConfig { } bundle: { active: boolean + targets?: string | string[] + identifier: string + icon: string[] + resources?: string[] + externalBin?: string[] + copyright?: string + category: string + shortDescription?: string + longDescription?: string + deb?: { + depends?: string[] + } + osx?: { + frameworks?: string[] + minimumSystemVersion?: string + } + exceptionDomain?: string } whitelist: { all: boolean