forked from mirrors/jj
cli: error out if colors section isn't of map type
This commit is contained in:
parent
7b24df25e4
commit
797189b106
3 changed files with 76 additions and 71 deletions
|
@ -1717,7 +1717,7 @@ fn handle_early_args(
|
||||||
}
|
}
|
||||||
if !args.config_toml.is_empty() {
|
if !args.config_toml.is_empty() {
|
||||||
layered_configs.parse_config_args(&args.config_toml)?;
|
layered_configs.parse_config_args(&args.config_toml)?;
|
||||||
ui.reset(&layered_configs.merge());
|
ui.reset(&layered_configs.merge())?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -1899,7 +1899,7 @@ impl CliRunner {
|
||||||
let cwd = env::current_dir().unwrap(); // TODO: maybe map_err to CommandError?
|
let cwd = env::current_dir().unwrap(); // TODO: maybe map_err to CommandError?
|
||||||
layered_configs.read_user_config()?;
|
layered_configs.read_user_config()?;
|
||||||
let config = layered_configs.merge();
|
let config = layered_configs.merge();
|
||||||
ui.reset(&config);
|
ui.reset(&config)?;
|
||||||
let string_args = expand_args(&self.app, std::env::args_os(), &config)?;
|
let string_args = expand_args(&self.app, std::env::args_os(), &config)?;
|
||||||
let (matches, args) = parse_args(
|
let (matches, args) = parse_args(
|
||||||
ui,
|
ui,
|
||||||
|
@ -1915,7 +1915,7 @@ impl CliRunner {
|
||||||
layered_configs.read_repo_config(loader.repo_path())?;
|
layered_configs.read_repo_config(loader.repo_path())?;
|
||||||
}
|
}
|
||||||
let config = layered_configs.merge();
|
let config = layered_configs.merge();
|
||||||
ui.reset(&config);
|
ui.reset(&config)?;
|
||||||
let settings = UserSettings::from_config(config);
|
let settings = UserSettings::from_config(config);
|
||||||
let command_helper = CommandHelper::new(
|
let command_helper = CommandHelper::new(
|
||||||
self.app,
|
self.app,
|
||||||
|
@ -1932,7 +1932,8 @@ impl CliRunner {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn run(self) -> ExitCode {
|
pub fn run(self) -> ExitCode {
|
||||||
let layered_configs = LayeredConfigs::from_environment();
|
let layered_configs = LayeredConfigs::from_environment();
|
||||||
let mut ui = Ui::with_config(&layered_configs.merge());
|
let mut ui = Ui::with_config(&layered_configs.merge())
|
||||||
|
.expect("default config should be valid, env vars are stringly typed");
|
||||||
let result = self.run_internal(&mut ui, layered_configs);
|
let result = self.run_internal(&mut ui, layered_configs);
|
||||||
let exit_code = handle_command_result(&mut ui, result);
|
let exit_code = handle_command_result(&mut ui, result);
|
||||||
ui.finalize_writes();
|
ui.finalize_writes();
|
||||||
|
|
125
src/formatter.rs
125
src/formatter.rs
|
@ -98,16 +98,20 @@ enum FormatterFactoryKind {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FormatterFactory {
|
impl FormatterFactory {
|
||||||
pub fn prepare(config: &config::Config, color: bool, sanitized: bool) -> Self {
|
pub fn prepare(
|
||||||
|
config: &config::Config,
|
||||||
|
color: bool,
|
||||||
|
sanitized: bool,
|
||||||
|
) -> Result<Self, config::ConfigError> {
|
||||||
let kind = if color {
|
let kind = if color {
|
||||||
let rules = Arc::new(rules_from_config(config));
|
let rules = Arc::new(rules_from_config(config)?);
|
||||||
FormatterFactoryKind::Color { rules }
|
FormatterFactoryKind::Color { rules }
|
||||||
} else if sanitized {
|
} else if sanitized {
|
||||||
FormatterFactoryKind::Sanitized
|
FormatterFactoryKind::Sanitized
|
||||||
} else {
|
} else {
|
||||||
FormatterFactoryKind::PlainText
|
FormatterFactoryKind::PlainText
|
||||||
};
|
};
|
||||||
FormatterFactory { kind }
|
Ok(FormatterFactory { kind })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_formatter<'output, W: Write + 'output>(
|
pub fn new_formatter<'output, W: Write + 'output>(
|
||||||
|
@ -232,9 +236,9 @@ impl<W: Write> ColorFormatter<W> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn for_config(output: W, config: &config::Config) -> ColorFormatter<W> {
|
pub fn for_config(output: W, config: &config::Config) -> Result<Self, config::ConfigError> {
|
||||||
let rules = rules_from_config(config);
|
let rules = rules_from_config(config)?;
|
||||||
Self::new(output, Arc::new(rules))
|
Ok(Self::new(output, Arc::new(rules)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn requested_style(&mut self) -> Style {
|
fn requested_style(&mut self) -> Style {
|
||||||
|
@ -316,53 +320,52 @@ impl<W: Write> ColorFormatter<W> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rules_from_config(config: &config::Config) -> Rules {
|
fn rules_from_config(config: &config::Config) -> Result<Rules, config::ConfigError> {
|
||||||
let mut result = vec![];
|
let mut result = vec![];
|
||||||
if let Ok(table) = config.get_table("colors") {
|
let table = config.get_table("colors")?;
|
||||||
for (key, value) in table {
|
for (key, value) in table {
|
||||||
let labels = key
|
let labels = key
|
||||||
.split_whitespace()
|
.split_whitespace()
|
||||||
.map(ToString::to_string)
|
.map(ToString::to_string)
|
||||||
.collect_vec();
|
.collect_vec();
|
||||||
match value.kind {
|
match value.kind {
|
||||||
config::ValueKind::String(color_name) => {
|
config::ValueKind::String(color_name) => {
|
||||||
let style = Style {
|
let style = Style {
|
||||||
fg_color: color_for_name(&color_name),
|
fg_color: color_for_name(&color_name),
|
||||||
bg_color: None,
|
bg_color: None,
|
||||||
bold: None,
|
bold: None,
|
||||||
underlined: None,
|
underlined: None,
|
||||||
};
|
};
|
||||||
result.push((labels, style));
|
result.push((labels, style));
|
||||||
}
|
|
||||||
config::ValueKind::Table(style_table) => {
|
|
||||||
let mut style = Style::default();
|
|
||||||
if let Some(value) = style_table.get("fg") {
|
|
||||||
if let config::ValueKind::String(color_name) = &value.kind {
|
|
||||||
style.fg_color = color_for_name(color_name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if let Some(value) = style_table.get("bg") {
|
|
||||||
if let config::ValueKind::String(color_name) = &value.kind {
|
|
||||||
style.bg_color = color_for_name(color_name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if let Some(value) = style_table.get("bold") {
|
|
||||||
if let config::ValueKind::Boolean(value) = &value.kind {
|
|
||||||
style.bold = Some(*value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if let Some(value) = style_table.get("underlined") {
|
|
||||||
if let config::ValueKind::Boolean(value) = &value.kind {
|
|
||||||
style.underlined = Some(*value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result.push((labels, style));
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
|
config::ValueKind::Table(style_table) => {
|
||||||
|
let mut style = Style::default();
|
||||||
|
if let Some(value) = style_table.get("fg") {
|
||||||
|
if let config::ValueKind::String(color_name) = &value.kind {
|
||||||
|
style.fg_color = color_for_name(color_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some(value) = style_table.get("bg") {
|
||||||
|
if let config::ValueKind::String(color_name) = &value.kind {
|
||||||
|
style.bg_color = color_for_name(color_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some(value) = style_table.get("bold") {
|
||||||
|
if let config::ValueKind::Boolean(value) = &value.kind {
|
||||||
|
style.bold = Some(*value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some(value) = style_table.get("underlined") {
|
||||||
|
if let config::ValueKind::Boolean(value) = &value.kind {
|
||||||
|
style.underlined = Some(*value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.push((labels, style));
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn color_for_name(color_name: &str) -> Option<Color> {
|
fn color_for_name(color_name: &str) -> Option<Color> {
|
||||||
|
@ -540,7 +543,7 @@ mod tests {
|
||||||
}
|
}
|
||||||
let mut output: Vec<u8> = vec![];
|
let mut output: Vec<u8> = vec![];
|
||||||
let mut formatter =
|
let mut formatter =
|
||||||
ColorFormatter::for_config(&mut output, &config_builder.build().unwrap());
|
ColorFormatter::for_config(&mut output, &config_builder.build().unwrap()).unwrap();
|
||||||
for color in colors {
|
for color in colors {
|
||||||
formatter.push_label(&color.replace(' ', "-")).unwrap();
|
formatter.push_label(&color.replace(' ', "-")).unwrap();
|
||||||
formatter.write_str(&format!(" {color} ")).unwrap();
|
formatter.write_str(&format!(" {color} ")).unwrap();
|
||||||
|
@ -577,7 +580,7 @@ mod tests {
|
||||||
"#,
|
"#,
|
||||||
);
|
);
|
||||||
let mut output: Vec<u8> = vec![];
|
let mut output: Vec<u8> = vec![];
|
||||||
let mut formatter = ColorFormatter::for_config(&mut output, &config);
|
let mut formatter = ColorFormatter::for_config(&mut output, &config).unwrap();
|
||||||
formatter.write_str(" before ").unwrap();
|
formatter.write_str(" before ").unwrap();
|
||||||
formatter.push_label("inside").unwrap();
|
formatter.push_label("inside").unwrap();
|
||||||
formatter.write_str(" inside ").unwrap();
|
formatter.write_str(" inside ").unwrap();
|
||||||
|
@ -600,7 +603,7 @@ mod tests {
|
||||||
"#,
|
"#,
|
||||||
);
|
);
|
||||||
let mut output: Vec<u8> = vec![];
|
let mut output: Vec<u8> = vec![];
|
||||||
let mut formatter = ColorFormatter::for_config(&mut output, &config);
|
let mut formatter = ColorFormatter::for_config(&mut output, &config).unwrap();
|
||||||
formatter.push_label("red_fg").unwrap();
|
formatter.push_label("red_fg").unwrap();
|
||||||
formatter.write_str(" fg only ").unwrap();
|
formatter.write_str(" fg only ").unwrap();
|
||||||
formatter.pop_label().unwrap();
|
formatter.pop_label().unwrap();
|
||||||
|
@ -647,7 +650,7 @@ mod tests {
|
||||||
"#,
|
"#,
|
||||||
);
|
);
|
||||||
let mut output: Vec<u8> = vec![];
|
let mut output: Vec<u8> = vec![];
|
||||||
let mut formatter = ColorFormatter::for_config(&mut output, &config);
|
let mut formatter = ColorFormatter::for_config(&mut output, &config).unwrap();
|
||||||
formatter.push_label("not_bold").unwrap();
|
formatter.push_label("not_bold").unwrap();
|
||||||
formatter.write_str(" not bold ").unwrap();
|
formatter.write_str(" not bold ").unwrap();
|
||||||
formatter.push_label("bold_font").unwrap();
|
formatter.push_label("bold_font").unwrap();
|
||||||
|
@ -668,7 +671,7 @@ mod tests {
|
||||||
"#,
|
"#,
|
||||||
);
|
);
|
||||||
let mut output: Vec<u8> = vec![];
|
let mut output: Vec<u8> = vec![];
|
||||||
let mut formatter = ColorFormatter::for_config(&mut output, &config);
|
let mut formatter = ColorFormatter::for_config(&mut output, &config).unwrap();
|
||||||
formatter.write_str("before").unwrap();
|
formatter.write_str("before").unwrap();
|
||||||
formatter.push_label("red").unwrap();
|
formatter.push_label("red").unwrap();
|
||||||
formatter.write_str("first").unwrap();
|
formatter.write_str("first").unwrap();
|
||||||
|
@ -689,7 +692,7 @@ mod tests {
|
||||||
"#,
|
"#,
|
||||||
);
|
);
|
||||||
let mut output: Vec<u8> = vec![];
|
let mut output: Vec<u8> = vec![];
|
||||||
let mut formatter = ColorFormatter::for_config(&mut output, &config);
|
let mut formatter = ColorFormatter::for_config(&mut output, &config).unwrap();
|
||||||
formatter.push_label("red").unwrap();
|
formatter.push_label("red").unwrap();
|
||||||
formatter
|
formatter
|
||||||
.write_str("\x1b[1mnot actually bold\x1b[0m")
|
.write_str("\x1b[1mnot actually bold\x1b[0m")
|
||||||
|
@ -711,7 +714,7 @@ mod tests {
|
||||||
"#,
|
"#,
|
||||||
);
|
);
|
||||||
let mut output: Vec<u8> = vec![];
|
let mut output: Vec<u8> = vec![];
|
||||||
let mut formatter = ColorFormatter::for_config(&mut output, &config);
|
let mut formatter = ColorFormatter::for_config(&mut output, &config).unwrap();
|
||||||
formatter.write_str(" before outer ").unwrap();
|
formatter.write_str(" before outer ").unwrap();
|
||||||
formatter.push_label("outer").unwrap();
|
formatter.push_label("outer").unwrap();
|
||||||
formatter.write_str(" before inner ").unwrap();
|
formatter.write_str(" before inner ").unwrap();
|
||||||
|
@ -734,7 +737,7 @@ mod tests {
|
||||||
"#,
|
"#,
|
||||||
);
|
);
|
||||||
let mut output: Vec<u8> = vec![];
|
let mut output: Vec<u8> = vec![];
|
||||||
let mut formatter = ColorFormatter::for_config(&mut output, &config);
|
let mut formatter = ColorFormatter::for_config(&mut output, &config).unwrap();
|
||||||
formatter.push_label("outer").unwrap();
|
formatter.push_label("outer").unwrap();
|
||||||
formatter.write_str(" not colored ").unwrap();
|
formatter.write_str(" not colored ").unwrap();
|
||||||
formatter.push_label("inner").unwrap();
|
formatter.push_label("inner").unwrap();
|
||||||
|
@ -756,7 +759,7 @@ mod tests {
|
||||||
"#,
|
"#,
|
||||||
);
|
);
|
||||||
let mut output: Vec<u8> = vec![];
|
let mut output: Vec<u8> = vec![];
|
||||||
let mut formatter = ColorFormatter::for_config(&mut output, &config);
|
let mut formatter = ColorFormatter::for_config(&mut output, &config).unwrap();
|
||||||
formatter.push_label("outer").unwrap();
|
formatter.push_label("outer").unwrap();
|
||||||
formatter.write_str(" red before ").unwrap();
|
formatter.write_str(" red before ").unwrap();
|
||||||
formatter.push_label("inner").unwrap();
|
formatter.push_label("inner").unwrap();
|
||||||
|
@ -778,7 +781,7 @@ mod tests {
|
||||||
"#,
|
"#,
|
||||||
);
|
);
|
||||||
let mut output: Vec<u8> = vec![];
|
let mut output: Vec<u8> = vec![];
|
||||||
let mut formatter = ColorFormatter::for_config(&mut output, &config);
|
let mut formatter = ColorFormatter::for_config(&mut output, &config).unwrap();
|
||||||
formatter.push_label("outer1").unwrap();
|
formatter.push_label("outer1").unwrap();
|
||||||
formatter.push_label("inner2").unwrap();
|
formatter.push_label("inner2").unwrap();
|
||||||
formatter.write_str(" hello ").unwrap();
|
formatter.write_str(" hello ").unwrap();
|
||||||
|
@ -797,7 +800,7 @@ mod tests {
|
||||||
"#,
|
"#,
|
||||||
);
|
);
|
||||||
let mut output: Vec<u8> = vec![];
|
let mut output: Vec<u8> = vec![];
|
||||||
let mut formatter = ColorFormatter::for_config(&mut output, &config);
|
let mut formatter = ColorFormatter::for_config(&mut output, &config).unwrap();
|
||||||
formatter.push_label("outer").unwrap();
|
formatter.push_label("outer").unwrap();
|
||||||
formatter.push_label("inner").unwrap();
|
formatter.push_label("inner").unwrap();
|
||||||
formatter.write_str(" hello ").unwrap();
|
formatter.write_str(" hello ").unwrap();
|
||||||
|
@ -818,7 +821,7 @@ mod tests {
|
||||||
"#,
|
"#,
|
||||||
);
|
);
|
||||||
let mut output: Vec<u8> = vec![];
|
let mut output: Vec<u8> = vec![];
|
||||||
let mut formatter = ColorFormatter::for_config(&mut output, &config);
|
let mut formatter = ColorFormatter::for_config(&mut output, &config).unwrap();
|
||||||
formatter.push_label("a").unwrap();
|
formatter.push_label("a").unwrap();
|
||||||
formatter.write_str(" a1 ").unwrap();
|
formatter.write_str(" a1 ").unwrap();
|
||||||
formatter.push_label("b").unwrap();
|
formatter.push_label("b").unwrap();
|
||||||
|
|
13
src/ui.rs
13
src/ui.rs
|
@ -107,29 +107,30 @@ fn pager_setting(config: &config::Config) -> FullCommandArgs {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Ui {
|
impl Ui {
|
||||||
pub fn with_config(config: &config::Config) -> Ui {
|
pub fn with_config(config: &config::Config) -> Result<Ui, config::ConfigError> {
|
||||||
let color = use_color(color_setting(config));
|
let color = use_color(color_setting(config));
|
||||||
// Sanitize ANSI escape codes if we're printing to a terminal. Doesn't affect
|
// Sanitize ANSI escape codes if we're printing to a terminal. Doesn't affect
|
||||||
// ANSI escape codes that originate from the formatter itself.
|
// ANSI escape codes that originate from the formatter itself.
|
||||||
let sanitize = io::stdout().is_tty();
|
let sanitize = io::stdout().is_tty();
|
||||||
let formatter_factory = FormatterFactory::prepare(config, color, sanitize);
|
let formatter_factory = FormatterFactory::prepare(config, color, sanitize)?;
|
||||||
let progress_indicator = progress_indicator_setting(config);
|
let progress_indicator = progress_indicator_setting(config);
|
||||||
Ui {
|
Ok(Ui {
|
||||||
color,
|
color,
|
||||||
formatter_factory,
|
formatter_factory,
|
||||||
pager_cmd: pager_setting(config),
|
pager_cmd: pager_setting(config),
|
||||||
paginate: PaginationChoice::Auto,
|
paginate: PaginationChoice::Auto,
|
||||||
progress_indicator,
|
progress_indicator,
|
||||||
output: UiOutput::new_terminal(),
|
output: UiOutput::new_terminal(),
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn reset(&mut self, config: &config::Config) {
|
pub fn reset(&mut self, config: &config::Config) -> Result<(), config::ConfigError> {
|
||||||
self.color = use_color(color_setting(config));
|
self.color = use_color(color_setting(config));
|
||||||
self.pager_cmd = pager_setting(config);
|
self.pager_cmd = pager_setting(config);
|
||||||
self.progress_indicator = progress_indicator_setting(config);
|
self.progress_indicator = progress_indicator_setting(config);
|
||||||
let sanitize = io::stdout().is_tty();
|
let sanitize = io::stdout().is_tty();
|
||||||
self.formatter_factory = FormatterFactory::prepare(config, self.color, sanitize);
|
self.formatter_factory = FormatterFactory::prepare(config, self.color, sanitize)?;
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the pagination value.
|
/// Sets the pagination value.
|
||||||
|
|
Loading…
Reference in a new issue