mirror of
https://github.com/casey/just
synced 2024-09-06 16:55:26 +00:00
fmt: check formatting with --check
(#1001)
This commit is contained in:
parent
9987a0b8ae
commit
1cf8a714e2
7
Cargo.lock
generated
7
Cargo.lock
generated
|
@ -231,6 +231,7 @@ dependencies = [
|
|||
"log",
|
||||
"pretty_assertions",
|
||||
"regex",
|
||||
"similar",
|
||||
"snafu",
|
||||
"strum",
|
||||
"strum_macros",
|
||||
|
@ -463,6 +464,12 @@ version = "1.0.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "61b3909d758bb75c79f23d4736fac9433868679d3ad2ea7a61e3c25cfda9a088"
|
||||
|
||||
[[package]]
|
||||
name = "similar"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e24979f63a11545f5f2c60141afe249d4f19f84581ea2138065e400941d83d3"
|
||||
|
||||
[[package]]
|
||||
name = "snafu"
|
||||
version = "0.6.10"
|
||||
|
|
|
@ -28,6 +28,7 @@ lexiclean = "0.0.1"
|
|||
libc = "0.2.0"
|
||||
log = "0.4.4"
|
||||
regex = "1.5.4"
|
||||
similar = "2.1.0"
|
||||
snafu = "0.6.0"
|
||||
strum_macros = "0.22.0"
|
||||
target = "2.0.0"
|
||||
|
|
|
@ -20,7 +20,7 @@ _just() {
|
|||
|
||||
case "${cmd}" in
|
||||
just)
|
||||
opts=" -q -u -v -e -l -h -V -f -d -c -s --dry-run --highlight --no-dotenv --no-highlight --quiet --shell-command --clear-shell-args --unsorted --unstable --verbose --changelog --choose --dump --edit --evaluate --fmt --init --list --summary --variables --help --version --chooser --color --list-heading --list-prefix --justfile --set --shell --shell-arg --working-directory --command --completions --show --dotenv-filename --dotenv-path <ARGUMENTS>... "
|
||||
opts=" -q -u -v -e -l -h -V -f -d -c -s --check --dry-run --highlight --no-dotenv --no-highlight --quiet --shell-command --clear-shell-args --unsorted --unstable --verbose --changelog --choose --dump --edit --evaluate --fmt --init --list --summary --variables --help --version --chooser --color --list-heading --list-prefix --justfile --set --shell --shell-arg --working-directory --command --completions --show --dotenv-filename --dotenv-path <ARGUMENTS>... "
|
||||
if [[ ${cur} == -* ]] ; then
|
||||
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
|
||||
return 0
|
||||
|
|
|
@ -32,6 +32,7 @@ edit:completion:arg-completer[just] = [@words]{
|
|||
cand --show 'Show information about <RECIPE>'
|
||||
cand --dotenv-filename 'Search for environment file named <DOTENV-FILENAME> instead of `.env`'
|
||||
cand --dotenv-path 'Load environment file at <DOTENV-PATH> instead of searching for one'
|
||||
cand --check 'Run `--fmt` in ''check'' mode. Exits with 0 if justfile is formatted correctly. Exits with 1 and prints a diff if formatting is required.'
|
||||
cand --dry-run 'Print what just would do without doing it'
|
||||
cand --highlight 'Highlight echoed recipe lines in bold'
|
||||
cand --no-dotenv 'Don''t load `.env` file'
|
||||
|
|
|
@ -23,6 +23,7 @@ complete -c just -n "__fish_use_subcommand" -l completions -d 'Print shell compl
|
|||
complete -c just -n "__fish_use_subcommand" -s s -l show -d 'Show information about <RECIPE>'
|
||||
complete -c just -n "__fish_use_subcommand" -l dotenv-filename -d 'Search for environment file named <DOTENV-FILENAME> instead of `.env`'
|
||||
complete -c just -n "__fish_use_subcommand" -l dotenv-path -d 'Load environment file at <DOTENV-PATH> instead of searching for one'
|
||||
complete -c just -n "__fish_use_subcommand" -l check -d 'Run `--fmt` in \'check\' mode. Exits with 0 if justfile is formatted correctly. Exits with 1 and prints a diff if formatting is required.'
|
||||
complete -c just -n "__fish_use_subcommand" -l dry-run -d 'Print what just would do without doing it'
|
||||
complete -c just -n "__fish_use_subcommand" -l highlight -d 'Highlight echoed recipe lines in bold'
|
||||
complete -c just -n "__fish_use_subcommand" -l no-dotenv -d 'Don\'t load `.env` file'
|
||||
|
|
|
@ -37,6 +37,7 @@ Register-ArgumentCompleter -Native -CommandName 'just' -ScriptBlock {
|
|||
[CompletionResult]::new('--show', 'show', [CompletionResultType]::ParameterName, 'Show information about <RECIPE>')
|
||||
[CompletionResult]::new('--dotenv-filename', 'dotenv-filename', [CompletionResultType]::ParameterName, 'Search for environment file named <DOTENV-FILENAME> instead of `.env`')
|
||||
[CompletionResult]::new('--dotenv-path', 'dotenv-path', [CompletionResultType]::ParameterName, 'Load environment file at <DOTENV-PATH> instead of searching for one')
|
||||
[CompletionResult]::new('--check', 'check', [CompletionResultType]::ParameterName, 'Run `--fmt` in ''check'' mode. Exits with 0 if justfile is formatted correctly. Exits with 1 and prints a diff if formatting is required.')
|
||||
[CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'Print what just would do without doing it')
|
||||
[CompletionResult]::new('--highlight', 'highlight', [CompletionResultType]::ParameterName, 'Highlight echoed recipe lines in bold')
|
||||
[CompletionResult]::new('--no-dotenv', 'no-dotenv', [CompletionResultType]::ParameterName, 'Don''t load `.env` file')
|
||||
|
|
|
@ -33,6 +33,7 @@ _just() {
|
|||
'--show=[Show information about <RECIPE>]: :_just_commands' \
|
||||
'(--dotenv-path)--dotenv-filename=[Search for environment file named <DOTENV-FILENAME> instead of `.env`]' \
|
||||
'--dotenv-path=[Load environment file at <DOTENV-PATH> instead of searching for one]' \
|
||||
'--check[Run `--fmt` in '\''check'\'' mode. Exits with 0 if justfile is formatted correctly. Exits with 1 and prints a diff if formatting is required.]' \
|
||||
'(-q --quiet)--dry-run[Print what just would do without doing it]' \
|
||||
'--highlight[Highlight echoed recipe lines in bold]' \
|
||||
'--no-dotenv[Don'\''t load `.env` file]' \
|
||||
|
|
|
@ -15,6 +15,7 @@ pub(crate) const DEFAULT_SHELL_ARG: &str = "-cu";
|
|||
#[derive(Debug, PartialEq)]
|
||||
pub(crate) struct Config {
|
||||
pub(crate) color: Color,
|
||||
pub(crate) check: bool,
|
||||
pub(crate) dry_run: bool,
|
||||
pub(crate) highlight: bool,
|
||||
pub(crate) invocation_directory: PathBuf,
|
||||
|
@ -81,6 +82,7 @@ mod cmd {
|
|||
|
||||
mod arg {
|
||||
pub(crate) const ARGUMENTS: &str = "ARGUMENTS";
|
||||
pub(crate) const CHECK: &str = "CHECK";
|
||||
pub(crate) const CHOOSER: &str = "CHOOSER";
|
||||
pub(crate) const CLEAR_SHELL_ARGS: &str = "CLEAR-SHELL-ARGS";
|
||||
pub(crate) const COLOR: &str = "COLOR";
|
||||
|
@ -116,6 +118,12 @@ impl Config {
|
|||
.version_message("Print version information")
|
||||
.setting(AppSettings::ColoredHelp)
|
||||
.setting(AppSettings::TrailingVarArg)
|
||||
.arg(
|
||||
Arg::with_name(arg::CHECK)
|
||||
.long("check")
|
||||
.requires(cmd::FORMAT)
|
||||
.help("Run `--fmt` in 'check' mode. Exits with 0 if justfile is formatted correctly. Exits with 1 and prints a diff if formatting is required."),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(arg::CHOOSER)
|
||||
.long("chooser")
|
||||
|
@ -532,6 +540,7 @@ impl Config {
|
|||
|| matches.occurrences_of(arg::SHELL_ARG) > 0;
|
||||
|
||||
Ok(Self {
|
||||
check: matches.is_present(arg::CHECK),
|
||||
dry_run: matches.is_present(arg::DRY_RUN),
|
||||
highlight: !matches.is_present(arg::NO_HIGHLIGHT),
|
||||
shell: matches.value_of(arg::SHELL).unwrap().to_owned(),
|
||||
|
@ -594,6 +603,9 @@ USAGE:
|
|||
|
||||
FLAGS:
|
||||
--changelog Print changelog
|
||||
--check Run `--fmt` in 'check' mode. Exits with 0 if
|
||||
justfile is formatted correctly. Exits with 1 and
|
||||
prints a diff if formatting is required.
|
||||
--choose Select one or more recipes to run using a binary.
|
||||
If `--chooser` is not passed the chooser defaults
|
||||
to the value of $JUST_CHOOSER, falling back to
|
||||
|
|
|
@ -75,6 +75,7 @@ pub(crate) enum Error<'src> {
|
|||
variable: String,
|
||||
suggestion: Option<Suggestion<'src>>,
|
||||
},
|
||||
FormatCheckFoundDiff,
|
||||
FunctionCall {
|
||||
function: Name<'src>,
|
||||
message: String,
|
||||
|
@ -458,6 +459,9 @@ impl<'src> ColorDisplay for Error<'src> {
|
|||
write!(f, "\n{}", suggestion)?;
|
||||
}
|
||||
}
|
||||
FormatCheckFoundDiff => {
|
||||
write!(f, "Formatted justfile differs from original.")?;
|
||||
}
|
||||
FunctionCall { function, message } => {
|
||||
write!(
|
||||
f,
|
||||
|
|
|
@ -77,7 +77,7 @@ impl Subcommand {
|
|||
justfile.run(config, &search, overrides, &[])?
|
||||
}
|
||||
Dump => Self::dump(ast),
|
||||
Format => Self::format(config, ast, &search)?,
|
||||
Format => Self::format(config, ast, &src, &search)?,
|
||||
List => Self::list(config, justfile),
|
||||
Run {
|
||||
arguments,
|
||||
|
@ -255,11 +255,22 @@ impl Subcommand {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn format(config: &Config, ast: Ast, search: &Search) -> Result<(), Error<'static>> {
|
||||
fn format(config: &Config, ast: Ast, src: &str, search: &Search) -> Result<(), Error<'static>> {
|
||||
config.require_unstable("The `--fmt` command is currently unstable.")?;
|
||||
|
||||
if let Err(io_error) =
|
||||
File::create(&search.justfile).and_then(|mut file| write!(file, "{}", ast))
|
||||
let src_formatted = ast.to_string();
|
||||
if config.check {
|
||||
if src == src_formatted {
|
||||
Ok(())
|
||||
} else {
|
||||
print!(
|
||||
"{}",
|
||||
similar::udiff::unified_diff(similar::Algorithm::Patience, &src, &src_formatted, 2, None)
|
||||
);
|
||||
Err(Error::FormatCheckFoundDiff)
|
||||
}
|
||||
} else if let Err(io_error) =
|
||||
File::create(&search.justfile).and_then(|mut file| file.write_all(&src_formatted.as_bytes()))
|
||||
{
|
||||
Err(Error::WriteJustfile {
|
||||
justfile: search.justfile.clone(),
|
||||
|
|
45
tests/fmt.rs
45
tests/fmt.rs
|
@ -11,6 +11,51 @@ test! {
|
|||
status: EXIT_FAILURE,
|
||||
}
|
||||
|
||||
test! {
|
||||
name: check_without_fmt,
|
||||
justfile: "",
|
||||
args: ("--check"),
|
||||
stderr_regex: "error: The following required arguments were not provided:
|
||||
--fmt
|
||||
(.|\\n)+",
|
||||
status: EXIT_FAILURE,
|
||||
}
|
||||
|
||||
test! {
|
||||
name: dry_run_ok,
|
||||
justfile: r#"
|
||||
# comment with spaces
|
||||
|
||||
export x := `backtick
|
||||
with
|
||||
lines`
|
||||
|
||||
recipe: deps
|
||||
echo "$x"
|
||||
|
||||
deps:
|
||||
echo {{ x }}
|
||||
echo '$x'
|
||||
"#,
|
||||
args: ("--unstable", "--fmt", "--check"),
|
||||
status: EXIT_SUCCESS,
|
||||
}
|
||||
|
||||
test! {
|
||||
name: dry_run_found_diff,
|
||||
justfile: "x:=``\n",
|
||||
args: ("--unstable", "--fmt", "--check"),
|
||||
stdout: "
|
||||
@@ -1 +1 @@
|
||||
-x:=``
|
||||
+x := ``
|
||||
",
|
||||
stderr: "
|
||||
error: Formatted justfile differs from original.
|
||||
",
|
||||
status: EXIT_FAILURE,
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unstable_passed() {
|
||||
let tmp = tempdir();
|
||||
|
|
Loading…
Reference in a new issue