List modules in source order with --unsorted (#2085)

This commit is contained in:
Casey Rodarmor 2024-05-25 01:01:37 -07:00 committed by GitHub
parent ed0dc20318
commit d7059f8bc8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 75 additions and 25 deletions

View File

@ -13,8 +13,9 @@ impl<'src> Analyzer<'src> {
paths: &HashMap<PathBuf, PathBuf>, paths: &HashMap<PathBuf, PathBuf>,
asts: &HashMap<PathBuf, Ast<'src>>, asts: &HashMap<PathBuf, Ast<'src>>,
root: &Path, root: &Path,
name: Option<Name<'src>>,
) -> CompileResult<'src, Justfile<'src>> { ) -> CompileResult<'src, Justfile<'src>> {
Self::default().justfile(loaded, paths, asts, root) Self::default().justfile(loaded, paths, asts, root, name)
} }
fn justfile( fn justfile(
@ -23,6 +24,7 @@ impl<'src> Analyzer<'src> {
paths: &HashMap<PathBuf, PathBuf>, paths: &HashMap<PathBuf, PathBuf>,
asts: &HashMap<PathBuf, Ast<'src>>, asts: &HashMap<PathBuf, Ast<'src>>,
root: &Path, root: &Path,
name: Option<Name<'src>>,
) -> CompileResult<'src, Justfile<'src>> { ) -> CompileResult<'src, Justfile<'src>> {
let mut recipes = Vec::new(); let mut recipes = Vec::new();
@ -33,7 +35,7 @@ impl<'src> Analyzer<'src> {
let mut warnings = Vec::new(); let mut warnings = Vec::new();
let mut modules: BTreeMap<String, (Name, Justfile)> = BTreeMap::new(); let mut modules: Table<Justfile> = Table::new();
let mut definitions: HashMap<&str, (&'static str, Name)> = HashMap::new(); let mut definitions: HashMap<&str, (&'static str, Name)> = HashMap::new();
@ -83,10 +85,7 @@ impl<'src> Analyzer<'src> {
Item::Module { absolute, name, .. } => { Item::Module { absolute, name, .. } => {
if let Some(absolute) = absolute { if let Some(absolute) = absolute {
define(*name, "module", false)?; define(*name, "module", false)?;
modules.insert( modules.insert(Self::analyze(loaded, paths, asts, absolute, Some(*name))?);
name.lexeme().into(),
(*name, Self::analyze(loaded, paths, asts, absolute)?),
);
} }
} }
Item::Recipe(recipe) => { Item::Recipe(recipe) => {
@ -149,6 +148,8 @@ impl<'src> Analyzer<'src> {
let root = paths.get(root).unwrap(); let root = paths.get(root).unwrap();
Ok(Justfile { Ok(Justfile {
aliases,
assignments: self.assignments,
default: recipes default: recipes
.values() .values()
.filter(|recipe| recipe.name.path == root) .filter(|recipe| recipe.name.path == root)
@ -160,16 +161,12 @@ impl<'src> Analyzer<'src> {
Rc::clone(next) Rc::clone(next)
}), }),
}), }),
aliases,
assignments: self.assignments,
loaded: loaded.into(), loaded: loaded.into(),
modules,
name,
recipes, recipes,
settings, settings,
warnings, warnings,
modules: modules
.into_iter()
.map(|(name, (_name, justfile))| (name, justfile))
.collect(),
}) })
} }

View File

@ -106,7 +106,7 @@ impl Compiler {
asts.insert(current.path, ast.clone()); asts.insert(current.path, ast.clone());
} }
let justfile = Analyzer::analyze(&loaded, &paths, &asts, root)?; let justfile = Analyzer::analyze(&loaded, &paths, &asts, root, None)?;
Ok(Compilation { Ok(Compilation {
asts, asts,
@ -182,7 +182,7 @@ impl Compiler {
asts.insert(root.clone(), ast); asts.insert(root.clone(), ast);
let mut paths: HashMap<PathBuf, PathBuf> = HashMap::new(); let mut paths: HashMap<PathBuf, PathBuf> = HashMap::new();
paths.insert(root.clone(), root.clone()); paths.insert(root.clone(), root.clone());
Analyzer::analyze(&[], &paths, &asts, &root) Analyzer::analyze(&[], &paths, &asts, &root, None)
} }
} }

View File

@ -16,7 +16,9 @@ pub(crate) struct Justfile<'src> {
pub(crate) default: Option<Rc<Recipe<'src>>>, pub(crate) default: Option<Rc<Recipe<'src>>>,
#[serde(skip)] #[serde(skip)]
pub(crate) loaded: Vec<PathBuf>, pub(crate) loaded: Vec<PathBuf>,
pub(crate) modules: BTreeMap<String, Justfile<'src>>, pub(crate) modules: Table<'src, Justfile<'src>>,
#[serde(skip)]
pub(crate) name: Option<Name<'src>>,
pub(crate) recipes: Table<'src, Rc<Recipe<'src>>>, pub(crate) recipes: Table<'src, Rc<Recipe<'src>>>,
pub(crate) settings: Settings<'src>, pub(crate) settings: Settings<'src>,
pub(crate) warnings: Vec<Warning>, pub(crate) warnings: Vec<Warning>,
@ -401,6 +403,10 @@ impl<'src> Justfile<'src> {
} }
} }
pub(crate) fn name(&self) -> &'src str {
self.name.map(|name| name.lexeme()).unwrap_or_default()
}
fn run_recipe( fn run_recipe(
arguments: &[String], arguments: &[String],
context: &RecipeContext<'src, '_>, context: &RecipeContext<'src, '_>,
@ -465,7 +471,22 @@ impl<'src> Justfile<'src> {
Ok(()) Ok(())
} }
pub(crate) fn public_recipes(&self, source_order: bool) -> Vec<&Recipe<'src, Dependency>> { pub(crate) fn modules(&self, config: &Config) -> Vec<&Justfile> {
let mut modules = self.modules.values().collect::<Vec<&Justfile>>();
if config.unsorted {
modules.sort_by_key(|module| {
module
.name
.map(|name| name.token.offset)
.unwrap_or_default()
});
}
modules
}
pub(crate) fn public_recipes(&self, config: &Config) -> Vec<&Recipe<'src, Dependency>> {
let mut recipes = self let mut recipes = self
.recipes .recipes
.values() .values()
@ -473,7 +494,7 @@ impl<'src> Justfile<'src> {
.filter(|recipe| recipe.is_public()) .filter(|recipe| recipe.is_public())
.collect::<Vec<&Recipe<Dependency>>>(); .collect::<Vec<&Recipe<Dependency>>>();
if source_order { if config.unsorted {
recipes.sort_by_key(|recipe| { recipes.sort_by_key(|recipe| {
( (
self self
@ -531,6 +552,12 @@ impl<'src> ColorDisplay for Justfile<'src> {
} }
} }
impl<'src> Keyed<'src> for Justfile<'src> {
fn key(&self) -> &'src str {
self.name()
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;

View File

@ -223,7 +223,7 @@ impl Subcommand {
while let Some(module) = stack.pop() { while let Some(module) = stack.pop() {
recipes.extend( recipes.extend(
module module
.public_recipes(config.unsorted) .public_recipes(config)
.iter() .iter()
.filter(|recipe| recipe.min_arguments() == 0), .filter(|recipe| recipe.min_arguments() == 0),
); );
@ -532,7 +532,7 @@ impl Subcommand {
let groups = { let groups = {
let mut groups = BTreeMap::<Option<String>, Vec<&Recipe>>::new(); let mut groups = BTreeMap::<Option<String>, Vec<&Recipe>>::new();
for recipe in justfile.public_recipes(config.unsorted) { for recipe in justfile.public_recipes(config) {
let recipe_groups = recipe.groups(); let recipe_groups = recipe.groups();
if recipe_groups.is_empty() { if recipe_groups.is_empty() {
groups.entry(None).or_default().push(recipe); groups.entry(None).or_default().push(recipe);
@ -592,12 +592,12 @@ impl Subcommand {
} }
} }
for (i, (name, module)) in justfile.modules.iter().enumerate() { for (i, module) in justfile.modules(config).into_iter().enumerate() {
if i + groups.len() > 0 { if i + groups.len() > 0 {
println!(); println!();
} }
println!("{}{name}:", config.list_prefix.repeat(level + 1)); println!("{}{}:", config.list_prefix.repeat(level + 1), module.name());
Self::list(config, level + 1, module); Self::list(config, level + 1, module);
} }
} }
@ -637,7 +637,7 @@ impl Subcommand {
) { ) {
let path = components.join("::"); let path = components.join("::");
for recipe in justfile.public_recipes(config.unsorted) { for recipe in justfile.public_recipes(config) {
if *printed > 0 { if *printed > 0 {
print!(" "); print!(" ");
} }

View File

@ -76,7 +76,7 @@ pub(crate) fn analysis_error(
let mut paths: HashMap<PathBuf, PathBuf> = HashMap::new(); let mut paths: HashMap<PathBuf, PathBuf> = HashMap::new();
paths.insert("justfile".into(), "justfile".into()); paths.insert("justfile".into(), "justfile".into());
match Analyzer::analyze(&[], &paths, &asts, &root) { match Analyzer::analyze(&[], &paths, &asts, &root, None) {
Ok(_) => panic!("Analysis unexpectedly succeeded"), Ok(_) => panic!("Analysis unexpectedly succeeded"),
Err(have) => { Err(have) => {
let want = CompileError { let want = CompileError {

View File

@ -35,8 +35,7 @@ fn modules_are_space_separated_in_output() {
", ",
) )
.test_round_trip(false) .test_round_trip(false)
.arg("--unstable") .args(["--unstable", "--list"])
.arg("--list")
.stdout( .stdout(
" "
Available recipes: Available recipes:
@ -50,6 +49,33 @@ fn modules_are_space_separated_in_output() {
.run(); .run();
} }
#[test]
fn modules_unsorted() {
Test::new()
.write("foo.just", "foo:")
.write("bar.just", "bar:")
.justfile(
"
mod foo
mod bar
",
)
.test_round_trip(false)
.args(["--unstable", "--list", "--unsorted"])
.stdout(
"
Available recipes:
foo:
foo
bar:
bar
",
)
.run();
}
#[test] #[test]
fn module_recipe_list_alignment_ignores_private_recipes() { fn module_recipe_list_alignment_ignores_private_recipes() {
Test::new() Test::new()