Fix submodule recipe listing indentation (#2063)
This commit is contained in:
parent
9e658fba39
commit
d6b2e6bad2
16
src/lib.rs
16
src/lib.rs
@ -29,13 +29,14 @@ pub(crate) use {
|
||||
output::output, output_error::OutputError, parameter::Parameter, parameter_kind::ParameterKind,
|
||||
parser::Parser, platform::Platform, platform_interface::PlatformInterface, position::Position,
|
||||
positional::Positional, ran::Ran, range_ext::RangeExt, recipe::Recipe,
|
||||
recipe_context::RecipeContext, recipe_resolver::RecipeResolver, scope::Scope, search::Search,
|
||||
search_config::SearchConfig, search_error::SearchError, set::Set, setting::Setting,
|
||||
settings::Settings, shebang::Shebang, shell::Shell, show_whitespace::ShowWhitespace,
|
||||
source::Source, string_kind::StringKind, string_literal::StringLiteral, subcommand::Subcommand,
|
||||
suggestion::Suggestion, table::Table, thunk::Thunk, token::Token, token_kind::TokenKind,
|
||||
unresolved_dependency::UnresolvedDependency, unresolved_recipe::UnresolvedRecipe,
|
||||
use_color::UseColor, variables::Variables, verbosity::Verbosity, warning::Warning,
|
||||
recipe_context::RecipeContext, recipe_resolver::RecipeResolver,
|
||||
recipe_signature::RecipeSignature, scope::Scope, search::Search, search_config::SearchConfig,
|
||||
search_error::SearchError, set::Set, setting::Setting, settings::Settings, shebang::Shebang,
|
||||
shell::Shell, show_whitespace::ShowWhitespace, source::Source, string_kind::StringKind,
|
||||
string_literal::StringLiteral, subcommand::Subcommand, suggestion::Suggestion, table::Table,
|
||||
thunk::Thunk, token::Token, token_kind::TokenKind, unresolved_dependency::UnresolvedDependency,
|
||||
unresolved_recipe::UnresolvedRecipe, use_color::UseColor, variables::Variables,
|
||||
verbosity::Verbosity, warning::Warning,
|
||||
},
|
||||
std::{
|
||||
borrow::Cow,
|
||||
@ -168,6 +169,7 @@ mod range_ext;
|
||||
mod recipe;
|
||||
mod recipe_context;
|
||||
mod recipe_resolver;
|
||||
mod recipe_signature;
|
||||
mod run;
|
||||
mod scope;
|
||||
mod search;
|
||||
|
16
src/recipe_signature.rs
Normal file
16
src/recipe_signature.rs
Normal file
@ -0,0 +1,16 @@
|
||||
use super::*;
|
||||
|
||||
pub(crate) struct RecipeSignature<'a> {
|
||||
pub(crate) name: &'a str,
|
||||
pub(crate) recipe: &'a Recipe<'a>,
|
||||
}
|
||||
|
||||
impl<'a> ColorDisplay for RecipeSignature<'a> {
|
||||
fn fmt(&self, f: &mut Formatter, color: Color) -> fmt::Result {
|
||||
write!(f, "{}", self.name)?;
|
||||
for parameter in &self.recipe.parameters {
|
||||
write!(f, " {}", parameter.color_display(color))?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
@ -466,8 +466,12 @@ impl Subcommand {
|
||||
fn list(config: &Config, level: usize, justfile: &Justfile) {
|
||||
const MAX_WIDTH: usize = 50;
|
||||
|
||||
if level == 0 {
|
||||
print!("{}", config.list_heading);
|
||||
}
|
||||
|
||||
// Construct a target to alias map.
|
||||
let mut recipe_aliases: BTreeMap<&str, Vec<&str>> = BTreeMap::new();
|
||||
let mut recipe_aliases = BTreeMap::<&str, Vec<&str>>::new();
|
||||
if !config.no_aliases {
|
||||
for alias in justfile.aliases.values() {
|
||||
if alias.is_private() {
|
||||
@ -483,7 +487,7 @@ impl Subcommand {
|
||||
}
|
||||
}
|
||||
|
||||
let mut line_widths: BTreeMap<&str, usize> = BTreeMap::new();
|
||||
let mut line_widths = BTreeMap::<&str, usize>::new();
|
||||
|
||||
for (name, recipe) in &justfile.recipes {
|
||||
if !recipe.is_public() {
|
||||
@ -491,26 +495,24 @@ impl Subcommand {
|
||||
}
|
||||
|
||||
for name in iter::once(name).chain(recipe_aliases.get(name).unwrap_or(&Vec::new())) {
|
||||
let mut line_width = UnicodeWidthStr::width(*name);
|
||||
|
||||
for parameter in &recipe.parameters {
|
||||
line_width += UnicodeWidthStr::width(
|
||||
format!(" {}", parameter.color_display(Color::never())).as_str(),
|
||||
line_widths.insert(
|
||||
name,
|
||||
UnicodeWidthStr::width(
|
||||
RecipeSignature { name, recipe }
|
||||
.color_display(Color::never())
|
||||
.to_string()
|
||||
.as_str(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
if line_width <= MAX_WIDTH {
|
||||
line_widths.insert(name, line_width);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let max_line_width = line_widths.values().copied().max().unwrap_or_default();
|
||||
let doc_color = config.color.stdout().doc();
|
||||
|
||||
if level == 0 {
|
||||
print!("{}", config.list_heading);
|
||||
}
|
||||
let max_line_width = line_widths
|
||||
.values()
|
||||
.filter(|line_width| **line_width <= MAX_WIDTH)
|
||||
.copied()
|
||||
.max()
|
||||
.unwrap_or_default();
|
||||
|
||||
for recipe in justfile.public_recipes(config.unsorted) {
|
||||
let name = recipe.name();
|
||||
@ -519,10 +521,11 @@ impl Subcommand {
|
||||
.chain(recipe_aliases.get(name).unwrap_or(&Vec::new()))
|
||||
.enumerate()
|
||||
{
|
||||
print!("{}{name}", config.list_prefix.repeat(level + 1));
|
||||
for parameter in &recipe.parameters {
|
||||
print!(" {}", parameter.color_display(config.color.stdout()));
|
||||
}
|
||||
print!(
|
||||
"{}{}",
|
||||
config.list_prefix.repeat(level + 1),
|
||||
RecipeSignature { name, recipe }.color_display(config.color.stdout())
|
||||
);
|
||||
|
||||
let doc = match (i, recipe.doc) {
|
||||
(0, Some(doc)) => Some(Cow::Borrowed(doc)),
|
||||
@ -534,10 +537,9 @@ impl Subcommand {
|
||||
print!(
|
||||
" {:padding$}{} {}",
|
||||
"",
|
||||
doc_color.paint("#"),
|
||||
doc_color.paint(&doc),
|
||||
padding = max_line_width
|
||||
.saturating_sub(line_widths.get(name).copied().unwrap_or(max_line_width))
|
||||
config.color.stdout().doc().paint("#"),
|
||||
config.color.stdout().doc().paint(&doc),
|
||||
padding = max_line_width.saturating_sub(line_widths[name]),
|
||||
);
|
||||
}
|
||||
|
||||
@ -546,7 +548,7 @@ impl Subcommand {
|
||||
}
|
||||
|
||||
for (name, module) in &justfile.modules {
|
||||
println!(" {name}:");
|
||||
println!("{}{name}:", config.list_prefix.repeat(level + 1));
|
||||
Self::list(config, level + 1, module);
|
||||
}
|
||||
}
|
||||
|
@ -69,6 +69,7 @@ mod interrupts;
|
||||
mod invocation_directory;
|
||||
mod json;
|
||||
mod line_prefixes;
|
||||
mod list;
|
||||
mod man;
|
||||
mod misc;
|
||||
mod modules;
|
||||
|
79
tests/list.rs
Normal file
79
tests/list.rs
Normal file
@ -0,0 +1,79 @@
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn list_displays_recipes_in_submodules() {
|
||||
Test::new()
|
||||
.write("foo.just", "bar:\n @echo FOO")
|
||||
.justfile(
|
||||
"
|
||||
mod foo
|
||||
",
|
||||
)
|
||||
.test_round_trip(false)
|
||||
.arg("--unstable")
|
||||
.arg("--list")
|
||||
.stdout(
|
||||
"
|
||||
Available recipes:
|
||||
foo:
|
||||
bar
|
||||
",
|
||||
)
|
||||
.run();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn module_recipe_list_alignment_ignores_private_recipes() {
|
||||
Test::new()
|
||||
.write(
|
||||
"foo.just",
|
||||
"
|
||||
# foos
|
||||
foo:
|
||||
@echo FOO
|
||||
|
||||
[private]
|
||||
barbarbar:
|
||||
@echo BAR
|
||||
|
||||
@_bazbazbaz:
|
||||
@echo BAZ
|
||||
",
|
||||
)
|
||||
.justfile("mod foo")
|
||||
.test_round_trip(false)
|
||||
.arg("--unstable")
|
||||
.arg("--list")
|
||||
.stdout(
|
||||
"
|
||||
Available recipes:
|
||||
foo:
|
||||
foo # foos
|
||||
",
|
||||
)
|
||||
.run();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn nested_modules_are_properly_indented() {
|
||||
Test::new()
|
||||
.write("foo.just", "mod bar")
|
||||
.write("bar.just", "baz:\n @echo FOO")
|
||||
.justfile(
|
||||
"
|
||||
mod foo
|
||||
",
|
||||
)
|
||||
.test_round_trip(false)
|
||||
.arg("--unstable")
|
||||
.arg("--list")
|
||||
.stdout(
|
||||
"
|
||||
Available recipes:
|
||||
foo:
|
||||
bar:
|
||||
baz
|
||||
",
|
||||
)
|
||||
.run();
|
||||
}
|
@ -512,28 +512,6 @@ fn missing_optional_modules_do_not_conflict() {
|
||||
.run();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn list_displays_recipes_in_submodules() {
|
||||
Test::new()
|
||||
.write("foo.just", "bar:\n @echo FOO")
|
||||
.justfile(
|
||||
"
|
||||
mod foo
|
||||
",
|
||||
)
|
||||
.test_round_trip(false)
|
||||
.arg("--unstable")
|
||||
.arg("--list")
|
||||
.stdout(
|
||||
"
|
||||
Available recipes:
|
||||
foo:
|
||||
bar
|
||||
",
|
||||
)
|
||||
.run();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn root_dotenv_is_available_to_submodules() {
|
||||
Test::new()
|
||||
@ -695,37 +673,6 @@ fn module_paths_beginning_with_tilde_are_expanded_to_homdir() {
|
||||
.run();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn module_recipe_list_alignment_ignores_private_recipes() {
|
||||
Test::new()
|
||||
.write(
|
||||
"foo.just",
|
||||
"
|
||||
# foos
|
||||
foo:
|
||||
@echo FOO
|
||||
|
||||
[private]
|
||||
barbarbar:
|
||||
@echo BAR
|
||||
|
||||
@_bazbazbaz:
|
||||
@echo BAZ
|
||||
",
|
||||
)
|
||||
.justfile("mod foo")
|
||||
.test_round_trip(false)
|
||||
.arg("--unstable")
|
||||
.arg("--list")
|
||||
.stdout(
|
||||
"Available recipes:
|
||||
foo:
|
||||
foo # foos
|
||||
",
|
||||
)
|
||||
.run();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn recipes_with_same_name_are_both_run() {
|
||||
Test::new()
|
||||
|
Loading…
Reference in New Issue
Block a user