Cleanup (#1566)
This commit is contained in:
parent
6a407813b4
commit
a1220c63e3
@ -43,7 +43,7 @@ impl<'src> Analyzer<'src> {
|
|||||||
|
|
||||||
let settings = Settings::from_setting_iter(self.sets.into_iter().map(|(_, set)| set.value));
|
let settings = Settings::from_setting_iter(self.sets.into_iter().map(|(_, set)| set.value));
|
||||||
|
|
||||||
let mut recipe_table: Table<'src, UnresolvedRecipe<'src>> = Default::default();
|
let mut recipe_table: Table<'src, UnresolvedRecipe<'src>> = Table::default();
|
||||||
|
|
||||||
AssignmentResolver::resolve_assignments(&self.assignments)?;
|
AssignmentResolver::resolve_assignments(&self.assignments)?;
|
||||||
|
|
||||||
|
@ -24,37 +24,27 @@ impl Display for CompileError<'_> {
|
|||||||
use CompileErrorKind::*;
|
use CompileErrorKind::*;
|
||||||
|
|
||||||
match &*self.kind {
|
match &*self.kind {
|
||||||
AliasInvalidAttribute { alias, attr } => {
|
AliasInvalidAttribute { alias, attr } => write!(
|
||||||
write!(
|
|
||||||
f,
|
f,
|
||||||
"Alias {} has an invalid attribute `{}`",
|
"Alias {alias} has an invalid attribute `{}`",
|
||||||
alias,
|
attr.to_str(),
|
||||||
attr.to_str()
|
),
|
||||||
)?;
|
AliasShadowsRecipe { alias, recipe_line } => write!(
|
||||||
}
|
|
||||||
AliasShadowsRecipe { alias, recipe_line } => {
|
|
||||||
write!(
|
|
||||||
f,
|
f,
|
||||||
"Alias `{}` defined on line {} shadows recipe `{}` defined on line {}",
|
"Alias `{alias}` defined on line {} shadows recipe `{alias}` defined on line {}",
|
||||||
alias,
|
|
||||||
self.token.line.ordinal(),
|
self.token.line.ordinal(),
|
||||||
alias,
|
|
||||||
recipe_line.ordinal(),
|
recipe_line.ordinal(),
|
||||||
)?;
|
),
|
||||||
}
|
BacktickShebang => write!(f, "Backticks may not start with `#!`"),
|
||||||
BacktickShebang => {
|
|
||||||
write!(f, "Backticks may not start with `#!`")?;
|
|
||||||
}
|
|
||||||
CircularRecipeDependency { recipe, ref circle } => {
|
CircularRecipeDependency { recipe, ref circle } => {
|
||||||
if circle.len() == 2 {
|
if circle.len() == 2 {
|
||||||
write!(f, "Recipe `{recipe}` depends on itself")?;
|
write!(f, "Recipe `{recipe}` depends on itself")
|
||||||
} else {
|
} else {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"Recipe `{}` has circular dependency `{}`",
|
"Recipe `{recipe}` has circular dependency `{}`",
|
||||||
recipe,
|
|
||||||
circle.join(" -> ")
|
circle.join(" -> ")
|
||||||
)?;
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CircularVariableDependency {
|
CircularVariableDependency {
|
||||||
@ -62,14 +52,13 @@ impl Display for CompileError<'_> {
|
|||||||
ref circle,
|
ref circle,
|
||||||
} => {
|
} => {
|
||||||
if circle.len() == 2 {
|
if circle.len() == 2 {
|
||||||
write!(f, "Variable `{variable}` is defined in terms of itself")?;
|
write!(f, "Variable `{variable}` is defined in terms of itself")
|
||||||
} else {
|
} else {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"Variable `{}` depends on its own value: `{}`",
|
"Variable `{variable}` depends on its own value: `{}`",
|
||||||
variable,
|
circle.join(" -> "),
|
||||||
circle.join(" -> ")
|
)
|
||||||
)?;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DependencyArgumentCountMismatch {
|
DependencyArgumentCountMismatch {
|
||||||
@ -80,206 +69,146 @@ impl Display for CompileError<'_> {
|
|||||||
} => {
|
} => {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"Dependency `{}` got {} {} but takes ",
|
"Dependency `{dependency}` got {found} {} but takes ",
|
||||||
dependency,
|
|
||||||
found,
|
|
||||||
Count("argument", *found),
|
Count("argument", *found),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
if min == max {
|
if min == max {
|
||||||
let expected = min;
|
let expected = min;
|
||||||
write!(f, "{expected} {}", Count("argument", *expected))?;
|
write!(f, "{expected} {}", Count("argument", *expected))
|
||||||
} else if found < min {
|
} else if found < min {
|
||||||
write!(f, "at least {min} {}", Count("argument", *min))?;
|
write!(f, "at least {min} {}", Count("argument", *min))
|
||||||
} else {
|
} else {
|
||||||
write!(f, "at most {max} {}", Count("argument", *max))?;
|
write!(f, "at most {max} {}", Count("argument", *max))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DuplicateAlias { alias, first } => {
|
DuplicateAlias { alias, first } => write!(
|
||||||
write!(
|
|
||||||
f,
|
f,
|
||||||
"Alias `{}` first defined on line {} is redefined on line {}",
|
"Alias `{alias}` first defined on line {} is redefined on line {}",
|
||||||
alias,
|
|
||||||
first.ordinal(),
|
first.ordinal(),
|
||||||
self.token.line.ordinal(),
|
self.token.line.ordinal(),
|
||||||
)?;
|
),
|
||||||
}
|
DuplicateAttribute { attribute, first } => write!(
|
||||||
DuplicateAttribute { attribute, first } => {
|
|
||||||
write!(
|
|
||||||
f,
|
f,
|
||||||
"Recipe attribute `{}` first used on line {} is duplicated on line {}",
|
"Recipe attribute `{attribute}` first used on line {} is duplicated on line {}",
|
||||||
attribute,
|
|
||||||
first.ordinal(),
|
first.ordinal(),
|
||||||
self.token.line.ordinal(),
|
self.token.line.ordinal(),
|
||||||
)?;
|
),
|
||||||
}
|
|
||||||
DuplicateParameter { recipe, parameter } => {
|
DuplicateParameter { recipe, parameter } => {
|
||||||
write!(f, "Recipe `{recipe}` has duplicate parameter `{parameter}`")?;
|
write!(f, "Recipe `{recipe}` has duplicate parameter `{parameter}`")
|
||||||
}
|
}
|
||||||
DuplicateRecipe { recipe, first } => {
|
DuplicateRecipe { recipe, first } => write!(
|
||||||
write!(
|
|
||||||
f,
|
f,
|
||||||
"Recipe `{}` first defined on line {} is redefined on line {}",
|
"Recipe `{recipe}` first defined on line {} is redefined on line {}",
|
||||||
recipe,
|
|
||||||
first.ordinal(),
|
|
||||||
self.token.line.ordinal()
|
|
||||||
)?;
|
|
||||||
}
|
|
||||||
DuplicateSet { setting, first } => {
|
|
||||||
write!(
|
|
||||||
f,
|
|
||||||
"Setting `{}` first set on line {} is redefined on line {}",
|
|
||||||
setting,
|
|
||||||
first.ordinal(),
|
first.ordinal(),
|
||||||
self.token.line.ordinal(),
|
self.token.line.ordinal(),
|
||||||
)?;
|
),
|
||||||
}
|
DuplicateSet { setting, first } => write!(
|
||||||
|
f,
|
||||||
|
"Setting `{setting}` first set on line {} is redefined on line {}",
|
||||||
|
first.ordinal(),
|
||||||
|
self.token.line.ordinal(),
|
||||||
|
),
|
||||||
DuplicateVariable { variable } => {
|
DuplicateVariable { variable } => {
|
||||||
write!(f, "Variable `{variable}` has multiple definitions")?;
|
write!(f, "Variable `{variable}` has multiple definitions")
|
||||||
}
|
}
|
||||||
ExpectedKeyword { expected, found } => {
|
ExpectedKeyword { expected, found } => {
|
||||||
|
let expected = List::or_ticked(expected);
|
||||||
if found.kind == TokenKind::Identifier {
|
if found.kind == TokenKind::Identifier {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"Expected keyword {} but found identifier `{}`",
|
"Expected keyword {expected} but found identifier `{}`",
|
||||||
List::or_ticked(expected),
|
|
||||||
found.lexeme()
|
found.lexeme()
|
||||||
)?;
|
)
|
||||||
} else {
|
} else {
|
||||||
write!(
|
write!(f, "Expected keyword {expected} but found `{}`", found.kind)
|
||||||
f,
|
|
||||||
"Expected keyword {} but found `{}`",
|
|
||||||
List::or_ticked(expected),
|
|
||||||
found.kind
|
|
||||||
)?;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ExtraLeadingWhitespace => {
|
ExtraLeadingWhitespace => write!(f, "Recipe line has extra leading whitespace"),
|
||||||
write!(f, "Recipe line has extra leading whitespace")?;
|
|
||||||
}
|
|
||||||
FunctionArgumentCountMismatch {
|
FunctionArgumentCountMismatch {
|
||||||
function,
|
function,
|
||||||
found,
|
found,
|
||||||
expected,
|
expected,
|
||||||
} => {
|
} => write!(
|
||||||
write!(
|
|
||||||
f,
|
f,
|
||||||
"Function `{}` called with {} {} but takes {}",
|
"Function `{function}` called with {found} {} but takes {}",
|
||||||
function,
|
|
||||||
found,
|
|
||||||
Count("argument", *found),
|
Count("argument", *found),
|
||||||
expected.display(),
|
expected.display(),
|
||||||
)?;
|
),
|
||||||
}
|
InconsistentLeadingWhitespace { expected, found } => write!(
|
||||||
InconsistentLeadingWhitespace { expected, found } => {
|
|
||||||
write!(
|
|
||||||
f,
|
f,
|
||||||
"Recipe line has inconsistent leading whitespace. Recipe started with `{}` but found \
|
"Recipe line has inconsistent leading whitespace. Recipe started with `{}` but found \
|
||||||
line with `{}`",
|
line with `{}`",
|
||||||
ShowWhitespace(expected),
|
ShowWhitespace(expected),
|
||||||
ShowWhitespace(found)
|
ShowWhitespace(found)
|
||||||
)?;
|
),
|
||||||
}
|
Internal { ref message } => write!(
|
||||||
Internal { ref message } => {
|
|
||||||
write!(
|
|
||||||
f,
|
f,
|
||||||
"Internal error, this may indicate a bug in just: {message}\n\
|
"Internal error, this may indicate a bug in just: {message}\n\
|
||||||
consider filing an issue: https://github.com/casey/just/issues/new"
|
consider filing an issue: https://github.com/casey/just/issues/new"
|
||||||
)?;
|
),
|
||||||
}
|
InvalidEscapeSequence { character } => write!(
|
||||||
InvalidEscapeSequence { character } => {
|
f,
|
||||||
let representation = match character {
|
"`\\{}` is not a valid escape sequence",
|
||||||
|
match character {
|
||||||
'`' => r"\`".to_owned(),
|
'`' => r"\`".to_owned(),
|
||||||
'\\' => r"\".to_owned(),
|
'\\' => r"\".to_owned(),
|
||||||
'\'' => r"'".to_owned(),
|
'\'' => r"'".to_owned(),
|
||||||
'"' => r#"""#.to_owned(),
|
'"' => r#"""#.to_owned(),
|
||||||
_ => character.escape_default().collect(),
|
_ => character.escape_default().collect(),
|
||||||
};
|
|
||||||
write!(f, "`\\{representation}` is not a valid escape sequence")?;
|
|
||||||
}
|
}
|
||||||
|
),
|
||||||
MismatchedClosingDelimiter {
|
MismatchedClosingDelimiter {
|
||||||
open,
|
open,
|
||||||
open_line,
|
open_line,
|
||||||
close,
|
close,
|
||||||
} => {
|
} => write!(
|
||||||
write!(
|
|
||||||
f,
|
f,
|
||||||
"Mismatched closing delimiter `{}`. (Did you mean to close the `{}` on line {}?)",
|
"Mismatched closing delimiter `{}`. (Did you mean to close the `{}` on line {}?)",
|
||||||
close.close(),
|
close.close(),
|
||||||
open.open(),
|
open.open(),
|
||||||
open_line.ordinal(),
|
open_line.ordinal(),
|
||||||
)?;
|
),
|
||||||
}
|
MixedLeadingWhitespace { whitespace } => write!(
|
||||||
MixedLeadingWhitespace { whitespace } => {
|
|
||||||
write!(
|
|
||||||
f,
|
f,
|
||||||
"Found a mix of tabs and spaces in leading whitespace: `{}`\nLeading whitespace may \
|
"Found a mix of tabs and spaces in leading whitespace: `{}`\nLeading whitespace may \
|
||||||
consist of tabs or spaces, but not both",
|
consist of tabs or spaces, but not both",
|
||||||
ShowWhitespace(whitespace)
|
ShowWhitespace(whitespace)
|
||||||
)?;
|
),
|
||||||
}
|
|
||||||
ParameterFollowsVariadicParameter { parameter } => {
|
ParameterFollowsVariadicParameter { parameter } => {
|
||||||
write!(f, "Parameter `{parameter}` follows variadic parameter")?;
|
write!(f, "Parameter `{parameter}` follows variadic parameter")
|
||||||
}
|
}
|
||||||
ParsingRecursionDepthExceeded => {
|
ParsingRecursionDepthExceeded => write!(f, "Parsing recursion depth exceeded"),
|
||||||
write!(f, "Parsing recursion depth exceeded")?;
|
RequiredParameterFollowsDefaultParameter { parameter } => write!(
|
||||||
}
|
|
||||||
RequiredParameterFollowsDefaultParameter { parameter } => {
|
|
||||||
write!(
|
|
||||||
f,
|
f,
|
||||||
"Non-default parameter `{parameter}` follows default parameter"
|
"Non-default parameter `{parameter}` follows default parameter"
|
||||||
)?;
|
),
|
||||||
}
|
UndefinedVariable { variable } => write!(f, "Variable `{variable}` not defined"),
|
||||||
UndefinedVariable { variable } => {
|
UnexpectedCharacter { expected } => write!(f, "Expected character `{expected}`"),
|
||||||
write!(f, "Variable `{variable}` not defined")?;
|
|
||||||
}
|
|
||||||
UnexpectedCharacter { expected } => {
|
|
||||||
write!(f, "Expected character `{expected}`")?;
|
|
||||||
}
|
|
||||||
UnexpectedClosingDelimiter { close } => {
|
UnexpectedClosingDelimiter { close } => {
|
||||||
write!(f, "Unexpected closing delimiter `{}`", close.close())?;
|
write!(f, "Unexpected closing delimiter `{}`", close.close())
|
||||||
}
|
}
|
||||||
UnexpectedEndOfToken { expected } => {
|
UnexpectedEndOfToken { expected } => {
|
||||||
write!(f, "Expected character `{expected}` but found end-of-file")?;
|
write!(f, "Expected character `{expected}` but found end-of-file")
|
||||||
}
|
}
|
||||||
UnexpectedToken {
|
UnexpectedToken {
|
||||||
ref expected,
|
ref expected,
|
||||||
found,
|
found,
|
||||||
} => {
|
} => write!(f, "Expected {}, but found {found}", List::or(expected)),
|
||||||
write!(f, "Expected {}, but found {found}", List::or(expected))?;
|
|
||||||
}
|
|
||||||
UnknownAliasTarget { alias, target } => {
|
UnknownAliasTarget { alias, target } => {
|
||||||
write!(f, "Alias `{alias}` has an unknown target `{target}`")?;
|
write!(f, "Alias `{alias}` has an unknown target `{target}`")
|
||||||
}
|
|
||||||
UnknownAttribute { attribute } => {
|
|
||||||
write!(f, "Unknown attribute `{attribute}`")?;
|
|
||||||
}
|
}
|
||||||
|
UnknownAttribute { attribute } => write!(f, "Unknown attribute `{attribute}`"),
|
||||||
UnknownDependency { recipe, unknown } => {
|
UnknownDependency { recipe, unknown } => {
|
||||||
write!(f, "Recipe `{recipe}` has unknown dependency `{unknown}`",)?;
|
write!(f, "Recipe `{recipe}` has unknown dependency `{unknown}`")
|
||||||
}
|
}
|
||||||
UnknownFunction { function } => {
|
UnknownFunction { function } => write!(f, "Call to unknown function `{function}`"),
|
||||||
write!(f, "Call to unknown function `{function}`")?;
|
UnknownSetting { setting } => write!(f, "Unknown setting `{setting}`"),
|
||||||
|
UnknownStartOfToken => write!(f, "Unknown start of token:"),
|
||||||
|
UnpairedCarriageReturn => write!(f, "Unpaired carriage return"),
|
||||||
|
UnterminatedBacktick => write!(f, "Unterminated backtick"),
|
||||||
|
UnterminatedInterpolation => write!(f, "Unterminated interpolation"),
|
||||||
|
UnterminatedString => write!(f, "Unterminated string"),
|
||||||
}
|
}
|
||||||
UnknownSetting { setting } => {
|
|
||||||
write!(f, "Unknown setting `{setting}`")?;
|
|
||||||
}
|
|
||||||
UnknownStartOfToken => {
|
|
||||||
write!(f, "Unknown start of token:")?;
|
|
||||||
}
|
|
||||||
UnpairedCarriageReturn => {
|
|
||||||
write!(f, "Unpaired carriage return")?;
|
|
||||||
}
|
|
||||||
UnterminatedBacktick => {
|
|
||||||
write!(f, "Unterminated backtick")?;
|
|
||||||
}
|
|
||||||
UnterminatedInterpolation => {
|
|
||||||
write!(f, "Unterminated interpolation")?;
|
|
||||||
}
|
|
||||||
UnterminatedString => {
|
|
||||||
write!(f, "Unterminated string")?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ pub(crate) const CHOOSE_HELP: &str = "Select one or more recipes to run using a
|
|||||||
of $JUST_CHOOSER, falling back to `fzf`";
|
of $JUST_CHOOSER, falling back to `fzf`";
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
|
#[allow(clippy::struct_excessive_bools)]
|
||||||
pub(crate) struct Config {
|
pub(crate) struct Config {
|
||||||
pub(crate) check: bool,
|
pub(crate) check: bool,
|
||||||
pub(crate) color: Color,
|
pub(crate) color: Color,
|
||||||
|
@ -1,6 +1,3 @@
|
|||||||
// `Self` cannot be used where type takes generic arguments
|
|
||||||
#![allow(clippy::use_self)]
|
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
pub struct Enclosure<T: Display> {
|
pub struct Enclosure<T: Display> {
|
||||||
|
73
src/error.rs
73
src/error.rs
@ -238,30 +238,21 @@ impl<'src> ColorDisplay for Error<'src> {
|
|||||||
let expected = min;
|
let expected = min;
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"Recipe `{}` got {} {} but {}takes {}",
|
"Recipe `{recipe}` got {found} {} but {}takes {expected}",
|
||||||
recipe,
|
|
||||||
found,
|
|
||||||
Count("argument", *found),
|
Count("argument", *found),
|
||||||
if expected < found { "only " } else { "" },
|
if expected < found { "only " } else { "" }
|
||||||
expected
|
|
||||||
)?;
|
)?;
|
||||||
} else if found < min {
|
} else if found < min {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"Recipe `{}` got {} {} but takes at least {}",
|
"Recipe `{recipe}` got {found} {} but takes at least {min}",
|
||||||
recipe,
|
Count("argument", *found)
|
||||||
found,
|
|
||||||
Count("argument", *found),
|
|
||||||
min
|
|
||||||
)?;
|
)?;
|
||||||
} else if found > max {
|
} else if found > max {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"Recipe `{}` got {} {} but takes at most {}",
|
"Recipe `{recipe}` got {found} {} but takes at most {max}",
|
||||||
recipe,
|
Count("argument", *found)
|
||||||
found,
|
|
||||||
Count("argument", *found),
|
|
||||||
max
|
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -306,35 +297,29 @@ impl<'src> ColorDisplay for Error<'src> {
|
|||||||
} => {
|
} => {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"Chooser `{} {} {}` invocation failed: {}",
|
"Chooser `{shell_binary} {shell_arguments} {}` invocation failed: {io_error}",
|
||||||
shell_binary,
|
|
||||||
shell_arguments,
|
|
||||||
chooser.to_string_lossy(),
|
chooser.to_string_lossy(),
|
||||||
io_error,
|
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
ChooserRead { chooser, io_error } => {
|
ChooserRead { chooser, io_error } => {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"Failed to read output from chooser `{}`: {}",
|
"Failed to read output from chooser `{}`: {io_error}",
|
||||||
chooser.to_string_lossy(),
|
chooser.to_string_lossy()
|
||||||
io_error
|
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
ChooserStatus { chooser, status } => {
|
ChooserStatus { chooser, status } => {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"Chooser `{}` failed: {}",
|
"Chooser `{}` failed: {status}",
|
||||||
chooser.to_string_lossy(),
|
chooser.to_string_lossy()
|
||||||
status
|
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
ChooserWrite { chooser, io_error } => {
|
ChooserWrite { chooser, io_error } => {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"Failed to write to chooser `{}`: {}",
|
"Failed to write to chooser `{}`: {io_error}",
|
||||||
chooser.to_string_lossy(),
|
chooser.to_string_lossy()
|
||||||
io_error
|
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
CircularInclude { current, include } => {
|
CircularInclude { current, include } => {
|
||||||
@ -365,13 +350,12 @@ impl<'src> ColorDisplay for Error<'src> {
|
|||||||
} => {
|
} => {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"Failed to invoke {}: {}",
|
"Failed to invoke {}: {io_error}",
|
||||||
iter::once(binary)
|
iter::once(binary)
|
||||||
.chain(arguments)
|
.chain(arguments)
|
||||||
.map(|value| Enclosure::tick(value.to_string_lossy()).to_string())
|
.map(|value| Enclosure::tick(value.to_string_lossy()).to_string())
|
||||||
.collect::<Vec<String>>()
|
.collect::<Vec<String>>()
|
||||||
.join(" "),
|
.join(" "),
|
||||||
io_error,
|
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
CommandStatus {
|
CommandStatus {
|
||||||
@ -381,13 +365,12 @@ impl<'src> ColorDisplay for Error<'src> {
|
|||||||
} => {
|
} => {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"Command {} failed: {}",
|
"Command {} failed: {status}",
|
||||||
iter::once(binary)
|
iter::once(binary)
|
||||||
.chain(arguments)
|
.chain(arguments)
|
||||||
.map(|value| Enclosure::tick(value.to_string_lossy()).to_string())
|
.map(|value| Enclosure::tick(value.to_string_lossy()).to_string())
|
||||||
.collect::<Vec<String>>()
|
.collect::<Vec<String>>()
|
||||||
.join(" "),
|
.join(" "),
|
||||||
status,
|
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
Compile { compile_error } => Display::fmt(compile_error, f)?,
|
Compile { compile_error } => Display::fmt(compile_error, f)?,
|
||||||
@ -446,9 +429,7 @@ impl<'src> ColorDisplay for Error<'src> {
|
|||||||
} => {
|
} => {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"Recipe `{}` cannot be used as default recipe since it requires at least {} {}.",
|
"Recipe `{recipe}` cannot be used as default recipe since it requires at least {min_arguments} {}.",
|
||||||
recipe,
|
|
||||||
min_arguments,
|
|
||||||
Count("argument", *min_arguments),
|
Count("argument", *min_arguments),
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
@ -483,9 +464,8 @@ impl<'src> ColorDisplay for Error<'src> {
|
|||||||
FunctionCall { function, message } => {
|
FunctionCall { function, message } => {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"Call to function `{}` failed: {}",
|
"Call to function `{}` failed: {message}",
|
||||||
function.lexeme(),
|
function.lexeme()
|
||||||
message
|
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
IncludeMissingPath {
|
IncludeMissingPath {
|
||||||
@ -532,9 +512,8 @@ impl<'src> ColorDisplay for Error<'src> {
|
|||||||
Load { io_error, path } => {
|
Load { io_error, path } => {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"Failed to read justfile at `{}`: {}",
|
"Failed to read justfile at `{}`: {io_error}",
|
||||||
path.display(),
|
path.display()
|
||||||
io_error
|
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
NoChoosableRecipes => {
|
NoChoosableRecipes => {
|
||||||
@ -628,9 +607,8 @@ impl<'src> ColorDisplay for Error<'src> {
|
|||||||
WriteJustfile { justfile, io_error } => {
|
WriteJustfile { justfile, io_error } => {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"Failed to write justfile to `{}`: {}",
|
"Failed to write justfile to `{}`: {io_error}",
|
||||||
justfile.display(),
|
justfile.display()
|
||||||
io_error
|
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -642,12 +620,7 @@ impl<'src> ColorDisplay for Error<'src> {
|
|||||||
} = self
|
} = self
|
||||||
{
|
{
|
||||||
writeln!(f)?;
|
writeln!(f)?;
|
||||||
write!(
|
write!(f, "{}:\n just {recipe}", color.message().paint("usage"))?;
|
||||||
f,
|
|
||||||
"{}:\n just {}",
|
|
||||||
color.message().paint("usage"),
|
|
||||||
recipe
|
|
||||||
)?;
|
|
||||||
for param in parameters {
|
for param in parameters {
|
||||||
write!(f, " {}", param.color_display(color))?;
|
write!(f, " {}", param.color_display(color))?;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,3 @@
|
|||||||
#![allow(unknown_lints)]
|
|
||||||
#![allow(clippy::unnecessary_wraps)]
|
|
||||||
|
|
||||||
use {
|
use {
|
||||||
super::*,
|
super::*,
|
||||||
heck::{
|
heck::{
|
||||||
@ -208,7 +205,7 @@ fn join(
|
|||||||
|
|
||||||
fn just_executable(_context: &FunctionContext) -> Result<String, String> {
|
fn just_executable(_context: &FunctionContext) -> Result<String, String> {
|
||||||
let exe_path =
|
let exe_path =
|
||||||
std::env::current_exe().map_err(|e| format!("Error getting current executable: {e}"))?;
|
env::current_exe().map_err(|e| format!("Error getting current executable: {e}"))?;
|
||||||
|
|
||||||
exe_path.to_str().map(str::to_owned).ok_or_else(|| {
|
exe_path.to_str().map(str::to_owned).ok_or_else(|| {
|
||||||
format!(
|
format!(
|
||||||
@ -323,7 +320,7 @@ fn sha256_file(context: &FunctionContext, path: &str) -> Result<String, String>
|
|||||||
use sha2::{Digest, Sha256};
|
use sha2::{Digest, Sha256};
|
||||||
let justpath = context.search.working_directory.join(path);
|
let justpath = context.search.working_directory.join(path);
|
||||||
let mut hasher = Sha256::new();
|
let mut hasher = Sha256::new();
|
||||||
let mut file = std::fs::File::open(&justpath)
|
let mut file = fs::File::open(&justpath)
|
||||||
.map_err(|err| format!("Failed to open file at `{:?}`: {err}", &justpath.to_str()))?;
|
.map_err(|err| format!("Failed to open file at `{:?}`: {err}", &justpath.to_str()))?;
|
||||||
std::io::copy(&mut file, &mut hasher)
|
std::io::copy(&mut file, &mut hasher)
|
||||||
.map_err(|err| format!("Failed to read file at `{:?}`: {err}", &justpath.to_str()))?;
|
.map_err(|err| format!("Failed to read file at `{:?}`: {err}", &justpath.to_str()))?;
|
||||||
|
@ -208,7 +208,7 @@ impl<'src> Lexer<'src> {
|
|||||||
};
|
};
|
||||||
CompileError::new(
|
CompileError::new(
|
||||||
token,
|
token,
|
||||||
CompileErrorKind::Internal {
|
Internal {
|
||||||
message: message.into(),
|
message: message.into(),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -773,7 +773,7 @@ impl<'src> Lexer<'src> {
|
|||||||
|
|
||||||
/// Lex a backtick, cooked string, or raw string.
|
/// Lex a backtick, cooked string, or raw string.
|
||||||
///
|
///
|
||||||
/// Backtick: `[^`]*`
|
/// Backtick: ``[^`]*``
|
||||||
/// Cooked string: "[^"]*" # also processes escape sequences
|
/// Cooked string: "[^"]*" # also processes escape sequences
|
||||||
/// Raw string: '[^']*'
|
/// Raw string: '[^']*'
|
||||||
fn lex_string(&mut self) -> CompileResult<'src, ()> {
|
fn lex_string(&mut self) -> CompileResult<'src, ()> {
|
||||||
|
@ -1,16 +1,10 @@
|
|||||||
#![deny(clippy::all, clippy::pedantic)]
|
#![deny(clippy::all, clippy::pedantic)]
|
||||||
#![allow(
|
#![allow(
|
||||||
clippy::default_trait_access,
|
|
||||||
clippy::doc_markdown,
|
|
||||||
clippy::enum_glob_use,
|
clippy::enum_glob_use,
|
||||||
clippy::let_underscore_untyped,
|
clippy::let_underscore_untyped,
|
||||||
clippy::missing_errors_doc,
|
|
||||||
clippy::needless_pass_by_value,
|
clippy::needless_pass_by_value,
|
||||||
clippy::non_ascii_literal,
|
|
||||||
clippy::shadow_unrelated,
|
|
||||||
clippy::struct_excessive_bools,
|
|
||||||
clippy::too_many_lines,
|
clippy::too_many_lines,
|
||||||
clippy::type_repetition_in_bounds,
|
clippy::unnecessary_wraps,
|
||||||
clippy::wildcard_imports
|
clippy::wildcard_imports
|
||||||
)]
|
)]
|
||||||
|
|
||||||
|
@ -1,6 +1,3 @@
|
|||||||
// `Self` cannot be used where type takes generic arguments
|
|
||||||
#![allow(clippy::use_self)]
|
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
pub struct List<T: Display, I: Iterator<Item = T> + Clone> {
|
pub struct List<T: Display, I: Iterator<Item = T> + Clone> {
|
||||||
|
@ -174,15 +174,14 @@ impl<'tokens, 'src> Parser<'tokens, 'src> {
|
|||||||
|
|
||||||
if next.kind != Identifier {
|
if next.kind != Identifier {
|
||||||
Err(self.internal_error(format!(
|
Err(self.internal_error(format!(
|
||||||
"Presumed next token would have kind {}, but found {}",
|
"Presumed next token would have kind {Identifier}, but found {}",
|
||||||
Identifier, next.kind
|
next.kind
|
||||||
))?)
|
))?)
|
||||||
} else if keyword == next.lexeme() {
|
} else if keyword == next.lexeme() {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(self.internal_error(format!(
|
Err(self.internal_error(format!(
|
||||||
"Presumed next token would have lexeme \"{}\", but found \"{}\"",
|
"Presumed next token would have lexeme \"{keyword}\", but found \"{}\"",
|
||||||
keyword,
|
|
||||||
next.lexeme(),
|
next.lexeme(),
|
||||||
))?)
|
))?)
|
||||||
}
|
}
|
||||||
@ -196,8 +195,8 @@ impl<'tokens, 'src> Parser<'tokens, 'src> {
|
|||||||
Ok(next)
|
Ok(next)
|
||||||
} else {
|
} else {
|
||||||
Err(self.internal_error(format!(
|
Err(self.internal_error(format!(
|
||||||
"Presumed next token would have kind {:?}, but found {:?}",
|
"Presumed next token would have kind {kind:?}, but found {:?}",
|
||||||
kind, next.kind
|
next.kind
|
||||||
))?)
|
))?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -869,7 +868,7 @@ impl<'tokens, 'src> Parser<'tokens, 'src> {
|
|||||||
}
|
}
|
||||||
attributes.insert(attribute, name.line);
|
attributes.insert(attribute, name.line);
|
||||||
|
|
||||||
if !self.accepted(TokenKind::Comma)? {
|
if !self.accepted(Comma)? {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
/// Main entry point into just binary.
|
/// Main entry point into just binary.
|
||||||
|
#[allow(clippy::missing_errors_doc)]
|
||||||
pub fn run() -> Result<(), i32> {
|
pub fn run() -> Result<(), i32> {
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
ansi_term::enable_ansi_support().ok();
|
ansi_term::enable_ansi_support().ok();
|
||||||
|
@ -6,6 +6,7 @@ pub(crate) const WINDOWS_POWERSHELL_SHELL: &str = "powershell.exe";
|
|||||||
pub(crate) const WINDOWS_POWERSHELL_ARGS: &[&str] = &["-NoLogo", "-Command"];
|
pub(crate) const WINDOWS_POWERSHELL_ARGS: &[&str] = &["-NoLogo", "-Command"];
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Serialize, Default)]
|
#[derive(Debug, PartialEq, Serialize, Default)]
|
||||||
|
#[allow(clippy::struct_excessive_bools)]
|
||||||
pub(crate) struct Settings<'src> {
|
pub(crate) struct Settings<'src> {
|
||||||
pub(crate) allow_duplicate_recipes: bool,
|
pub(crate) allow_duplicate_recipes: bool,
|
||||||
pub(crate) dotenv_load: Option<bool>,
|
pub(crate) dotenv_load: Option<bool>,
|
||||||
|
@ -116,7 +116,7 @@ fn editor_precedence() {
|
|||||||
assert_stdout(&output, JUSTFILE);
|
assert_stdout(&output, JUSTFILE);
|
||||||
|
|
||||||
let cat = which("cat").unwrap();
|
let cat = which("cat").unwrap();
|
||||||
let vim = tmp.path().join(format!("vim{}", env::consts::EXE_SUFFIX));
|
let vim = tmp.path().join(format!("vim{}", EXE_SUFFIX));
|
||||||
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
std::os::unix::fs::symlink(cat, vim).unwrap();
|
std::os::unix::fs::symlink(cat, vim).unwrap();
|
||||||
@ -154,7 +154,7 @@ fn editor_working_directory() {
|
|||||||
let editor = tmp.path().join("editor");
|
let editor = tmp.path().join("editor");
|
||||||
|
|
||||||
let permissions = std::os::unix::fs::PermissionsExt::from_mode(0o700);
|
let permissions = std::os::unix::fs::PermissionsExt::from_mode(0o700);
|
||||||
std::fs::set_permissions(&editor, permissions).unwrap();
|
fs::set_permissions(&editor, permissions).unwrap();
|
||||||
|
|
||||||
let output = Command::new(executable_path("just"))
|
let output = Command::new(executable_path("just"))
|
||||||
.current_dir(tmp.path().join("child"))
|
.current_dir(tmp.path().join("child"))
|
||||||
@ -164,8 +164,7 @@ fn editor_working_directory() {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let want = format!(
|
let want = format!(
|
||||||
"{}{}\n",
|
"{JUSTFILE}{}\n",
|
||||||
JUSTFILE,
|
|
||||||
tmp.path().canonicalize().unwrap().display()
|
tmp.path().canonicalize().unwrap().display()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -169,8 +169,8 @@ impl Test {
|
|||||||
|
|
||||||
pub(crate) fn write(self, path: impl AsRef<Path>, content: impl AsRef<[u8]>) -> Self {
|
pub(crate) fn write(self, path: impl AsRef<Path>, content: impl AsRef<[u8]>) -> Self {
|
||||||
let path = self.tempdir.path().join(path);
|
let path = self.tempdir.path().join(path);
|
||||||
std::fs::create_dir_all(path.parent().unwrap()).unwrap();
|
fs::create_dir_all(path.parent().unwrap()).unwrap();
|
||||||
std::fs::write(path, content).unwrap();
|
fs::write(path, content).unwrap();
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -224,7 +224,7 @@ impl Test {
|
|||||||
fn compare<T: PartialEq + Debug>(name: &str, have: T, want: T) -> bool {
|
fn compare<T: PartialEq + Debug>(name: &str, have: T, want: T) -> bool {
|
||||||
let equal = have == want;
|
let equal = have == want;
|
||||||
if !equal {
|
if !equal {
|
||||||
eprintln!("Bad {}: {}", name, Comparison::new(&have, &want));
|
eprintln!("Bad {name}: {}", Comparison::new(&have, &want));
|
||||||
}
|
}
|
||||||
equal
|
equal
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user