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",
|
"log",
|
||||||
"pretty_assertions",
|
"pretty_assertions",
|
||||||
"regex",
|
"regex",
|
||||||
|
"similar",
|
||||||
"snafu",
|
"snafu",
|
||||||
"strum",
|
"strum",
|
||||||
"strum_macros",
|
"strum_macros",
|
||||||
@ -463,6 +464,12 @@ version = "1.0.5"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "61b3909d758bb75c79f23d4736fac9433868679d3ad2ea7a61e3c25cfda9a088"
|
checksum = "61b3909d758bb75c79f23d4736fac9433868679d3ad2ea7a61e3c25cfda9a088"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "similar"
|
||||||
|
version = "2.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2e24979f63a11545f5f2c60141afe249d4f19f84581ea2138065e400941d83d3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "snafu"
|
name = "snafu"
|
||||||
version = "0.6.10"
|
version = "0.6.10"
|
||||||
|
@ -28,6 +28,7 @@ lexiclean = "0.0.1"
|
|||||||
libc = "0.2.0"
|
libc = "0.2.0"
|
||||||
log = "0.4.4"
|
log = "0.4.4"
|
||||||
regex = "1.5.4"
|
regex = "1.5.4"
|
||||||
|
similar = "2.1.0"
|
||||||
snafu = "0.6.0"
|
snafu = "0.6.0"
|
||||||
strum_macros = "0.22.0"
|
strum_macros = "0.22.0"
|
||||||
target = "2.0.0"
|
target = "2.0.0"
|
||||||
|
@ -20,7 +20,7 @@ _just() {
|
|||||||
|
|
||||||
case "${cmd}" in
|
case "${cmd}" in
|
||||||
just)
|
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
|
if [[ ${cur} == -* ]] ; then
|
||||||
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
|
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
|
||||||
return 0
|
return 0
|
||||||
|
@ -32,6 +32,7 @@ edit:completion:arg-completer[just] = [@words]{
|
|||||||
cand --show 'Show information about <RECIPE>'
|
cand --show 'Show information about <RECIPE>'
|
||||||
cand --dotenv-filename 'Search for environment file named <DOTENV-FILENAME> instead of `.env`'
|
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 --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 --dry-run 'Print what just would do without doing it'
|
||||||
cand --highlight 'Highlight echoed recipe lines in bold'
|
cand --highlight 'Highlight echoed recipe lines in bold'
|
||||||
cand --no-dotenv 'Don''t load `.env` file'
|
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" -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-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 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 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 highlight -d 'Highlight echoed recipe lines in bold'
|
||||||
complete -c just -n "__fish_use_subcommand" -l no-dotenv -d 'Don\'t load `.env` file'
|
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('--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-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('--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('--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('--highlight', 'highlight', [CompletionResultType]::ParameterName, 'Highlight echoed recipe lines in bold')
|
||||||
[CompletionResult]::new('--no-dotenv', 'no-dotenv', [CompletionResultType]::ParameterName, 'Don''t load `.env` file')
|
[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' \
|
'--show=[Show information about <RECIPE>]: :_just_commands' \
|
||||||
'(--dotenv-path)--dotenv-filename=[Search for environment file named <DOTENV-FILENAME> instead of `.env`]' \
|
'(--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]' \
|
'--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]' \
|
'(-q --quiet)--dry-run[Print what just would do without doing it]' \
|
||||||
'--highlight[Highlight echoed recipe lines in bold]' \
|
'--highlight[Highlight echoed recipe lines in bold]' \
|
||||||
'--no-dotenv[Don'\''t load `.env` file]' \
|
'--no-dotenv[Don'\''t load `.env` file]' \
|
||||||
|
@ -15,6 +15,7 @@ pub(crate) const DEFAULT_SHELL_ARG: &str = "-cu";
|
|||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub(crate) struct Config {
|
pub(crate) struct Config {
|
||||||
pub(crate) color: Color,
|
pub(crate) color: Color,
|
||||||
|
pub(crate) check: bool,
|
||||||
pub(crate) dry_run: bool,
|
pub(crate) dry_run: bool,
|
||||||
pub(crate) highlight: bool,
|
pub(crate) highlight: bool,
|
||||||
pub(crate) invocation_directory: PathBuf,
|
pub(crate) invocation_directory: PathBuf,
|
||||||
@ -81,6 +82,7 @@ mod cmd {
|
|||||||
|
|
||||||
mod arg {
|
mod arg {
|
||||||
pub(crate) const ARGUMENTS: &str = "ARGUMENTS";
|
pub(crate) const ARGUMENTS: &str = "ARGUMENTS";
|
||||||
|
pub(crate) const CHECK: &str = "CHECK";
|
||||||
pub(crate) const CHOOSER: &str = "CHOOSER";
|
pub(crate) const CHOOSER: &str = "CHOOSER";
|
||||||
pub(crate) const CLEAR_SHELL_ARGS: &str = "CLEAR-SHELL-ARGS";
|
pub(crate) const CLEAR_SHELL_ARGS: &str = "CLEAR-SHELL-ARGS";
|
||||||
pub(crate) const COLOR: &str = "COLOR";
|
pub(crate) const COLOR: &str = "COLOR";
|
||||||
@ -116,6 +118,12 @@ impl Config {
|
|||||||
.version_message("Print version information")
|
.version_message("Print version information")
|
||||||
.setting(AppSettings::ColoredHelp)
|
.setting(AppSettings::ColoredHelp)
|
||||||
.setting(AppSettings::TrailingVarArg)
|
.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(
|
||||||
Arg::with_name(arg::CHOOSER)
|
Arg::with_name(arg::CHOOSER)
|
||||||
.long("chooser")
|
.long("chooser")
|
||||||
@ -532,6 +540,7 @@ impl Config {
|
|||||||
|| matches.occurrences_of(arg::SHELL_ARG) > 0;
|
|| matches.occurrences_of(arg::SHELL_ARG) > 0;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
|
check: matches.is_present(arg::CHECK),
|
||||||
dry_run: matches.is_present(arg::DRY_RUN),
|
dry_run: matches.is_present(arg::DRY_RUN),
|
||||||
highlight: !matches.is_present(arg::NO_HIGHLIGHT),
|
highlight: !matches.is_present(arg::NO_HIGHLIGHT),
|
||||||
shell: matches.value_of(arg::SHELL).unwrap().to_owned(),
|
shell: matches.value_of(arg::SHELL).unwrap().to_owned(),
|
||||||
@ -594,6 +603,9 @@ USAGE:
|
|||||||
|
|
||||||
FLAGS:
|
FLAGS:
|
||||||
--changelog Print changelog
|
--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.
|
--choose Select one or more recipes to run using a binary.
|
||||||
If `--chooser` is not passed the chooser defaults
|
If `--chooser` is not passed the chooser defaults
|
||||||
to the value of $JUST_CHOOSER, falling back to
|
to the value of $JUST_CHOOSER, falling back to
|
||||||
|
@ -75,6 +75,7 @@ pub(crate) enum Error<'src> {
|
|||||||
variable: String,
|
variable: String,
|
||||||
suggestion: Option<Suggestion<'src>>,
|
suggestion: Option<Suggestion<'src>>,
|
||||||
},
|
},
|
||||||
|
FormatCheckFoundDiff,
|
||||||
FunctionCall {
|
FunctionCall {
|
||||||
function: Name<'src>,
|
function: Name<'src>,
|
||||||
message: String,
|
message: String,
|
||||||
@ -458,6 +459,9 @@ impl<'src> ColorDisplay for Error<'src> {
|
|||||||
write!(f, "\n{}", suggestion)?;
|
write!(f, "\n{}", suggestion)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
FormatCheckFoundDiff => {
|
||||||
|
write!(f, "Formatted justfile differs from original.")?;
|
||||||
|
}
|
||||||
FunctionCall { function, message } => {
|
FunctionCall { function, message } => {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
|
@ -77,7 +77,7 @@ impl Subcommand {
|
|||||||
justfile.run(config, &search, overrides, &[])?
|
justfile.run(config, &search, overrides, &[])?
|
||||||
}
|
}
|
||||||
Dump => Self::dump(ast),
|
Dump => Self::dump(ast),
|
||||||
Format => Self::format(config, ast, &search)?,
|
Format => Self::format(config, ast, &src, &search)?,
|
||||||
List => Self::list(config, justfile),
|
List => Self::list(config, justfile),
|
||||||
Run {
|
Run {
|
||||||
arguments,
|
arguments,
|
||||||
@ -255,11 +255,22 @@ impl Subcommand {
|
|||||||
Ok(())
|
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.")?;
|
config.require_unstable("The `--fmt` command is currently unstable.")?;
|
||||||
|
|
||||||
if let Err(io_error) =
|
let src_formatted = ast.to_string();
|
||||||
File::create(&search.justfile).and_then(|mut file| write!(file, "{}", ast))
|
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 {
|
Err(Error::WriteJustfile {
|
||||||
justfile: search.justfile.clone(),
|
justfile: search.justfile.clone(),
|
||||||
|
45
tests/fmt.rs
45
tests/fmt.rs
@ -11,6 +11,51 @@ test! {
|
|||||||
status: EXIT_FAILURE,
|
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]
|
#[test]
|
||||||
fn unstable_passed() {
|
fn unstable_passed() {
|
||||||
let tmp = tempdir();
|
let tmp = tempdir();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user