diff --git a/.changes/revert-cli-async.md b/.changes/revert-cli-async.md new file mode 100644 index 000000000..f69c1fd92 --- /dev/null +++ b/.changes/revert-cli-async.md @@ -0,0 +1,5 @@ +--- +"cli.js": patch +--- + +Revert the `run` command to run in a separate thread. diff --git a/tooling/cli/Cargo.lock b/tooling/cli/Cargo.lock index d1f58c2e8..c83a292e4 100644 --- a/tooling/cli/Cargo.lock +++ b/tooling/cli/Cargo.lock @@ -2805,6 +2805,7 @@ dependencies = [ name = "tauri-cli-node" version = "0.0.0" dependencies = [ + "log", "napi", "napi-build", "napi-derive", diff --git a/tooling/cli/node/Cargo.toml b/tooling/cli/node/Cargo.toml index a2271f3bf..d8566033d 100644 --- a/tooling/cli/node/Cargo.toml +++ b/tooling/cli/node/Cargo.toml @@ -11,6 +11,7 @@ crate-type = ["cdylib"] napi = { version = "2.5", default-features = false, features = ["napi4"] } napi-derive = "2.5" tauri-cli = { path = ".." } +log = "0.4.17" [build-dependencies] napi-build = "2.0" diff --git a/tooling/cli/node/index.d.ts b/tooling/cli/node/index.d.ts index e0ef900ae..b562ef74a 100644 --- a/tooling/cli/node/index.d.ts +++ b/tooling/cli/node/index.d.ts @@ -3,4 +3,5 @@ /* auto-generated by NAPI-RS */ -export function run(args: Array, binName?: string | undefined | null): void +export function run(args: Array, binName: string | undefined | null, callback: (...args: any[]) => any): void +export function logError(error: string): void diff --git a/tooling/cli/node/index.js b/tooling/cli/node/index.js index 7ca66a61d..071e8b0d7 100644 --- a/tooling/cli/node/index.js +++ b/tooling/cli/node/index.js @@ -236,6 +236,7 @@ if (!nativeBinding) { throw new Error(`Failed to load native binding`) } -const { run } = nativeBinding +const { run, logError } = nativeBinding module.exports.run = run +module.exports.logError = logError diff --git a/tooling/cli/node/main.js b/tooling/cli/node/main.js index 4be39dd5f..2d8e8590f 100644 --- a/tooling/cli/node/main.js +++ b/tooling/cli/node/main.js @@ -1,4 +1,4 @@ -const { run } = require('./index') +const { run, logError } = require('./index') module.exports.run = (args, binName) => { return new Promise((resolve, reject) => { @@ -11,3 +11,5 @@ module.exports.run = (args, binName) => { }) }) } + +module.exports.logError = logError diff --git a/tooling/cli/node/src/lib.rs b/tooling/cli/node/src/lib.rs index 9c32a3aaf..b67af45dd 100644 --- a/tooling/cli/node/src/lib.rs +++ b/tooling/cli/node/src/lib.rs @@ -2,7 +2,30 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT +use napi::{ + threadsafe_function::{ErrorStrategy, ThreadsafeFunction, ThreadsafeFunctionCallMode}, + Error, JsFunction, Result, Status, +}; + #[napi_derive::napi] -pub fn run(args: Vec, bin_name: Option) { - tauri_cli::run(args, bin_name); +pub fn run(args: Vec, bin_name: Option, callback: JsFunction) -> Result<()> { + let function: ThreadsafeFunction = callback + .create_threadsafe_function(0, |ctx| ctx.env.get_boolean(ctx.value).map(|v| vec![v]))?; + + // we need to run in a separate thread so Node.js (e.g. vue-cli-plugin-tauri) consumers + // can do work while `tauri dev` is running. + std::thread::spawn(move || match tauri_cli::try_run(args, bin_name) { + Ok(_) => function.call(Ok(true), ThreadsafeFunctionCallMode::Blocking), + Err(e) => function.call( + Err(Error::new(Status::GenericFailure, format!("{:#}", e))), + ThreadsafeFunctionCallMode::Blocking, + ), + }); + + Ok(()) +} + +#[napi_derive::napi] +pub fn log_error(error: String) { + log::error!("{}", error); } diff --git a/tooling/cli/node/tauri.js b/tooling/cli/node/tauri.js index 363c2404e..e934c2ef1 100755 --- a/tooling/cli/node/tauri.js +++ b/tooling/cli/node/tauri.js @@ -43,4 +43,7 @@ if (binStem === 'node' || binStem === 'nodejs') { arguments.unshift(bin) } -cli.run(arguments, binName) +cli.run(arguments, binName).catch((err) => { + cli.logError(err.message) + process.exit(1) +}) diff --git a/tooling/cli/node/test/jest/__tests__/template.spec.js b/tooling/cli/node/test/jest/__tests__/template.spec.js index bfe57161b..75bc2bb6a 100644 --- a/tooling/cli/node/test/jest/__tests__/template.spec.js +++ b/tooling/cli/node/test/jest/__tests__/template.spec.js @@ -23,7 +23,7 @@ describe('[CLI] cli.js template', () => { await move(outPath, cacheOutPath) } - cli.run(['init', '--directory', process.cwd(), '--force', '--tauri-path', resolve(currentDirName, '../../../../../..'), '--ci']) + await cli.run(['init', '--directory', process.cwd(), '--force', '--tauri-path', resolve(currentDirName, '../../../../../..'), '--ci']) if (outExists) { await move(cacheOutPath, outPath) @@ -39,7 +39,7 @@ describe('[CLI] cli.js template', () => { const config = readFileSync(configPath).toString() writeFileSync(configPath, config.replace('com.tauri.dev', 'com.tauri.test')) - cli.run(['build', '--verbose']) + await cli.run(['build', '--verbose']) process.chdir(cwd) }) }) diff --git a/tooling/cli/src/lib.rs b/tooling/cli/src/lib.rs index af7593389..f96294060 100644 --- a/tooling/cli/src/lib.rs +++ b/tooling/cli/src/lib.rs @@ -73,7 +73,7 @@ fn format_error(err: clap::Error) -> clap::Error { err.format(&mut app) } -/// Run the Tauri CLI with the passed arguments. +/// Run the Tauri CLI with the passed arguments, exiting if an error occurrs. /// /// The passed arguments should have the binary argument(s) stripped out before being passed. /// @@ -96,7 +96,10 @@ where } } -fn try_run(args: I, bin_name: Option) -> Result<()> +/// Run the Tauri CLI with the passed arguments. +/// +/// It is similar to [`run`], but instead of exiting on an error, it returns a result. +pub fn try_run(args: I, bin_name: Option) -> Result<()> where I: IntoIterator, A: Into + Clone,