1
1
mirror of https://github.com/casey/just.git synced 2024-11-22 02:09:44 +03:00
This commit is contained in:
Marc Addeo 2024-11-05 11:00:32 -05:00 committed by GitHub
commit 04adca563b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 176 additions and 32 deletions

8
src/alias_style.rs Normal file
View File

@ -0,0 +1,8 @@
use super::*;
#[derive(Debug, PartialEq, Clone, ValueEnum)]
pub(crate) enum AliasStyle {
Inline,
InlineLeft,
Recipe,
}

View File

@ -66,6 +66,10 @@ impl Color {
self.restyle(Style::new().fg(Blue))
}
pub(crate) fn alias(self) -> Self {
self.restyle(Style::new().fg(Purple))
}
pub(crate) fn error(self) -> Self {
self.restyle(Style::new().fg(Red).bold())
}

View File

@ -9,6 +9,7 @@ use {
#[derive(Debug, PartialEq)]
pub(crate) struct Config {
pub(crate) alias_style: AliasStyle,
pub(crate) check: bool,
pub(crate) color: Color,
pub(crate) command_color: Option<ansi_term::Color>,
@ -80,6 +81,7 @@ mod cmd {
}
mod arg {
pub(crate) const ALIAS_STYLE: &str = "ALIAS_STYLE";
pub(crate) const ARGUMENTS: &str = "ARGUMENTS";
pub(crate) const CHECK: &str = "CHECK";
pub(crate) const CHOOSER: &str = "CHOOSER";
@ -135,6 +137,16 @@ impl Config {
.placeholder(AnsiColor::Green.on_default())
.usage(AnsiColor::Yellow.on_default()),
)
.arg(
Arg::new(arg::ALIAS_STYLE)
.long("alias-style")
.env("JUST_ALIAS_STYLE")
.action(ArgAction::Set)
.value_parser(clap::value_parser!(AliasStyle))
.default_value("inline")
.help("Set the style that the list command will display aliases")
.conflicts_with(arg::NO_ALIASES),
)
.arg(
Arg::new(arg::CHECK)
.long("check")
@ -706,6 +718,10 @@ impl Config {
let explain = matches.get_flag(arg::EXPLAIN);
Ok(Self {
alias_style: matches
.get_one::<AliasStyle>(arg::ALIAS_STYLE)
.unwrap()
.clone(),
check: matches.get_flag(arg::CHECK),
color: (*matches.get_one::<UseColor>(arg::COLOR).unwrap()).into(),
command_color: matches

View File

@ -6,16 +6,16 @@
pub(crate) use {
crate::{
alias::Alias, analyzer::Analyzer, argument_parser::ArgumentParser, assignment::Assignment,
assignment_resolver::AssignmentResolver, ast::Ast, attribute::Attribute, binding::Binding,
color::Color, color_display::ColorDisplay, command_color::CommandColor,
command_ext::CommandExt, compilation::Compilation, compile_error::CompileError,
compile_error_kind::CompileErrorKind, compiler::Compiler, condition::Condition,
conditional_operator::ConditionalOperator, config::Config, config_error::ConfigError,
constants::constants, count::Count, delimiter::Delimiter, dependency::Dependency,
dump_format::DumpFormat, enclosure::Enclosure, error::Error, evaluator::Evaluator,
execution_context::ExecutionContext, executor::Executor, expression::Expression,
fragment::Fragment, function::Function, interpreter::Interpreter,
alias::Alias, alias_style::AliasStyle, analyzer::Analyzer, argument_parser::ArgumentParser,
assignment::Assignment, assignment_resolver::AssignmentResolver, ast::Ast,
attribute::Attribute, binding::Binding, color::Color, color_display::ColorDisplay,
command_color::CommandColor, command_ext::CommandExt, compilation::Compilation,
compile_error::CompileError, compile_error_kind::CompileErrorKind, compiler::Compiler,
condition::Condition, conditional_operator::ConditionalOperator, config::Config,
config_error::ConfigError, constants::constants, count::Count, delimiter::Delimiter,
dependency::Dependency, dump_format::DumpFormat, enclosure::Enclosure, error::Error,
evaluator::Evaluator, execution_context::ExecutionContext, executor::Executor,
expression::Expression, fragment::Fragment, function::Function, interpreter::Interpreter,
interrupt_guard::InterruptGuard, interrupt_handler::InterruptHandler, item::Item,
justfile::Justfile, keyed::Keyed, keyword::Keyword, lexer::Lexer, line::Line, list::List,
load_dotenv::load_dotenv, loader::Loader, module_path::ModulePath, name::Name,
@ -107,6 +107,7 @@ pub mod fuzzing;
pub mod summary;
mod alias;
mod alias_style;
mod analyzer;
mod argument_parser;
mod assignment;

View File

@ -408,20 +408,49 @@ impl Subcommand {
config: &Config,
name: &str,
doc: Option<&str>,
aliases: &[&str],
max_signature_width: usize,
signature_widths: &BTreeMap<&str, usize>,
) {
if let Some(doc) = doc {
if !doc.is_empty() && doc.lines().count() <= 1 {
print!(
"{:padding$}{} {}",
"",
config.color.stdout().doc().paint("#"),
config.color.stdout().doc().paint(doc),
padding = max_signature_width.saturating_sub(signature_widths[name]) + 1,
);
}
let doc = doc.unwrap_or_default();
let print_doc = !doc.is_empty() && doc.lines().count() <= 1;
let print_aliases = config.alias_style != AliasStyle::Recipe && !aliases.is_empty();
if print_doc || print_aliases {
print!(
"{:padding$}{}",
"",
config.color.stdout().doc().paint("#"),
padding = max_signature_width.saturating_sub(signature_widths[name]) + 1,
);
}
let doc = print_doc.then_some(format!("{}", config.color.stdout().doc().paint(doc)));
let aliases = print_aliases.then_some(format!(
"{}",
config
.color
.stdout()
.alias()
.paint(&format!("[aliases: {}]", aliases.join(", ")))
));
let (left, right) = if config.alias_style == AliasStyle::InlineLeft {
(aliases, doc)
} else {
(doc, aliases)
};
if print_doc || print_aliases {
print!(
" {}",
[left, right]
.map(Option::unwrap_or_default)
.join(" ")
.trim()
);
}
println!();
}
@ -545,8 +574,14 @@ impl Subcommand {
if let Some(recipes) = recipe_groups.get(&group) {
for recipe in recipes {
let recipe_alias_entries = if config.alias_style == AliasStyle::Recipe {
aliases.get(recipe.name())
} else {
None
};
for (i, name) in iter::once(&recipe.name())
.chain(aliases.get(recipe.name()).unwrap_or(&Vec::new()))
.chain(recipe_alias_entries.unwrap_or(&Vec::new()))
.enumerate()
{
let doc = if i == 0 {
@ -576,6 +611,7 @@ impl Subcommand {
config,
name,
doc.as_deref(),
aliases.get(recipe.name()).unwrap_or(&Vec::new()),
max_signature_width,
&signature_widths,
);
@ -598,6 +634,7 @@ impl Subcommand {
config,
submodule.name(),
submodule.doc.as_deref(),
&Vec::new(),
max_signature_width,
&signature_widths,
);

60
tests/alias_style.rs Normal file
View File

@ -0,0 +1,60 @@
use super::*;
#[test]
fn alias_style_inline() {
Test::new()
.justfile(
"
alias t := test1
# A test recipe
test1:
@echo 'test1'
test2:
@echo 'test2'
",
)
.args(["--alias-style=inline", "--list"])
.stdout("Available recipes:\n test1 # A test recipe [aliases: t]\n test2\n")
.run();
}
#[test]
fn alias_style_inline_left() {
Test::new()
.justfile(
"
alias t := test1
# A test recipe
test1:
@echo 'test1'
test2:
@echo 'test2'
",
)
.args(["--alias-style=inline-left", "--list"])
.stdout("Available recipes:\n test1 # [aliases: t] A test recipe\n test2\n")
.run();
}
#[test]
fn alias_style_recipe() {
Test::new()
.justfile(
"
alias t := test1
test1:
@echo 'test1'
test2:
@echo 'test2'
",
)
.args(["--alias-style=recipe", "--list"])
.stdout("Available recipes:\n test1\n t # alias for `test1`\n test2\n")
.run();
}

View File

@ -31,6 +31,7 @@ pub(crate) use {
#[macro_use]
mod test;
mod alias_style;
mod allow_duplicate_recipes;
mod allow_duplicate_variables;
mod assert_stdout;

View File

@ -11,20 +11,40 @@ test! {
args: ("--list"),
stdout: "
Available recipes:
foo
f # alias for `foo`
foo # [aliases: f]
",
}
#[test]
fn alias_listing_with_doc() {
Test::new()
.justfile(
"
# foo command
foo:
echo foo
alias f := foo
",
)
.arg("--list")
.stdout(
"
Available recipes:
foo # foo command [aliases: f]
",
)
.status(EXIT_SUCCESS)
.run();
}
test! {
name: alias_listing_multiple_aliases,
justfile: "foo:\n echo foo\nalias f := foo\nalias fo := foo",
args: ("--list"),
stdout: "
Available recipes:
foo
f # alias for `foo`
fo # alias for `foo`
foo # [aliases: f, fo]
",
}
@ -34,8 +54,7 @@ test! {
args: ("--list"),
stdout: "
Available recipes:
foo PARAM='foo'
f PARAM='foo' # alias for `foo`
foo PARAM='foo' # [aliases: f]
",
}
@ -927,8 +946,7 @@ a:
stdout: r"
Available recipes:
a
b
c # alias for `b`
b # [aliases: c]
",
}
@ -942,8 +960,7 @@ a:
args: ("--list", "--unsorted"),
stdout: r"
Available recipes:
b
c # alias for `b`
b # [aliases: c]
a
",
}