Add --dump-format json
(#992)
This commit is contained in:
parent
53d3c7569c
commit
0ae91884e2
87
Cargo.lock
generated
87
Cargo.lock
generated
@ -1,7 +1,5 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.7.18"
|
||||
@ -71,9 +69,9 @@ checksum = "52d74260d9bf6944e2208aa46841b4b8f0d7ffc0849a06837b2f510337f86b2b"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.71"
|
||||
version = "1.0.70"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "79c2681d6594606957bbb8631c4b90a7fcaaa72cdb714743a437b156d6a7eedd"
|
||||
checksum = "d26a6ce4b6a484fa3edb70f7efa6fc430fd2b87285fe8b84304fd0936faa0dc0"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
@ -118,9 +116,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ctrlc"
|
||||
version = "3.2.1"
|
||||
version = "3.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a19c6cedffdc8c03a3346d723eb20bd85a13362bb96dc2ac000842c6381ec7bf"
|
||||
checksum = "377c9b002a72a0b2c1a18c62e2f3864bdfea4a015e3683a96e24aa45dd6c02d1"
|
||||
dependencies = [
|
||||
"nix",
|
||||
"winapi",
|
||||
@ -221,6 +219,12 @@ version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "0.4.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"
|
||||
|
||||
[[package]]
|
||||
name = "just"
|
||||
version = "0.10.3"
|
||||
@ -242,6 +246,8 @@ dependencies = [
|
||||
"log",
|
||||
"pretty_assertions",
|
||||
"regex",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"similar",
|
||||
"snafu",
|
||||
"strum",
|
||||
@ -269,9 +275,9 @@ checksum = "441225017b106b9f902e97947a6d31e44ebcf274b91bdbfb51e5c477fcd468e5"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.106"
|
||||
version = "0.2.103"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a60553f9a9e039a333b4e9b20573b9e9b9c0bb3a11e201ccc48ef4283456d673"
|
||||
checksum = "dd8f7255a17a627354f321ef0055d63b898c6fb27eff628af4d1b66b7331edf6"
|
||||
|
||||
[[package]]
|
||||
name = "linked-hash-map"
|
||||
@ -305,9 +311,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nix"
|
||||
version = "0.23.0"
|
||||
version = "0.22.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f305c2c2e4c39a82f7bf0bf65fb557f9070ce06781d4f2454295cc34b1c43188"
|
||||
checksum = "cf1e25ee6b412c2a1e3fcb6a4499a5c1bfe7f43e014bdce9a6b6666e5aa2d187"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cc",
|
||||
@ -327,9 +333,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.15"
|
||||
version = "0.2.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed0cfbc8191465bed66e1718596ee0b0b35d5ee1f41c5df2189d0fe8bde535ba"
|
||||
checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
|
||||
|
||||
[[package]]
|
||||
name = "pretty_assertions"
|
||||
@ -369,18 +375,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.32"
|
||||
version = "1.0.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba508cc11742c0dc5c1659771673afbab7a0efab23aa17e854cbab0837ed0b43"
|
||||
checksum = "b9f5105d4fdaab20335ca9565e106a5d9b82b6219b5ba735731124ac6711d23d"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.10"
|
||||
version = "1.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05"
|
||||
checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
@ -481,6 +487,43 @@ version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "61b3909d758bb75c79f23d4736fac9433868679d3ad2ea7a61e3c25cfda9a088"
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.130"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.130"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.68"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0f690853975602e1bfe1ccbf50504d67174e3bcf340f23b5ea9992e0587a52d8"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "similar"
|
||||
version = "2.1.0"
|
||||
@ -520,9 +563,9 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
||||
|
||||
[[package]]
|
||||
name = "structopt"
|
||||
version = "0.3.25"
|
||||
version = "0.3.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "40b9788f4202aa75c240ecc9c15c65185e6a39ccdeb0fd5d008b98825464c87c"
|
||||
checksum = "bf9d950ef167e25e0bdb073cf1d68e9ad2795ac826f2f3f59647817cf23c0bfa"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"lazy_static",
|
||||
@ -531,9 +574,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "structopt-derive"
|
||||
version = "0.4.18"
|
||||
version = "0.4.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0"
|
||||
checksum = "134d838a2c9943ac3125cf6df165eda53493451b719f3255b2a26b85f772d0ba"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro-error",
|
||||
@ -565,9 +608,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.81"
|
||||
version = "1.0.77"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2afee18b8beb5a596ecb4a2dce128c719b4ba399d34126b9e4396e3f9860966"
|
||||
checksum = "5239bc68e0fef57495900cfea4e8dc75596d9a319d7e16b1e0a440d24e6fe0a0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
22
Cargo.toml
22
Cargo.toml
@ -19,6 +19,8 @@ members = [".", "bin/ref-type"]
|
||||
ansi_term = "0.12.0"
|
||||
atty = "0.2.0"
|
||||
camino = "1.0.4"
|
||||
clap = { version = "2.33.0", features = ["wrap_help"] }
|
||||
ctrlc = { version = "3.1.1", features = ["termination"] }
|
||||
derivative = "2.0.0"
|
||||
dotenv = "0.15.0"
|
||||
edit-distance = "2.0.0"
|
||||
@ -28,29 +30,17 @@ lexiclean = "0.0.1"
|
||||
libc = "0.2.0"
|
||||
log = "0.4.4"
|
||||
regex = "1.5.4"
|
||||
serde = { version = "1.0.130", features = ["derive", "rc"] }
|
||||
serde_json = "1.0.68"
|
||||
similar = { version = "2.1.0", features = ["unicode"] }
|
||||
snafu = "0.6.0"
|
||||
strum = { version = "0.22.0", features = ["derive"] }
|
||||
strum_macros = "0.22.0"
|
||||
target = "2.0.0"
|
||||
tempfile = "3.0.0"
|
||||
typed-arena = "2.0.1"
|
||||
unicode-width = "0.1.0"
|
||||
|
||||
[dependencies.clap]
|
||||
version = "2.33.0"
|
||||
features = ["wrap_help"]
|
||||
|
||||
[dependencies.ctrlc]
|
||||
version = "3.1.1"
|
||||
features = ["termination"]
|
||||
|
||||
[dependencies.similar]
|
||||
version = "2.1.0"
|
||||
features = ["unicode"]
|
||||
|
||||
[dependencies.strum]
|
||||
version = "0.22.0"
|
||||
features = ["derive"]
|
||||
|
||||
[dev-dependencies]
|
||||
cradle = "0.2.0"
|
||||
executable-path = "1.0.0"
|
||||
|
@ -1730,6 +1730,10 @@ default:
|
||||
echo foo
|
||||
```
|
||||
|
||||
=== Dumping Justfiles as JSON
|
||||
|
||||
The `--dump` command can be used with `--dump-format json` to print a JSON representation of a justfile. The JSON format is currently unstable, so the `--unstable` flag is required.
|
||||
|
||||
=== Changelog
|
||||
|
||||
A changelog for the latest release is available in link:CHANGELOG.md[]. Changelogs for previous releases are available on https://github.com/casey/just/releases[the releases page]. `just --changelog` can also be used to make a `just` binary print its changelog.
|
||||
|
@ -20,7 +20,7 @@ _just() {
|
||||
|
||||
case "${cmd}" in
|
||||
just)
|
||||
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>... "
|
||||
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 --dump-format --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
|
||||
@ -41,6 +41,10 @@ _just() {
|
||||
COMPREPLY=($(compgen -W "auto always never" -- "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--dump-format)
|
||||
COMPREPLY=($(compgen -W "just json" -- "${cur}"))
|
||||
return 0
|
||||
;;
|
||||
--list-heading)
|
||||
COMPREPLY=($(compgen -f "${cur}"))
|
||||
return 0
|
||||
|
@ -16,6 +16,7 @@ edit:completion:arg-completer[just] = [@words]{
|
||||
&'just'= {
|
||||
cand --chooser 'Override binary invoked by `--choose`'
|
||||
cand --color 'Print colorful output'
|
||||
cand --dump-format 'Dump justfile as <FORMAT>'
|
||||
cand --list-heading 'Print <TEXT> before list'
|
||||
cand --list-prefix 'Print <TEXT> before each list item'
|
||||
cand -f 'Use <JUSTFILE> as justfile'
|
||||
@ -48,7 +49,7 @@ edit:completion:arg-completer[just] = [@words]{
|
||||
cand --verbose 'Use verbose output'
|
||||
cand --changelog 'Print changelog'
|
||||
cand --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 `fzf`'
|
||||
cand --dump 'Print entire justfile'
|
||||
cand --dump 'Print justfile'
|
||||
cand -e 'Edit justfile with editor given by $VISUAL or $EDITOR, falling back to `vim`'
|
||||
cand --edit 'Edit justfile with editor given by $VISUAL or $EDITOR, falling back to `vim`'
|
||||
cand --evaluate 'Evaluate and print all variables. If a variable name is given as an argument, only print that variable''s value.'
|
||||
|
@ -11,6 +11,7 @@ complete -c just -a '(__fish_just_complete_recipes)'
|
||||
# autogenerated completions
|
||||
complete -c just -n "__fish_use_subcommand" -l chooser -d 'Override binary invoked by `--choose`'
|
||||
complete -c just -n "__fish_use_subcommand" -l color -d 'Print colorful output' -r -f -a "auto always never"
|
||||
complete -c just -n "__fish_use_subcommand" -l dump-format -d 'Dump justfile as <FORMAT>' -r -f -a "just json"
|
||||
complete -c just -n "__fish_use_subcommand" -l list-heading -d 'Print <TEXT> before list'
|
||||
complete -c just -n "__fish_use_subcommand" -l list-prefix -d 'Print <TEXT> before each list item'
|
||||
complete -c just -n "__fish_use_subcommand" -s f -l justfile -d 'Use <JUSTFILE> as justfile'
|
||||
@ -36,7 +37,7 @@ complete -c just -n "__fish_use_subcommand" -l unstable -d 'Enable unstable feat
|
||||
complete -c just -n "__fish_use_subcommand" -s v -l verbose -d 'Use verbose output'
|
||||
complete -c just -n "__fish_use_subcommand" -l changelog -d 'Print changelog'
|
||||
complete -c just -n "__fish_use_subcommand" -l choose -d '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 `fzf`'
|
||||
complete -c just -n "__fish_use_subcommand" -l dump -d 'Print entire justfile'
|
||||
complete -c just -n "__fish_use_subcommand" -l dump -d 'Print justfile'
|
||||
complete -c just -n "__fish_use_subcommand" -s e -l edit -d 'Edit justfile with editor given by $VISUAL or $EDITOR, falling back to `vim`'
|
||||
complete -c just -n "__fish_use_subcommand" -l evaluate -d 'Evaluate and print all variables. If a variable name is given as an argument, only print that variable\'s value.'
|
||||
complete -c just -n "__fish_use_subcommand" -l fmt -d 'Format and overwrite justfile'
|
||||
|
@ -21,6 +21,7 @@ Register-ArgumentCompleter -Native -CommandName 'just' -ScriptBlock {
|
||||
'just' {
|
||||
[CompletionResult]::new('--chooser', 'chooser', [CompletionResultType]::ParameterName, 'Override binary invoked by `--choose`')
|
||||
[CompletionResult]::new('--color', 'color', [CompletionResultType]::ParameterName, 'Print colorful output')
|
||||
[CompletionResult]::new('--dump-format', 'dump-format', [CompletionResultType]::ParameterName, 'Dump justfile as <FORMAT>')
|
||||
[CompletionResult]::new('--list-heading', 'list-heading', [CompletionResultType]::ParameterName, 'Print <TEXT> before list')
|
||||
[CompletionResult]::new('--list-prefix', 'list-prefix', [CompletionResultType]::ParameterName, 'Print <TEXT> before each list item')
|
||||
[CompletionResult]::new('-f', 'f', [CompletionResultType]::ParameterName, 'Use <JUSTFILE> as justfile')
|
||||
@ -53,7 +54,7 @@ Register-ArgumentCompleter -Native -CommandName 'just' -ScriptBlock {
|
||||
[CompletionResult]::new('--verbose', 'verbose', [CompletionResultType]::ParameterName, 'Use verbose output')
|
||||
[CompletionResult]::new('--changelog', 'changelog', [CompletionResultType]::ParameterName, 'Print changelog')
|
||||
[CompletionResult]::new('--choose', 'choose', [CompletionResultType]::ParameterName, '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 `fzf`')
|
||||
[CompletionResult]::new('--dump', 'dump', [CompletionResultType]::ParameterName, 'Print entire justfile')
|
||||
[CompletionResult]::new('--dump', 'dump', [CompletionResultType]::ParameterName, 'Print justfile')
|
||||
[CompletionResult]::new('-e', 'e', [CompletionResultType]::ParameterName, 'Edit justfile with editor given by $VISUAL or $EDITOR, falling back to `vim`')
|
||||
[CompletionResult]::new('--edit', 'edit', [CompletionResultType]::ParameterName, 'Edit justfile with editor given by $VISUAL or $EDITOR, falling back to `vim`')
|
||||
[CompletionResult]::new('--evaluate', 'evaluate', [CompletionResultType]::ParameterName, 'Evaluate and print all variables. If a variable name is given as an argument, only print that variable''s value.')
|
||||
|
@ -17,6 +17,7 @@ _just() {
|
||||
local common=(
|
||||
'--chooser=[Override binary invoked by `--choose`]' \
|
||||
'--color=[Print colorful output]: :(auto always never)' \
|
||||
'--dump-format=[Dump justfile as <FORMAT>]: :(just json)' \
|
||||
'--list-heading=[Print <TEXT> before list]' \
|
||||
'--list-prefix=[Print <TEXT> before each list item]' \
|
||||
'-f+[Use <JUSTFILE> as justfile]' \
|
||||
@ -49,7 +50,7 @@ _just() {
|
||||
'*--verbose[Use verbose output]' \
|
||||
'--changelog[Print changelog]' \
|
||||
'--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 `fzf`]' \
|
||||
'--dump[Print entire justfile]' \
|
||||
'--dump[Print justfile]' \
|
||||
'-e[Edit justfile with editor given by $VISUAL or $EDITOR, falling back to `vim`]' \
|
||||
'--edit[Edit justfile with editor given by $VISUAL or $EDITOR, falling back to `vim`]' \
|
||||
'--evaluate[Evaluate and print all variables. If a variable name is given as an argument, only print that variable'\''s value.]' \
|
||||
|
@ -1,9 +1,13 @@
|
||||
use crate::common::*;
|
||||
|
||||
/// An alias, e.g. `name := target`
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
#[derive(Debug, PartialEq, Clone, Serialize)]
|
||||
pub(crate) struct Alias<'src, T = Rc<Recipe<'src>>> {
|
||||
pub(crate) name: Name<'src>,
|
||||
#[serde(
|
||||
bound(serialize = "T: Keyed<'src>"),
|
||||
serialize_with = "keyed::serialize"
|
||||
)]
|
||||
pub(crate) target: T,
|
||||
}
|
||||
|
||||
|
@ -81,6 +81,16 @@ impl<'src> Analyzer<'src> {
|
||||
|
||||
Ok(Justfile {
|
||||
warnings: ast.warnings,
|
||||
first: recipes
|
||||
.values()
|
||||
.fold(None, |accumulator, next| match accumulator {
|
||||
None => Some(Rc::clone(next)),
|
||||
Some(previous) => Some(if previous.line_number() < next.line_number() {
|
||||
previous
|
||||
} else {
|
||||
Rc::clone(next)
|
||||
}),
|
||||
}),
|
||||
aliases,
|
||||
assignments,
|
||||
recipes,
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::common::*;
|
||||
|
||||
/// A binding of `name` to `value`
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[derive(Debug, Clone, PartialEq, Serialize)]
|
||||
pub(crate) struct Binding<'src, V = String> {
|
||||
/// Export binding as an environment variable to child processes
|
||||
pub(crate) export: bool,
|
||||
|
@ -27,6 +27,10 @@ pub(crate) use ::{
|
||||
libc::EXIT_FAILURE,
|
||||
log::{info, warn},
|
||||
regex::Regex,
|
||||
serde::{
|
||||
ser::{SerializeMap, SerializeSeq},
|
||||
Serialize, Serializer,
|
||||
},
|
||||
snafu::{ResultExt, Snafu},
|
||||
strum::{Display, EnumString, IntoStaticStr},
|
||||
typed_arena::Arena,
|
||||
@ -34,7 +38,7 @@ pub(crate) use ::{
|
||||
};
|
||||
|
||||
// modules
|
||||
pub(crate) use crate::{completions, config, config_error, setting};
|
||||
pub(crate) use crate::{completions, config, config_error, keyed, setting};
|
||||
|
||||
// functions
|
||||
pub(crate) use crate::{load_dotenv::load_dotenv, output::output, unindent::unindent};
|
||||
@ -51,18 +55,18 @@ pub(crate) use crate::{
|
||||
assignment_resolver::AssignmentResolver, ast::Ast, binding::Binding, color::Color,
|
||||
compile_error::CompileError, compile_error_kind::CompileErrorKind,
|
||||
conditional_operator::ConditionalOperator, config::Config, config_error::ConfigError,
|
||||
count::Count, delimiter::Delimiter, dependency::Dependency, enclosure::Enclosure, error::Error,
|
||||
evaluator::Evaluator, expression::Expression, fragment::Fragment, function::Function,
|
||||
function_context::FunctionContext, interrupt_guard::InterruptGuard,
|
||||
interrupt_handler::InterruptHandler, item::Item, justfile::Justfile, keyword::Keyword,
|
||||
lexer::Lexer, line::Line, list::List, loader::Loader, name::Name, output_error::OutputError,
|
||||
parameter::Parameter, parameter_kind::ParameterKind, parser::Parser, platform::Platform,
|
||||
position::Position, positional::Positional, recipe::Recipe, recipe_context::RecipeContext,
|
||||
recipe_resolver::RecipeResolver, scope::Scope, search::Search, search_config::SearchConfig,
|
||||
search_error::SearchError, set::Set, setting::Setting, settings::Settings, shebang::Shebang,
|
||||
show_whitespace::ShowWhitespace, string_kind::StringKind, string_literal::StringLiteral,
|
||||
subcommand::Subcommand, suggestion::Suggestion, table::Table, thunk::Thunk, token::Token,
|
||||
token_kind::TokenKind, unresolved_dependency::UnresolvedDependency,
|
||||
count::Count, delimiter::Delimiter, dependency::Dependency, dump_format::DumpFormat,
|
||||
enclosure::Enclosure, error::Error, evaluator::Evaluator, expression::Expression,
|
||||
fragment::Fragment, function::Function, function_context::FunctionContext,
|
||||
interrupt_guard::InterruptGuard, interrupt_handler::InterruptHandler, item::Item,
|
||||
justfile::Justfile, keyword::Keyword, lexer::Lexer, line::Line, list::List, loader::Loader,
|
||||
name::Name, output_error::OutputError, parameter::Parameter, parameter_kind::ParameterKind,
|
||||
parser::Parser, platform::Platform, position::Position, positional::Positional, recipe::Recipe,
|
||||
recipe_context::RecipeContext, recipe_resolver::RecipeResolver, scope::Scope, search::Search,
|
||||
search_config::SearchConfig, search_error::SearchError, set::Set, setting::Setting,
|
||||
settings::Settings, shebang::Shebang, show_whitespace::ShowWhitespace, string_kind::StringKind,
|
||||
string_literal::StringLiteral, subcommand::Subcommand, suggestion::Suggestion, table::Table,
|
||||
thunk::Thunk, token::Token, token_kind::TokenKind, unresolved_dependency::UnresolvedDependency,
|
||||
unresolved_recipe::UnresolvedRecipe, use_color::UseColor, variables::Variables,
|
||||
verbosity::Verbosity, warning::Warning,
|
||||
};
|
||||
|
@ -14,9 +14,12 @@ 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) color: Color,
|
||||
pub(crate) dotenv_filename: Option<String>,
|
||||
pub(crate) dotenv_path: Option<PathBuf>,
|
||||
pub(crate) dry_run: bool,
|
||||
pub(crate) dump_format: DumpFormat,
|
||||
pub(crate) highlight: bool,
|
||||
pub(crate) invocation_directory: PathBuf,
|
||||
pub(crate) list_heading: String,
|
||||
@ -30,8 +33,6 @@ pub(crate) struct Config {
|
||||
pub(crate) subcommand: Subcommand,
|
||||
pub(crate) unsorted: bool,
|
||||
pub(crate) unstable: bool,
|
||||
pub(crate) dotenv_filename: Option<String>,
|
||||
pub(crate) dotenv_path: Option<PathBuf>,
|
||||
pub(crate) verbosity: Verbosity,
|
||||
}
|
||||
|
||||
@ -86,7 +87,10 @@ mod arg {
|
||||
pub(crate) const CHOOSER: &str = "CHOOSER";
|
||||
pub(crate) const CLEAR_SHELL_ARGS: &str = "CLEAR-SHELL-ARGS";
|
||||
pub(crate) const COLOR: &str = "COLOR";
|
||||
pub(crate) const DOTENV_FILENAME: &str = "DOTENV-FILENAME";
|
||||
pub(crate) const DOTENV_PATH: &str = "DOTENV-PATH";
|
||||
pub(crate) const DRY_RUN: &str = "DRY-RUN";
|
||||
pub(crate) const DUMP_FORMAT: &str = "DUMP-FORMAT";
|
||||
pub(crate) const HIGHLIGHT: &str = "HIGHLIGHT";
|
||||
pub(crate) const JUSTFILE: &str = "JUSTFILE";
|
||||
pub(crate) const LIST_HEADING: &str = "LIST-HEADING";
|
||||
@ -100,8 +104,6 @@ mod arg {
|
||||
pub(crate) const SHELL_COMMAND: &str = "SHELL-COMMAND";
|
||||
pub(crate) const UNSORTED: &str = "UNSORTED";
|
||||
pub(crate) const UNSTABLE: &str = "UNSTABLE";
|
||||
pub(crate) const DOTENV_FILENAME: &str = "DOTENV_FILENAME";
|
||||
pub(crate) const DOTENV_PATH: &str = "DOTENV_PATH";
|
||||
pub(crate) const VERBOSE: &str = "VERBOSE";
|
||||
pub(crate) const WORKING_DIRECTORY: &str = "WORKING-DIRECTORY";
|
||||
|
||||
@ -109,6 +111,10 @@ mod arg {
|
||||
pub(crate) const COLOR_AUTO: &str = "auto";
|
||||
pub(crate) const COLOR_NEVER: &str = "never";
|
||||
pub(crate) const COLOR_VALUES: &[&str] = &[COLOR_AUTO, COLOR_ALWAYS, COLOR_NEVER];
|
||||
|
||||
pub(crate) const DUMP_FORMAT_JSON: &str = "json";
|
||||
pub(crate) const DUMP_FORMAT_JUST: &str = "just";
|
||||
pub(crate) const DUMP_FORMAT_VALUES: &[&str] = &[DUMP_FORMAT_JUST, DUMP_FORMAT_JSON];
|
||||
}
|
||||
|
||||
impl Config {
|
||||
@ -144,6 +150,15 @@ impl Config {
|
||||
.help("Print what just would do without doing it")
|
||||
.conflicts_with(arg::QUIET),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(arg::DUMP_FORMAT)
|
||||
.long("dump-format")
|
||||
.takes_value(true)
|
||||
.possible_values(arg::DUMP_FORMAT_VALUES)
|
||||
.default_value(arg::DUMP_FORMAT_JUST)
|
||||
.value_name("FORMAT")
|
||||
.help("Dump justfile as <FORMAT>"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(arg::HIGHLIGHT)
|
||||
.long("highlight")
|
||||
@ -283,7 +298,7 @@ impl Config {
|
||||
.arg(
|
||||
Arg::with_name(cmd::DUMP)
|
||||
.long("dump")
|
||||
.help("Print entire justfile"),
|
||||
.help("Print justfile"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name(cmd::EDIT)
|
||||
@ -367,7 +382,13 @@ impl Config {
|
||||
}
|
||||
}
|
||||
|
||||
fn color_from_value(value: &str) -> ConfigResult<Color> {
|
||||
fn color_from_matches(matches: &ArgMatches) -> ConfigResult<Color> {
|
||||
let value = matches
|
||||
.value_of(arg::COLOR)
|
||||
.ok_or_else(|| ConfigError::Internal {
|
||||
message: "`--color` had no value".to_string(),
|
||||
})?;
|
||||
|
||||
match value {
|
||||
arg::COLOR_AUTO => Ok(Color::auto()),
|
||||
arg::COLOR_ALWAYS => Ok(Color::always()),
|
||||
@ -378,6 +399,22 @@ impl Config {
|
||||
}
|
||||
}
|
||||
|
||||
fn dump_format_from_matches(matches: &ArgMatches) -> ConfigResult<DumpFormat> {
|
||||
let value = matches
|
||||
.value_of(arg::DUMP_FORMAT)
|
||||
.ok_or_else(|| ConfigError::Internal {
|
||||
message: "`--dump-format` had no value".to_string(),
|
||||
})?;
|
||||
|
||||
match value {
|
||||
arg::DUMP_FORMAT_JSON => Ok(DumpFormat::Json),
|
||||
arg::DUMP_FORMAT_JUST => Ok(DumpFormat::Just),
|
||||
_ => Err(ConfigError::Internal {
|
||||
message: format!("Invalid argument `{}` to --dump-format.", value),
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn from_matches(matches: &ArgMatches) -> ConfigResult<Self> {
|
||||
let invocation_directory = env::current_dir().context(config_error::CurrentDir)?;
|
||||
|
||||
@ -387,11 +424,7 @@ impl Config {
|
||||
Verbosity::from_flag_occurrences(matches.occurrences_of(arg::VERBOSE))
|
||||
};
|
||||
|
||||
let color = Self::color_from_value(
|
||||
matches
|
||||
.value_of(arg::COLOR)
|
||||
.expect("`--color` had no value"),
|
||||
)?;
|
||||
let color = Self::color_from_matches(matches)?;
|
||||
|
||||
let set_count = matches.occurrences_of(arg::SET);
|
||||
let mut overrides = BTreeMap::new();
|
||||
@ -542,6 +575,7 @@ impl Config {
|
||||
Ok(Self {
|
||||
check: matches.is_present(arg::CHECK),
|
||||
dry_run: matches.is_present(arg::DRY_RUN),
|
||||
dump_format: Self::dump_format_from_matches(matches)?,
|
||||
highlight: !matches.is_present(arg::NO_HIGHLIGHT),
|
||||
shell: matches.value_of(arg::SHELL).unwrap().to_owned(),
|
||||
load_dotenv: !matches.is_present(arg::NO_DOTENV),
|
||||
@ -612,7 +646,7 @@ FLAGS:
|
||||
`fzf`
|
||||
--clear-shell-args Clear shell arguments
|
||||
--dry-run Print what just would do without doing it
|
||||
--dump Print entire justfile
|
||||
--dump Print justfile
|
||||
-e, --edit Edit justfile with editor given by $VISUAL or
|
||||
$EDITOR, falling back to `vim`
|
||||
--evaluate Evaluate and print all variables. If a variable
|
||||
@ -646,12 +680,15 @@ OPTIONS:
|
||||
--completions <SHELL>
|
||||
Print shell completion script for <SHELL> [possible values: zsh,
|
||||
bash, fish, powershell, elvish]
|
||||
--dotenv-filename <DOTENV_FILENAME>
|
||||
--dotenv-filename <DOTENV-FILENAME>
|
||||
Search for environment file named <DOTENV-FILENAME> instead of
|
||||
`.env`
|
||||
--dotenv-path <DOTENV_PATH>
|
||||
--dotenv-path <DOTENV-PATH>
|
||||
Load environment file at <DOTENV-PATH> instead of searching for one
|
||||
|
||||
--dump-format <FORMAT>
|
||||
Dump justfile as <FORMAT> [default: just] [possible values: just,
|
||||
json]
|
||||
-f, --justfile <JUSTFILE> Use <JUSTFILE> as justfile
|
||||
--list-heading <TEXT> Print <TEXT> before list
|
||||
--list-prefix <TEXT>
|
||||
@ -693,6 +730,7 @@ ARGS:
|
||||
args: [$($arg:expr),*],
|
||||
$(color: $color:expr,)?
|
||||
$(dry_run: $dry_run:expr,)?
|
||||
$(dump_format: $dump_format:expr,)?
|
||||
$(highlight: $highlight:expr,)?
|
||||
$(search_config: $search_config:expr,)?
|
||||
$(shell: $shell:expr,)?
|
||||
@ -712,6 +750,7 @@ ARGS:
|
||||
let want = Config {
|
||||
$(color: $color,)?
|
||||
$(dry_run: $dry_run,)?
|
||||
$(dump_format: $dump_format,)?
|
||||
$(highlight: $highlight,)?
|
||||
$(search_config: $search_config,)?
|
||||
$(shell: $shell.to_owned(),)?
|
||||
@ -1101,6 +1140,12 @@ ARGS:
|
||||
subcommand: Subcommand::Dump,
|
||||
}
|
||||
|
||||
test! {
|
||||
name: dump_format,
|
||||
args: ["--dump-format", "json"],
|
||||
dump_format: DumpFormat::Json,
|
||||
}
|
||||
|
||||
test! {
|
||||
name: subcommand_edit,
|
||||
args: ["--edit"],
|
||||
|
@ -1,9 +1,10 @@
|
||||
use crate::common::*;
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
#[derive(PartialEq, Debug, Serialize)]
|
||||
pub(crate) struct Dependency<'src> {
|
||||
pub(crate) recipe: Rc<Recipe<'src>>,
|
||||
pub(crate) arguments: Vec<Expression<'src>>,
|
||||
#[serde(serialize_with = "keyed::serialize")]
|
||||
pub(crate) recipe: Rc<Recipe<'src>>,
|
||||
}
|
||||
|
||||
impl<'src> Display for Dependency<'src> {
|
||||
|
5
src/dump_format.rs
Normal file
5
src/dump_format.rs
Normal file
@ -0,0 +1,5 @@
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub(crate) enum DumpFormat {
|
||||
Json,
|
||||
Just,
|
||||
}
|
@ -63,6 +63,9 @@ pub(crate) enum Error<'src> {
|
||||
Dotenv {
|
||||
dotenv_error: dotenv::Error,
|
||||
},
|
||||
DumpJson {
|
||||
serde_json_error: serde_json::Error,
|
||||
},
|
||||
EditorInvoke {
|
||||
editor: OsString,
|
||||
io_error: io::Error,
|
||||
@ -434,6 +437,9 @@ impl<'src> ColorDisplay for Error<'src> {
|
||||
Dotenv { dotenv_error } => {
|
||||
write!(f, "Failed to load environment file: {}", dotenv_error)?;
|
||||
}
|
||||
DumpJson { serde_json_error } => {
|
||||
write!(f, "Failed to dump JSON to stdout: {}", serde_json_error)?;
|
||||
}
|
||||
EditorInvoke { editor, io_error } => {
|
||||
write!(
|
||||
f,
|
||||
|
@ -65,3 +65,51 @@ impl<'src> Display for Expression<'src> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'src> Serialize for Expression<'src> {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
match self {
|
||||
Self::Backtick { contents, .. } => {
|
||||
let mut seq = serializer.serialize_seq(None)?;
|
||||
seq.serialize_element("evaluate")?;
|
||||
seq.serialize_element(contents)?;
|
||||
seq.end()
|
||||
}
|
||||
Self::Call { thunk } => thunk.serialize(serializer),
|
||||
Self::Concatination { lhs, rhs } => {
|
||||
let mut seq = serializer.serialize_seq(None)?;
|
||||
seq.serialize_element("concatinate")?;
|
||||
seq.serialize_element(lhs)?;
|
||||
seq.serialize_element(rhs)?;
|
||||
seq.end()
|
||||
}
|
||||
Self::Conditional {
|
||||
lhs,
|
||||
rhs,
|
||||
then,
|
||||
otherwise,
|
||||
operator,
|
||||
} => {
|
||||
let mut seq = serializer.serialize_seq(None)?;
|
||||
seq.serialize_element("if")?;
|
||||
seq.serialize_element(&operator.to_string())?;
|
||||
seq.serialize_element(lhs)?;
|
||||
seq.serialize_element(rhs)?;
|
||||
seq.serialize_element(then)?;
|
||||
seq.serialize_element(otherwise)?;
|
||||
seq.end()
|
||||
}
|
||||
Self::Group { contents } => contents.serialize(serializer),
|
||||
Self::StringLiteral { string_literal } => string_literal.serialize(serializer),
|
||||
Self::Variable { name } => {
|
||||
let mut seq = serializer.serialize_seq(None)?;
|
||||
seq.serialize_element("variable")?;
|
||||
seq.serialize_element(name)?;
|
||||
seq.end()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,3 +8,19 @@ pub(crate) enum Fragment<'src> {
|
||||
/// …an interpolation containing `expression`.
|
||||
Interpolation { expression: Expression<'src> },
|
||||
}
|
||||
|
||||
impl<'src> Serialize for Fragment<'src> {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
match self {
|
||||
Self::Text { token } => serializer.serialize_str(token.lexeme()),
|
||||
Self::Interpolation { expression } => {
|
||||
let mut seq = serializer.serialize_seq(None)?;
|
||||
seq.serialize_element(expression)?;
|
||||
seq.end()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,29 +1,19 @@
|
||||
use crate::common::*;
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
use serde::Serialize;
|
||||
|
||||
#[derive(Debug, PartialEq, Serialize)]
|
||||
pub(crate) struct Justfile<'src> {
|
||||
pub(crate) recipes: Table<'src, Rc<Recipe<'src>>>,
|
||||
pub(crate) assignments: Table<'src, Assignment<'src>>,
|
||||
pub(crate) aliases: Table<'src, Alias<'src>>,
|
||||
pub(crate) assignments: Table<'src, Assignment<'src>>,
|
||||
#[serde(serialize_with = "keyed::serialize_option")]
|
||||
pub(crate) first: Option<Rc<Recipe<'src>>>,
|
||||
pub(crate) recipes: Table<'src, Rc<Recipe<'src>>>,
|
||||
pub(crate) settings: Settings<'src>,
|
||||
pub(crate) warnings: Vec<Warning>,
|
||||
}
|
||||
|
||||
impl<'src> Justfile<'src> {
|
||||
pub(crate) fn first(&self) -> Option<&Recipe<'src>> {
|
||||
let mut first: Option<&Recipe<Dependency>> = None;
|
||||
for recipe in self.recipes.values() {
|
||||
if let Some(first_recipe) = first {
|
||||
if recipe.line_number() < first_recipe.line_number() {
|
||||
first = Some(recipe);
|
||||
}
|
||||
} else {
|
||||
first = Some(recipe);
|
||||
}
|
||||
}
|
||||
first
|
||||
}
|
||||
|
||||
pub(crate) fn count(&self) -> usize {
|
||||
self.recipes.len()
|
||||
}
|
||||
@ -206,7 +196,7 @@ impl<'src> Justfile<'src> {
|
||||
|
||||
let argvec: Vec<&str> = if !arguments.is_empty() {
|
||||
arguments.iter().map(String::as_str).collect()
|
||||
} else if let Some(recipe) = self.first() {
|
||||
} else if let Some(recipe) = &self.first {
|
||||
let min_arguments = recipe.min_arguments();
|
||||
if min_arguments > 0 {
|
||||
return Err(Error::DefaultRecipeRequiresArguments {
|
||||
|
22
src/keyed.rs
22
src/keyed.rs
@ -9,3 +9,25 @@ impl<'key, T: Keyed<'key>> Keyed<'key> for Rc<T> {
|
||||
self.as_ref().key()
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn serialize<'src, S, K>(keyed: &K, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
K: Keyed<'src>,
|
||||
{
|
||||
serializer.serialize_str(&keyed.key())
|
||||
}
|
||||
|
||||
pub(crate) fn serialize_option<'src, S, K>(
|
||||
recipe: &Option<K>,
|
||||
serializer: S,
|
||||
) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
K: Keyed<'src>,
|
||||
{
|
||||
match recipe {
|
||||
None => serializer.serialize_none(),
|
||||
Some(keyed) => serialize(keyed, serializer),
|
||||
}
|
||||
}
|
||||
|
25
src/lib.rs
25
src/lib.rs
@ -12,6 +12,12 @@
|
||||
clippy::wildcard_imports
|
||||
)]
|
||||
|
||||
pub use crate::run::run;
|
||||
|
||||
// Used in integration tests.
|
||||
#[doc(hidden)]
|
||||
pub use unindent::unindent;
|
||||
|
||||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
|
||||
@ -29,6 +35,12 @@ pub mod node;
|
||||
#[cfg(fuzzing)]
|
||||
pub(crate) mod fuzzing;
|
||||
|
||||
// Used by Janus, https://github.com/casey/janus, a tool
|
||||
// that analyses all public justfiles on GitHub to avoid
|
||||
// breaking changes.
|
||||
#[doc(hidden)]
|
||||
pub mod summary;
|
||||
|
||||
mod alias;
|
||||
mod analyzer;
|
||||
mod assignment;
|
||||
@ -49,6 +61,7 @@ mod config_error;
|
||||
mod count;
|
||||
mod delimiter;
|
||||
mod dependency;
|
||||
mod dump_format;
|
||||
mod enclosure;
|
||||
mod error;
|
||||
mod evaluator;
|
||||
@ -107,15 +120,3 @@ mod use_color;
|
||||
mod variables;
|
||||
mod verbosity;
|
||||
mod warning;
|
||||
|
||||
pub use crate::run::run;
|
||||
|
||||
// Used in integration tests.
|
||||
#[doc(hidden)]
|
||||
pub use unindent::unindent;
|
||||
|
||||
// Used by Janus, https://github.com/casey/janus, a tool
|
||||
// that analyses all public justfiles on GitHub to avoid
|
||||
// breaking changes.
|
||||
#[doc(hidden)]
|
||||
pub mod summary;
|
||||
|
@ -1,7 +1,8 @@
|
||||
use crate::common::*;
|
||||
|
||||
/// A single line in a recipe body, consisting of any number of `Fragment`s.
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[derive(Debug, Clone, PartialEq, Serialize)]
|
||||
#[serde(transparent)]
|
||||
pub(crate) struct Line<'src> {
|
||||
pub(crate) fragments: Vec<Fragment<'src>>,
|
||||
}
|
||||
|
@ -50,3 +50,12 @@ impl Display for Name<'_> {
|
||||
write!(f, "{}", self.lexeme())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'src> Serialize for Name<'src> {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
serializer.serialize_str(&self.lexeme())
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +1,16 @@
|
||||
use crate::common::*;
|
||||
|
||||
/// A single function parameter
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
#[derive(PartialEq, Debug, Clone, Serialize)]
|
||||
pub(crate) struct Parameter<'src> {
|
||||
/// The parameter name
|
||||
pub(crate) name: Name<'src>,
|
||||
/// The kind of parameter
|
||||
pub(crate) kind: ParameterKind,
|
||||
/// An optional default expression
|
||||
pub(crate) default: Option<Expression<'src>>,
|
||||
/// Export parameter as environment variable
|
||||
pub(crate) export: bool,
|
||||
/// The kind of parameter
|
||||
pub(crate) kind: ParameterKind,
|
||||
/// The parameter name
|
||||
pub(crate) name: Name<'src>,
|
||||
}
|
||||
|
||||
impl<'src> ColorDisplay for Parameter<'src> {
|
||||
|
@ -1,7 +1,8 @@
|
||||
use crate::common::*;
|
||||
|
||||
/// Parameters can either be…
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq, Serialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub(crate) enum ParameterKind {
|
||||
/// …singular, accepting a single argument
|
||||
Singular,
|
||||
|
@ -19,17 +19,17 @@ fn error_from_signal(recipe: &str, line_number: Option<usize>, exit_status: Exit
|
||||
}
|
||||
|
||||
/// A recipe, e.g. `foo: bar baz`
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
#[derive(PartialEq, Debug, Clone, Serialize)]
|
||||
pub(crate) struct Recipe<'src, D = Dependency<'src>> {
|
||||
pub(crate) body: Vec<Line<'src>>,
|
||||
pub(crate) dependencies: Vec<D>,
|
||||
pub(crate) doc: Option<&'src str>,
|
||||
pub(crate) name: Name<'src>,
|
||||
pub(crate) parameters: Vec<Parameter<'src>>,
|
||||
pub(crate) priors: usize,
|
||||
pub(crate) private: bool,
|
||||
pub(crate) quiet: bool,
|
||||
pub(crate) shebang: bool,
|
||||
pub(crate) priors: usize,
|
||||
}
|
||||
|
||||
impl<'src, D> Recipe<'src, D> {
|
||||
@ -302,12 +302,6 @@ impl<'src, D> Recipe<'src, D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'src, D> Keyed<'src> for Recipe<'src, D> {
|
||||
fn key(&self) -> &'src str {
|
||||
self.name.lexeme()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'src, D: Display> ColorDisplay for Recipe<'src, D> {
|
||||
fn fmt(&self, f: &mut Formatter, color: Color) -> Result<(), fmt::Error> {
|
||||
if let Some(doc) = self.doc {
|
||||
@ -353,3 +347,9 @@ impl<'src, D: Display> ColorDisplay for Recipe<'src, D> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'src, D> Keyed<'src> for Recipe<'src, D> {
|
||||
fn key(&self) -> &'src str {
|
||||
self.name.lexeme()
|
||||
}
|
||||
}
|
||||
|
@ -8,10 +8,10 @@ pub(crate) enum Setting<'src> {
|
||||
Shell(Shell<'src>),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[derive(Debug, Clone, PartialEq, Serialize)]
|
||||
pub(crate) struct Shell<'src> {
|
||||
pub(crate) command: StringLiteral<'src>,
|
||||
pub(crate) arguments: Vec<StringLiteral<'src>>,
|
||||
pub(crate) command: StringLiteral<'src>,
|
||||
}
|
||||
|
||||
impl<'src> Display for Setting<'src> {
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::common::*;
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
#[derive(Debug, PartialEq, Serialize)]
|
||||
pub(crate) struct Settings<'src> {
|
||||
pub(crate) dotenv_load: Option<bool>,
|
||||
pub(crate) export: bool,
|
||||
|
@ -18,3 +18,12 @@ impl Display for StringLiteral<'_> {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'src> Serialize for StringLiteral<'src> {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
serializer.serialize_str(&self.cooked)
|
||||
}
|
||||
}
|
||||
|
@ -76,7 +76,7 @@ impl Subcommand {
|
||||
Command { overrides, .. } | Evaluate { overrides, .. } => {
|
||||
justfile.run(config, &search, overrides, &[])?
|
||||
}
|
||||
Dump => Self::dump(ast),
|
||||
Dump => Self::dump(config, ast, justfile)?,
|
||||
Format => Self::format(config, &search, &src, ast)?,
|
||||
List => Self::list(config, justfile),
|
||||
Run {
|
||||
@ -229,8 +229,17 @@ impl Subcommand {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn dump(ast: Ast) {
|
||||
print!("{}", ast);
|
||||
fn dump(config: &Config, ast: Ast, justfile: Justfile) -> Result<(), Error<'static>> {
|
||||
match config.dump_format {
|
||||
DumpFormat::Json => {
|
||||
config.require_unstable("The JSON dump format is currently unstable.")?;
|
||||
serde_json::to_writer(io::stdout(), &justfile)
|
||||
.map_err(|serde_json_error| Error::DumpJson { serde_json_error })?;
|
||||
println!();
|
||||
}
|
||||
DumpFormat::Just => print!("{}", ast),
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn edit(search: &Search) -> Result<(), Error<'static>> {
|
||||
|
@ -2,7 +2,8 @@ use crate::common::*;
|
||||
|
||||
use std::collections::btree_map;
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
#[derive(Debug, PartialEq, Serialize)]
|
||||
#[serde(transparent)]
|
||||
pub(crate) struct Table<'key, V: Keyed<'key>> {
|
||||
map: BTreeMap<&'key str, V>,
|
||||
}
|
||||
|
41
src/thunk.rs
41
src/thunk.rs
@ -35,6 +35,16 @@ pub(crate) enum Thunk<'src> {
|
||||
}
|
||||
|
||||
impl<'src> Thunk<'src> {
|
||||
fn name(&self) -> &Name<'src> {
|
||||
match self {
|
||||
Self::Nullary { name, .. }
|
||||
| Self::Unary { name, .. }
|
||||
| Self::Binary { name, .. }
|
||||
| Self::BinaryPlus { name, .. }
|
||||
| Self::Ternary { name, .. } => name,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn resolve(
|
||||
name: Name<'src>,
|
||||
mut arguments: Vec<Expression<'src>>,
|
||||
@ -120,3 +130,34 @@ impl Display for Thunk<'_> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'src> Serialize for Thunk<'src> {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
let mut seq = serializer.serialize_seq(None)?;
|
||||
seq.serialize_element("call")?;
|
||||
seq.serialize_element(self.name())?;
|
||||
match self {
|
||||
Self::Nullary { .. } => {}
|
||||
Self::Unary { arg, .. } => seq.serialize_element(&arg)?,
|
||||
Self::Binary { args, .. } => {
|
||||
for arg in args {
|
||||
seq.serialize_element(arg)?;
|
||||
}
|
||||
}
|
||||
Self::BinaryPlus { args, .. } => {
|
||||
for arg in args.0.iter().map(Box::as_ref).chain(&args.1) {
|
||||
seq.serialize_element(arg)?;
|
||||
}
|
||||
}
|
||||
Self::Ternary { args, .. } => {
|
||||
for arg in args {
|
||||
seq.serialize_element(arg)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
seq.end()
|
||||
}
|
||||
}
|
||||
|
@ -54,3 +54,16 @@ See https://github.com/casey/just/issues/469 for more details.")?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for Warning {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
let mut map = serializer.serialize_map(None)?;
|
||||
|
||||
map.serialize_entry("message", &self.color_display(Color::never()).to_string())?;
|
||||
|
||||
map.end()
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ test! {
|
||||
error: The argument '--command <COMMAND>' requires a value but none was supplied
|
||||
|
||||
USAGE:
|
||||
just{} --color <COLOR> --shell <SHELL> --shell-arg <SHELL-ARG>... \
|
||||
just{} --color <COLOR> --dump-format <FORMAT> --shell <SHELL> --shell-arg <SHELL-ARG>... \
|
||||
<--changelog|--choose|--command <COMMAND>|--completions <SHELL>|--dump|--edit|\
|
||||
--evaluate|--fmt|--init|--list|--show <RECIPE>|--summary|--variables>
|
||||
|
||||
|
@ -11,16 +11,19 @@ pub(crate) use std::{
|
||||
str,
|
||||
};
|
||||
|
||||
pub(crate) use cradle::input::Input;
|
||||
pub(crate) use executable_path::executable_path;
|
||||
pub(crate) use just::unindent;
|
||||
pub(crate) use libc::{EXIT_FAILURE, EXIT_SUCCESS};
|
||||
pub(crate) use pretty_assertions::Comparison;
|
||||
pub(crate) use regex::Regex;
|
||||
pub(crate) use tempfile::TempDir;
|
||||
pub(crate) use temptree::{temptree, tree, Tree};
|
||||
pub(crate) use which::which;
|
||||
pub(crate) use yaml_rust::YamlLoader;
|
||||
pub(crate) use ::{
|
||||
cradle::input::Input,
|
||||
executable_path::executable_path,
|
||||
just::unindent,
|
||||
libc::{EXIT_FAILURE, EXIT_SUCCESS},
|
||||
pretty_assertions::Comparison,
|
||||
regex::Regex,
|
||||
serde_json::{json, Value},
|
||||
tempfile::TempDir,
|
||||
temptree::{temptree, tree, Tree},
|
||||
which::which,
|
||||
yaml_rust::YamlLoader,
|
||||
};
|
||||
|
||||
pub(crate) use crate::{
|
||||
assert_stdout::assert_stdout, assert_success::assert_success, tempdir::tempdir, test::Test,
|
||||
|
683
tests/json.rs
Normal file
683
tests/json.rs
Normal file
@ -0,0 +1,683 @@
|
||||
use crate::common::*;
|
||||
|
||||
fn test(justfile: &str, value: Value) {
|
||||
Test::new()
|
||||
.justfile(justfile)
|
||||
.args(&["--dump", "--dump-format", "json", "--unstable"])
|
||||
.stdout(format!("{}\n", serde_json::to_string(&value).unwrap()))
|
||||
.run();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn alias() {
|
||||
test(
|
||||
"
|
||||
alias f := foo
|
||||
|
||||
foo:
|
||||
",
|
||||
json!({
|
||||
"first": "foo",
|
||||
"aliases": {
|
||||
"f": {
|
||||
"name": "f",
|
||||
"target": "foo",
|
||||
}
|
||||
},
|
||||
"assignments": {},
|
||||
"recipes": {
|
||||
"foo": {
|
||||
"body": [],
|
||||
"dependencies": [],
|
||||
"doc": null,
|
||||
"name": "foo",
|
||||
"parameters": [],
|
||||
"priors": 0,
|
||||
"private": false,
|
||||
"quiet": false,
|
||||
"shebang": false,
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"dotenv_load": null,
|
||||
"export": false,
|
||||
"positional_arguments": false,
|
||||
"shell": null,
|
||||
},
|
||||
"warnings": [],
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn assignment() {
|
||||
test(
|
||||
"foo := 'bar'",
|
||||
json!({
|
||||
"aliases": {},
|
||||
"assignments": {
|
||||
"foo": {
|
||||
"export": false,
|
||||
"name": "foo",
|
||||
"value": "bar",
|
||||
}
|
||||
},
|
||||
"first": null,
|
||||
"recipes": {},
|
||||
"settings": {
|
||||
"dotenv_load": null,
|
||||
"export": false,
|
||||
"positional_arguments": false,
|
||||
"shell": null,
|
||||
},
|
||||
"warnings": [],
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn body() {
|
||||
test(
|
||||
"
|
||||
foo:
|
||||
bar
|
||||
abc{{ 'xyz' }}def
|
||||
",
|
||||
json!({
|
||||
"aliases": {},
|
||||
"assignments": {},
|
||||
"first": "foo",
|
||||
"recipes": {
|
||||
"foo": {
|
||||
"body": [
|
||||
["bar"],
|
||||
["abc", ["xyz"], "def"],
|
||||
],
|
||||
"dependencies": [],
|
||||
"doc": null,
|
||||
"name": "foo",
|
||||
"parameters": [],
|
||||
"priors": 0,
|
||||
"private": false,
|
||||
"quiet": false,
|
||||
"shebang": false,
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"dotenv_load": null,
|
||||
"export": false,
|
||||
"positional_arguments": false,
|
||||
"shell": null,
|
||||
},
|
||||
"warnings": [],
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dependencies() {
|
||||
test(
|
||||
"
|
||||
foo:
|
||||
bar: foo
|
||||
",
|
||||
json!({
|
||||
"aliases": {},
|
||||
"assignments": {},
|
||||
"first": "foo",
|
||||
"recipes": {
|
||||
"bar": {
|
||||
"doc": null,
|
||||
"name": "bar",
|
||||
"body": [],
|
||||
"dependencies": [{
|
||||
"arguments": [],
|
||||
"recipe": "foo"
|
||||
}],
|
||||
"parameters": [],
|
||||
"priors": 1,
|
||||
"private": false,
|
||||
"quiet": false,
|
||||
"shebang": false,
|
||||
},
|
||||
"foo": {
|
||||
"body": [],
|
||||
"dependencies": [],
|
||||
"doc": null,
|
||||
"name": "foo",
|
||||
"parameters": [],
|
||||
"priors": 0,
|
||||
"private": false,
|
||||
"quiet": false,
|
||||
"shebang": false,
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"dotenv_load": null,
|
||||
"export": false,
|
||||
"positional_arguments": false,
|
||||
"shell": null,
|
||||
},
|
||||
"warnings": [],
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dependency_argument() {
|
||||
test(
|
||||
"
|
||||
x := 'foo'
|
||||
foo *args:
|
||||
bar: (
|
||||
foo
|
||||
'baz'
|
||||
('baz')
|
||||
('a' + 'b')
|
||||
`echo`
|
||||
x
|
||||
if 'a' == 'b' { 'c' } else { 'd' }
|
||||
arch()
|
||||
env_var('foo')
|
||||
join('a', 'b')
|
||||
replace('a', 'b', 'c')
|
||||
)
|
||||
",
|
||||
json!({
|
||||
"aliases": {},
|
||||
"first": "foo",
|
||||
"assignments": {
|
||||
"x": {
|
||||
"export": false,
|
||||
"name": "x",
|
||||
"value": "foo",
|
||||
},
|
||||
},
|
||||
"recipes": {
|
||||
"bar": {
|
||||
"doc": null,
|
||||
"name": "bar",
|
||||
"body": [],
|
||||
"dependencies": [{
|
||||
"arguments": [
|
||||
"baz",
|
||||
"baz",
|
||||
["concatinate", "a", "b"],
|
||||
["evaluate", "echo"],
|
||||
["variable", "x"],
|
||||
["if", "==", "a", "b", "c", "d"],
|
||||
["call", "arch"],
|
||||
["call", "env_var", "foo"],
|
||||
["call", "join", "a", "b"],
|
||||
["call", "replace", "a", "b", "c"],
|
||||
],
|
||||
"recipe": "foo"
|
||||
}],
|
||||
"parameters": [],
|
||||
"priors": 1,
|
||||
"private": false,
|
||||
"quiet": false,
|
||||
"shebang": false,
|
||||
},
|
||||
"foo": {
|
||||
"body": [],
|
||||
"dependencies": [],
|
||||
"doc": null,
|
||||
"name": "foo",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "args",
|
||||
"export": false,
|
||||
"default": null,
|
||||
"kind": "star",
|
||||
}
|
||||
],
|
||||
"priors": 0,
|
||||
"private": false,
|
||||
"quiet": false,
|
||||
"shebang": false,
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"dotenv_load": null,
|
||||
"export": false,
|
||||
"positional_arguments": false,
|
||||
"shell": null,
|
||||
},
|
||||
"warnings": [],
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn doc_comment() {
|
||||
test(
|
||||
"# hello\nfoo:",
|
||||
json!({
|
||||
"aliases": {},
|
||||
"first": "foo",
|
||||
"assignments": {},
|
||||
"recipes": {
|
||||
"foo": {
|
||||
"body": [],
|
||||
"dependencies": [],
|
||||
"doc": "hello",
|
||||
"name": "foo",
|
||||
"parameters": [],
|
||||
"priors": 0,
|
||||
"private": false,
|
||||
"quiet": false,
|
||||
"shebang": false,
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"dotenv_load": null,
|
||||
"export": false,
|
||||
"positional_arguments": false,
|
||||
"shell": null,
|
||||
},
|
||||
"warnings": [],
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn empty_justfile() {
|
||||
test(
|
||||
"",
|
||||
json!({
|
||||
"aliases": {},
|
||||
"assignments": {},
|
||||
"first": null,
|
||||
"recipes": {},
|
||||
"settings": {
|
||||
"dotenv_load": null,
|
||||
"export": false,
|
||||
"positional_arguments": false,
|
||||
"shell": null,
|
||||
},
|
||||
"warnings": [],
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parameters() {
|
||||
test(
|
||||
"
|
||||
a:
|
||||
b x:
|
||||
c x='y':
|
||||
d +x:
|
||||
e *x:
|
||||
f $x:
|
||||
",
|
||||
json!({
|
||||
"aliases": {},
|
||||
"first": "a",
|
||||
"assignments": {},
|
||||
"recipes": {
|
||||
"a": {
|
||||
"body": [],
|
||||
"dependencies": [],
|
||||
"doc": null,
|
||||
"name": "a",
|
||||
"parameters": [],
|
||||
"priors": 0,
|
||||
"private": false,
|
||||
"quiet": false,
|
||||
"shebang": false,
|
||||
},
|
||||
"b": {
|
||||
"body": [],
|
||||
"dependencies": [],
|
||||
"doc": null,
|
||||
"name": "b",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "x",
|
||||
"export": false,
|
||||
"default": null,
|
||||
"kind": "singular",
|
||||
},
|
||||
],
|
||||
"priors": 0,
|
||||
"private": false,
|
||||
"quiet": false,
|
||||
"shebang": false,
|
||||
},
|
||||
"c": {
|
||||
"body": [],
|
||||
"dependencies": [],
|
||||
"doc": null,
|
||||
"name": "c",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "x",
|
||||
"export": false,
|
||||
"default": "y",
|
||||
"kind": "singular",
|
||||
}
|
||||
],
|
||||
"priors": 0,
|
||||
"private": false,
|
||||
"quiet": false,
|
||||
"shebang": false,
|
||||
},
|
||||
"d": {
|
||||
"body": [],
|
||||
"dependencies": [],
|
||||
"doc": null,
|
||||
"name": "d",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "x",
|
||||
"export": false,
|
||||
"default": null,
|
||||
"kind": "plus",
|
||||
}
|
||||
],
|
||||
"priors": 0,
|
||||
"private": false,
|
||||
"quiet": false,
|
||||
"shebang": false,
|
||||
},
|
||||
"e": {
|
||||
"body": [],
|
||||
"dependencies": [],
|
||||
"doc": null,
|
||||
"name": "e",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "x",
|
||||
"export": false,
|
||||
"default": null,
|
||||
"kind": "star",
|
||||
}
|
||||
],
|
||||
"priors": 0,
|
||||
"private": false,
|
||||
"quiet": false,
|
||||
"shebang": false,
|
||||
},
|
||||
"f": {
|
||||
"body": [],
|
||||
"dependencies": [],
|
||||
"doc": null,
|
||||
"name": "f",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "x",
|
||||
"export": true,
|
||||
"default": null,
|
||||
"kind": "singular",
|
||||
}
|
||||
],
|
||||
"priors": 0,
|
||||
"private": false,
|
||||
"quiet": false,
|
||||
"shebang": false,
|
||||
},
|
||||
},
|
||||
"settings": {
|
||||
"dotenv_load": null,
|
||||
"export": false,
|
||||
"positional_arguments": false,
|
||||
"shell": null,
|
||||
},
|
||||
"warnings": [],
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn priors() {
|
||||
test(
|
||||
"
|
||||
a:
|
||||
b: a && c
|
||||
c:
|
||||
",
|
||||
json!({
|
||||
"aliases": {},
|
||||
"assignments": {},
|
||||
"first": "a",
|
||||
"recipes": {
|
||||
"a": {
|
||||
"body": [],
|
||||
"dependencies": [],
|
||||
"doc": null,
|
||||
"name": "a",
|
||||
"parameters": [],
|
||||
"priors": 0,
|
||||
"private": false,
|
||||
"quiet": false,
|
||||
"shebang": false,
|
||||
},
|
||||
"b": {
|
||||
"body": [],
|
||||
"dependencies": [
|
||||
{
|
||||
"arguments": [],
|
||||
"recipe": "a",
|
||||
},
|
||||
{
|
||||
"arguments": [],
|
||||
"recipe": "c",
|
||||
}
|
||||
],
|
||||
"doc": null,
|
||||
"name": "b",
|
||||
"private": false,
|
||||
"quiet": false,
|
||||
"shebang": false,
|
||||
"parameters": [],
|
||||
"priors": 1,
|
||||
},
|
||||
"c": {
|
||||
"body": [],
|
||||
"dependencies": [],
|
||||
"doc": null,
|
||||
"name": "c",
|
||||
"parameters": [],
|
||||
"private": false,
|
||||
"quiet": false,
|
||||
"shebang": false,
|
||||
"parameters": [],
|
||||
"priors": 0,
|
||||
},
|
||||
},
|
||||
"settings": {
|
||||
"dotenv_load": null,
|
||||
"export": false,
|
||||
"positional_arguments": false,
|
||||
"shell": null,
|
||||
},
|
||||
"warnings": [],
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn private() {
|
||||
test(
|
||||
"_foo:",
|
||||
json!({
|
||||
"aliases": {},
|
||||
"assignments": {},
|
||||
"first": "_foo",
|
||||
"recipes": {
|
||||
"_foo": {
|
||||
"body": [],
|
||||
"dependencies": [],
|
||||
"doc": null,
|
||||
"name": "_foo",
|
||||
"parameters": [],
|
||||
"priors": 0,
|
||||
"private": true,
|
||||
"quiet": false,
|
||||
"shebang": false,
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"dotenv_load": null,
|
||||
"export": false,
|
||||
"positional_arguments": false,
|
||||
"shell": null,
|
||||
},
|
||||
"warnings": [],
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn quiet() {
|
||||
test(
|
||||
"@foo:",
|
||||
json!({
|
||||
"aliases": {},
|
||||
"assignments": {},
|
||||
"first": "foo",
|
||||
"recipes": {
|
||||
"foo": {
|
||||
"body": [],
|
||||
"dependencies": [],
|
||||
"doc": null,
|
||||
"name": "foo",
|
||||
"parameters": [],
|
||||
"priors": 0,
|
||||
"private": false,
|
||||
"quiet": true,
|
||||
"shebang": false,
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"dotenv_load": null,
|
||||
"export": false,
|
||||
"positional_arguments": false,
|
||||
"shell": null,
|
||||
},
|
||||
"warnings": [],
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn requires_unstable() {
|
||||
Test::new()
|
||||
.justfile("foo:")
|
||||
.args(&["--dump", "--dump-format", "json"])
|
||||
.stderr("error: The JSON dump format is currently unstable. Invoke `just` with the `--unstable` flag to enable unstable features.\n")
|
||||
.status(EXIT_FAILURE)
|
||||
.run();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn settings() {
|
||||
test(
|
||||
"
|
||||
set dotenv-load
|
||||
set export
|
||||
set positional-arguments
|
||||
set shell := ['a', 'b', 'c']
|
||||
|
||||
foo:
|
||||
#!bar
|
||||
",
|
||||
json!({
|
||||
"aliases": {},
|
||||
"assignments": {},
|
||||
"first": "foo",
|
||||
"recipes": {
|
||||
"foo": {
|
||||
"body": [["#!bar"]],
|
||||
"dependencies": [],
|
||||
"doc": null,
|
||||
"name": "foo",
|
||||
"parameters": [],
|
||||
"priors": 0,
|
||||
"private": false,
|
||||
"quiet": false,
|
||||
"shebang": true,
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"dotenv_load": true,
|
||||
"export": true,
|
||||
"positional_arguments": true,
|
||||
"shell": {
|
||||
"arguments": ["b", "c"],
|
||||
"command": "a",
|
||||
},
|
||||
},
|
||||
"warnings": [],
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shebang() {
|
||||
test(
|
||||
"
|
||||
foo:
|
||||
#!bar
|
||||
",
|
||||
json!({
|
||||
"aliases": {},
|
||||
"assignments": {},
|
||||
"first": "foo",
|
||||
"recipes": {
|
||||
"foo": {
|
||||
"body": [["#!bar"]],
|
||||
"dependencies": [],
|
||||
"doc": null,
|
||||
"name": "foo",
|
||||
"parameters": [],
|
||||
"priors": 0,
|
||||
"private": false,
|
||||
"quiet": false,
|
||||
"shebang": true,
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"dotenv_load": null,
|
||||
"export": false,
|
||||
"positional_arguments": false,
|
||||
"shell": null,
|
||||
},
|
||||
"warnings": [],
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn simple() {
|
||||
test(
|
||||
"foo:",
|
||||
json!({
|
||||
"aliases": {},
|
||||
"assignments": {},
|
||||
"first": "foo",
|
||||
"recipes": {
|
||||
"foo": {
|
||||
"body": [],
|
||||
"dependencies": [],
|
||||
"doc": null,
|
||||
"name": "foo",
|
||||
"parameters": [],
|
||||
"priors": 0,
|
||||
"private": false,
|
||||
"quiet": false,
|
||||
"shebang": false,
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"dotenv_load": null,
|
||||
"export": false,
|
||||
"positional_arguments": false,
|
||||
"shell": null,
|
||||
},
|
||||
"warnings": [],
|
||||
}),
|
||||
);
|
||||
}
|
@ -23,6 +23,7 @@ mod functions;
|
||||
mod init;
|
||||
mod interrupts;
|
||||
mod invocation_directory;
|
||||
mod json;
|
||||
mod misc;
|
||||
mod positional_arguments;
|
||||
mod quiet;
|
||||
|
Loading…
Reference in New Issue
Block a user