config: add type alias for config::ConfigError

We'll probably add our own ConfigError type later.
This commit is contained in:
Yuya Nishihara 2024-11-21 22:47:38 +09:00
parent c0250f1904
commit 6d26d53eab
17 changed files with 70 additions and 62 deletions

View file

@ -56,6 +56,7 @@ use jj_lib::backend::CommitId;
use jj_lib::backend::MergedTreeId;
use jj_lib::backend::TreeValue;
use jj_lib::commit::Commit;
use jj_lib::config::ConfigError;
use jj_lib::config::ConfigNamePathBuf;
use jj_lib::file_util;
use jj_lib::fileset;
@ -2685,7 +2686,7 @@ pub struct LogContentFormat {
impl LogContentFormat {
/// Creates new formatting helper for the terminal.
pub fn new(ui: &Ui, settings: &UserSettings) -> Result<Self, config::ConfigError> {
pub fn new(ui: &Ui, settings: &UserSettings) -> Result<Self, ConfigError> {
Ok(LogContentFormat {
width: ui.term_width(),
word_wrap: settings.config().get_bool("ui.log-word-wrap")?,
@ -3065,10 +3066,7 @@ impl ValueParserFactory for RevisionArg {
}
}
fn get_string_or_array(
config: &config::Config,
key: &str,
) -> Result<Vec<String>, config::ConfigError> {
fn get_string_or_array(config: &config::Config, key: &str) -> Result<Vec<String>, ConfigError> {
config
.get(key)
.map(|string| vec![string])

View file

@ -22,6 +22,7 @@ use std::sync::Arc;
use itertools::Itertools as _;
use jj_lib::backend::BackendError;
use jj_lib::config::ConfigError;
use jj_lib::dsl_util::Diagnostics;
use jj_lib::fileset::FilePatternParseError;
use jj_lib::fileset::FilesetParseError;
@ -238,8 +239,8 @@ impl From<jj_lib::file_util::PathError> for CommandError {
}
}
impl From<config::ConfigError> for CommandError {
fn from(err: config::ConfigError) -> Self {
impl From<ConfigError> for CommandError {
fn from(err: ConfigError) -> Self {
config_error(err)
}
}

View file

@ -15,6 +15,7 @@
use std::io::Write as _;
use clap_complete::ArgValueCandidates;
use jj_lib::config::ConfigError;
use jj_lib::config::ConfigNamePathBuf;
use tracing::instrument;
@ -51,7 +52,7 @@ pub fn cmd_config_get(
.lookup_value(command.settings().config())
.and_then(|value| value.into_string())
.map_err(|err| match err {
config::ConfigError::Type {
ConfigError::Type {
origin,
unexpected,
expected,

View file

@ -14,6 +14,7 @@
use clap_complete::ArgValueCandidates;
use jj_lib::backend::CommitId;
use jj_lib::config::ConfigError;
use jj_lib::graph::GraphEdgeType;
use jj_lib::graph::ReverseGraphIterator;
use jj_lib::graph::TopoGroupedGraphIterator;
@ -331,7 +332,7 @@ pub(crate) fn cmd_log(
pub fn get_node_template(
style: GraphStyle,
settings: &UserSettings,
) -> Result<String, config::ConfigError> {
) -> Result<String, ConfigError> {
let symbol = settings
.config()
.get_string("templates.log_node")

View file

@ -15,6 +15,7 @@
use std::slice;
use itertools::Itertools as _;
use jj_lib::config::ConfigError;
use jj_lib::op_walk;
use jj_lib::operation::Operation;
use jj_lib::repo::RepoLoader;
@ -239,10 +240,7 @@ fn do_op_log(
Ok(())
}
fn get_node_template(
style: GraphStyle,
settings: &UserSettings,
) -> Result<String, config::ConfigError> {
fn get_node_template(style: GraphStyle, settings: &UserSettings) -> Result<String, ConfigError> {
let symbol = settings
.config()
.get_string("templates.op_log_node")

View file

@ -22,6 +22,7 @@ use std::path::PathBuf;
use std::process::Command;
use itertools::Itertools;
use jj_lib::config::ConfigError;
use jj_lib::config::ConfigNamePathBuf;
use jj_lib::settings::ConfigResultExt as _;
use regex::Captures;
@ -47,9 +48,9 @@ pub fn parse_toml_value_or_bare_string(value_str: &str) -> toml_edit::Value {
}
}
pub fn to_toml_value(value: &config::Value) -> Result<toml_edit::Value, config::ConfigError> {
fn type_error<T: fmt::Display>(message: T) -> config::ConfigError {
config::ConfigError::Message(message.to_string())
pub fn to_toml_value(value: &config::Value) -> Result<toml_edit::Value, ConfigError> {
fn type_error<T: fmt::Display>(message: T) -> ConfigError {
ConfigError::Message(message.to_string())
}
// It's unlikely that the config object contained unsupported values, but
// there's no guarantee. For example, values coming from environment
@ -76,7 +77,7 @@ pub fn to_toml_value(value: &config::Value) -> Result<toml_edit::Value, config::
#[derive(Error, Debug)]
pub enum ConfigEnvError {
#[error(transparent)]
ConfigReadError(#[from] config::ConfigError),
ConfigReadError(#[from] ConfigError),
#[error("Both {0} and {1} exist. Please consolidate your configs in one of them.")]
AmbiguousSource(PathBuf, PathBuf),
#[error(transparent)]
@ -439,7 +440,7 @@ fn env_overrides() -> config::Config {
builder.build().unwrap()
}
fn read_config_file(path: &Path) -> Result<config::Config, config::ConfigError> {
fn read_config_file(path: &Path) -> Result<config::Config, ConfigError> {
config::Config::builder()
.add_source(
config::File::from(path)
@ -449,7 +450,7 @@ fn read_config_file(path: &Path) -> Result<config::Config, config::ConfigError>
.build()
}
fn read_config_path(config_path: &Path) -> Result<config::Config, config::ConfigError> {
fn read_config_path(config_path: &Path) -> Result<config::Config, ConfigError> {
let mut files = vec![];
if config_path.is_dir() {
if let Ok(read_dir) = config_path.read_dir() {
@ -556,11 +557,11 @@ pub fn remove_config_value_from_file(
let target_table = key_iter.try_fold(doc.as_table_mut(), |table, key| {
table
.get_mut(key)
.ok_or_else(|| config::ConfigError::NotFound(key.to_string()))
.ok_or_else(|| ConfigError::NotFound(key.to_string()))
.and_then(|table| {
table.as_table_mut().ok_or_else(|| {
config::ConfigError::Message(format!(r#""{key}" is not a table"#))
})
table
.as_table_mut()
.ok_or_else(|| ConfigError::Message(format!(r#""{key}" is not a table"#)))
})
})?;
@ -573,7 +574,7 @@ pub fn remove_config_value_from_file(
entry.remove();
}
toml_edit::Entry::Vacant(_) => {
return Err(config::ConfigError::NotFound(key.to_string()).into());
return Err(ConfigError::NotFound(key.to_string()).into());
}
}

View file

@ -32,6 +32,7 @@ use jj_lib::backend::CommitId;
use jj_lib::backend::CopyRecord;
use jj_lib::backend::TreeValue;
use jj_lib::commit::Commit;
use jj_lib::config::ConfigError;
use jj_lib::conflicts::materialize_merge_result_to_bytes;
use jj_lib::conflicts::materialized_diff_stream;
use jj_lib::conflicts::MaterializedTreeDiffEntry;
@ -145,7 +146,7 @@ pub enum DiffFormat {
pub fn diff_formats_for(
settings: &UserSettings,
args: &DiffFormatArgs,
) -> Result<Vec<DiffFormat>, config::ConfigError> {
) -> Result<Vec<DiffFormat>, ConfigError> {
let formats = diff_formats_from_args(settings, args)?;
if formats.is_empty() {
Ok(vec![default_diff_format(settings, args)?])
@ -160,7 +161,7 @@ pub fn diff_formats_for_log(
settings: &UserSettings,
args: &DiffFormatArgs,
patch: bool,
) -> Result<Vec<DiffFormat>, config::ConfigError> {
) -> Result<Vec<DiffFormat>, ConfigError> {
let mut formats = diff_formats_from_args(settings, args)?;
// --patch implies default if no format other than --summary is specified
if patch && matches!(formats.as_slice(), [] | [DiffFormat::Summary]) {
@ -173,7 +174,7 @@ pub fn diff_formats_for_log(
fn diff_formats_from_args(
settings: &UserSettings,
args: &DiffFormatArgs,
) -> Result<Vec<DiffFormat>, config::ConfigError> {
) -> Result<Vec<DiffFormat>, ConfigError> {
let mut formats = Vec::new();
if args.summary {
formats.push(DiffFormat::Summary);
@ -207,7 +208,7 @@ fn diff_formats_from_args(
fn default_diff_format(
settings: &UserSettings,
args: &DiffFormatArgs,
) -> Result<DiffFormat, config::ConfigError> {
) -> Result<DiffFormat, ConfigError> {
let config = settings.config();
if let Some(args) = config.get("ui.diff.tool").optional()? {
// External "tool" overrides the internal "format" option.
@ -242,9 +243,7 @@ fn default_diff_format(
let options = DiffStatOptions::from_args(args);
Ok(DiffFormat::Stat(Box::new(options)))
}
_ => Err(config::ConfigError::Message(format!(
"invalid diff format: {name}"
))),
_ => Err(ConfigError::Message(format!("invalid diff format: {name}"))),
}
}
@ -512,15 +511,16 @@ impl ColorWordsDiffOptions {
fn from_settings_and_args(
settings: &UserSettings,
args: &DiffFormatArgs,
) -> Result<Self, config::ConfigError> {
) -> Result<Self, ConfigError> {
let config = settings.config();
let max_inline_alternation = {
let key = "diff.color-words.max-inline-alternation";
match config.get_int(key)? {
-1 => None, // unlimited
n => Some(usize::try_from(n).map_err(|err| {
config::ConfigError::Message(format!("invalid {key}: {err}"))
})?),
n => Some(
usize::try_from(n)
.map_err(|err| ConfigError::Message(format!("invalid {key}: {err}")))?,
),
}
};
let context = args
@ -1213,7 +1213,7 @@ impl UnifiedDiffOptions {
fn from_settings_and_args(
settings: &UserSettings,
args: &DiffFormatArgs,
) -> Result<Self, config::ConfigError> {
) -> Result<Self, ConfigError> {
let context = args
.context
.map_or_else(|| settings.config().get("diff.git.context"), Ok)?;

View file

@ -29,6 +29,7 @@ use crossterm::style::SetAttribute;
use crossterm::style::SetBackgroundColor;
use crossterm::style::SetForegroundColor;
use itertools::Itertools;
use jj_lib::config::ConfigError;
// Lets the caller label strings and translates the labels to colors
pub trait Formatter: Write {
@ -158,7 +159,7 @@ impl FormatterFactory {
FormatterFactory { kind }
}
pub fn color(config: &config::Config, debug: bool) -> Result<Self, config::ConfigError> {
pub fn color(config: &config::Config, debug: bool) -> Result<Self, ConfigError> {
let rules = Arc::new(rules_from_config(config)?);
let kind = FormatterFactoryKind::Color { rules, debug };
Ok(FormatterFactory { kind })
@ -299,7 +300,7 @@ impl<W: Write> ColorFormatter<W> {
output: W,
config: &config::Config,
debug: bool,
) -> Result<Self, config::ConfigError> {
) -> Result<Self, ConfigError> {
let rules = rules_from_config(config)?;
Ok(Self::new(output, Arc::new(rules), debug))
}
@ -403,7 +404,7 @@ impl<W: Write> ColorFormatter<W> {
}
}
fn rules_from_config(config: &config::Config) -> Result<Rules, config::ConfigError> {
fn rules_from_config(config: &config::Config) -> Result<Rules, ConfigError> {
let mut result = vec![];
let table = config.get_table("colors")?;
for (key, value) in table {
@ -451,7 +452,7 @@ fn rules_from_config(config: &config::Config) -> Result<Rules, config::ConfigErr
Ok(result)
}
fn color_for_name_or_hex(name_or_hex: &str) -> Result<Color, config::ConfigError> {
fn color_for_name_or_hex(name_or_hex: &str) -> Result<Color, ConfigError> {
match name_or_hex {
"default" => Ok(Color::Reset),
"black" => Ok(Color::Black),
@ -471,7 +472,7 @@ fn color_for_name_or_hex(name_or_hex: &str) -> Result<Color, config::ConfigError
"bright cyan" => Ok(Color::Cyan),
"bright white" => Ok(Color::White),
_ => color_for_hex(name_or_hex)
.ok_or_else(|| config::ConfigError::Message(format!("invalid color: {name_or_hex}"))),
.ok_or_else(|| ConfigError::Message(format!("invalid color: {name_or_hex}"))),
}
}

View file

@ -17,6 +17,7 @@ use std::io;
use std::io::Write;
use itertools::Itertools;
use jj_lib::config::ConfigError;
use jj_lib::settings::UserSettings;
use renderdag::Ancestor;
use renderdag::GraphRowRenderer;
@ -112,7 +113,7 @@ pub enum GraphStyle {
}
impl GraphStyle {
pub fn from_settings(settings: &UserSettings) -> Result<Self, config::ConfigError> {
pub fn from_settings(settings: &UserSettings) -> Result<Self, ConfigError> {
settings.config().get("ui.graph.style")
}

View file

@ -18,8 +18,8 @@ mod external;
use std::sync::Arc;
use config::ConfigError;
use jj_lib::backend::MergedTreeId;
use jj_lib::config::ConfigError;
use jj_lib::conflicts::extract_as_single_hunk;
use jj_lib::gitignore::GitIgnoreFile;
use jj_lib::matchers::Matcher;
@ -60,7 +60,7 @@ pub enum DiffEditError {
#[error("Failed to snapshot changes")]
Snapshot(#[from] SnapshotError),
#[error(transparent)]
Config(#[from] config::ConfigError),
Config(#[from] ConfigError),
}
#[derive(Debug, Error)]

View file

@ -32,6 +32,7 @@ use std::thread::JoinHandle;
use indoc::indoc;
use itertools::Itertools as _;
use jj_lib::config::ConfigError;
use minus::MinusError;
use minus::Pager as MinusPager;
use tracing::instrument;
@ -311,7 +312,7 @@ fn color_setting(config: &config::Config) -> ColorChoice {
fn prepare_formatter_factory(
config: &config::Config,
stdout: &Stdout,
) -> Result<FormatterFactory, config::ConfigError> {
) -> Result<FormatterFactory, ConfigError> {
let terminal = stdout.is_terminal();
let (color, debug) = match color_setting(config) {
ColorChoice::Always => (true, false),

View file

@ -22,6 +22,10 @@ use std::str::FromStr;
use config::Source as _;
use itertools::Itertools as _;
/// Error that can occur when accessing configuration.
// TODO: will be replaced with our custom error type
pub type ConfigError = config::ConfigError;
/// Dotted config name path.
#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct ConfigNamePathBuf(Vec<toml_edit::Key>);
@ -54,10 +58,7 @@ impl ConfigNamePathBuf {
/// This is a workaround for the `config.get()` API, which doesn't support
/// literal path expression. If we implement our own config abstraction,
/// this method should be moved there.
pub fn lookup_value(
&self,
config: &config::Config,
) -> Result<config::Value, config::ConfigError> {
pub fn lookup_value(&self, config: &config::Config) -> Result<config::Value, ConfigError> {
// Use config.get() if the TOML keys can be converted to config path
// syntax. This should be cheaper than cloning the whole config map.
let (key_prefix, components) = self.split_safe_prefix();
@ -71,7 +72,7 @@ impl ConfigNamePathBuf {
let mut table = value.into_table().ok()?;
table.remove(key.get())
})
.ok_or_else(|| config::ConfigError::NotFound(self.to_string()))
.ok_or_else(|| ConfigError::NotFound(self.to_string()))
}
/// Splits path to dotted literal expression and remainder.

View file

@ -25,8 +25,8 @@
use std::path::PathBuf;
use config::Config;
use config::ConfigError;
use crate::config::ConfigError;
use crate::settings::ConfigResultExt;
/// Config for Watchman filesystem monitor (<https://facebook.github.io/watchman/>).

View file

@ -25,6 +25,7 @@ use std::str;
use thiserror::Error;
use crate::config::ConfigError;
use crate::settings::ConfigResultExt as _;
use crate::settings::UserSettings;
use crate::signing::SigStatus;
@ -145,7 +146,7 @@ impl GpgBackend {
self
}
pub fn from_settings(settings: &UserSettings) -> Result<Self, config::ConfigError> {
pub fn from_settings(settings: &UserSettings) -> Result<Self, ConfigError> {
let program = settings
.config()
.get_string("signing.backends.gpg.program")

View file

@ -26,6 +26,7 @@ use crate::backend::ChangeId;
use crate::backend::Commit;
use crate::backend::Signature;
use crate::backend::Timestamp;
use crate::config::ConfigError;
use crate::fmt_util::binary_prefix;
use crate::fsmonitor::FsmonitorSettings;
use crate::signing::SignBehavior;
@ -147,7 +148,7 @@ impl UserSettings {
// TODO: Reconsider UserSettings/RepoSettings abstraction. See
// https://github.com/martinvonz/jj/issues/616#issuecomment-1345170699
pub fn with_repo(&self, _repo_path: &Path) -> Result<RepoSettings, config::ConfigError> {
pub fn with_repo(&self, _repo_path: &Path) -> Result<RepoSettings, ConfigError> {
let config = self.config.clone();
Ok(RepoSettings { _config: config })
}
@ -167,7 +168,7 @@ impl UserSettings {
self.config.get_string("user.email").unwrap_or_default()
}
pub fn fsmonitor_settings(&self) -> Result<FsmonitorSettings, config::ConfigError> {
pub fn fsmonitor_settings(&self) -> Result<FsmonitorSettings, ConfigError> {
FsmonitorSettings::from_config(&self.config)
}
@ -238,7 +239,7 @@ impl UserSettings {
GitSettings::from_config(&self.config)
}
pub fn max_new_file_size(&self) -> Result<u64, config::ConfigError> {
pub fn max_new_file_size(&self) -> Result<u64, ConfigError> {
let cfg = self
.config
.get::<HumanByteSize>("snapshot.max-new-file-size")
@ -246,7 +247,7 @@ impl UserSettings {
match cfg {
Ok(0) => Ok(u64::MAX),
x @ Ok(_) => x,
Err(config::ConfigError::NotFound(_)) => Ok(1024 * 1024),
Err(ConfigError::NotFound(_)) => Ok(1024 * 1024),
e @ Err(_) => e,
}
}
@ -290,14 +291,14 @@ impl JJRng {
}
pub trait ConfigResultExt<T> {
fn optional(self) -> Result<Option<T>, config::ConfigError>;
fn optional(self) -> Result<Option<T>, ConfigError>;
}
impl<T> ConfigResultExt<T> for Result<T, config::ConfigError> {
fn optional(self) -> Result<Option<T>, config::ConfigError> {
impl<T> ConfigResultExt<T> for Result<T, ConfigError> {
fn optional(self) -> Result<Option<T>, ConfigError> {
match self {
Ok(value) => Ok(Some(value)),
Err(config::ConfigError::NotFound(_)) => Ok(None),
Err(ConfigError::NotFound(_)) => Ok(None),
Err(err) => Err(err),
}
}

View file

@ -22,6 +22,7 @@ use std::sync::RwLock;
use thiserror::Error;
use crate::backend::CommitId;
use crate::config::ConfigError;
use crate::gpg_signing::GpgBackend;
use crate::settings::UserSettings;
use crate::ssh_signing::SshBackend;
@ -121,7 +122,7 @@ pub enum SignInitError {
UnknownBackend(String),
/// Failed to load backend configuration.
#[error("Failed to configure signing backend")]
BackendConfig(#[source] config::ConfigError),
BackendConfig(#[source] ConfigError),
}
/// A enum that describes if a created/rewritten commit should be signed or not.

View file

@ -26,6 +26,7 @@ use std::process::Stdio;
use either::Either;
use thiserror::Error;
use crate::config::ConfigError;
use crate::settings::ConfigResultExt as _;
use crate::settings::UserSettings;
use crate::signing::SigStatus;
@ -118,7 +119,7 @@ impl SshBackend {
}
}
pub fn from_settings(settings: &UserSettings) -> Result<Self, config::ConfigError> {
pub fn from_settings(settings: &UserSettings) -> Result<Self, ConfigError> {
let program = settings
.config()
.get_string("signing.backends.ssh.program")