mirror of
https://github.com/tauri-apps/tauri.git
synced 2026-04-01 10:01:07 +02:00
feat(cli): allow merging multiple configuration values (#12970)
* feat(cli): allow merging multiple configuration values Currently the dev/build/bundle commands can only merge a single Tauri configuration value (file or raw JSON string), which imposes a limitation in scenarios where you need more flexibility (like multiple app flavors and environments). This changes the config CLI option to allow multiple values, letting you merge multiple Tauri config files with the main one. * fix ios build
This commit is contained in:
committed by
GitHub
parent
f67a4a6bfe
commit
d91bfa5cb9
6
.changes/cli-multiple-config.md
Normal file
6
.changes/cli-multiple-config.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"@tauri-apps/cli": minor:feat
|
||||
"tauri-cli": minor:feat
|
||||
---
|
||||
|
||||
Allow merging multiple configuration values on `tauri dev`, `tauri build`, `tauri bundle`, `tauri android dev`, `tauri android build`, `tauri ios dev` and `tauri ios build`.
|
||||
@@ -47,9 +47,15 @@ pub struct Options {
|
||||
/// Skip the bundling step even if `bundle > active` is `true` in tauri config.
|
||||
#[clap(long)]
|
||||
pub no_bundle: bool,
|
||||
/// JSON string or path to JSON file to merge with tauri.conf.json
|
||||
/// JSON strings or path to JSON files to merge with the default configuration file
|
||||
///
|
||||
/// Configurations are merged in the order they are provided, which means a particular value overwrites previous values when a config key-value pair conflicts.
|
||||
///
|
||||
/// Note that a platform-specific file is looked up and merged with the default file by default
|
||||
/// (tauri.macos.conf.json, tauri.linux.conf.json, tauri.windows.conf.json, tauri.android.conf.json and tauri.ios.conf.json)
|
||||
/// but you can use this for more specific use cases such as different build flavors.
|
||||
#[clap(short, long)]
|
||||
pub config: Option<ConfigValue>,
|
||||
pub config: Vec<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
|
||||
@@ -68,7 +74,10 @@ 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_ref().map(|c| &c.0))?;
|
||||
let config = get_config(
|
||||
target,
|
||||
&options.config.iter().map(|c| &c.0).collect::<Vec<_>>(),
|
||||
)?;
|
||||
|
||||
let mut interface = AppInterface::new(
|
||||
config.lock().unwrap().as_ref().unwrap(),
|
||||
|
||||
@@ -67,9 +67,15 @@ pub struct Options {
|
||||
/// Note that the `updater` bundle is not automatically added so you must specify it if the updater is enabled.
|
||||
#[clap(short, long, action = ArgAction::Append, num_args(0..), value_delimiter = ',')]
|
||||
pub bundles: Option<Vec<BundleFormat>>,
|
||||
/// JSON string or path to JSON file to merge with tauri.conf.json
|
||||
/// JSON strings or path to JSON files to merge with the default configuration file
|
||||
///
|
||||
/// Configurations are merged in the order they are provided, which means a particular value overwrites previous values when a config key-value pair conflicts.
|
||||
///
|
||||
/// Note that a platform-specific file is looked up and merged with the default file by default
|
||||
/// (tauri.macos.conf.json, tauri.linux.conf.json, tauri.windows.conf.json, tauri.android.conf.json and tauri.ios.conf.json)
|
||||
/// but you can use this for more specific use cases such as different build flavors.
|
||||
#[clap(short, long)]
|
||||
pub config: Option<ConfigValue>,
|
||||
pub config: Vec<ConfigValue>,
|
||||
/// Space or comma separated list of features, should be the same features passed to `tauri build` if any.
|
||||
#[clap(short, long, action = ArgAction::Append, num_args(0..))]
|
||||
pub features: Option<Vec<String>>,
|
||||
@@ -109,7 +115,10 @@ pub fn command(options: Options, verbosity: u8) -> crate::Result<()> {
|
||||
.map(Target::from_triple)
|
||||
.unwrap_or_else(Target::current);
|
||||
|
||||
let config = get_config(target, options.config.as_ref().map(|c| &c.0))?;
|
||||
let config = get_config(
|
||||
target,
|
||||
&options.config.iter().map(|c| &c.0).collect::<Vec<_>>(),
|
||||
)?;
|
||||
|
||||
let interface = AppInterface::new(
|
||||
config.lock().unwrap().as_ref().unwrap(),
|
||||
|
||||
@@ -59,9 +59,15 @@ pub struct Options {
|
||||
/// Exit on panic
|
||||
#[clap(short, long)]
|
||||
pub exit_on_panic: bool,
|
||||
/// JSON string or path to JSON file to merge with tauri.conf.json
|
||||
/// JSON strings or path to JSON files to merge with the default configuration file
|
||||
///
|
||||
/// Configurations are merged in the order they are provided, which means a particular value overwrites previous values when a config key-value pair conflicts.
|
||||
///
|
||||
/// Note that a platform-specific file is looked up and merged with the default file by default
|
||||
/// (tauri.macos.conf.json, tauri.linux.conf.json, tauri.windows.conf.json, tauri.android.conf.json and tauri.ios.conf.json)
|
||||
/// but you can use this for more specific use cases such as different build flavors.
|
||||
#[clap(short, long)]
|
||||
pub config: Option<ConfigValue>,
|
||||
pub config: Vec<ConfigValue>,
|
||||
/// Run the code in release mode
|
||||
#[clap(long = "release")]
|
||||
pub release_mode: bool,
|
||||
@@ -104,7 +110,10 @@ fn command_internal(mut options: Options) -> Result<()> {
|
||||
.map(Target::from_triple)
|
||||
.unwrap_or_else(Target::current);
|
||||
|
||||
let config = get_config(target, options.config.as_ref().map(|c| &c.0))?;
|
||||
let config = get_config(
|
||||
target,
|
||||
&options.config.iter().map(|c| &c.0).collect::<Vec<_>>(),
|
||||
)?;
|
||||
|
||||
let mut interface = AppInterface::new(
|
||||
config.lock().unwrap().as_ref().unwrap(),
|
||||
@@ -262,26 +271,13 @@ pub fn setup(interface: &AppInterface, options: &mut Options, config: ConfigHand
|
||||
let server_url = format!("http://{server_url}");
|
||||
dev_url = Some(server_url.parse().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());
|
||||
options.config.push(crate::ConfigValue(serde_json::json!({
|
||||
"build": {
|
||||
"devUrl": server_url
|
||||
}
|
||||
} else {
|
||||
options
|
||||
.config
|
||||
.replace(crate::ConfigValue(serde_json::json!({
|
||||
"build": {
|
||||
"devUrl": server_url
|
||||
}
|
||||
})));
|
||||
}
|
||||
})));
|
||||
|
||||
reload_config(options.config.as_ref().map(|c| &c.0))?;
|
||||
reload_config(&options.config.iter().map(|c| &c.0).collect::<Vec<_>>())?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,7 +138,7 @@ fn config_handle() -> &'static ConfigHandle {
|
||||
|
||||
/// Gets the static parsed config from `tauri.conf.json`.
|
||||
fn get_internal(
|
||||
merge_config: Option<&serde_json::Value>,
|
||||
merge_configs: &[&serde_json::Value],
|
||||
reload: bool,
|
||||
target: Target,
|
||||
) -> crate::Result<ConfigHandle> {
|
||||
@@ -162,12 +162,17 @@ fn get_internal(
|
||||
);
|
||||
}
|
||||
|
||||
if let Some(merge_config) = merge_config {
|
||||
if !merge_configs.is_empty() {
|
||||
let mut merge_config = serde_json::Value::Object(Default::default());
|
||||
for conf in merge_configs {
|
||||
merge(&mut merge_config, conf);
|
||||
}
|
||||
|
||||
let merge_config_str = serde_json::to_string(&merge_config).unwrap();
|
||||
set_var("TAURI_CONFIG", merge_config_str);
|
||||
merge(&mut config, merge_config);
|
||||
merge(&mut config, &merge_config);
|
||||
extensions.insert(MERGE_CONFIG_EXTENSION_NAME.into(), merge_config.clone());
|
||||
};
|
||||
}
|
||||
|
||||
if config_path.extension() == Some(OsStr::new("json"))
|
||||
|| config_path.extension() == Some(OsStr::new("json5"))
|
||||
@@ -217,35 +222,42 @@ fn get_internal(
|
||||
Ok(config_handle().clone())
|
||||
}
|
||||
|
||||
pub fn get(
|
||||
target: Target,
|
||||
merge_config: Option<&serde_json::Value>,
|
||||
) -> crate::Result<ConfigHandle> {
|
||||
get_internal(merge_config, false, target)
|
||||
pub fn get(target: Target, merge_configs: &[&serde_json::Value]) -> crate::Result<ConfigHandle> {
|
||||
get_internal(merge_configs, false, target)
|
||||
}
|
||||
|
||||
pub fn reload(merge_config: Option<&serde_json::Value>) -> crate::Result<ConfigHandle> {
|
||||
pub fn reload(merge_configs: &[&serde_json::Value]) -> crate::Result<ConfigHandle> {
|
||||
let target = config_handle()
|
||||
.lock()
|
||||
.unwrap()
|
||||
.as_ref()
|
||||
.map(|conf| conf.target);
|
||||
if let Some(target) = target {
|
||||
get_internal(merge_config, true, target)
|
||||
get_internal(merge_configs, true, target)
|
||||
} else {
|
||||
Err(anyhow::anyhow!("config not loaded"))
|
||||
}
|
||||
}
|
||||
|
||||
/// merges the loaded config with the given value
|
||||
pub fn merge_with(merge_config: &serde_json::Value) -> crate::Result<ConfigHandle> {
|
||||
pub fn merge_with(merge_configs: &[&serde_json::Value]) -> crate::Result<ConfigHandle> {
|
||||
let handle = config_handle();
|
||||
|
||||
if merge_configs.is_empty() {
|
||||
return Ok(handle.clone());
|
||||
}
|
||||
|
||||
if let Some(config_metadata) = &mut *handle.lock().unwrap() {
|
||||
let merge_config_str = serde_json::to_string(merge_config).unwrap();
|
||||
let mut merge_config = serde_json::Value::Object(Default::default());
|
||||
for conf in merge_configs {
|
||||
merge(&mut merge_config, conf);
|
||||
}
|
||||
|
||||
let merge_config_str = serde_json::to_string(&merge_config).unwrap();
|
||||
set_var("TAURI_CONFIG", merge_config_str);
|
||||
|
||||
let mut value = serde_json::to_value(config_metadata.inner.clone())?;
|
||||
merge(&mut value, merge_config);
|
||||
merge(&mut value, &merge_config);
|
||||
config_metadata.inner = serde_json::from_value(value)?;
|
||||
|
||||
Ok(handle.clone())
|
||||
|
||||
@@ -13,7 +13,7 @@ use tauri_utils::platform::Target;
|
||||
pub fn items(frontend_dir: Option<&PathBuf>, tauri_dir: Option<&Path>) -> Vec<SectionItem> {
|
||||
let mut items = Vec::new();
|
||||
if tauri_dir.is_some() {
|
||||
if let Ok(config) = crate::helpers::config::get(Target::current(), None) {
|
||||
if let Ok(config) = crate::helpers::config::get(Target::current(), &[]) {
|
||||
let config_guard = config.lock().unwrap();
|
||||
let config = config_guard.as_ref().unwrap();
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ fn wix_upgrade_code() -> Result<()> {
|
||||
crate::helpers::app_paths::resolve();
|
||||
|
||||
let target = tauri_utils::platform::Target::Windows;
|
||||
let config = crate::helpers::config::get(target, None)?;
|
||||
let config = crate::helpers::config::get(target, &[])?;
|
||||
|
||||
let interface = AppInterface::new(config.lock().unwrap().as_ref().unwrap(), None)?;
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ pub struct Options {
|
||||
pub target: Option<String>,
|
||||
pub features: Option<Vec<String>>,
|
||||
pub args: Vec<String>,
|
||||
pub config: Option<ConfigValue>,
|
||||
pub config: Vec<ConfigValue>,
|
||||
pub no_watch: bool,
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ pub struct MobileOptions {
|
||||
pub debug: bool,
|
||||
pub features: Option<Vec<String>>,
|
||||
pub args: Vec<String>,
|
||||
pub config: Option<ConfigValue>,
|
||||
pub config: Vec<ConfigValue>,
|
||||
pub no_watch: bool,
|
||||
}
|
||||
|
||||
@@ -207,14 +207,14 @@ impl Interface for Rust {
|
||||
rx.recv().unwrap();
|
||||
Ok(())
|
||||
} else {
|
||||
let config = options.config.clone().map(|c| c.0);
|
||||
let merge_configs = options.config.iter().map(|c| &c.0).collect::<Vec<_>>();
|
||||
let run = Arc::new(|rust: &mut Rust| {
|
||||
let on_exit = on_exit.clone();
|
||||
rust.run_dev(options.clone(), run_args.clone(), move |status, reason| {
|
||||
on_exit(status, reason)
|
||||
})
|
||||
});
|
||||
self.run_dev_watcher(config, run)
|
||||
self.run_dev_watcher(&merge_configs, run)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -236,9 +236,9 @@ impl Interface for Rust {
|
||||
runner(options)?;
|
||||
Ok(())
|
||||
} else {
|
||||
let config = options.config.clone().map(|c| c.0);
|
||||
let merge_configs = options.config.iter().map(|c| &c.0).collect::<Vec<_>>();
|
||||
let run = Arc::new(|_rust: &mut Rust| runner(options.clone()));
|
||||
self.run_dev_watcher(config, run)
|
||||
self.run_dev_watcher(&merge_configs, run)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -487,7 +487,7 @@ impl Rust {
|
||||
|
||||
fn run_dev_watcher<F: Fn(&mut Rust) -> crate::Result<Box<dyn DevProcess + Send>>>(
|
||||
&mut self,
|
||||
config: Option<serde_json::Value>,
|
||||
merge_configs: &[&serde_json::Value],
|
||||
run: Arc<F>,
|
||||
) -> crate::Result<()> {
|
||||
let child = run(self)?;
|
||||
@@ -537,7 +537,7 @@ impl Rust {
|
||||
if let Some(event_path) = event.paths.first() {
|
||||
if !ignore_matcher.is_ignore(event_path, event_path.is_dir()) {
|
||||
if is_configuration_file(self.app_settings.target, event_path) {
|
||||
if let Ok(config) = reload_config(config.as_ref()) {
|
||||
if let Ok(config) = reload_config(merge_configs) {
|
||||
let (manifest, modified) =
|
||||
rewrite_manifest(config.lock().unwrap().as_ref().unwrap())?;
|
||||
if modified {
|
||||
|
||||
@@ -46,7 +46,7 @@ pub fn command(options: Options) -> Result<()> {
|
||||
Profile::Debug
|
||||
};
|
||||
|
||||
let tauri_config = get_tauri_config(tauri_utils::platform::Target::Android, None)?;
|
||||
let tauri_config = get_tauri_config(tauri_utils::platform::Target::Android, &[])?;
|
||||
|
||||
let (config, metadata, cli_options) = {
|
||||
let tauri_config_guard = tauri_config.lock().unwrap();
|
||||
@@ -72,8 +72,14 @@ pub fn command(options: Options) -> Result<()> {
|
||||
MobileTarget::Android,
|
||||
)?;
|
||||
|
||||
if let Some(config) = &cli_options.config {
|
||||
crate::helpers::config::merge_with(&config.0)?;
|
||||
if !cli_options.config.is_empty() {
|
||||
crate::helpers::config::merge_with(
|
||||
&cli_options
|
||||
.config
|
||||
.iter()
|
||||
.map(|conf| &conf.0)
|
||||
.collect::<Vec<_>>(),
|
||||
)?;
|
||||
}
|
||||
|
||||
let env = env()?;
|
||||
|
||||
@@ -49,9 +49,15 @@ pub struct Options {
|
||||
/// List of cargo features to activate
|
||||
#[clap(short, long, action = ArgAction::Append, num_args(0..))]
|
||||
pub features: Option<Vec<String>>,
|
||||
/// JSON string or path to JSON file to merge with tauri.conf.json
|
||||
/// JSON strings or path to JSON files to merge with the default configuration file
|
||||
///
|
||||
/// Configurations are merged in the order they are provided, which means a particular value overwrites previous values when a config key-value pair conflicts.
|
||||
///
|
||||
/// Note that a platform-specific file is looked up and merged with the default file by default
|
||||
/// (tauri.macos.conf.json, tauri.linux.conf.json, tauri.windows.conf.json, tauri.android.conf.json and tauri.ios.conf.json)
|
||||
/// but you can use this for more specific use cases such as different build flavors.
|
||||
#[clap(short, long)]
|
||||
pub config: Option<ConfigValue>,
|
||||
pub config: Vec<ConfigValue>,
|
||||
/// Whether to split the APKs and AABs per ABIs.
|
||||
#[clap(long)]
|
||||
pub split_per_abi: bool,
|
||||
@@ -105,7 +111,11 @@ pub fn command(options: Options, noise_level: NoiseLevel) -> Result<()> {
|
||||
|
||||
let tauri_config = get_tauri_config(
|
||||
tauri_utils::platform::Target::Android,
|
||||
options.config.as_ref().map(|c| &c.0),
|
||||
&options
|
||||
.config
|
||||
.iter()
|
||||
.map(|conf| &conf.0)
|
||||
.collect::<Vec<_>>(),
|
||||
)?;
|
||||
let (interface, config, metadata) = {
|
||||
let tauri_config_guard = tauri_config.lock().unwrap();
|
||||
|
||||
@@ -48,9 +48,15 @@ pub struct Options {
|
||||
/// Exit on panic
|
||||
#[clap(short, long)]
|
||||
exit_on_panic: bool,
|
||||
/// JSON string or path to JSON file to merge with tauri.conf.json
|
||||
/// JSON strings or path to JSON files to merge with the default configuration file
|
||||
///
|
||||
/// Configurations are merged in the order they are provided, which means a particular value overwrites previous values when a config key-value pair conflicts.
|
||||
///
|
||||
/// Note that a platform-specific file is looked up and merged with the default file by default
|
||||
/// (tauri.macos.conf.json, tauri.linux.conf.json, tauri.windows.conf.json, tauri.android.conf.json and tauri.ios.conf.json)
|
||||
/// but you can use this for more specific use cases such as different build flavors.
|
||||
#[clap(short, long)]
|
||||
pub config: Option<ConfigValue>,
|
||||
pub config: Vec<ConfigValue>,
|
||||
/// Run the code in release mode
|
||||
#[clap(long = "release")]
|
||||
pub release_mode: bool,
|
||||
@@ -126,7 +132,11 @@ fn run_command(options: Options, noise_level: NoiseLevel) -> Result<()> {
|
||||
|
||||
let tauri_config = get_tauri_config(
|
||||
tauri_utils::platform::Target::Android,
|
||||
options.config.as_ref().map(|c| &c.0),
|
||||
&options
|
||||
.config
|
||||
.iter()
|
||||
.map(|conf| &conf.0)
|
||||
.collect::<Vec<_>>(),
|
||||
)?;
|
||||
|
||||
let env = env()?;
|
||||
|
||||
@@ -43,7 +43,7 @@ pub fn exec(
|
||||
#[allow(unused_variables)] reinstall_deps: bool,
|
||||
skip_targets_install: bool,
|
||||
) -> Result<App> {
|
||||
let tauri_config = get_tauri_config(target.platform_target(), None)?;
|
||||
let tauri_config = get_tauri_config(target.platform_target(), &[])?;
|
||||
|
||||
let tauri_config_guard = tauri_config.lock().unwrap();
|
||||
let tauri_config_ = tauri_config_guard.as_ref().unwrap();
|
||||
|
||||
@@ -60,9 +60,15 @@ pub struct Options {
|
||||
/// List of cargo features to activate
|
||||
#[clap(short, long, action = ArgAction::Append, num_args(0..))]
|
||||
pub features: Option<Vec<String>>,
|
||||
/// JSON string or path to JSON file to merge with tauri.conf.json
|
||||
/// JSON strings or path to JSON files to merge with the default configuration file
|
||||
///
|
||||
/// Configurations are merged in the order they are provided, which means a particular value overwrites previous values when a config key-value pair conflicts.
|
||||
///
|
||||
/// Note that a platform-specific file is looked up and merged with the default file by default
|
||||
/// (tauri.macos.conf.json, tauri.linux.conf.json, tauri.windows.conf.json, tauri.android.conf.json and tauri.ios.conf.json)
|
||||
/// but you can use this for more specific use cases such as different build flavors.
|
||||
#[clap(short, long)]
|
||||
pub config: Option<ConfigValue>,
|
||||
pub config: Vec<ConfigValue>,
|
||||
/// Build number to append to the app version.
|
||||
#[clap(long)]
|
||||
pub build_number: Option<u32>,
|
||||
@@ -145,7 +151,7 @@ pub fn command(options: Options, noise_level: NoiseLevel) -> Result<()> {
|
||||
|
||||
let tauri_config = get_tauri_config(
|
||||
tauri_utils::platform::Target::Ios,
|
||||
options.config.as_ref().map(|c| &c.0),
|
||||
&options.config.iter().map(|c| &c.0).collect::<Vec<_>>(),
|
||||
)?;
|
||||
let (interface, mut config) = {
|
||||
let tauri_config_guard = tauri_config.lock().unwrap();
|
||||
|
||||
@@ -54,9 +54,15 @@ pub struct Options {
|
||||
/// Exit on panic
|
||||
#[clap(short, long)]
|
||||
exit_on_panic: bool,
|
||||
/// JSON string or path to JSON file to merge with tauri.conf.json
|
||||
/// JSON strings or path to JSON files to merge with the default configuration file
|
||||
///
|
||||
/// Configurations are merged in the order they are provided, which means a particular value overwrites previous values when a config key-value pair conflicts.
|
||||
///
|
||||
/// Note that a platform-specific file is looked up and merged with the default file by default
|
||||
/// (tauri.macos.conf.json, tauri.linux.conf.json, tauri.windows.conf.json, tauri.android.conf.json and tauri.ios.conf.json)
|
||||
/// but you can use this for more specific use cases such as different build flavors.
|
||||
#[clap(short, long)]
|
||||
pub config: Option<ConfigValue>,
|
||||
pub config: Vec<ConfigValue>,
|
||||
/// Run the code in release mode
|
||||
#[clap(long = "release")]
|
||||
pub release_mode: bool,
|
||||
@@ -148,7 +154,7 @@ fn run_command(options: Options, noise_level: NoiseLevel) -> Result<()> {
|
||||
|
||||
let tauri_config = get_tauri_config(
|
||||
tauri_utils::platform::Target::Ios,
|
||||
options.config.as_ref().map(|c| &c.0),
|
||||
&options.config.iter().map(|c| &c.0).collect::<Vec<_>>(),
|
||||
)?;
|
||||
let (interface, config) = {
|
||||
let tauri_config_guard = tauri_config.lock().unwrap();
|
||||
|
||||
@@ -78,7 +78,7 @@ pub fn command(options: Options) -> Result<()> {
|
||||
let profile = profile_from_configuration(&options.configuration);
|
||||
let macos = macos_from_platform(&options.platform);
|
||||
|
||||
let tauri_config = get_tauri_config(tauri_utils::platform::Target::Ios, None)?;
|
||||
let tauri_config = get_tauri_config(tauri_utils::platform::Target::Ios, &[])?;
|
||||
|
||||
let (config, metadata, cli_options) = {
|
||||
let tauri_config_guard = tauri_config.lock().unwrap();
|
||||
@@ -103,8 +103,14 @@ pub fn command(options: Options) -> Result<()> {
|
||||
MobileTarget::Ios,
|
||||
)?;
|
||||
|
||||
if let Some(config) = &cli_options.config {
|
||||
crate::helpers::config::merge_with(&config.0)?;
|
||||
if !cli_options.config.is_empty() {
|
||||
crate::helpers::config::merge_with(
|
||||
&cli_options
|
||||
.config
|
||||
.iter()
|
||||
.map(|conf| &conf.0)
|
||||
.collect::<Vec<_>>(),
|
||||
)?;
|
||||
}
|
||||
|
||||
let env = env()?.explicit_env_vars(cli_options.vars);
|
||||
|
||||
@@ -187,7 +187,7 @@ pub struct CliOptions {
|
||||
pub args: Vec<String>,
|
||||
pub noise_level: NoiseLevel,
|
||||
pub vars: HashMap<String, OsString>,
|
||||
pub config: Option<ConfigValue>,
|
||||
pub config: Vec<ConfigValue>,
|
||||
pub target_device: Option<TargetDevice>,
|
||||
}
|
||||
|
||||
@@ -199,7 +199,7 @@ impl Default for CliOptions {
|
||||
args: vec!["--lib".into()],
|
||||
noise_level: Default::default(),
|
||||
vars: Default::default(),
|
||||
config: None,
|
||||
config: Vec::new(),
|
||||
target_device: None,
|
||||
}
|
||||
}
|
||||
@@ -292,26 +292,21 @@ fn use_network_address_for_dev_url(
|
||||
url.path()
|
||||
))?;
|
||||
|
||||
if let Some(c) = &mut dev_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(), url.to_string().into());
|
||||
}
|
||||
} else {
|
||||
let mut build = serde_json::Map::new();
|
||||
build.insert("devUrl".into(), url.to_string().into());
|
||||
dev_options
|
||||
.config
|
||||
.push(crate::ConfigValue(serde_json::json!({
|
||||
"build": {
|
||||
"devUrl": url
|
||||
}
|
||||
})));
|
||||
|
||||
dev_options
|
||||
reload_config(
|
||||
&dev_options
|
||||
.config
|
||||
.replace(crate::ConfigValue(serde_json::json!({
|
||||
"build": build
|
||||
})));
|
||||
}
|
||||
reload_config(dev_options.config.as_ref().map(|c| &c.0))?;
|
||||
.iter()
|
||||
.map(|conf| &conf.0)
|
||||
.collect::<Vec<_>>(),
|
||||
)?;
|
||||
|
||||
Some(ip)
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user