mirror of
https://github.com/tauri-apps/tauri.git
synced 2026-01-31 00:35:19 +01:00
refactor tauri-cli (#14836)
* refactor(tauri-cli): use OsString where possible * refactor(tauri-cli): remove needless scoping blocks * refactor(tauri-cli): make return type concrete * refactor(tauri-cli): use ? * refactor(tauri-cli): coerce later to trait object * refactor(tauri-cli): remove clone * refactor(tauri-cli): make better use of static OnceLock * fix(tauri-cli): upgrade atomics to SeqCst * Add change file * Update .changes/change-pr-14836.md Co-authored-by: Tony <68118705+Legend-Master@users.noreply.github.com>
This commit is contained in:
6
.changes/change-pr-14836.md
Normal file
6
.changes/change-pr-14836.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"@tauri-apps/cli": patch:changes
|
||||
"tauri-cli": patch:changes
|
||||
---
|
||||
|
||||
Continued refactors of tauri-cli, fix too weak atomics.
|
||||
@@ -25,13 +25,13 @@ use std::{
|
||||
process::{exit, Command, Stdio},
|
||||
sync::{
|
||||
atomic::{AtomicBool, Ordering},
|
||||
Arc, Mutex, OnceLock,
|
||||
OnceLock,
|
||||
},
|
||||
};
|
||||
|
||||
mod builtin_dev_server;
|
||||
|
||||
static BEFORE_DEV: OnceLock<Mutex<Arc<SharedChild>>> = OnceLock::new();
|
||||
static BEFORE_DEV: OnceLock<SharedChild> = OnceLock::new();
|
||||
static KILL_BEFORE_DEV_FLAG: AtomicBool = AtomicBool::new(false);
|
||||
|
||||
#[cfg(unix)]
|
||||
@@ -205,21 +205,18 @@ pub fn setup(
|
||||
|
||||
let child = SharedChild::spawn(&mut command)
|
||||
.unwrap_or_else(|_| panic!("failed to run `{before_dev}`"));
|
||||
let child = Arc::new(child);
|
||||
let child_ = child.clone();
|
||||
|
||||
let child = BEFORE_DEV.get_or_init(move || child);
|
||||
std::thread::spawn(move || {
|
||||
let status = child_
|
||||
let status = child
|
||||
.wait()
|
||||
.expect("failed to wait on \"beforeDevCommand\"");
|
||||
if !(status.success() || KILL_BEFORE_DEV_FLAG.load(Ordering::Relaxed)) {
|
||||
if !(status.success() || KILL_BEFORE_DEV_FLAG.load(Ordering::SeqCst)) {
|
||||
log::error!("The \"beforeDevCommand\" terminated with a non-zero status code.");
|
||||
exit(status.code().unwrap_or(1));
|
||||
}
|
||||
});
|
||||
|
||||
BEFORE_DEV.set(Mutex::new(child)).unwrap();
|
||||
|
||||
let _ = ctrlc::set_handler(move || {
|
||||
kill_before_dev_process();
|
||||
exit(130);
|
||||
@@ -336,11 +333,10 @@ pub fn on_app_exit(code: Option<i32>, reason: ExitReason, exit_on_panic: bool, n
|
||||
|
||||
pub fn kill_before_dev_process() {
|
||||
if let Some(child) = BEFORE_DEV.get() {
|
||||
let child = child.lock().unwrap();
|
||||
if KILL_BEFORE_DEV_FLAG.load(Ordering::Relaxed) {
|
||||
if KILL_BEFORE_DEV_FLAG.load(Ordering::SeqCst) {
|
||||
return;
|
||||
}
|
||||
KILL_BEFORE_DEV_FLAG.store(true, Ordering::Relaxed);
|
||||
KILL_BEFORE_DEV_FLAG.store(true, Ordering::SeqCst);
|
||||
#[cfg(windows)]
|
||||
{
|
||||
let powershell_path = std::env::var("SYSTEMROOT").map_or_else(
|
||||
|
||||
@@ -210,7 +210,7 @@ impl Rust {
|
||||
|
||||
if options.no_watch {
|
||||
let (tx, rx) = sync_channel(1);
|
||||
self.run_dev(options, run_args, move |status, reason| {
|
||||
self.run_dev(options, &run_args, move |status, reason| {
|
||||
on_exit(status, reason);
|
||||
tx.send(()).unwrap();
|
||||
})?;
|
||||
@@ -225,9 +225,11 @@ impl Rust {
|
||||
&merge_configs,
|
||||
|rust: &mut Rust, _config| {
|
||||
let on_exit = on_exit.clone();
|
||||
rust.run_dev(options.clone(), run_args.clone(), move |status, reason| {
|
||||
on_exit(status, reason)
|
||||
})
|
||||
rust
|
||||
.run_dev(options.clone(), &run_args, move |status, reason| {
|
||||
on_exit(status, reason)
|
||||
})
|
||||
.map(|child| Box::new(child) as Box<dyn DevProcess + Send>)
|
||||
},
|
||||
dirs,
|
||||
)
|
||||
@@ -361,7 +363,7 @@ fn build_ignore_matcher(dir: &Path) -> IgnoreMatcher {
|
||||
|
||||
ignore_builder.add(path);
|
||||
|
||||
if let Ok(ignore_file) = std::env::var("TAURI_CLI_WATCHER_IGNORE_FILENAME") {
|
||||
if let Some(ignore_file) = std::env::var_os("TAURI_CLI_WATCHER_IGNORE_FILENAME") {
|
||||
ignore_builder.add(dir.join(ignore_file));
|
||||
}
|
||||
|
||||
@@ -393,7 +395,7 @@ fn lookup<F: FnMut(FileType, PathBuf)>(dir: &Path, mut f: F) {
|
||||
let mut builder = ignore::WalkBuilder::new(dir);
|
||||
builder.add_custom_ignore_filename(".taurignore");
|
||||
let _ = builder.add_ignore(default_gitignore);
|
||||
if let Ok(ignore_file) = std::env::var("TAURI_CLI_WATCHER_IGNORE_FILENAME") {
|
||||
if let Some(ignore_file) = std::env::var_os("TAURI_CLI_WATCHER_IGNORE_FILENAME") {
|
||||
builder.add_ignore(ignore_file);
|
||||
}
|
||||
builder.require_git(false).ignore(false).max_depth(Some(1));
|
||||
@@ -490,9 +492,9 @@ impl Rust {
|
||||
fn run_dev<F: Fn(Option<i32>, ExitReason) + Send + Sync + 'static>(
|
||||
&mut self,
|
||||
options: Options,
|
||||
run_args: Vec<String>,
|
||||
run_args: &[String],
|
||||
on_exit: F,
|
||||
) -> crate::Result<Box<dyn DevProcess + Send>> {
|
||||
) -> crate::Result<desktop::DevChild> {
|
||||
desktop::run_dev(
|
||||
options,
|
||||
run_args,
|
||||
@@ -500,7 +502,6 @@ impl Rust {
|
||||
self.config_features.clone(),
|
||||
on_exit,
|
||||
)
|
||||
.map(|c| Box::new(c) as Box<dyn DevProcess + Send>)
|
||||
}
|
||||
|
||||
fn run_dev_watcher<
|
||||
@@ -1380,7 +1381,7 @@ fn tauri_config_to_bundle_settings(
|
||||
if enabled_features.contains(&"tray-icon".into())
|
||||
|| enabled_features.contains(&"tauri/tray-icon".into())
|
||||
{
|
||||
let (tray_kind, path) = std::env::var("TAURI_LINUX_AYATANA_APPINDICATOR")
|
||||
let (tray_kind, path) = std::env::var_os("TAURI_LINUX_AYATANA_APPINDICATOR")
|
||||
.map(|ayatana| {
|
||||
if ayatana == "true" || ayatana == "1" {
|
||||
(
|
||||
@@ -1402,7 +1403,7 @@ fn tauri_config_to_bundle_settings(
|
||||
)
|
||||
}
|
||||
})
|
||||
.unwrap_or_else(|_| pkgconfig_utils::get_appindicator_library_path());
|
||||
.unwrap_or_else(pkgconfig_utils::get_appindicator_library_path);
|
||||
match tray_kind {
|
||||
pkgconfig_utils::TrayKind::Ayatana => {
|
||||
depends_deb.push("libayatana-appindicator3-1".into());
|
||||
|
||||
@@ -29,7 +29,7 @@ pub struct DevChild {
|
||||
impl DevProcess for DevChild {
|
||||
fn kill(&self) -> std::io::Result<()> {
|
||||
self.dev_child.kill()?;
|
||||
self.manually_killed_app.store(true, Ordering::Relaxed);
|
||||
self.manually_killed_app.store(true, Ordering::SeqCst);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -42,17 +42,17 @@ impl DevProcess for DevChild {
|
||||
}
|
||||
|
||||
fn manually_killed_process(&self) -> bool {
|
||||
self.manually_killed_app.load(Ordering::Relaxed)
|
||||
self.manually_killed_app.load(Ordering::SeqCst)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run_dev<F: Fn(Option<i32>, ExitReason) + Send + Sync + 'static>(
|
||||
options: Options,
|
||||
run_args: Vec<String>,
|
||||
run_args: &[String],
|
||||
available_targets: &mut Option<Vec<RustupTarget>>,
|
||||
config_features: Vec<String>,
|
||||
on_exit: F,
|
||||
) -> crate::Result<impl DevProcess> {
|
||||
) -> crate::Result<DevChild> {
|
||||
let mut dev_cmd = cargo_command(true, options, available_targets, config_features)?;
|
||||
let runner = dev_cmd.get_program().to_string_lossy().into_owned();
|
||||
|
||||
@@ -137,7 +137,7 @@ pub fn run_dev<F: Fn(Option<i32>, ExitReason) + Send + Sync + 'static>(
|
||||
status.code(),
|
||||
if status.code() == Some(101) && is_cargo_compile_error {
|
||||
ExitReason::CompilationFailed
|
||||
} else if manually_killed_app_.load(Ordering::Relaxed) {
|
||||
} else if manually_killed_app_.load(Ordering::SeqCst) {
|
||||
ExitReason::TriggeredKill
|
||||
} else {
|
||||
ExitReason::NormalExit
|
||||
@@ -163,7 +163,7 @@ pub fn build(
|
||||
let out_dir = app_settings.out_dir(&options, tauri_dir)?;
|
||||
let bin_path = app_settings.app_binary_path(&options, tauri_dir)?;
|
||||
|
||||
if !std::env::var("STATIC_VCRUNTIME").is_ok_and(|v| v == "false") {
|
||||
if !std::env::var_os("STATIC_VCRUNTIME").is_some_and(|v| v == "false") {
|
||||
std::env::set_var("STATIC_VCRUNTIME", "true");
|
||||
}
|
||||
|
||||
|
||||
@@ -62,20 +62,17 @@ pub fn command(options: Options) -> Result<()> {
|
||||
)?
|
||||
};
|
||||
|
||||
let (config, metadata) = {
|
||||
let (config, metadata) = get_config(
|
||||
&get_app(
|
||||
MobileTarget::Android,
|
||||
&tauri_config,
|
||||
&AppInterface::new(&tauri_config, None, dirs.tauri)?,
|
||||
dirs.tauri,
|
||||
),
|
||||
let (config, metadata) = get_config(
|
||||
&get_app(
|
||||
MobileTarget::Android,
|
||||
&tauri_config,
|
||||
&[],
|
||||
&cli_options,
|
||||
);
|
||||
(config, metadata)
|
||||
};
|
||||
&AppInterface::new(&tauri_config, None, dirs.tauri)?,
|
||||
dirs.tauri,
|
||||
),
|
||||
&tauri_config,
|
||||
&[],
|
||||
&cli_options,
|
||||
);
|
||||
|
||||
ensure_init(
|
||||
&tauri_config,
|
||||
|
||||
@@ -153,19 +153,16 @@ pub fn run(
|
||||
.unwrap();
|
||||
build_options.target = Some(first_target.triple.into());
|
||||
|
||||
let (interface, config, metadata) = {
|
||||
let interface = AppInterface::new(tauri_config, build_options.target.clone(), dirs.tauri)?;
|
||||
interface.build_options(&mut Vec::new(), &mut build_options.features, true);
|
||||
let interface = AppInterface::new(tauri_config, build_options.target.clone(), dirs.tauri)?;
|
||||
interface.build_options(&mut Vec::new(), &mut build_options.features, true);
|
||||
|
||||
let app = get_app(MobileTarget::Android, tauri_config, &interface, dirs.tauri);
|
||||
let (config, metadata) = get_config(
|
||||
&app,
|
||||
tauri_config,
|
||||
&build_options.features,
|
||||
&Default::default(),
|
||||
);
|
||||
(interface, config, metadata)
|
||||
};
|
||||
let app = get_app(MobileTarget::Android, tauri_config, &interface, dirs.tauri);
|
||||
let (config, metadata) = get_config(
|
||||
&app,
|
||||
tauri_config,
|
||||
&build_options.features,
|
||||
&Default::default(),
|
||||
);
|
||||
|
||||
let profile = if options.debug {
|
||||
Profile::Debug
|
||||
|
||||
@@ -183,18 +183,15 @@ fn run_command(options: Options, noise_level: NoiseLevel, dirs: Dirs) -> Result<
|
||||
.unwrap_or_else(|| Target::all().values().next().unwrap().triple.into());
|
||||
dev_options.target = Some(target_triple);
|
||||
|
||||
let (interface, config, metadata) = {
|
||||
let interface = AppInterface::new(&tauri_config, dev_options.target.clone(), dirs.tauri)?;
|
||||
let interface = AppInterface::new(&tauri_config, dev_options.target.clone(), dirs.tauri)?;
|
||||
|
||||
let app = get_app(MobileTarget::Android, &tauri_config, &interface, dirs.tauri);
|
||||
let (config, metadata) = get_config(
|
||||
&app,
|
||||
&tauri_config,
|
||||
dev_options.features.as_ref(),
|
||||
&Default::default(),
|
||||
);
|
||||
(interface, config, metadata)
|
||||
};
|
||||
let app = get_app(MobileTarget::Android, &tauri_config, &interface, dirs.tauri);
|
||||
let (config, metadata) = get_config(
|
||||
&app,
|
||||
&tauri_config,
|
||||
dev_options.features.as_ref(),
|
||||
&Default::default(),
|
||||
);
|
||||
|
||||
set_current_dir(dirs.tauri).context("failed to set current directory to Tauri directory")?;
|
||||
|
||||
|
||||
@@ -194,20 +194,17 @@ pub fn run(options: Options, noise_level: NoiseLevel, dirs: &Dirs) -> Result<Bui
|
||||
&options.config.iter().map(|c| &c.0).collect::<Vec<_>>(),
|
||||
dirs.tauri,
|
||||
)?;
|
||||
let (interface, mut config) = {
|
||||
let interface = AppInterface::new(&tauri_config, build_options.target.clone(), dirs.tauri)?;
|
||||
interface.build_options(&mut Vec::new(), &mut build_options.features, true);
|
||||
let interface = AppInterface::new(&tauri_config, build_options.target.clone(), dirs.tauri)?;
|
||||
interface.build_options(&mut Vec::new(), &mut build_options.features, true);
|
||||
|
||||
let app = get_app(MobileTarget::Ios, &tauri_config, &interface, dirs.tauri);
|
||||
let (config, _metadata) = get_config(
|
||||
&app,
|
||||
&tauri_config,
|
||||
&build_options.features,
|
||||
&Default::default(),
|
||||
dirs.tauri,
|
||||
)?;
|
||||
(interface, config)
|
||||
};
|
||||
let app = get_app(MobileTarget::Ios, &tauri_config, &interface, dirs.tauri);
|
||||
let (mut config, _) = get_config(
|
||||
&app,
|
||||
&tauri_config,
|
||||
&build_options.features,
|
||||
&Default::default(),
|
||||
dirs.tauri,
|
||||
)?;
|
||||
|
||||
set_current_dir(dirs.tauri).context("failed to set current directory")?;
|
||||
|
||||
|
||||
@@ -188,20 +188,16 @@ fn run_command(options: Options, noise_level: NoiseLevel, dirs: Dirs) -> Result<
|
||||
&options.config.iter().map(|c| &c.0).collect::<Vec<_>>(),
|
||||
dirs.tauri,
|
||||
)?;
|
||||
let (interface, config) = {
|
||||
let interface = AppInterface::new(&tauri_config, Some(target_triple), dirs.tauri)?;
|
||||
let interface = AppInterface::new(&tauri_config, Some(target_triple), dirs.tauri)?;
|
||||
|
||||
let app = get_app(MobileTarget::Ios, &tauri_config, &interface, dirs.tauri);
|
||||
let (config, _metadata) = get_config(
|
||||
&app,
|
||||
&tauri_config,
|
||||
&dev_options.features,
|
||||
&Default::default(),
|
||||
dirs.tauri,
|
||||
)?;
|
||||
|
||||
(interface, config)
|
||||
};
|
||||
let app = get_app(MobileTarget::Ios, &tauri_config, &interface, dirs.tauri);
|
||||
let (config, _) = get_config(
|
||||
&app,
|
||||
&tauri_config,
|
||||
&dev_options.features,
|
||||
&Default::default(),
|
||||
dirs.tauri,
|
||||
)?;
|
||||
|
||||
set_current_dir(dirs.tauri).context("failed to set current directory to Tauri directory")?;
|
||||
|
||||
|
||||
@@ -95,40 +95,33 @@ pub fn command(options: Options) -> Result<()> {
|
||||
let macos = macos_from_platform(&options.platform);
|
||||
|
||||
let mut tauri_config = get_tauri_config(tauri_utils::platform::Target::Ios, &[], dirs.tauri)?;
|
||||
let cli_options = {
|
||||
let cli_options = { read_options(&tauri_config) };
|
||||
if !cli_options.config.is_empty() {
|
||||
// reload config with merges from the ios dev|build script
|
||||
reload_tauri_config(
|
||||
&mut tauri_config,
|
||||
&cli_options
|
||||
.config
|
||||
.iter()
|
||||
.map(|conf| &conf.0)
|
||||
.collect::<Vec<_>>(),
|
||||
dirs.tauri,
|
||||
)?
|
||||
};
|
||||
|
||||
cli_options
|
||||
};
|
||||
|
||||
let (config, metadata) = {
|
||||
let cli_options = read_options(&tauri_config);
|
||||
let (config, metadata) = get_config(
|
||||
&get_app(
|
||||
MobileTarget::Ios,
|
||||
&tauri_config,
|
||||
&AppInterface::new(&tauri_config, None, dirs.tauri)?,
|
||||
dirs.tauri,
|
||||
),
|
||||
&tauri_config,
|
||||
&[],
|
||||
&cli_options,
|
||||
let cli_options = read_options(&tauri_config);
|
||||
if !cli_options.config.is_empty() {
|
||||
// reload config with merges from the ios dev|build script
|
||||
reload_tauri_config(
|
||||
&mut tauri_config,
|
||||
&cli_options
|
||||
.config
|
||||
.iter()
|
||||
.map(|conf| &conf.0)
|
||||
.collect::<Vec<_>>(),
|
||||
dirs.tauri,
|
||||
)?;
|
||||
(config, metadata)
|
||||
)?
|
||||
};
|
||||
|
||||
let (config, metadata) = get_config(
|
||||
&get_app(
|
||||
MobileTarget::Ios,
|
||||
&tauri_config,
|
||||
&AppInterface::new(&tauri_config, None, dirs.tauri)?,
|
||||
dirs.tauri,
|
||||
),
|
||||
&tauri_config,
|
||||
&[],
|
||||
&cli_options,
|
||||
dirs.tauri,
|
||||
)?;
|
||||
|
||||
ensure_init(
|
||||
&tauri_config,
|
||||
config.app(),
|
||||
|
||||
@@ -67,14 +67,9 @@ impl DevChild {
|
||||
|
||||
impl DevProcess for DevChild {
|
||||
fn kill(&self) -> std::io::Result<()> {
|
||||
self.manually_killed_process.store(true, Ordering::Relaxed);
|
||||
match self.child.kill() {
|
||||
Ok(_) => Ok(()),
|
||||
Err(e) => {
|
||||
self.manually_killed_process.store(false, Ordering::Relaxed);
|
||||
Err(e)
|
||||
}
|
||||
}
|
||||
self.child.kill()?;
|
||||
self.manually_killed_process.store(true, Ordering::SeqCst);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn try_wait(&self) -> std::io::Result<Option<ExitStatus>> {
|
||||
@@ -86,7 +81,7 @@ impl DevProcess for DevChild {
|
||||
}
|
||||
|
||||
fn manually_killed_process(&self) -> bool {
|
||||
self.manually_killed_process.load(Ordering::Relaxed)
|
||||
self.manually_killed_process.load(Ordering::SeqCst)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user