From cb28ecabd8e7c0b95b1eb60105a797030da279b6 Mon Sep 17 00:00:00 2001 From: amrbashir Date: Thu, 25 May 2023 17:51:27 +0300 Subject: [PATCH 1/4] feat(cli/mobile/init): add `--skip-targets-install`, closes #7044 --- .changes/cli-skip-targets-install.md | 5 +++++ tooling/cli/src/mobile/android.rs | 10 +++++++++- tooling/cli/src/mobile/android/project.rs | 7 +++++-- tooling/cli/src/mobile/init.rs | 18 ++++++++++++++++-- tooling/cli/src/mobile/ios.rs | 10 +++++++++- tooling/cli/src/mobile/ios/project.rs | 7 +++++-- 6 files changed, 49 insertions(+), 8 deletions(-) create mode 100644 .changes/cli-skip-targets-install.md diff --git a/.changes/cli-skip-targets-install.md b/.changes/cli-skip-targets-install.md new file mode 100644 index 000000000000..c49f82ac5d38 --- /dev/null +++ b/.changes/cli-skip-targets-install.md @@ -0,0 +1,5 @@ +--- +'cli.rs': 'patch' +--- + +Add `--skip-targets-install` flag for `tauri android init` and `tauri ios init` to skip installing needed rust targets vie rustup. diff --git a/tooling/cli/src/mobile/android.rs b/tooling/cli/src/mobile/android.rs index c517d5f35067..f6641eb08ff6 100644 --- a/tooling/cli/src/mobile/android.rs +++ b/tooling/cli/src/mobile/android.rs @@ -62,6 +62,9 @@ pub struct InitOptions { /// Skip prompting for values #[clap(long)] ci: bool, + /// Skips installing rust toolchains via rustup + #[clap(long)] + skip_targets_install: bool, } #[derive(Subcommand)] @@ -78,7 +81,12 @@ enum Commands { pub fn command(cli: Cli, verbosity: u8) -> Result<()> { let noise_level = NoiseLevel::from_occurrences(verbosity as u64); match cli.command { - Commands::Init(options) => init_command(MobileTarget::Android, options.ci, false)?, + Commands::Init(options) => init_command( + MobileTarget::Android, + options.ci, + false, + options.skip_targets_install, + )?, Commands::Open => open::command()?, Commands::Dev(options) => dev::command(options, noise_level)?, Commands::Build(options) => build::command(options, noise_level)?, diff --git a/tooling/cli/src/mobile/android/project.rs b/tooling/cli/src/mobile/android/project.rs index 62950088fb3d..0e72a3c238dc 100644 --- a/tooling/cli/src/mobile/android/project.rs +++ b/tooling/cli/src/mobile/android/project.rs @@ -34,9 +34,12 @@ pub fn gen( metadata: &Metadata, (handlebars, mut map): (Handlebars, template::JsonMap), wrapper: &TextWrapper, + skip_targets_install: bool, ) -> Result<()> { - println!("Installing Android toolchains..."); - Target::install_all().with_context(|| "failed to run rustup")?; + if !skip_targets_install { + println!("Installing Android Rust toolchains..."); + Target::install_all().with_context(|| "failed to run rustup")?; + } println!("Generating Android Studio project..."); let dest = config.project_dir(); let asset_packs = metadata.asset_packs().unwrap_or_default(); diff --git a/tooling/cli/src/mobile/init.rs b/tooling/cli/src/mobile/init.rs index b750611f6cd9..9aa261f229ad 100644 --- a/tooling/cli/src/mobile/init.rs +++ b/tooling/cli/src/mobile/init.rs @@ -24,13 +24,19 @@ use std::{ path::PathBuf, }; -pub fn command(target: Target, ci: bool, reinstall_deps: bool) -> Result<()> { +pub fn command( + target: Target, + ci: bool, + reinstall_deps: bool, + skip_targets_install: bool, +) -> Result<()> { let wrapper = TextWrapper::with_splitter(textwrap::termwidth(), textwrap::NoHyphenation); exec( target, &wrapper, ci || var_os("CI").is_some(), reinstall_deps, + skip_targets_install, ) .map_err(|e| anyhow::anyhow!("{:#}", e))?; Ok(()) @@ -78,6 +84,7 @@ pub fn exec( wrapper: &TextWrapper, #[allow(unused_variables)] non_interactive: bool, #[allow(unused_variables)] reinstall_deps: bool, + skip_targets_install: bool, ) -> Result { let tauri_config = get_tauri_config(None)?; let tauri_config_guard = tauri_config.lock().unwrap(); @@ -154,7 +161,13 @@ pub fn exec( let (app, config, metadata) = super::android::get_config(Some(app), tauri_config_, &Default::default()); map.insert("android", &config); - super::android::project::gen(&config, &metadata, (handlebars, map), wrapper)?; + super::android::project::gen( + &config, + &metadata, + (handlebars, map), + wrapper, + skip_targets_install, + )?; app } Err(err) => { @@ -183,6 +196,7 @@ pub fn exec( wrapper, non_interactive, reinstall_deps, + skip_targets_install, )?; app } diff --git a/tooling/cli/src/mobile/ios.rs b/tooling/cli/src/mobile/ios.rs index c944796817c5..08f008743d37 100644 --- a/tooling/cli/src/mobile/ios.rs +++ b/tooling/cli/src/mobile/ios.rs @@ -66,6 +66,9 @@ pub struct InitOptions { /// Reinstall dependencies #[clap(short, long)] reinstall_deps: bool, + /// Skips installing rust toolchains via rustup + #[clap(long)] + skip_targets_install: bool, } #[derive(Subcommand)] @@ -82,7 +85,12 @@ enum Commands { pub fn command(cli: Cli, verbosity: u8) -> Result<()> { let noise_level = NoiseLevel::from_occurrences(verbosity as u64); match cli.command { - Commands::Init(options) => init_command(MobileTarget::Ios, options.ci, options.reinstall_deps)?, + Commands::Init(options) => init_command( + MobileTarget::Ios, + options.ci, + options.reinstall_deps, + options.skip_targets_install, + )?, Commands::Open => open::command()?, Commands::Dev(options) => dev::command(options, noise_level)?, Commands::Build(options) => build::command(options, noise_level)?, diff --git a/tooling/cli/src/mobile/ios/project.rs b/tooling/cli/src/mobile/ios/project.rs index 19b509d4b7ae..175304739c2b 100644 --- a/tooling/cli/src/mobile/ios/project.rs +++ b/tooling/cli/src/mobile/ios/project.rs @@ -33,9 +33,12 @@ pub fn gen( wrapper: &TextWrapper, non_interactive: bool, reinstall_deps: bool, + skip_targets_install: bool, ) -> Result<()> { - println!("Installing iOS toolchains..."); - Target::install_all()?; + if !skip_targets_install { + println!("Installing iOS Rust toolchains..."); + Target::install_all()?; + } rust_version_check(wrapper)?; deps::install_all(wrapper, non_interactive, true, reinstall_deps) From 376ababba58cd2c258851de0da8d15eab84a6e8e Mon Sep 17 00:00:00 2001 From: Amr Bashir Date: Thu, 25 May 2023 18:20:15 +0300 Subject: [PATCH 2/4] Update .changes/cli-skip-targets-install.md Co-authored-by: Lucas Fernandes Nogueira --- .changes/cli-skip-targets-install.md | 1 + 1 file changed, 1 insertion(+) diff --git a/.changes/cli-skip-targets-install.md b/.changes/cli-skip-targets-install.md index c49f82ac5d38..60c4eba9b42c 100644 --- a/.changes/cli-skip-targets-install.md +++ b/.changes/cli-skip-targets-install.md @@ -1,5 +1,6 @@ --- 'cli.rs': 'patch' +'cli.js': 'patch' --- Add `--skip-targets-install` flag for `tauri android init` and `tauri ios init` to skip installing needed rust targets vie rustup. From 5c37e60399273d859a80a414ec9da61a1e8c0b59 Mon Sep 17 00:00:00 2001 From: Lucas Nogueira Date: Thu, 25 May 2023 18:45:14 -0300 Subject: [PATCH 3/4] refactor: check installed targets instead --- .changes/cli-skip-targets-install.md | 2 +- tooling/cli/src/interface/rust.rs | 1 + .../cli/src/interface/rust/installation.rs | 22 +++++++++++++++++++ tooling/cli/src/mobile/android.rs | 10 +-------- tooling/cli/src/mobile/android/project.rs | 17 +++++++++++--- tooling/cli/src/mobile/init.rs | 18 ++------------- tooling/cli/src/mobile/ios.rs | 10 +-------- tooling/cli/src/mobile/ios/project.rs | 17 +++++++++++--- 8 files changed, 56 insertions(+), 41 deletions(-) create mode 100644 tooling/cli/src/interface/rust/installation.rs diff --git a/.changes/cli-skip-targets-install.md b/.changes/cli-skip-targets-install.md index 60c4eba9b42c..0e84a5ba028d 100644 --- a/.changes/cli-skip-targets-install.md +++ b/.changes/cli-skip-targets-install.md @@ -3,4 +3,4 @@ 'cli.js': 'patch' --- -Add `--skip-targets-install` flag for `tauri android init` and `tauri ios init` to skip installing needed rust targets vie rustup. +Skip Rust target installation if they are already installed. diff --git a/tooling/cli/src/interface/rust.rs b/tooling/cli/src/interface/rust.rs index 3fc4a6a33cdb..05ffd5e3b67a 100644 --- a/tooling/cli/src/interface/rust.rs +++ b/tooling/cli/src/interface/rust.rs @@ -36,6 +36,7 @@ use tauri_utils::display_path; mod cargo_config; mod desktop; +pub mod installation; pub mod manifest; use cargo_config::Config as CargoConfig; use manifest::{rewrite_manifest, Manifest}; diff --git a/tooling/cli/src/interface/rust/installation.rs b/tooling/cli/src/interface/rust/installation.rs new file mode 100644 index 000000000000..aa1d61c6946b --- /dev/null +++ b/tooling/cli/src/interface/rust/installation.rs @@ -0,0 +1,22 @@ +use crate::Result; + +use std::{fs::read_dir, path::PathBuf, process::Command}; + +pub fn installed_targets() -> Result> { + let output = Command::new("rustc") + .args(["--print", "sysroot"]) + .output()?; + let sysroot_path = PathBuf::from(String::from_utf8_lossy(&output.stdout).trim().to_string()); + + let mut targets = Vec::new(); + for entry in read_dir(sysroot_path.join("lib").join("rustlib"))?.flatten() { + if entry.file_type().map(|t| t.is_dir()).unwrap_or_default() { + let name = entry.file_name(); + if name != "etc" && name != "src" { + targets.push(name.to_string_lossy().into_owned()); + } + } + } + + Ok(targets) +} diff --git a/tooling/cli/src/mobile/android.rs b/tooling/cli/src/mobile/android.rs index f6641eb08ff6..c517d5f35067 100644 --- a/tooling/cli/src/mobile/android.rs +++ b/tooling/cli/src/mobile/android.rs @@ -62,9 +62,6 @@ pub struct InitOptions { /// Skip prompting for values #[clap(long)] ci: bool, - /// Skips installing rust toolchains via rustup - #[clap(long)] - skip_targets_install: bool, } #[derive(Subcommand)] @@ -81,12 +78,7 @@ enum Commands { pub fn command(cli: Cli, verbosity: u8) -> Result<()> { let noise_level = NoiseLevel::from_occurrences(verbosity as u64); match cli.command { - Commands::Init(options) => init_command( - MobileTarget::Android, - options.ci, - false, - options.skip_targets_install, - )?, + Commands::Init(options) => init_command(MobileTarget::Android, options.ci, false)?, Commands::Open => open::command()?, Commands::Dev(options) => dev::command(options, noise_level)?, Commands::Build(options) => build::command(options, noise_level)?, diff --git a/tooling/cli/src/mobile/android/project.rs b/tooling/cli/src/mobile/android/project.rs index 0e72a3c238dc..24c3d380ccc8 100644 --- a/tooling/cli/src/mobile/android/project.rs +++ b/tooling/cli/src/mobile/android/project.rs @@ -34,12 +34,23 @@ pub fn gen( metadata: &Metadata, (handlebars, mut map): (Handlebars, template::JsonMap), wrapper: &TextWrapper, - skip_targets_install: bool, ) -> Result<()> { - if !skip_targets_install { + let installed_targets = + crate::interface::rust::installation::installed_targets().unwrap_or_default(); + let missing_targets = Target::all() + .values() + .filter(|t| !installed_targets.contains(&t.triple().into())) + .collect::>(); + + if !missing_targets.is_empty() { println!("Installing Android Rust toolchains..."); - Target::install_all().with_context(|| "failed to run rustup")?; + for target in missing_targets { + target + .install() + .context("failed to install target with rustup")?; + } } + println!("Generating Android Studio project..."); let dest = config.project_dir(); let asset_packs = metadata.asset_packs().unwrap_or_default(); diff --git a/tooling/cli/src/mobile/init.rs b/tooling/cli/src/mobile/init.rs index 9aa261f229ad..b750611f6cd9 100644 --- a/tooling/cli/src/mobile/init.rs +++ b/tooling/cli/src/mobile/init.rs @@ -24,19 +24,13 @@ use std::{ path::PathBuf, }; -pub fn command( - target: Target, - ci: bool, - reinstall_deps: bool, - skip_targets_install: bool, -) -> Result<()> { +pub fn command(target: Target, ci: bool, reinstall_deps: bool) -> Result<()> { let wrapper = TextWrapper::with_splitter(textwrap::termwidth(), textwrap::NoHyphenation); exec( target, &wrapper, ci || var_os("CI").is_some(), reinstall_deps, - skip_targets_install, ) .map_err(|e| anyhow::anyhow!("{:#}", e))?; Ok(()) @@ -84,7 +78,6 @@ pub fn exec( wrapper: &TextWrapper, #[allow(unused_variables)] non_interactive: bool, #[allow(unused_variables)] reinstall_deps: bool, - skip_targets_install: bool, ) -> Result { let tauri_config = get_tauri_config(None)?; let tauri_config_guard = tauri_config.lock().unwrap(); @@ -161,13 +154,7 @@ pub fn exec( let (app, config, metadata) = super::android::get_config(Some(app), tauri_config_, &Default::default()); map.insert("android", &config); - super::android::project::gen( - &config, - &metadata, - (handlebars, map), - wrapper, - skip_targets_install, - )?; + super::android::project::gen(&config, &metadata, (handlebars, map), wrapper)?; app } Err(err) => { @@ -196,7 +183,6 @@ pub fn exec( wrapper, non_interactive, reinstall_deps, - skip_targets_install, )?; app } diff --git a/tooling/cli/src/mobile/ios.rs b/tooling/cli/src/mobile/ios.rs index 08f008743d37..c944796817c5 100644 --- a/tooling/cli/src/mobile/ios.rs +++ b/tooling/cli/src/mobile/ios.rs @@ -66,9 +66,6 @@ pub struct InitOptions { /// Reinstall dependencies #[clap(short, long)] reinstall_deps: bool, - /// Skips installing rust toolchains via rustup - #[clap(long)] - skip_targets_install: bool, } #[derive(Subcommand)] @@ -85,12 +82,7 @@ enum Commands { pub fn command(cli: Cli, verbosity: u8) -> Result<()> { let noise_level = NoiseLevel::from_occurrences(verbosity as u64); match cli.command { - Commands::Init(options) => init_command( - MobileTarget::Ios, - options.ci, - options.reinstall_deps, - options.skip_targets_install, - )?, + Commands::Init(options) => init_command(MobileTarget::Ios, options.ci, options.reinstall_deps)?, Commands::Open => open::command()?, Commands::Dev(options) => dev::command(options, noise_level)?, Commands::Build(options) => build::command(options, noise_level)?, diff --git a/tooling/cli/src/mobile/ios/project.rs b/tooling/cli/src/mobile/ios/project.rs index 175304739c2b..8d87edc2b13a 100644 --- a/tooling/cli/src/mobile/ios/project.rs +++ b/tooling/cli/src/mobile/ios/project.rs @@ -33,12 +33,23 @@ pub fn gen( wrapper: &TextWrapper, non_interactive: bool, reinstall_deps: bool, - skip_targets_install: bool, ) -> Result<()> { - if !skip_targets_install { + let installed_targets = + crate::interface::rust::installation::installed_targets().unwrap_or_default(); + let missing_targets = Target::all() + .values() + .filter(|t| !installed_targets.contains(&t.triple().into())) + .collect::>(); + + if !missing_targets.is_empty() { println!("Installing iOS Rust toolchains..."); - Target::install_all()?; + for target in missing_targets { + target + .install() + .context("failed to install target with rustup")?; + } } + rust_version_check(wrapper)?; deps::install_all(wrapper, non_interactive, true, reinstall_deps) From ad1e774b971b7bc9c2b1797e1875ce255e2f0adc Mon Sep 17 00:00:00 2001 From: Lucas Nogueira Date: Thu, 25 May 2023 18:46:56 -0300 Subject: [PATCH 4/4] add header --- .github/workflows/check-license-header.yml | 2 +- tooling/cli/src/interface/rust/installation.rs | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/check-license-header.yml b/.github/workflows/check-license-header.yml index fb2055c10d00..c0d6da66b276 100644 --- a/.github/workflows/check-license-header.yml +++ b/.github/workflows/check-license-header.yml @@ -2,7 +2,7 @@ # SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: MIT -name: Check generated files +name: check license header on: pull_request: diff --git a/tooling/cli/src/interface/rust/installation.rs b/tooling/cli/src/interface/rust/installation.rs index aa1d61c6946b..c06d7feb5a94 100644 --- a/tooling/cli/src/interface/rust/installation.rs +++ b/tooling/cli/src/interface/rust/installation.rs @@ -1,3 +1,7 @@ +// Copyright 2019-2023 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + use crate::Result; use std::{fs::read_dir, path::PathBuf, process::Command};