cli: migrate --config-toml processing, make UserSettings immutable

It's unclear whether parse_args() or its caller should update LayeredConfigs.
--config-toml is processed by callee to apply --color early. -R/--repository
will be processed by caller since it will instantiate WorkspaceLoader.
Maybe --config-toml can be removed from EarlyArgs, and handle_early_args()
just updates ui state based on --color argument?
This commit is contained in:
Yuya Nishihara 2023-01-05 15:15:56 +09:00
parent 39d5ce97ad
commit 6addfb0198
3 changed files with 24 additions and 33 deletions

View file

@ -61,25 +61,6 @@ impl UserSettings {
}
}
pub fn incorporate_toml_strings(
&mut self,
toml_strs: &[String],
) -> Result<(), config::ConfigError> {
let mut config_builder = config::Config::builder().add_source(self.config.clone());
for s in toml_strs {
config_builder =
config_builder.add_source(config::File::from_str(s, config::FileFormat::Toml));
}
let new_config = config_builder.build()?;
let new_rng_seed = get_rng_seed_config(&new_config);
if new_rng_seed != get_rng_seed_config(&self.config) {
self.rng.reset(new_rng_seed);
}
self.timestamp = get_timestamp_config(&new_config, "debug.commit-timestamp");
self.config = new_config;
Ok(())
}
pub fn with_repo(&self, repo_path: &Path) -> Result<RepoSettings, config::ConfigError> {
let config = config::Config::builder()
.add_source(self.config.clone())
@ -204,11 +185,6 @@ impl JJRng {
Self(Mutex::new(JJRng::internal_rng_from_seed(seed)))
}
fn reset(&self, seed: Option<u64>) {
let mut rng = self.0.lock().unwrap();
*rng = JJRng::internal_rng_from_seed(seed)
}
fn internal_rng_from_seed(seed: Option<u64>) -> ChaCha20Rng {
match seed {
Some(seed) => ChaCha20Rng::seed_from_u64(seed),

View file

@ -1607,7 +1607,7 @@ fn handle_early_args(
ui: &mut Ui,
app: &clap::Command,
args: &[String],
settings: &mut UserSettings,
layered_configs: &mut LayeredConfigs,
) -> Result<(), CommandError> {
// ignore_errors() bypasses errors like "--help" or missing subcommand
let early_matches = app.clone().ignore_errors(true).get_matches_from(args);
@ -1620,8 +1620,8 @@ fn handle_early_args(
ui.set_pagination(crate::ui::PaginationChoice::No);
}
if !args.config_toml.is_empty() {
settings.incorporate_toml_strings(&args.config_toml)?;
ui.reset(settings.config());
layered_configs.parse_config_args(&args.config_toml)?;
ui.reset(&layered_configs.merge());
}
Ok(())
}
@ -1648,11 +1648,11 @@ pub fn parse_args(
app: &clap::Command,
tracing_subscription: &TracingSubscription,
string_args: &[String],
settings: &mut UserSettings,
layered_configs: &mut LayeredConfigs,
) -> Result<(ArgMatches, Args), CommandError> {
// TODO: read user configs from the repo pointed to by -R.
handle_early_args(ui, app, string_args, settings)?;
handle_early_args(ui, app, string_args, layered_configs)?;
let matches = app.clone().try_get_matches_from(string_args)?;
let args: Args = Args::from_arg_matches(&matches).unwrap();
@ -1785,15 +1785,16 @@ impl CliRunner {
let config = layered_configs.merge();
ui.reset(&config);
let string_args = expand_args(&self.app, std::env::args_os(), &config)?;
let mut settings = UserSettings::from_config(config);
let (matches, args) = parse_args(
ui,
&self.app,
&self.tracing_subscription,
&string_args,
&mut settings,
&mut layered_configs,
)?;
// TODO: maybe instantiate UserSettings here
let config = layered_configs.merge();
let settings = UserSettings::from_config(config);
let command_helper = CommandHelper::new(
self.app,
cwd,

View file

@ -36,13 +36,14 @@ pub enum ConfigError {
/// 4. TODO: Repo config `.jj/repo/config.toml`
/// 5. TODO: Workspace config `.jj/config.toml`
/// 6. Override environment variables
/// 7. TODO: Command-line arguments `--config-toml`
/// 7. Command-line arguments `--config-toml`
#[derive(Clone, Debug)]
pub struct LayeredConfigs {
default: config::Config,
env_base: config::Config,
user: Option<config::Config>,
env_overrides: config::Config,
arg_overrides: Option<config::Config>,
}
impl LayeredConfigs {
@ -53,6 +54,7 @@ impl LayeredConfigs {
env_base: env_base(),
user: None,
env_overrides: env_overrides(),
arg_overrides: None,
}
}
@ -63,6 +65,17 @@ impl LayeredConfigs {
Ok(())
}
pub fn parse_config_args(&mut self, toml_strs: &[String]) -> Result<(), ConfigError> {
let config = toml_strs
.iter()
.fold(config::Config::builder(), |builder, s| {
builder.add_source(config::File::from_str(s, config::FileFormat::Toml))
})
.build()?;
self.arg_overrides = Some(config);
Ok(())
}
/// Creates new merged config.
pub fn merge(&self) -> config::Config {
let config_sources = [
@ -70,6 +83,7 @@ impl LayeredConfigs {
Some(&self.env_base),
self.user.as_ref(),
Some(&self.env_overrides),
self.arg_overrides.as_ref(),
];
config_sources
.into_iter()