List unsorted imported recipes by import depth and offset (#2092)

This commit is contained in:
Casey Rodarmor 2024-05-25 18:10:06 -07:00 committed by GitHub
parent 00eb17ef07
commit 16a27dba87
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 147 additions and 12 deletions

View File

@ -23,6 +23,7 @@ impl Compiler {
let mut ast = Parser::parse( let mut ast = Parser::parse(
current.file_depth, current.file_depth,
&current.path, &current.path,
&current.import_offsets,
&current.namepath, &current.namepath,
current.submodule_depth, current.submodule_depth,
&tokens, &tokens,
@ -94,7 +95,7 @@ impl Compiler {
}); });
} }
*absolute = Some(import.clone()); *absolute = Some(import.clone());
stack.push(current.import(import)); stack.push(current.import(import, path.offset));
} else if !*optional { } else if !*optional {
return Err(Error::MissingImportFile { path: *path }); return Err(Error::MissingImportFile { path: *path });
} }
@ -172,6 +173,7 @@ impl Compiler {
let ast = Parser::parse( let ast = Parser::parse(
0, 0,
&PathBuf::new(), &PathBuf::new(),
&[],
&Namepath::default(), &Namepath::default(),
0, 0,
&tokens, &tokens,

View File

@ -495,16 +495,7 @@ impl<'src> Justfile<'src> {
.collect::<Vec<&Recipe<Dependency>>>(); .collect::<Vec<&Recipe<Dependency>>>();
if config.unsorted { if config.unsorted {
recipes.sort_by_key(|recipe| { recipes.sort_by_key(|recipe| (&recipe.import_offsets, recipe.name.offset));
(
self
.loaded
.iter()
.position(|path| path == recipe.name.path)
.unwrap(),
recipe.name.offset,
)
});
} }
recipes recipes

View File

@ -27,6 +27,7 @@ pub(crate) struct Parser<'run, 'src> {
expected_tokens: BTreeSet<TokenKind>, expected_tokens: BTreeSet<TokenKind>,
file_depth: u32, file_depth: u32,
file_path: &'run Path, file_path: &'run Path,
import_offsets: Vec<usize>,
module_namepath: &'run Namepath<'src>, module_namepath: &'run Namepath<'src>,
next_token: usize, next_token: usize,
recursion_depth: usize, recursion_depth: usize,
@ -40,6 +41,7 @@ impl<'run, 'src> Parser<'run, 'src> {
pub(crate) fn parse( pub(crate) fn parse(
file_depth: u32, file_depth: u32,
file_path: &'run Path, file_path: &'run Path,
import_offsets: &[usize],
module_namepath: &'run Namepath<'src>, module_namepath: &'run Namepath<'src>,
submodule_depth: u32, submodule_depth: u32,
tokens: &'run [Token<'src>], tokens: &'run [Token<'src>],
@ -49,6 +51,7 @@ impl<'run, 'src> Parser<'run, 'src> {
expected_tokens: BTreeSet::new(), expected_tokens: BTreeSet::new(),
file_depth, file_depth,
file_path, file_path,
import_offsets: import_offsets.to_vec(),
module_namepath, module_namepath,
next_token: 0, next_token: 0,
recursion_depth: 0, recursion_depth: 0,
@ -801,6 +804,7 @@ impl<'run, 'src> Parser<'run, 'src> {
doc, doc,
file_depth: self.file_depth, file_depth: self.file_depth,
file_path: self.file_path.into(), file_path: self.file_path.into(),
import_offsets: self.import_offsets.clone(),
name, name,
namepath: self.module_namepath.join(name), namepath: self.module_namepath.join(name),
parameters: positional.into_iter().chain(variadic).collect(), parameters: positional.into_iter().chain(variadic).collect(),
@ -1040,6 +1044,7 @@ mod tests {
let justfile = Parser::parse( let justfile = Parser::parse(
0, 0,
&PathBuf::new(), &PathBuf::new(),
&[],
&Namepath::default(), &Namepath::default(),
0, 0,
&tokens, &tokens,
@ -1086,6 +1091,7 @@ mod tests {
match Parser::parse( match Parser::parse(
0, 0,
&PathBuf::new(), &PathBuf::new(),
&[],
&Namepath::default(), &Namepath::default(),
0, 0,
&tokens, &tokens,

View File

@ -27,6 +27,8 @@ pub(crate) struct Recipe<'src, D = Dependency<'src>> {
pub(crate) file_depth: u32, pub(crate) file_depth: u32,
#[serde(skip)] #[serde(skip)]
pub(crate) file_path: PathBuf, pub(crate) file_path: PathBuf,
#[serde(skip)]
pub(crate) import_offsets: Vec<usize>,
pub(crate) name: Name<'src>, pub(crate) name: Name<'src>,
pub(crate) namepath: Namepath<'src>, pub(crate) namepath: Namepath<'src>,
pub(crate) parameters: Vec<Parameter<'src>>, pub(crate) parameters: Vec<Parameter<'src>>,

View File

@ -4,6 +4,7 @@ use super::*;
pub(crate) struct Source<'src> { pub(crate) struct Source<'src> {
pub(crate) file_depth: u32, pub(crate) file_depth: u32,
pub(crate) file_path: Vec<PathBuf>, pub(crate) file_path: Vec<PathBuf>,
pub(crate) import_offsets: Vec<usize>,
pub(crate) namepath: Namepath<'src>, pub(crate) namepath: Namepath<'src>,
pub(crate) path: PathBuf, pub(crate) path: PathBuf,
pub(crate) submodule_depth: u32, pub(crate) submodule_depth: u32,
@ -15,6 +16,7 @@ impl<'src> Source<'src> {
Self { Self {
file_depth: 0, file_depth: 0,
file_path: vec![path.into()], file_path: vec![path.into()],
import_offsets: Vec::new(),
namepath: Namepath::default(), namepath: Namepath::default(),
path: path.into(), path: path.into(),
submodule_depth: 0, submodule_depth: 0,
@ -22,7 +24,7 @@ impl<'src> Source<'src> {
} }
} }
pub(crate) fn import(&self, path: PathBuf) -> Self { pub(crate) fn import(&self, path: PathBuf, import_offset: usize) -> Self {
Self { Self {
file_depth: self.file_depth + 1, file_depth: self.file_depth + 1,
file_path: self file_path: self
@ -31,6 +33,12 @@ impl<'src> Source<'src> {
.into_iter() .into_iter()
.chain(iter::once(path.clone())) .chain(iter::once(path.clone()))
.collect(), .collect(),
import_offsets: self
.import_offsets
.iter()
.copied()
.chain(iter::once(import_offset))
.collect(),
namepath: self.namepath.clone(), namepath: self.namepath.clone(),
path, path,
submodule_depth: self.submodule_depth, submodule_depth: self.submodule_depth,
@ -47,6 +55,7 @@ impl<'src> Source<'src> {
.into_iter() .into_iter()
.chain(iter::once(path.clone())) .chain(iter::once(path.clone()))
.collect(), .collect(),
import_offsets: Vec::new(),
namepath: self.namepath.join(name), namepath: self.namepath.join(name),
path: path.clone(), path: path.clone(),
submodule_depth: self.submodule_depth + 1, submodule_depth: self.submodule_depth + 1,

View File

@ -62,6 +62,7 @@ pub(crate) fn analysis_error(
let ast = Parser::parse( let ast = Parser::parse(
0, 0,
&PathBuf::new(), &PathBuf::new(),
&[],
&Namepath::default(), &Namepath::default(),
0, 0,
&tokens, &tokens,

View File

@ -51,6 +51,7 @@ impl<'src> UnresolvedRecipe<'src> {
doc: self.doc, doc: self.doc,
file_depth: self.file_depth, file_depth: self.file_depth,
file_path: self.file_path, file_path: self.file_path,
import_offsets: self.import_offsets,
name: self.name, name: self.name,
namepath: self.namepath, namepath: self.namepath,
parameters: self.parameters, parameters: self.parameters,

View File

@ -131,3 +131,126 @@ fn nested_modules_are_properly_indented() {
) )
.run(); .run();
} }
#[test]
fn unsorted_list_order() {
Test::new()
.write("a.just", "a:")
.write("b.just", "b:")
.write("c.just", "c:")
.write("d.just", "d:")
.justfile(
"
import 'a.just'
import 'b.just'
import 'c.just'
import 'd.just'
x:
y:
z:
",
)
.args(["--list", "--unsorted"])
.stdout(
"
Available recipes:
x
y
z
a
b
c
d
",
)
.run();
Test::new()
.write("a.just", "a:")
.write("b.just", "b:")
.write("c.just", "c:")
.write("d.just", "d:")
.justfile(
"
x:
y:
z:
import 'd.just'
import 'c.just'
import 'b.just'
import 'a.just'
",
)
.args(["--list", "--unsorted"])
.stdout(
"
Available recipes:
x
y
z
d
c
b
a
",
)
.run();
Test::new()
.write("a.just", "a:\nimport 'e.just'")
.write("b.just", "b:\nimport 'f.just'")
.write("c.just", "c:\nimport 'g.just'")
.write("d.just", "d:\nimport 'h.just'")
.write("e.just", "e:")
.write("f.just", "f:")
.write("g.just", "g:")
.write("h.just", "h:")
.justfile(
"
x:
y:
z:
import 'd.just'
import 'c.just'
import 'b.just'
import 'a.just'
",
)
.args(["--list", "--unsorted"])
.stdout(
"
Available recipes:
x
y
z
d
h
c
g
b
f
a
e
",
)
.run();
Test::new()
.write("task1.just", "task1:")
.write("task2.just", "task2:")
.justfile(
"
import 'task1.just'
import 'task2.just'
",
)
.args(["--list", "--unsorted"])
.stdout(
"
Available recipes:
task1
task2
",
)
.run();
}