fix(cli): regression on --config not accepting file paths (#8783)

* fix(cli): regression on --config not accepting file paths

* enhance dev server config parsing

* use serde_json::json!

* pass config to setup
This commit is contained in:
Lucas Fernandes Nogueira 2024-02-07 12:08:05 -03:00 committed by GitHub
parent 8751c3299f
commit fb0d997117
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 144 additions and 139 deletions

View File

@ -0,0 +1,6 @@
---
"tauri-cli": patch:bug
"@tauri-apps/cli": patch:bug
---
Fixes a regression on the `--config` argument not accepting file paths.

View File

@ -3677,7 +3677,7 @@ checksum = "69758bda2e78f098e4ccb393021a0963bb3442eac05f135c30f61b7370bbafae"
[[package]]
name = "tauri"
version = "2.0.0-beta.1"
version = "2.0.0-beta.2"
dependencies = [
"anyhow",
"bytes",
@ -3728,7 +3728,7 @@ dependencies = [
[[package]]
name = "tauri-build"
version = "2.0.0-beta.0"
version = "2.0.0-beta.1"
dependencies = [
"anyhow",
"cargo_toml",
@ -3750,7 +3750,7 @@ dependencies = [
[[package]]
name = "tauri-codegen"
version = "2.0.0-beta.0"
version = "2.0.0-beta.1"
dependencies = [
"base64",
"brotli",
@ -3774,7 +3774,7 @@ dependencies = [
[[package]]
name = "tauri-macros"
version = "2.0.0-beta.0"
version = "2.0.0-beta.1"
dependencies = [
"heck",
"proc-macro2",
@ -3786,7 +3786,7 @@ dependencies = [
[[package]]
name = "tauri-plugin"
version = "2.0.0-beta.0"
version = "2.0.0-beta.1"
dependencies = [
"anyhow",
"glob",
@ -3825,7 +3825,7 @@ dependencies = [
[[package]]
name = "tauri-runtime"
version = "2.0.0-beta.0"
version = "2.0.0-beta.1"
dependencies = [
"gtk",
"http",
@ -3841,7 +3841,7 @@ dependencies = [
[[package]]
name = "tauri-runtime-wry"
version = "2.0.0-beta.0"
version = "2.0.0-beta.1"
dependencies = [
"cocoa",
"gtk",
@ -3861,7 +3861,7 @@ dependencies = [
[[package]]
name = "tauri-utils"
version = "2.0.0-beta.0"
version = "2.0.0-beta.1"
dependencies = [
"aes-gcm",
"brotli",

View File

@ -6,12 +6,11 @@ use crate::{
helpers::{
app_paths::{app_dir, tauri_dir},
command_env,
config::{get as get_config, FrontendDist, HookCommand, MERGE_CONFIG_EXTENSION_NAME},
resolve_merge_config,
config::{get as get_config, ConfigHandle, FrontendDist, HookCommand},
updater_signature::{secret_key as updater_secret_key, sign_file},
},
interface::{AppInterface, AppSettings, Interface},
CommandExt, Result,
CommandExt, ConfigValue, Result,
};
use anyhow::{bail, Context};
use base64::Engine;
@ -57,7 +56,7 @@ pub struct Options {
pub bundles: Option<Vec<String>>,
/// JSON string or path to JSON file to merge with tauri.conf.json
#[clap(short, long)]
pub config: Option<String>,
pub config: Option<ConfigValue>,
/// Command line arguments passed to the runner. Use `--` to explicitly mark the start of the arguments.
pub args: Vec<String>,
/// Skip prompting for values
@ -75,14 +74,14 @@ pub fn command(mut options: Options, verbosity: u8) -> Result<()> {
.map(Target::from_triple)
.unwrap_or_else(Target::current);
let config = get_config(target, options.config.as_deref())?;
let config = get_config(target, options.config.as_ref().map(|c| &c.0))?;
let mut interface = AppInterface::new(
config.lock().unwrap().as_ref().unwrap(),
options.target.clone(),
)?;
setup(target, &interface, &mut options, false)?;
setup(&interface, &mut options, config.clone(), false)?;
let config_guard = config.lock().unwrap();
let config_ = config_guard.as_ref().unwrap();
@ -267,27 +266,20 @@ pub fn command(mut options: Options, verbosity: u8) -> Result<()> {
}
pub fn setup(
target: Target,
interface: &AppInterface,
options: &mut Options,
config: ConfigHandle,
mobile: bool,
) -> Result<()> {
let (merge_config, merge_config_path) = resolve_merge_config(&options.config)?;
options.config = merge_config;
let config = get_config(target, options.config.as_deref())?;
let tauri_path = tauri_dir();
set_current_dir(tauri_path).with_context(|| "failed to change current working directory")?;
let config_guard = config.lock().unwrap();
let config_ = config_guard.as_ref().unwrap();
let bundle_identifier_source = match config_.find_bundle_identifier_overwriter() {
Some(source) if source == MERGE_CONFIG_EXTENSION_NAME => merge_config_path.unwrap_or(source),
Some(source) => source,
None => "tauri.conf.json".into(),
};
let bundle_identifier_source = config_
.find_bundle_identifier_overwriter()
.unwrap_or_else(|| "tauri.conf.json".into());
if config_.identifier == "com.tauri.dev" {
error!(

View File

@ -6,11 +6,12 @@ use crate::{
helpers::{
app_paths::{app_dir, tauri_dir},
command_env,
config::{get as get_config, reload as reload_config, BeforeDevCommand, FrontendDist},
resolve_merge_config,
config::{
get as get_config, reload as reload_config, BeforeDevCommand, ConfigHandle, FrontendDist,
},
},
interface::{AppInterface, DevProcess, ExitReason, Interface},
CommandExt, Result,
CommandExt, ConfigValue, Result,
};
use anyhow::{bail, Context};
@ -59,7 +60,7 @@ pub struct Options {
pub exit_on_panic: bool,
/// JSON string or path to JSON file to merge with tauri.conf.json
#[clap(short, long)]
pub config: Option<String>,
pub config: Option<ConfigValue>,
/// Run the code in release mode
#[clap(long = "release")]
pub release_mode: bool,
@ -100,14 +101,14 @@ fn command_internal(mut options: Options) -> Result<()> {
.map(Target::from_triple)
.unwrap_or_else(Target::current);
let config = get_config(target, options.config.as_deref())?;
let config = get_config(target, options.config.as_ref().map(|c| &c.0))?;
let mut interface = AppInterface::new(
config.lock().unwrap().as_ref().unwrap(),
options.target.clone(),
)?;
setup(target, &interface, &mut options, false)?;
setup(&interface, &mut options, config, false)?;
let exit_on_panic = options.exit_on_panic;
let no_watch = options.no_watch;
@ -160,16 +161,11 @@ pub fn local_ip_address(force: bool) -> &'static IpAddr {
}
pub fn setup(
target: Target,
interface: &AppInterface,
options: &mut Options,
config: ConfigHandle,
mobile: bool,
) -> Result<()> {
let (merge_config, _merge_config_path) = resolve_merge_config(&options.config)?;
options.config = merge_config;
let config = get_config(target, options.config.as_deref())?;
let tauri_path = tauri_dir();
set_current_dir(tauri_path).with_context(|| "failed to change current working directory")?;
@ -344,15 +340,26 @@ pub fn setup(
let server_url = format!("http://{server_url}");
dev_url = Some(server_url.parse().unwrap());
if let Some(c) = &options.config {
let mut c: tauri_utils::config::Config = serde_json::from_str(c)?;
c.build.dev_url = dev_url.clone();
options.config = Some(serde_json::to_string(&c).unwrap());
if let Some(c) = &mut options.config {
if let Some(build) = c
.0
.as_object_mut()
.and_then(|root| root.get_mut("build"))
.and_then(|build| build.as_object_mut())
{
build.insert("devUrl".into(), server_url.into());
}
} else {
options.config = Some(format!(r#"{{ "build": {{ "devUrl": "{server_url}" }} }}"#))
options
.config
.replace(crate::ConfigValue(serde_json::json!({
"build": {
"devUrl": server_url
}
})));
}
reload_config(options.config.as_deref())?;
reload_config(options.config.as_ref().map(|c| &c.0))?;
}
}
}

View File

@ -2,7 +2,6 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
use anyhow::Context;
use json_patch::merge;
use log::error;
use serde_json::Value as JsonValue;
@ -118,7 +117,7 @@ fn config_handle() -> &'static ConfigHandle {
/// Gets the static parsed config from `tauri.conf.json`.
fn get_internal(
merge_config: Option<&str>,
merge_config: Option<&serde_json::Value>,
reload: bool,
target: Target,
) -> crate::Result<ConfigHandle> {
@ -143,11 +142,10 @@ fn get_internal(
}
if let Some(merge_config) = merge_config {
set_var("TAURI_CONFIG", merge_config);
let merge_config: JsonValue =
serde_json::from_str(merge_config).with_context(|| "failed to parse config to merge")?;
merge(&mut config, &merge_config);
extensions.insert(MERGE_CONFIG_EXTENSION_NAME.into(), merge_config);
let merge_config_str = serde_json::to_string(&merge_config).unwrap();
set_var("TAURI_CONFIG", merge_config_str);
merge(&mut config, merge_config);
extensions.insert(MERGE_CONFIG_EXTENSION_NAME.into(), merge_config.clone());
};
if config_path.extension() == Some(OsStr::new("json"))
@ -198,11 +196,14 @@ fn get_internal(
Ok(config_handle().clone())
}
pub fn get(target: Target, merge_config: Option<&str>) -> crate::Result<ConfigHandle> {
pub fn get(
target: Target,
merge_config: Option<&serde_json::Value>,
) -> crate::Result<ConfigHandle> {
get_internal(merge_config, false, target)
}
pub fn reload(merge_config: Option<&str>) -> crate::Result<ConfigHandle> {
pub fn reload(merge_config: Option<&serde_json::Value>) -> crate::Result<ConfigHandle> {
let target = config_handle()
.lock()
.unwrap()

View File

@ -11,8 +11,6 @@ pub mod template;
pub mod updater_signature;
pub mod web_dev_server;
use anyhow::Context;
use std::{
collections::HashMap,
path::{Path, PathBuf},
@ -54,16 +52,3 @@ pub fn cross_command(bin: &str) -> Command {
let cmd = Command::new(bin);
cmd
}
pub fn resolve_merge_config(
config: &Option<String>,
) -> crate::Result<(Option<String>, Option<String>)> {
match config {
Some(config) if config.starts_with('{') => Ok((Some(config.to_string()), None)),
Some(config) => Ok((
Some(std::fs::read_to_string(config).with_context(|| "failed to read custom configuration")?),
Some(config.clone()),
)),
None => Ok((None, None)),
}
}

View File

@ -28,9 +28,12 @@ use tauri_bundler::{
use tauri_utils::config::{parse::is_configuration_file, DeepLinkProtocol};
use super::{AppSettings, DevProcess, ExitReason, Interface};
use crate::helpers::{
app_paths::{app_dir, tauri_dir},
config::{nsis_settings, reload as reload_config, wix_settings, BundleResources, Config},
use crate::{
helpers::{
app_paths::{app_dir, tauri_dir},
config::{nsis_settings, reload as reload_config, wix_settings, BundleResources, Config},
},
ConfigValue,
};
use tauri_utils::{display_path, platform::Target};
@ -48,7 +51,7 @@ pub struct Options {
pub target: Option<String>,
pub features: Option<Vec<String>>,
pub args: Vec<String>,
pub config: Option<String>,
pub config: Option<ConfigValue>,
pub no_watch: bool,
}
@ -85,7 +88,7 @@ pub struct MobileOptions {
pub debug: bool,
pub features: Option<Vec<String>>,
pub args: Vec<String>,
pub config: Option<String>,
pub config: Option<ConfigValue>,
pub no_watch: bool,
}
@ -186,7 +189,7 @@ impl Interface for Rust {
rx.recv().unwrap();
Ok(())
} else {
let config = options.config.clone();
let config = options.config.clone().map(|c| c.0);
let run = Arc::new(|rust: &mut Rust| {
let on_exit = on_exit.clone();
rust.run_dev(options.clone(), run_args.clone(), move |status, reason| {
@ -215,7 +218,7 @@ impl Interface for Rust {
runner(options)?;
Ok(())
} else {
let config = options.config.clone();
let config = options.config.clone().map(|c| c.0);
let run = Arc::new(|_rust: &mut Rust| runner(options.clone()));
self.run_dev_watcher(config, run)
}
@ -438,7 +441,7 @@ impl Rust {
fn run_dev_watcher<F: Fn(&mut Rust) -> crate::Result<Box<dyn DevProcess + Send>>>(
&mut self,
config: Option<String>,
config: Option<serde_json::Value>,
run: Arc<F>,
) -> crate::Result<()> {
let child = run(self)?;
@ -503,7 +506,7 @@ impl Rust {
if !ignore_matcher.is_ignore(&event_path, event_path.is_dir()) {
if is_configuration_file(self.app_settings.target, &event_path) {
match reload_config(config.as_deref()) {
match reload_config(config.as_ref()) {
Ok(config) => {
info!("Tauri configuration changed. Rewriting manifest...");
*self.app_settings.manifest.lock().unwrap() =

View File

@ -11,6 +11,7 @@
html_favicon_url = "https://github.com/tauri-apps/tauri/raw/dev/app-icon.png"
)]
use anyhow::Context;
pub use anyhow::Result;
mod add;
@ -37,10 +38,39 @@ use std::process::{exit, Command, ExitStatus, Output, Stdio};
use std::{
ffi::OsString,
fmt::Display,
fs::read_to_string,
io::BufRead,
path::PathBuf,
str::FromStr,
sync::{Arc, Mutex},
};
/// Tauri configuration argument option.
#[derive(Debug, Clone)]
pub struct ConfigValue(pub(crate) serde_json::Value);
impl FromStr for ConfigValue {
type Err = anyhow::Error;
fn from_str(config: &str) -> std::result::Result<Self, Self::Err> {
if config.starts_with('{') {
Ok(Self(
serde_json::from_str(config).context("invalid configuration JSON")?,
))
} else {
let path = PathBuf::from(config);
if path.exists() {
Ok(Self(serde_json::from_str(
&read_to_string(&path)
.with_context(|| format!("invalid configuration at file {config}"))?,
)?))
} else {
anyhow::bail!("provided configuration path does not exist")
}
}
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum)]
pub enum RunMode {
Desktop,

View File

@ -11,11 +11,11 @@ use crate::{
helpers::{
app_paths::tauri_dir,
config::{get as get_tauri_config, ConfigHandle},
flock, resolve_merge_config,
flock,
},
interface::{AppInterface, AppSettings, Interface, Options as InterfaceOptions},
mobile::{write_options, CliOptions},
Result,
ConfigValue, Result,
};
use clap::{ArgAction, Parser};
@ -51,7 +51,7 @@ pub struct Options {
pub features: Option<Vec<String>>,
/// JSON string or path to JSON file to merge with tauri.conf.json
#[clap(short, long)]
pub config: Option<String>,
pub config: Option<ConfigValue>,
/// Whether to split the APKs and AABs per ABIs.
#[clap(long)]
pub split_per_abi: bool,
@ -81,12 +81,9 @@ impl From<Options> for BuildOptions {
}
}
pub fn command(mut options: Options, noise_level: NoiseLevel) -> Result<()> {
pub fn command(options: Options, noise_level: NoiseLevel) -> Result<()> {
delete_codegen_vars();
let (merge_config, _merge_config_path) = resolve_merge_config(&options.config)?;
options.config = merge_config;
let mut build_options: BuildOptions = options.clone().into();
build_options.target = Some(
Target::all()
@ -98,7 +95,7 @@ pub fn command(mut options: Options, noise_level: NoiseLevel) -> Result<()> {
let tauri_config = get_tauri_config(
tauri_utils::platform::Target::Android,
options.config.as_deref(),
options.config.as_ref().map(|c| &c.0),
)?;
let (interface, app, config, metadata) = {
let tauri_config_guard = tauri_config.lock().unwrap();
@ -178,12 +175,7 @@ fn run_build(
options.aab = true;
}
crate::build::setup(
tauri_utils::platform::Target::Android,
&interface,
&mut build_options,
true,
)?;
crate::build::setup(&interface, &mut build_options, tauri_config.clone(), true)?;
let interface_options = InterfaceOptions {
debug: build_options.debug,

View File

@ -11,11 +11,11 @@ use crate::{
helpers::{
app_paths::tauri_dir,
config::{get as get_tauri_config, ConfigHandle},
flock, resolve_merge_config,
flock,
},
interface::{AppInterface, AppSettings, Interface, MobileOptions, Options as InterfaceOptions},
mobile::{write_options, CliOptions, DevChild, DevProcess},
Result,
ConfigValue, Result,
};
use clap::{ArgAction, Parser};
@ -57,7 +57,7 @@ pub struct Options {
exit_on_panic: bool,
/// JSON string or path to JSON file to merge with tauri.conf.json
#[clap(short, long)]
pub config: Option<String>,
pub config: Option<ConfigValue>,
/// Run the code in release mode
#[clap(long = "release")]
pub release_mode: bool,
@ -110,15 +110,12 @@ pub fn command(options: Options, noise_level: NoiseLevel) -> Result<()> {
result
}
fn run_command(mut options: Options, noise_level: NoiseLevel) -> Result<()> {
fn run_command(options: Options, noise_level: NoiseLevel) -> Result<()> {
delete_codegen_vars();
let (merge_config, _merge_config_path) = resolve_merge_config(&options.config)?;
options.config = merge_config;
let tauri_config = get_tauri_config(
tauri_utils::platform::Target::Android,
options.config.as_deref(),
options.config.as_ref().map(|c| &c.0),
)?;
let env = env()?;
@ -195,12 +192,7 @@ fn run_dev(
options.force_ip_prompt,
)?;
crate::dev::setup(
tauri_utils::platform::Target::Android,
&interface,
&mut dev_options,
true,
)?;
crate::dev::setup(&interface, &mut dev_options, tauri_config.clone(), true)?;
let interface_options = InterfaceOptions {
debug: !dev_options.release_mode,

View File

@ -11,11 +11,11 @@ use crate::{
helpers::{
app_paths::tauri_dir,
config::{get as get_tauri_config, ConfigHandle},
flock, resolve_merge_config,
flock,
},
interface::{AppInterface, AppSettings, Interface, Options as InterfaceOptions},
mobile::{write_options, CliOptions},
Result,
ConfigValue, Result,
};
use clap::{ArgAction, Parser};
@ -53,7 +53,7 @@ pub struct Options {
pub features: Option<Vec<String>>,
/// JSON string or path to JSON file to merge with tauri.conf.json
#[clap(short, long)]
pub config: Option<String>,
pub config: Option<ConfigValue>,
/// Build number to append to the app version.
#[clap(long)]
pub build_number: Option<u32>,
@ -77,10 +77,7 @@ impl From<Options> for BuildOptions {
}
}
pub fn command(mut options: Options, noise_level: NoiseLevel) -> Result<()> {
let (merge_config, _merge_config_path) = resolve_merge_config(&options.config)?;
options.config = merge_config;
pub fn command(options: Options, noise_level: NoiseLevel) -> Result<()> {
let mut build_options: BuildOptions = options.clone().into();
build_options.target = Some(
Target::all()
@ -92,7 +89,7 @@ pub fn command(mut options: Options, noise_level: NoiseLevel) -> Result<()> {
let tauri_config = get_tauri_config(
tauri_utils::platform::Target::Ios,
options.config.as_deref(),
options.config.as_ref().map(|c| &c.0),
)?;
let (interface, app, config) = {
let tauri_config_guard = tauri_config.lock().unwrap();
@ -159,12 +156,7 @@ fn run_build(
Profile::Release
};
crate::build::setup(
tauri_utils::platform::Target::Ios,
&interface,
&mut build_options,
true,
)?;
crate::build::setup(&interface, &mut build_options, tauri_config.clone(), true)?;
let app_settings = interface.app_settings();
let bin_path = app_settings.app_binary_path(&InterfaceOptions {

View File

@ -11,11 +11,11 @@ use crate::{
helpers::{
app_paths::tauri_dir,
config::{get as get_tauri_config, ConfigHandle},
flock, resolve_merge_config,
flock,
},
interface::{AppInterface, AppSettings, Interface, MobileOptions, Options as InterfaceOptions},
mobile::{write_options, CliOptions, DevChild, DevProcess},
Result,
ConfigValue, Result,
};
use clap::{ArgAction, Parser};
@ -44,7 +44,7 @@ pub struct Options {
exit_on_panic: bool,
/// JSON string or path to JSON file to merge with tauri.conf.json
#[clap(short, long)]
pub config: Option<String>,
pub config: Option<ConfigValue>,
/// Run the code in release mode
#[clap(long = "release")]
pub release_mode: bool,
@ -97,7 +97,7 @@ pub fn command(options: Options, noise_level: NoiseLevel) -> Result<()> {
result
}
fn run_command(mut options: Options, noise_level: NoiseLevel) -> Result<()> {
fn run_command(options: Options, noise_level: NoiseLevel) -> Result<()> {
if var_os(APPLE_DEVELOPMENT_TEAM_ENV_VAR_NAME).is_none() {
if let Ok(teams) = find_development_teams() {
let index = match teams.len() {
@ -142,9 +142,6 @@ fn run_command(mut options: Options, noise_level: NoiseLevel) -> Result<()> {
}
};
let (merge_config, _merge_config_path) = resolve_merge_config(&options.config)?;
options.config = merge_config;
let mut dev_options: DevOptions = options.clone().into();
let target_triple = device
.as_ref()
@ -154,7 +151,7 @@ fn run_command(mut options: Options, noise_level: NoiseLevel) -> Result<()> {
let tauri_config = get_tauri_config(
tauri_utils::platform::Target::Ios,
options.config.as_deref(),
options.config.as_ref().map(|c| &c.0),
)?;
let (interface, app, config) = {
let tauri_config_guard = tauri_config.lock().unwrap();
@ -216,12 +213,7 @@ fn run_dev(
options.force_ip_prompt,
)?;
crate::dev::setup(
tauri_utils::platform::Target::Ios,
&interface,
&mut dev_options,
true,
)?;
crate::dev::setup(&interface, &mut dev_options, tauri_config.clone(), true)?;
let app_settings = interface.app_settings();
let bin_path = app_settings.app_binary_path(&InterfaceOptions {

View File

@ -8,6 +8,7 @@ use crate::{
config::{get as get_config, reload as reload_config, Config as TauriConfig},
},
interface::{AppInterface, AppSettings, DevProcess, Interface, Options as InterfaceOptions},
ConfigValue,
};
use anyhow::{bail, Result};
use heck::ToSnekCase;
@ -152,10 +153,13 @@ impl Default for CliOptions {
fn setup_dev_config(
target: Target,
config_extension: &mut Option<String>,
config_extension: &mut Option<ConfigValue>,
force_ip_prompt: bool,
) -> crate::Result<()> {
let config = get_config(target.platform_target(), config_extension.as_deref())?;
let config = get_config(
target.platform_target(),
config_extension.as_ref().map(|c| &c.0),
)?;
let mut dev_url = config
.lock()
@ -178,13 +182,22 @@ fn setup_dev_config(
let ip = crate::dev::local_ip_address(force_ip_prompt);
url.set_host(Some(&ip.to_string())).unwrap();
if let Some(c) = config_extension {
let mut c: tauri_utils::config::Config = serde_json::from_str(c)?;
c.build.dev_url = dev_url.clone();
config_extension.replace(serde_json::to_string(&c).unwrap());
if let Some(build) = c
.0
.as_object_mut()
.and_then(|root| root.get_mut("build"))
.and_then(|build| build.as_object_mut())
{
build.insert("devUrl".into(), url.to_string().into());
}
} else {
config_extension.replace(format!(r#"{{ "build": {{ "devUrl": "{url}" }} }}"#));
config_extension.replace(crate::ConfigValue(serde_json::json!({
"build": {
"devUrl": url
}
})));
}
reload_config(config_extension.as_deref())?;
reload_config(config_extension.as_ref().map(|c| &c.0))?;
}
}