From 8289e874231a24f75e85df82c0df835bcd58ab1b Mon Sep 17 00:00:00 2001 From: Martin von Zweigbergk Date: Sat, 30 Apr 2022 23:57:09 -0700 Subject: [PATCH] cli: move config-reading to new `config` module --- src/config.rs | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 1 + src/main.rs | 76 +------------------------------------------ 3 files changed, 92 insertions(+), 75 deletions(-) create mode 100644 src/config.rs diff --git a/src/config.rs b/src/config.rs new file mode 100644 index 000000000..71ec2d408 --- /dev/null +++ b/src/config.rs @@ -0,0 +1,90 @@ +// Copyright 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use std::env; +use std::path::PathBuf; + +use jujutsu_lib::settings::UserSettings; + +fn config_path() -> Option { + if let Ok(config_path) = env::var("JJ_CONFIG") { + // TODO: We should probably support colon-separated (std::env::split_paths) + // paths here + Some(PathBuf::from(config_path)) + } else { + // TODO: Should we drop the final `/config.toml` and read all files in the + // directory? + dirs::config_dir().map(|config_dir| config_dir.join("jj").join("config.toml")) + } +} + +/// Environment variables that should be overridden by config values +fn env_base() -> config::Config { + let mut builder = config::Config::builder(); + if let Ok(value) = env::var("EDITOR") { + builder = builder.set_override("ui.editor", value).unwrap(); + } + builder.build().unwrap() +} + +/// Environment variables that override config values +fn env_overrides() -> config::Config { + let mut builder = config::Config::builder(); + if let Ok(value) = env::var("JJ_USER") { + builder = builder.set_override("user.name", value).unwrap(); + } + if let Ok(value) = env::var("JJ_EMAIL") { + builder = builder.set_override("user.email", value).unwrap(); + } + if let Ok(value) = env::var("JJ_TIMESTAMP") { + builder = builder.set_override("user.timestamp", value).unwrap(); + } + if let Ok(value) = env::var("JJ_EDITOR") { + builder = builder.set_override("ui.editor", value).unwrap(); + } + builder.build().unwrap() +} + +pub fn read_config() -> Result { + let mut config_builder = config::Config::builder().add_source(env_base()); + + if let Some(config_path) = config_path() { + let mut files = vec![]; + if config_path.is_dir() { + if let Ok(read_dir) = config_path.read_dir() { + // TODO: Walk the directory recursively? + for dir_entry in read_dir.flatten() { + let path = dir_entry.path(); + if path.is_file() { + files.push(path); + } + } + } + files.sort(); + } else { + files.push(config_path); + } + for file in files { + // TODO: Accept other formats and/or accept only certain file extensions? + config_builder = config_builder.add_source( + config::File::from(file) + .required(false) + .format(config::FileFormat::Toml), + ); + } + }; + + let config = config_builder.add_source(env_overrides()).build()?; + Ok(UserSettings::from_config(config)) +} diff --git a/src/lib.rs b/src/lib.rs index 6ea65f4e0..d84a18387 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -18,6 +18,7 @@ extern crate pest_derive; pub mod commands; +pub mod config; pub mod diff_edit; pub mod formatter; pub mod graphlog; diff --git a/src/main.rs b/src/main.rs index 4becb72c6..89806c675 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,85 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::env; -use std::path::PathBuf; - use jujutsu::commands::{dispatch, CommandError}; +use jujutsu::config::read_config; use jujutsu::ui::Ui; use jujutsu_lib::settings::UserSettings; -fn config_path() -> Option { - if let Ok(config_path) = env::var("JJ_CONFIG") { - // TODO: We should probably support colon-separated (std::env::split_paths) - // paths here - Some(PathBuf::from(config_path)) - } else { - // TODO: Should we drop the final `/config.toml` and read all files in the - // directory? - dirs::config_dir().map(|config_dir| config_dir.join("jj").join("config.toml")) - } -} - -/// Environment variables that should be overridden by config values -fn env_base() -> config::Config { - let mut builder = config::Config::builder(); - if let Ok(value) = env::var("EDITOR") { - builder = builder.set_override("ui.editor", value).unwrap(); - } - builder.build().unwrap() -} - -/// Environment variables that override config values -fn env_overrides() -> config::Config { - let mut builder = config::Config::builder(); - if let Ok(value) = env::var("JJ_USER") { - builder = builder.set_override("user.name", value).unwrap(); - } - if let Ok(value) = env::var("JJ_EMAIL") { - builder = builder.set_override("user.email", value).unwrap(); - } - if let Ok(value) = env::var("JJ_TIMESTAMP") { - builder = builder.set_override("user.timestamp", value).unwrap(); - } - if let Ok(value) = env::var("JJ_EDITOR") { - builder = builder.set_override("ui.editor", value).unwrap(); - } - builder.build().unwrap() -} - -fn read_config() -> Result { - let mut config_builder = config::Config::builder().add_source(env_base()); - - if let Some(config_path) = config_path() { - let mut files = vec![]; - if config_path.is_dir() { - if let Ok(read_dir) = config_path.read_dir() { - // TODO: Walk the directory recursively? - for dir_entry in read_dir.flatten() { - let path = dir_entry.path(); - if path.is_file() { - files.push(path); - } - } - } - files.sort(); - } else { - files.push(config_path); - } - for file in files { - // TODO: Accept other formats and/or accept only certain file extensions? - config_builder = config_builder.add_source( - config::File::from(file) - .required(false) - .format(config::FileFormat::Toml), - ); - } - }; - - let config = config_builder.add_source(env_overrides()).build()?; - Ok(UserSettings::from_config(config)) -} - fn main() { // TODO: We need to do some argument parsing here, at least for things like // --config, and for reading user configs from the repo pointed to by