Compare commits

...

3 Commits

Author SHA1 Message Date
FabianLars
69e00db0e6 fix(core): clear State map on exit 2025-11-05 15:43:23 +01:00
Fabian-Lars
dd70d213cd chore(deps): update minisign to 0.8 (#14415) 2025-11-05 14:58:54 +01:00
Kushal Meghani
d06a1994e9 refactor: improve cli code readability (#14333) 2025-11-05 13:48:32 +01:00
6 changed files with 94 additions and 71 deletions

27
Cargo.lock generated
View File

@@ -1319,7 +1319,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c"
dependencies = [
"lazy_static",
"windows-sys 0.48.0",
"windows-sys 0.59.0",
]
[[package]]
@@ -1641,6 +1641,12 @@ dependencies = [
"syn 2.0.95",
]
[[package]]
name = "ct-codecs"
version = "1.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b10589d1a5e400d61f9f38f12f884cfd080ff345de8f17efda36fe0e4a02aa8"
[[package]]
name = "ctor"
version = "0.2.9"
@@ -2860,9 +2866,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4"
dependencies = [
"cfg-if",
"js-sys",
"libc",
"r-efi",
"wasi 0.14.2+wasi-0.2.4",
"wasm-bindgen",
]
[[package]]
@@ -4311,7 +4319,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34"
dependencies = [
"cfg-if",
"windows-targets 0.48.5",
"windows-targets 0.52.6",
]
[[package]]
@@ -4592,11 +4600,12 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
[[package]]
name = "minisign"
version = "0.7.3"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b23ef13ff1d745b1e52397daaa247e333c607f3cff96d4df2b798dc252db974b"
checksum = "e6bf96cef396a17a96f7600281aa4da9229860b7a082601b1f6db6eaa5f99ee5"
dependencies = [
"getrandom 0.2.15",
"ct-codecs",
"getrandom 0.3.3",
"rpassword",
"scrypt",
]
@@ -6976,13 +6985,13 @@ checksum = "6c20b6793b5c2fa6553b250154b78d6d0db37e72700ae35fad9387a46f487c97"
[[package]]
name = "rpassword"
version = "7.3.1"
version = "7.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "80472be3c897911d0137b2d2b9055faf6eeac5b14e324073d83bc17b191d7e3f"
checksum = "66d4c8b64f049c6721ec8ccec37ddfc3d641c4a7fca57e8f2a89de509c73df39"
dependencies = [
"libc",
"rtoolbox",
"windows-sys 0.48.0",
"windows-sys 0.59.0",
]
[[package]]
@@ -10315,7 +10324,7 @@ version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
dependencies = [
"windows-sys 0.48.0",
"windows-sys 0.59.0",
]
[[package]]

View File

@@ -70,7 +70,7 @@ jsonschema = "0.33"
handlebars = "6"
include_dir = "0.7"
dirs = "6"
minisign = "=0.7.3"
minisign = "0.8"
base64 = "0.22"
ureq = { version = "3", default-features = false, features = ["gzip"] }
os_info = "3"

View File

@@ -203,7 +203,7 @@ where
mod tests {
const PRIVATE_KEY: &str = "dW50cnVzdGVkIGNvbW1lbnQ6IHJzaWduIGVuY3J5cHRlZCBzZWNyZXQga2V5ClJXUlRZMEl5dkpDN09RZm5GeVAzc2RuYlNzWVVJelJRQnNIV2JUcGVXZUplWXZXYXpqUUFBQkFBQUFBQUFBQUFBQUlBQUFBQTZrN2RnWGh5dURxSzZiL1ZQSDdNcktiaHRxczQwMXdQelRHbjRNcGVlY1BLMTBxR2dpa3I3dDE1UTVDRDE4MXR4WlQwa1BQaXdxKy9UU2J2QmVSNXhOQWFDeG1GSVllbUNpTGJQRkhhTnROR3I5RmdUZi90OGtvaGhJS1ZTcjdZU0NyYzhQWlQ5cGM9Cg==";
// we use minisign=0.7.3 to prevent a breaking change
// minisign >=0.7.4,<0.8.0 couldn't handle empty passwords.
#[test]
fn empty_password_is_valid() {
let path = std::env::temp_dir().join("minisign-password-text.txt");

View File

@@ -65,28 +65,23 @@ impl FromStr for ConfigValue {
let path = PathBuf::from(config);
let raw =
read_to_string(&path).fs_context("failed to read configuration file", path.clone())?;
match path.extension() {
Some(ext) if ext == "toml" => {
Ok(Self(::toml::from_str(&raw).with_context(|| {
format!("failed to parse config at {} as TOML", path.display())
})?))
}
Some(ext) if ext == "json5" => {
Ok(Self(::json5::from_str(&raw).with_context(|| {
format!("failed to parse config at {} as JSON5", path.display())
})?))
}
// treat all other extensions as json
_ => Ok(Self(
// from tauri-utils/src/config/parse.rs:
// we also want to support **valid** json5 in the .json extension
// if the json5 is not valid the serde_json error for regular json will be returned.
match ::json5::from_str(&raw) {
Ok(json5) => json5,
Err(_) => serde_json::from_str(&raw)
.with_context(|| format!("failed to parse config at {} as JSON", path.display()))?,
},
)),
// treat all other extensions as json
// from tauri-utils/src/config/parse.rs:
// we also want to support **valid** json5 in the .json extension
// if the json5 is not valid the serde_json error for regular json will be returned.
match path.extension().and_then(|ext| ext.to_str()) {
Some("toml") => Ok(Self(::toml::from_str(&raw).with_context(|| {
format!("failed to parse config at {} as TOML", path.display())
})?)),
Some("json5") => Ok(Self(::json5::from_str(&raw).with_context(|| {
format!("failed to parse config at {} as JSON5", path.display())
})?)),
_ => Ok(Self(match ::json5::from_str(&raw) {
Ok(json5) => json5,
Err(_) => serde_json::from_str(&raw)
.with_context(|| format!("failed to parse config at {} as JSON", path.display()))?,
})),
}
}
}
@@ -178,6 +173,13 @@ fn format_error<I: CommandFactory>(err: clap::Error) -> clap::Error {
err.format(&mut app)
}
fn get_verbosity(cli_verbose: u8) -> u8 {
std::env::var("TAURI_CLI_VERBOSITY")
.ok()
.and_then(|v| v.parse().ok())
.unwrap_or(cli_verbose)
}
/// Run the Tauri CLI with the passed arguments, exiting if an error occurs.
///
/// The passed arguments should have the binary argument(s) stripped out before being passed.
@@ -222,23 +224,17 @@ where
Err(e) => e.exit(),
};
let verbosity_number = std::env::var("TAURI_CLI_VERBOSITY")
.ok()
.and_then(|v| v.parse().ok())
.unwrap_or(cli.verbose);
// set the verbosity level so subsequent CLI calls (xcode-script, android-studio-script) refer to it
let verbosity_number = get_verbosity(cli.verbose);
std::env::set_var("TAURI_CLI_VERBOSITY", verbosity_number.to_string());
let mut builder = Builder::from_default_env();
let init_res = builder
if let Err(err) = builder
.format_indent(Some(12))
.filter(None, verbosity_level(verbosity_number).to_level_filter())
// golbin spams an insane amount of really technical logs on the debug level so we're reducing one level
.filter(
Some("goblin"),
verbosity_level(verbosity_number.saturating_sub(1)).to_level_filter(),
)
// handlebars is not that spammy but its debug logs are typically far from being helpful
.filter(
Some("handlebars"),
verbosity_level(verbosity_number.saturating_sub(1)).to_level_filter(),
@@ -250,7 +246,6 @@ where
is_command_output = action == "stdout" || action == "stderr";
if !is_command_output {
let style = Style::new().fg_color(Some(AnsiColor::Green.into())).bold();
write!(f, "{style}{action:>12}{style:#} ")?;
}
} else {
@@ -264,15 +259,13 @@ where
if !is_command_output && log::log_enabled!(Level::Debug) {
let style = Style::new().fg_color(Some(AnsiColor::Black.into()));
write!(f, "[{style}{}{style:#}] ", record.target())?;
}
writeln!(f, "{}", record.args())
})
.try_init();
if let Err(err) = init_res {
.try_init()
{
eprintln!("Failed to attach logger: {err}");
}
@@ -305,7 +298,7 @@ fn verbosity_level(num: u8) -> Level {
match num {
0 => Level::Info,
1 => Level::Debug,
2.. => Level::Trace,
_ => Level::Trace,
}
}
@@ -321,8 +314,6 @@ fn prettyprint_level(lvl: Level) -> &'static str {
}
pub trait CommandExt {
// The `pipe` function sets the stdout and stderr to properly
// show the command output in the Node.js wrapper.
fn piped(&mut self) -> std::io::Result<ExitStatus>;
fn output_ok(&mut self) -> crate::Result<Output>;
}
@@ -332,9 +323,15 @@ impl CommandExt for Command {
self.stdin(os_pipe::dup_stdin()?);
self.stdout(os_pipe::dup_stdout()?);
self.stderr(os_pipe::dup_stderr()?);
let program = self.get_program().to_string_lossy().into_owned();
log::debug!(action = "Running"; "Command `{} {}`", program, self.get_args().map(|arg| arg.to_string_lossy()).fold(String::new(), |acc, arg| format!("{acc} {arg}")));
let program = self.get_program().to_string_lossy().into_owned();
let args = self
.get_args()
.map(|a| a.to_string_lossy())
.collect::<Vec<_>>()
.join(" ");
log::debug!(action = "Running"; "Command `{program} {args}`");
self.status()
}
@@ -342,8 +339,9 @@ impl CommandExt for Command {
let program = self.get_program().to_string_lossy().into_owned();
let args = self
.get_args()
.map(|arg| arg.to_string_lossy())
.fold(String::new(), |acc, arg| format!("{acc} {arg}"));
.map(|a| a.to_string_lossy())
.collect::<Vec<_>>()
.join(" ");
let cmdline = format!("{program} {args}");
log::debug!(action = "Running"; "Command `{cmdline}`");
@@ -359,16 +357,17 @@ impl CommandExt for Command {
let stdout_lines_ = stdout_lines.clone();
std::thread::spawn(move || {
let mut line = String::new();
let mut lines = stdout_lines_.lock().unwrap();
loop {
line.clear();
match stdout.read_line(&mut line) {
Ok(0) => break,
Ok(_) => {
log::debug!(action = "stdout"; "{}", line.trim_end());
lines.extend(line.as_bytes().to_vec());
if let Ok(mut lines) = stdout_lines_.lock() {
loop {
line.clear();
match stdout.read_line(&mut line) {
Ok(0) => break,
Ok(_) => {
log::debug!(action = "stdout"; "{}", line.trim_end());
lines.extend(line.as_bytes());
}
Err(_) => (),
}
Err(_) => (),
}
}
});
@@ -378,16 +377,17 @@ impl CommandExt for Command {
let stderr_lines_ = stderr_lines.clone();
std::thread::spawn(move || {
let mut line = String::new();
let mut lines = stderr_lines_.lock().unwrap();
loop {
line.clear();
match stderr.read_line(&mut line) {
Ok(0) => break,
Ok(_) => {
log::debug!(action = "stderr"; "{}", line.trim_end());
lines.extend(line.as_bytes().to_vec());
if let Ok(mut lines) = stderr_lines_.lock() {
loop {
line.clear();
match stderr.read_line(&mut line) {
Ok(0) => break,
Ok(_) => {
log::debug!(action = "stderr"; "{}", line.trim_end());
lines.extend(line.as_bytes());
}
Err(_) => (),
}
Err(_) => (),
}
}
});
@@ -423,4 +423,10 @@ mod tests {
fn verify_cli() {
Cli::command().debug_assert();
}
#[test]
fn help_output_includes_build() {
let help = Cli::command().render_help().to_string();
assert!(help.contains("Build"));
}
}

View File

@@ -1037,6 +1037,7 @@ macro_rules! shared_app_impl {
for (_, webview) in self.manager.webviews() {
webview.resources_table().clear();
}
unsafe { self.manager.state.clear() };
}
/// Gets the invoke key that must be referenced when using [`crate::webview::InvokeRequest`].

View File

@@ -149,6 +149,13 @@ impl StateManager {
Some(*value)
}
/// SAFETY: This will cause all references obtained through [Self::try_get] to dangle.
/// This must only be called on app exit (in cleanup_before_exit).
pub(crate) unsafe fn clear(&self) {
let mut map = self.map.lock().unwrap();
map.clear();
}
/// Gets the state associated with the specified type.
pub fn get<T: Send + Sync + 'static>(&self) -> State<'_, T> {
self