List groups in source order with just --groups --unsorted
(#2160)
This commit is contained in:
parent
5f91b37c82
commit
b05a75d168
@ -1861,6 +1861,8 @@ Recipe groups:
|
||||
rust recipes
|
||||
```
|
||||
|
||||
Use `just --groups --unsorted` to print groups in their justfile order.
|
||||
|
||||
### Command Evaluation Using Backticks
|
||||
|
||||
Backticks can be used to store the result of commands:
|
||||
|
@ -4,7 +4,7 @@ use super::*;
|
||||
pub(crate) type Assignment<'src> = Binding<'src, Expression<'src>>;
|
||||
|
||||
impl<'src> Display for Assignment<'src> {
|
||||
fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
|
||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||
if self.export {
|
||||
write!(f, "export ")?;
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ pub(crate) struct Ast<'src> {
|
||||
}
|
||||
|
||||
impl<'src> Display for Ast<'src> {
|
||||
fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
|
||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||
let mut iter = self.items.iter().peekable();
|
||||
|
||||
while let Some(item) = iter.next() {
|
||||
|
@ -110,7 +110,7 @@ impl<'src> Attribute<'src> {
|
||||
}
|
||||
|
||||
impl<'src> Display for Attribute<'src> {
|
||||
fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
|
||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||
write!(f, "{}", self.name())?;
|
||||
if let Some(argument) = self.argument() {
|
||||
write!(f, "({argument})")?;
|
||||
|
@ -28,7 +28,7 @@ fn capitalize(s: &str) -> String {
|
||||
}
|
||||
|
||||
impl Display for CompileError<'_> {
|
||||
fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
|
||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||
use CompileErrorKind::*;
|
||||
|
||||
match &*self.kind {
|
||||
|
@ -8,7 +8,7 @@ pub(crate) struct Condition<'src> {
|
||||
}
|
||||
|
||||
impl<'src> Display for Condition<'src> {
|
||||
fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
|
||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||
write!(f, "{} {} {}", self.lhs, self.operator, self.rhs)
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ pub(crate) struct Dependency<'src> {
|
||||
}
|
||||
|
||||
impl<'src> Display for Dependency<'src> {
|
||||
fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
|
||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||
if self.arguments.is_empty() {
|
||||
write!(f, "{}", self.recipe.name())
|
||||
} else {
|
||||
|
@ -51,7 +51,7 @@ impl<'src> Expression<'src> {
|
||||
}
|
||||
|
||||
impl<'src> Display for Expression<'src> {
|
||||
fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
|
||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||
match self {
|
||||
Self::Assert { condition, error } => write!(f, "assert({condition}, {error})"),
|
||||
Self::Backtick { token, .. } => write!(f, "{}", token.lexeme()),
|
||||
|
@ -365,13 +365,13 @@ impl<'src> Justfile<'src> {
|
||||
modules
|
||||
}
|
||||
|
||||
pub(crate) fn public_recipes(&self, config: &Config) -> Vec<&Recipe<'src, Dependency>> {
|
||||
pub(crate) fn public_recipes(&self, config: &Config) -> Vec<&Recipe> {
|
||||
let mut recipes = self
|
||||
.recipes
|
||||
.values()
|
||||
.map(AsRef::as_ref)
|
||||
.filter(|recipe| recipe.is_public())
|
||||
.collect::<Vec<&Recipe<Dependency>>>();
|
||||
.collect::<Vec<&Recipe>>();
|
||||
|
||||
if config.unsorted {
|
||||
recipes.sort_by_key(|recipe| (&recipe.import_offsets, recipe.name.offset));
|
||||
@ -380,19 +380,33 @@ impl<'src> Justfile<'src> {
|
||||
recipes
|
||||
}
|
||||
|
||||
pub(crate) fn public_groups(&self) -> BTreeSet<String> {
|
||||
self
|
||||
.recipes
|
||||
.values()
|
||||
.map(AsRef::as_ref)
|
||||
.filter(|recipe| recipe.is_public())
|
||||
.flat_map(Recipe::groups)
|
||||
.collect()
|
||||
pub(crate) fn public_groups(&self, config: &Config) -> Vec<String> {
|
||||
let mut groups = Vec::new();
|
||||
|
||||
for recipe in self.recipes.values() {
|
||||
if recipe.is_public() {
|
||||
for group in recipe.groups() {
|
||||
groups.push((&recipe.import_offsets, recipe.name.offset, group));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if config.unsorted {
|
||||
groups.sort();
|
||||
} else {
|
||||
groups.sort_by(|(_, _, a), (_, _, b)| a.cmp(b));
|
||||
}
|
||||
|
||||
let mut seen = HashSet::new();
|
||||
|
||||
groups.retain(|(_, _, group)| seen.insert(group.clone()));
|
||||
|
||||
groups.into_iter().map(|(_, _, group)| group).collect()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'src> ColorDisplay for Justfile<'src> {
|
||||
fn fmt(&self, f: &mut Formatter, color: Color) -> Result<(), fmt::Error> {
|
||||
fn fmt(&self, f: &mut Formatter, color: Color) -> fmt::Result {
|
||||
let mut items = self.recipes.len() + self.assignments.len() + self.aliases.len();
|
||||
for (name, assignment) in &self.assignments {
|
||||
if assignment.export {
|
||||
|
@ -15,7 +15,7 @@ pub(crate) enum OutputError {
|
||||
}
|
||||
|
||||
impl Display for OutputError {
|
||||
fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
|
||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Self::Code(code) => write!(f, "Process exited with status code {code}"),
|
||||
Self::Io(ref io_error) => write!(f, "Error executing process: {io_error}"),
|
||||
|
@ -14,7 +14,7 @@ pub(crate) struct Parameter<'src> {
|
||||
}
|
||||
|
||||
impl<'src> ColorDisplay for Parameter<'src> {
|
||||
fn fmt(&self, f: &mut Formatter, color: Color) -> Result<(), fmt::Error> {
|
||||
fn fmt(&self, f: &mut Formatter, color: Color) -> fmt::Result {
|
||||
if let Some(prefix) = self.kind.prefix() {
|
||||
write!(f, "{}", color.annotation().paint(prefix))?;
|
||||
}
|
||||
|
@ -476,7 +476,7 @@ impl<'src, D> Recipe<'src, D> {
|
||||
}
|
||||
|
||||
impl<'src, D: Display> ColorDisplay for Recipe<'src, D> {
|
||||
fn fmt(&self, f: &mut Formatter, color: Color) -> Result<(), fmt::Error> {
|
||||
fn fmt(&self, f: &mut Formatter, color: Color) -> fmt::Result {
|
||||
if let Some(doc) = self.doc {
|
||||
writeln!(f, "# {doc}")?;
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ impl<'src> Keyed<'src> for Set<'src> {
|
||||
}
|
||||
|
||||
impl<'src> Display for Set<'src> {
|
||||
fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
|
||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||
write!(f, "set {} := {}", self.name, self.value)
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ pub(crate) enum Setting<'src> {
|
||||
}
|
||||
|
||||
impl<'src> Display for Setting<'src> {
|
||||
fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
|
||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||
match self {
|
||||
Self::AllowDuplicateRecipes(value)
|
||||
| Self::AllowDuplicateVariables(value)
|
||||
|
@ -7,7 +7,7 @@ pub(crate) struct Shell<'src> {
|
||||
}
|
||||
|
||||
impl<'src> Display for Shell<'src> {
|
||||
fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
|
||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||
write!(f, "[{}", self.command)?;
|
||||
|
||||
for argument in &self.arguments {
|
||||
|
@ -97,7 +97,7 @@ impl Subcommand {
|
||||
|
||||
fn groups(config: &Config, justfile: &Justfile) {
|
||||
println!("Recipe groups:");
|
||||
for group in justfile.public_groups() {
|
||||
for group in justfile.public_groups(config) {
|
||||
println!("{}{group}", config.list_prefix);
|
||||
}
|
||||
}
|
||||
@ -215,7 +215,7 @@ impl Subcommand {
|
||||
overrides: &BTreeMap<String, String>,
|
||||
chooser: Option<&str>,
|
||||
) -> Result<(), Error<'src>> {
|
||||
let mut recipes = Vec::<&Recipe<Dependency>>::new();
|
||||
let mut recipes = Vec::<&Recipe>::new();
|
||||
let mut stack = vec![justfile];
|
||||
while let Some(module) = stack.pop() {
|
||||
recipes.extend(
|
||||
|
@ -39,7 +39,7 @@ pub(crate) enum TokenKind {
|
||||
}
|
||||
|
||||
impl Display for TokenKind {
|
||||
fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
|
||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||
use TokenKind::*;
|
||||
write!(
|
||||
f,
|
||||
|
@ -7,7 +7,7 @@ pub(crate) struct UnresolvedDependency<'src> {
|
||||
}
|
||||
|
||||
impl<'src> Display for UnresolvedDependency<'src> {
|
||||
fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
|
||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||
if self.arguments.is_empty() {
|
||||
write!(f, "{}", self.recipe)
|
||||
} else {
|
||||
|
@ -157,12 +157,89 @@ fn list_groups_with_shorthand_syntax() {
|
||||
bar:
|
||||
",
|
||||
)
|
||||
.args(["--groups", "--list-prefix", "..."])
|
||||
.arg("--groups")
|
||||
.stdout(
|
||||
"
|
||||
Recipe groups:
|
||||
...A
|
||||
...B
|
||||
A
|
||||
B
|
||||
",
|
||||
)
|
||||
.run();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn list_groups_unsorted() {
|
||||
Test::new()
|
||||
.justfile(
|
||||
"
|
||||
[group: 'Z']
|
||||
baz:
|
||||
|
||||
[group: 'B']
|
||||
foo:
|
||||
|
||||
[group: 'A', group: 'B']
|
||||
bar:
|
||||
",
|
||||
)
|
||||
.args(["--groups", "--unsorted"])
|
||||
.stdout(
|
||||
"
|
||||
Recipe groups:
|
||||
Z
|
||||
B
|
||||
A
|
||||
",
|
||||
)
|
||||
.run();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn list_groups_private_unsorted() {
|
||||
Test::new()
|
||||
.justfile(
|
||||
"
|
||||
[private]
|
||||
[group: 'A']
|
||||
foo:
|
||||
|
||||
[group: 'B']
|
||||
bar:
|
||||
|
||||
[group: 'A']
|
||||
baz:
|
||||
",
|
||||
)
|
||||
.args(["--groups", "--unsorted"])
|
||||
.stdout(
|
||||
"
|
||||
Recipe groups:
|
||||
B
|
||||
A
|
||||
",
|
||||
)
|
||||
.run();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn list_groups_private() {
|
||||
Test::new()
|
||||
.justfile(
|
||||
"
|
||||
[private]
|
||||
[group: 'A']
|
||||
foo:
|
||||
|
||||
[group: 'B']
|
||||
bar:
|
||||
",
|
||||
)
|
||||
.args(["--groups", "--unsorted"])
|
||||
.stdout(
|
||||
"
|
||||
Recipe groups:
|
||||
B
|
||||
",
|
||||
)
|
||||
.run();
|
||||
|
Loading…
Reference in New Issue
Block a user