Compare commits
No commits in common. "ba89f94e7ec4102202562caea188c515f8dab8bb" and "458805e2834c9436aa558d5cca62bba74caf4bc8" have entirely different histories.
ba89f94e7e
...
458805e283
17
CHANGELOG.md
17
CHANGELOG.md
@ -1,23 +1,6 @@
|
|||||||
Changelog
|
Changelog
|
||||||
=========
|
=========
|
||||||
|
|
||||||
[1.31.0](https://github.com/casey/just/releases/tag/1.31.0) - 2024-07-14
|
|
||||||
------------------------------------------------------------------------
|
|
||||||
|
|
||||||
### Stabilized
|
|
||||||
- Stabilize modules ([#2250](https://github.com/casey/just/pull/2250) by [casey](https://github.com/casey))
|
|
||||||
|
|
||||||
### Added
|
|
||||||
- Allow `mod` path to be directory containing module source ([#2238](https://github.com/casey/just/pull/2238) by [casey](https://github.com/casey))
|
|
||||||
- Allow enabling unstable features with `set unstable` ([#2237](https://github.com/casey/just/pull/2237) by [casey](https://github.com/casey))
|
|
||||||
- Allow abbreviating functions ending in `_directory` to `_dir` ([#2235](https://github.com/casey/just/pull/2235) by [casey](https://github.com/casey))
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
- Lexiclean search directory so `..` does not check the current directory ([#2236](https://github.com/casey/just/pull/2236) by [casey](https://github.com/casey))
|
|
||||||
|
|
||||||
### Misc
|
|
||||||
- Print space before submodules in `--list` with groups ([#2244](https://github.com/casey/just/pull/2244) by [casey](https://github.com/casey))
|
|
||||||
|
|
||||||
[1.30.1](https://github.com/casey/just/releases/tag/1.30.1) - 2024-07-06
|
[1.30.1](https://github.com/casey/just/releases/tag/1.30.1) - 2024-07-06
|
||||||
------------------------------------------------------------------------
|
------------------------------------------------------------------------
|
||||||
|
|
||||||
|
78
Cargo.lock
generated
78
Cargo.lock
generated
@ -127,9 +127,9 @@ checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "blake3"
|
name = "blake3"
|
||||||
version = "1.5.2"
|
version = "1.5.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3d08263faac5cde2a4d52b513dadb80846023aade56fcd8fc99ba73ba8050e92"
|
checksum = "30cca6d3674597c30ddf2c587bf8d9d65c9a84d2326d941cc79c9842dfe0ef52"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arrayref",
|
"arrayref",
|
||||||
"arrayvec",
|
"arrayvec",
|
||||||
@ -137,7 +137,7 @@ dependencies = [
|
|||||||
"cfg-if",
|
"cfg-if",
|
||||||
"constant_time_eq",
|
"constant_time_eq",
|
||||||
"memmap2",
|
"memmap2",
|
||||||
"rayon-core",
|
"rayon",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -174,9 +174,9 @@ checksum = "e0ec6b951b160caa93cc0c7b209e5a3bff7aae9062213451ac99493cd844c239"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.1.4"
|
version = "1.0.104"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9711f33475c22aab363b05564a17d7b789bf3dfec5ebabb586adee56f0e271b5"
|
checksum = "74b6a57f98764a267ff415d50a25e6e166f3831a5071af4995296ea97d210490"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
@ -221,9 +221,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "4.5.9"
|
version = "4.5.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "64acc1846d54c1fe936a78dc189c34e28d3f5afc348403f28ecf53660b9b8462"
|
checksum = "84b3edb18336f4df585bc9aa31dd99c036dfa5dc5e9a2939a722a188f3a8970d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap_builder",
|
"clap_builder",
|
||||||
"clap_derive",
|
"clap_derive",
|
||||||
@ -231,9 +231,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap_builder"
|
name = "clap_builder"
|
||||||
version = "4.5.9"
|
version = "4.5.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6fb8393d67ba2e7bfaf28a23458e4e2b543cc73a99595511eb207fdb8aede942"
|
checksum = "c1c09dd5ada6c6c78075d6fd0da3f90d8080651e2d6cc8eb2f1aaa4034ced708"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anstream",
|
"anstream",
|
||||||
"anstyle",
|
"anstyle",
|
||||||
@ -244,11 +244,11 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap_complete"
|
name = "clap_complete"
|
||||||
version = "4.5.8"
|
version = "4.5.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5b4be9c4c4b1f30b78d8a750e0822b6a6102d97e62061c583a6c1dea2dfb33ae"
|
checksum = "1d598e88f6874d4b888ed40c71efbcbf4076f1dfbae128a08a8c9e45f710605d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 4.5.9",
|
"clap 4.5.8",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -260,7 +260,7 @@ dependencies = [
|
|||||||
"heck 0.5.0",
|
"heck 0.5.0",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.71",
|
"syn 2.0.69",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -275,7 +275,7 @@ version = "0.2.22"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f50dde5bc0c853d6248de457e5eb6e5a674a54b93810a34ded88d882ca1fe2de"
|
checksum = "f50dde5bc0c853d6248de457e5eb6e5a674a54b93810a34ded88d882ca1fe2de"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 4.5.9",
|
"clap 4.5.8",
|
||||||
"roff",
|
"roff",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -591,13 +591,13 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "just"
|
name = "just"
|
||||||
version = "1.31.0"
|
version = "1.30.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ansi_term",
|
"ansi_term",
|
||||||
"blake3",
|
"blake3",
|
||||||
"camino",
|
"camino",
|
||||||
"chrono",
|
"chrono",
|
||||||
"clap 4.5.9",
|
"clap 4.5.8",
|
||||||
"clap_complete",
|
"clap_complete",
|
||||||
"clap_mangen",
|
"clap_mangen",
|
||||||
"ctrlc",
|
"ctrlc",
|
||||||
@ -846,6 +846,16 @@ dependencies = [
|
|||||||
"getrandom",
|
"getrandom",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rayon"
|
||||||
|
version = "1.10.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa"
|
||||||
|
dependencies = [
|
||||||
|
"either",
|
||||||
|
"rayon-core",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rayon-core"
|
name = "rayon-core"
|
||||||
version = "1.12.1"
|
version = "1.12.1"
|
||||||
@ -965,7 +975,7 @@ checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.71",
|
"syn 2.0.69",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1011,23 +1021,23 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "snafu"
|
name = "snafu"
|
||||||
version = "0.8.4"
|
version = "0.8.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2b835cb902660db3415a672d862905e791e54d306c6e8189168c7f3d9ae1c79d"
|
checksum = "418b8136fec49956eba89be7da2847ec1909df92a9ae4178b5ff0ff092c8d95e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"snafu-derive",
|
"snafu-derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "snafu-derive"
|
name = "snafu-derive"
|
||||||
version = "0.8.4"
|
version = "0.8.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "38d1e02fca405f6280643174a50c942219f0bbf4dbf7d480f1dd864d6f211ae5"
|
checksum = "1a4812a669da00d17d8266a0439eddcacbc88b17f732f927e52eeb9d196f7fb5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"heck 0.5.0",
|
"heck 0.5.0",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.71",
|
"syn 2.0.69",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1085,7 +1095,7 @@ dependencies = [
|
|||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"rustversion",
|
"rustversion",
|
||||||
"syn 2.0.71",
|
"syn 2.0.69",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1101,9 +1111,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "2.0.71"
|
version = "2.0.69"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b146dcf730474b4bcd16c311627b31ede9ab149045db4d6088b3becaea046462"
|
checksum = "201fcda3845c23e8212cd466bfebf0bd20694490fc0356ae8e428e0824a915a6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -1158,22 +1168,22 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "thiserror"
|
||||||
version = "1.0.62"
|
version = "1.0.61"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f2675633b1499176c2dff06b0856a27976a8f9d436737b4cf4f312d4d91d8bbb"
|
checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"thiserror-impl",
|
"thiserror-impl",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror-impl"
|
name = "thiserror-impl"
|
||||||
version = "1.0.62"
|
version = "1.0.61"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d20468752b09f49e909e55a5d338caa8bedf615594e9d80bc4c565d30faf798c"
|
checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.71",
|
"syn 2.0.69",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1230,9 +1240,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "uuid"
|
name = "uuid"
|
||||||
version = "1.10.0"
|
version = "1.9.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314"
|
checksum = "5de17fd2f7da591098415cff336e12965a28061ddace43b59cb3c430179c9439"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"getrandom",
|
"getrandom",
|
||||||
]
|
]
|
||||||
@ -1276,7 +1286,7 @@ dependencies = [
|
|||||||
"once_cell",
|
"once_cell",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.71",
|
"syn 2.0.69",
|
||||||
"wasm-bindgen-shared",
|
"wasm-bindgen-shared",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -1298,7 +1308,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.71",
|
"syn 2.0.69",
|
||||||
"wasm-bindgen-backend",
|
"wasm-bindgen-backend",
|
||||||
"wasm-bindgen-shared",
|
"wasm-bindgen-shared",
|
||||||
]
|
]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "just"
|
name = "just"
|
||||||
version = "1.31.0"
|
version = "1.30.1"
|
||||||
authors = ["Casey Rodarmor <casey@rodarmor.com>"]
|
authors = ["Casey Rodarmor <casey@rodarmor.com>"]
|
||||||
autotests = false
|
autotests = false
|
||||||
categories = ["command-line-utilities", "development-tools"]
|
categories = ["command-line-utilities", "development-tools"]
|
||||||
|
19
README.md
19
README.md
@ -667,10 +667,10 @@ $ cat foo.just
|
|||||||
mod bar
|
mod bar
|
||||||
$ cat bar.just
|
$ cat bar.just
|
||||||
baz:
|
baz:
|
||||||
$ just foo bar
|
$ just --unstable foo bar
|
||||||
Available recipes:
|
Available recipes:
|
||||||
baz
|
baz
|
||||||
$ just foo::bar
|
$ just --unstable foo::bar
|
||||||
Available recipes:
|
Available recipes:
|
||||||
baz
|
baz
|
||||||
```
|
```
|
||||||
@ -820,7 +820,7 @@ foo:
|
|||||||
| `positional-arguments` | boolean | `false` | Pass positional arguments. |
|
| `positional-arguments` | boolean | `false` | Pass positional arguments. |
|
||||||
| `shell` | `[COMMAND, ARGS…]` | - | Set the command used to invoke recipes and evaluate backticks. |
|
| `shell` | `[COMMAND, ARGS…]` | - | Set the command used to invoke recipes and evaluate backticks. |
|
||||||
| `tempdir` | string | - | Create temporary directories in `tempdir` instead of the system default temporary directory. |
|
| `tempdir` | string | - | Create temporary directories in `tempdir` instead of the system default temporary directory. |
|
||||||
| `unstable`<sup>1.31.0</sup> | boolean | `false` | Enable unstable features. |
|
| `unstable`<sup>master</sup> | boolean | `false` | Enable unstable features. |
|
||||||
| `windows-powershell` | boolean | `false` | Use PowerShell on Windows as default shell. (Deprecated. Use `windows-shell` instead. |
|
| `windows-powershell` | boolean | `false` | Use PowerShell on Windows as default shell. (Deprecated. Use `windows-shell` instead. |
|
||||||
| `windows-shell` | `[COMMAND, ARGS…]` | - | Set the command used to invoke recipes and evaluate backticks. |
|
| `windows-shell` | `[COMMAND, ARGS…]` | - | Set the command used to invoke recipes and evaluate backticks. |
|
||||||
|
|
||||||
@ -1712,7 +1712,6 @@ Recipes may be annotated with attributes that change their behavior.
|
|||||||
| `[confirm]`<sup>1.17.0</sup> | Require confirmation prior to executing recipe. |
|
| `[confirm]`<sup>1.17.0</sup> | Require confirmation prior to executing recipe. |
|
||||||
| `[confirm('PROMPT')]`<sup>1.23.0</sup> | Require confirmation prior to executing recipe with a custom prompt. |
|
| `[confirm('PROMPT')]`<sup>1.23.0</sup> | Require confirmation prior to executing recipe with a custom prompt. |
|
||||||
| `[doc('DOC')]`<sup>1.27.0</sup> | Set recipe's [documentation comment](#documentation-comments) to `DOC`. |
|
| `[doc('DOC')]`<sup>1.27.0</sup> | Set recipe's [documentation comment](#documentation-comments) to `DOC`. |
|
||||||
| `[extension('EXT')]`<sup>master</sup> | Set shebang recipe script's file extension to `EXT`. `EXT` should include a period if one is desired. |
|
|
||||||
| `[group('NAME')]`<sup>1.27.0</sup> | Put recipe in [recipe group](#recipe-groups) `NAME`. |
|
| `[group('NAME')]`<sup>1.27.0</sup> | Put recipe in [recipe group](#recipe-groups) `NAME`. |
|
||||||
| `[linux]`<sup>1.8.0</sup> | Enable recipe on Linux. |
|
| `[linux]`<sup>1.8.0</sup> | Enable recipe on Linux. |
|
||||||
| `[macos]`<sup>1.8.0</sup> | Enable recipe on MacOS. |
|
| `[macos]`<sup>1.8.0</sup> | Enable recipe on MacOS. |
|
||||||
@ -3155,11 +3154,9 @@ Missing source files for optional imports do not produce an error.
|
|||||||
|
|
||||||
### Modules<sup>1.19.0</sup>
|
### Modules<sup>1.19.0</sup>
|
||||||
|
|
||||||
A `justfile` can declare modules using `mod` statements.
|
A `justfile` can declare modules using `mod` statements. `mod` statements are
|
||||||
|
currently unstable, so you'll need to use the `--unstable` flag,
|
||||||
`mod` statements were stabilized in `just`<sup>1.31.0</sup>. In earlier
|
`set unstable`, or set the `JUST_UNSTABLE` environment variable to use them.
|
||||||
versions, you'll need to use the `--unstable` flag, `set unstable`, or set the
|
|
||||||
`JUST_UNSTABLE` environment variable to use them.
|
|
||||||
|
|
||||||
If you have the following `justfile`:
|
If you have the following `justfile`:
|
||||||
|
|
||||||
@ -3184,14 +3181,14 @@ uses its own settings.
|
|||||||
Recipes in submodules can be invoked as subcommands:
|
Recipes in submodules can be invoked as subcommands:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
$ just bar b
|
$ just --unstable bar b
|
||||||
B
|
B
|
||||||
```
|
```
|
||||||
|
|
||||||
Or with path syntax:
|
Or with path syntax:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
$ just bar::b
|
$ just --unstable bar::b
|
||||||
B
|
B
|
||||||
```
|
```
|
||||||
|
|
||||||
|
47
justfile
47
justfile
@ -13,24 +13,16 @@ export JUST_LOG := log
|
|||||||
watch +args='test':
|
watch +args='test':
|
||||||
cargo watch --clear --exec '{{ args }}'
|
cargo watch --clear --exec '{{ args }}'
|
||||||
|
|
||||||
[group: "testing"]
|
|
||||||
[doc: "Run just test suite"]
|
|
||||||
test:
|
test:
|
||||||
cargo test
|
cargo test
|
||||||
|
|
||||||
ci: lint build-book
|
ci: build-book
|
||||||
cargo test --all
|
cargo test --all
|
||||||
|
|
||||||
# Run lint checks
|
|
||||||
[group: "code-checking"]
|
|
||||||
lint:
|
|
||||||
cargo clippy --all --all-targets -- --deny warnings
|
cargo clippy --all --all-targets -- --deny warnings
|
||||||
./bin/forbid
|
|
||||||
cargo fmt --all -- --check
|
cargo fmt --all -- --check
|
||||||
|
./bin/forbid
|
||||||
cargo update --locked --package just
|
cargo update --locked --package just
|
||||||
|
|
||||||
[group: "testing"]
|
|
||||||
[doc: "Run fuzz tests"]
|
|
||||||
fuzz:
|
fuzz:
|
||||||
cargo +nightly fuzz run fuzz-compiler
|
cargo +nightly fuzz run fuzz-compiler
|
||||||
|
|
||||||
@ -38,46 +30,33 @@ run:
|
|||||||
cargo run
|
cargo run
|
||||||
|
|
||||||
# only run tests matching PATTERN
|
# only run tests matching PATTERN
|
||||||
[group: "testing"]
|
|
||||||
filter PATTERN:
|
filter PATTERN:
|
||||||
cargo test {{PATTERN}}
|
cargo test {{PATTERN}}
|
||||||
|
|
||||||
# Build just
|
|
||||||
[group: "developer-workflow"]
|
|
||||||
build:
|
build:
|
||||||
cargo build
|
cargo build
|
||||||
|
|
||||||
[group: "code-checking"]
|
|
||||||
fmt:
|
fmt:
|
||||||
cargo fmt --all
|
cargo fmt --all
|
||||||
|
|
||||||
[group: "code-checking"]
|
|
||||||
shellcheck:
|
shellcheck:
|
||||||
shellcheck www/install.sh
|
shellcheck www/install.sh
|
||||||
|
|
||||||
# Generate the just manpage
|
|
||||||
[group: "documentation"]
|
|
||||||
man:
|
man:
|
||||||
mkdir -p man
|
mkdir -p man
|
||||||
cargo run -- --man > man/just.1
|
cargo run -- --man > man/just.1
|
||||||
|
|
||||||
# View the Just manpage
|
|
||||||
[group: "documentation"]
|
|
||||||
view-man: man
|
view-man: man
|
||||||
man man/just.1
|
man man/just.1
|
||||||
|
|
||||||
# add git log messages to changelog
|
# add git log messages to changelog
|
||||||
[group: "developer-workflow"]
|
|
||||||
update-changelog:
|
update-changelog:
|
||||||
echo >> CHANGELOG.md
|
echo >> CHANGELOG.md
|
||||||
git log --pretty='format:- %s' >> CHANGELOG.md
|
git log --pretty='format:- %s' >> CHANGELOG.md
|
||||||
|
|
||||||
# Update the contributors file
|
|
||||||
[group: "developer-workflow"]
|
|
||||||
update-contributors:
|
update-contributors:
|
||||||
cargo run --release --package update-contributors
|
cargo run --release --package update-contributors
|
||||||
|
|
||||||
[group: "code-checking"]
|
|
||||||
check: fmt clippy test forbid
|
check: fmt clippy test forbid
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -euxo pipefail
|
set -euxo pipefail
|
||||||
@ -85,11 +64,7 @@ check: fmt clippy test forbid
|
|||||||
VERSION=`sed -En 's/version[[:space:]]*=[[:space:]]*"([^"]+)"/\1/p' Cargo.toml | head -1`
|
VERSION=`sed -En 's/version[[:space:]]*=[[:space:]]*"([^"]+)"/\1/p' Cargo.toml | head -1`
|
||||||
grep "^\[$VERSION\]" CHANGELOG.md
|
grep "^\[$VERSION\]" CHANGELOG.md
|
||||||
|
|
||||||
outdated:
|
|
||||||
cargo outdated -R
|
|
||||||
|
|
||||||
# publish current GitHub master branch
|
# publish current GitHub master branch
|
||||||
[group: "developer-workflow"]
|
|
||||||
publish:
|
publish:
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -euxo pipefail
|
set -euxo pipefail
|
||||||
@ -104,19 +79,13 @@ publish:
|
|||||||
cd ../..
|
cd ../..
|
||||||
rm -rf tmp/release
|
rm -rf tmp/release
|
||||||
|
|
||||||
[group: "documentation"]
|
|
||||||
[doc: "Search for master version note subscripts in the README"]
|
|
||||||
readme-version-notes:
|
readme-version-notes:
|
||||||
grep '<sup>master</sup>' README.md
|
grep '<sup>master</sup>' README.md
|
||||||
|
|
||||||
[group: "developer-workflow"]
|
|
||||||
[doc: "Push to GitHub"]
|
|
||||||
push: check
|
push: check
|
||||||
! git branch | grep '* master'
|
! git branch | grep '* master'
|
||||||
git push github
|
git push github
|
||||||
|
|
||||||
[group: "developer-workflow"]
|
|
||||||
[doc: "Create a pull request"]
|
|
||||||
pr: push
|
pr: push
|
||||||
gh pr create --web
|
gh pr create --web
|
||||||
|
|
||||||
@ -142,7 +111,6 @@ install-dev-deps:
|
|||||||
cargo install mdbook mdbook-linkcheck
|
cargo install mdbook mdbook-linkcheck
|
||||||
|
|
||||||
# everyone's favorite animate paper clip
|
# everyone's favorite animate paper clip
|
||||||
[group: "code-checking"]
|
|
||||||
clippy:
|
clippy:
|
||||||
cargo clippy --all --all-targets --all-features
|
cargo clippy --all --all-targets --all-features
|
||||||
|
|
||||||
@ -150,19 +118,16 @@ forbid:
|
|||||||
./bin/forbid
|
./bin/forbid
|
||||||
|
|
||||||
# count non-empty lines of code
|
# count non-empty lines of code
|
||||||
[group: "developer-workflow"]
|
|
||||||
sloc:
|
sloc:
|
||||||
@cat src/*.rs | sed '/^\s*$/d' | wc -l
|
@cat src/*.rs | sed '/^\s*$/d' | wc -l
|
||||||
|
|
||||||
replace FROM TO:
|
replace FROM TO:
|
||||||
sd '{{FROM}}' '{{TO}}' src/*.rs
|
sd '{{FROM}}' '{{TO}}' src/*.rs
|
||||||
|
|
||||||
[group: "demo-recipes"]
|
|
||||||
test-quine:
|
test-quine:
|
||||||
cargo run -- quine
|
cargo run -- quine
|
||||||
|
|
||||||
# make a quine, compile it, and verify it
|
# make a quine, compile it, and verify it
|
||||||
[group: "demo-recipes"]
|
|
||||||
quine:
|
quine:
|
||||||
mkdir -p tmp
|
mkdir -p tmp
|
||||||
@echo '{{quine-text}}' > tmp/gen0.c
|
@echo '{{quine-text}}' > tmp/gen0.c
|
||||||
@ -190,24 +155,19 @@ quine-text := '
|
|||||||
}
|
}
|
||||||
'
|
'
|
||||||
|
|
||||||
[group: "documentation"]
|
|
||||||
render-readme:
|
render-readme:
|
||||||
#!/usr/bin/env ruby
|
#!/usr/bin/env ruby
|
||||||
require 'github/markup'
|
require 'github/markup'
|
||||||
$rendered = GitHub::Markup.render("README.adoc", File.read("README.adoc"))
|
$rendered = GitHub::Markup.render("README.adoc", File.read("README.adoc"))
|
||||||
File.write('tmp/README.html', $rendered)
|
File.write('tmp/README.html', $rendered)
|
||||||
|
|
||||||
[group: "documentation"]
|
|
||||||
watch-readme:
|
watch-readme:
|
||||||
just render-readme
|
just render-readme
|
||||||
fswatch -ro README.adoc | xargs -n1 -I{} just render-readme
|
fswatch -ro README.adoc | xargs -n1 -I{} just render-readme
|
||||||
|
|
||||||
# Test shell completions
|
|
||||||
[group: "testing"]
|
|
||||||
test-completions:
|
test-completions:
|
||||||
./tests/completions/just.bash
|
./tests/completions/just.bash
|
||||||
|
|
||||||
[group: "documentation"]
|
|
||||||
build-book:
|
build-book:
|
||||||
cargo run --package generate-book
|
cargo run --package generate-book
|
||||||
mdbook build book/en
|
mdbook build book/en
|
||||||
@ -225,7 +185,6 @@ convert-integration-test test:
|
|||||||
-e 's/\.run\(\)/.run();/'
|
-e 's/\.run\(\)/.run();/'
|
||||||
|
|
||||||
# run all polyglot recipes
|
# run all polyglot recipes
|
||||||
[group: "demo-recipes"]
|
|
||||||
polyglot: _python _js _perl _sh _ruby
|
polyglot: _python _js _perl _sh _ruby
|
||||||
|
|
||||||
_python:
|
_python:
|
||||||
@ -255,11 +214,9 @@ _ruby:
|
|||||||
puts "Hello from ruby!"
|
puts "Hello from ruby!"
|
||||||
|
|
||||||
# Print working directory, for demonstration purposes!
|
# Print working directory, for demonstration purposes!
|
||||||
[group: "demo-recipes"]
|
|
||||||
pwd:
|
pwd:
|
||||||
echo {{invocation_directory()}}
|
echo {{invocation_directory()}}
|
||||||
|
|
||||||
[group: "testing"]
|
|
||||||
test-bash-completions:
|
test-bash-completions:
|
||||||
rm -rf tmp
|
rm -rf tmp
|
||||||
mkdir -p tmp/bin
|
mkdir -p tmp/bin
|
||||||
|
@ -10,7 +10,7 @@ pub(crate) struct Analyzer<'src> {
|
|||||||
impl<'src> Analyzer<'src> {
|
impl<'src> Analyzer<'src> {
|
||||||
pub(crate) fn analyze(
|
pub(crate) fn analyze(
|
||||||
asts: &HashMap<PathBuf, Ast<'src>>,
|
asts: &HashMap<PathBuf, Ast<'src>>,
|
||||||
doc: Option<String>,
|
doc: Option<&'src str>,
|
||||||
loaded: &[PathBuf],
|
loaded: &[PathBuf],
|
||||||
name: Option<Name<'src>>,
|
name: Option<Name<'src>>,
|
||||||
paths: &HashMap<PathBuf, PathBuf>,
|
paths: &HashMap<PathBuf, PathBuf>,
|
||||||
@ -22,7 +22,7 @@ impl<'src> Analyzer<'src> {
|
|||||||
fn justfile(
|
fn justfile(
|
||||||
mut self,
|
mut self,
|
||||||
asts: &HashMap<PathBuf, Ast<'src>>,
|
asts: &HashMap<PathBuf, Ast<'src>>,
|
||||||
doc: Option<String>,
|
doc: Option<&'src str>,
|
||||||
loaded: &[PathBuf],
|
loaded: &[PathBuf],
|
||||||
name: Option<Name<'src>>,
|
name: Option<Name<'src>>,
|
||||||
paths: &HashMap<PathBuf, PathBuf>,
|
paths: &HashMap<PathBuf, PathBuf>,
|
||||||
@ -37,6 +37,8 @@ impl<'src> Analyzer<'src> {
|
|||||||
|
|
||||||
let mut warnings = Vec::new();
|
let mut warnings = Vec::new();
|
||||||
|
|
||||||
|
let mut unstable = BTreeSet::new();
|
||||||
|
|
||||||
let mut modules: Table<Justfile> = Table::new();
|
let mut modules: Table<Justfile> = Table::new();
|
||||||
|
|
||||||
let mut unexports: HashSet<String> = HashSet::new();
|
let mut unexports: HashSet<String> = HashSet::new();
|
||||||
@ -90,27 +92,15 @@ impl<'src> Analyzer<'src> {
|
|||||||
absolute,
|
absolute,
|
||||||
name,
|
name,
|
||||||
doc,
|
doc,
|
||||||
attributes,
|
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
let mut doc_attr: Option<&str> = None;
|
unstable.insert(Unstable::Modules);
|
||||||
for attribute in attributes {
|
|
||||||
if let Attribute::Doc(ref doc) = attribute {
|
|
||||||
doc_attr = Some(doc.as_ref().map(|s| s.cooked.as_ref()).unwrap_or_default());
|
|
||||||
} else {
|
|
||||||
return Err(name.token.error(InvalidAttribute {
|
|
||||||
item_kind: "Module",
|
|
||||||
item_name: name.lexeme(),
|
|
||||||
attribute: attribute.clone(),
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(absolute) = absolute {
|
if let Some(absolute) = absolute {
|
||||||
define(*name, "module", false)?;
|
define(*name, "module", false)?;
|
||||||
modules.insert(Self::analyze(
|
modules.insert(Self::analyze(
|
||||||
asts,
|
asts,
|
||||||
doc_attr.or(*doc).map(ToOwned::to_owned),
|
*doc,
|
||||||
loaded,
|
loaded,
|
||||||
Some(*name),
|
Some(*name),
|
||||||
paths,
|
paths,
|
||||||
@ -208,7 +198,7 @@ impl<'src> Analyzer<'src> {
|
|||||||
settings,
|
settings,
|
||||||
source: root.into(),
|
source: root.into(),
|
||||||
unexports,
|
unexports,
|
||||||
unstable_features: BTreeSet::new(),
|
unstable,
|
||||||
warnings,
|
warnings,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -255,29 +245,16 @@ impl<'src> Analyzer<'src> {
|
|||||||
continued = line.is_continuation();
|
continued = line.is_continuation();
|
||||||
}
|
}
|
||||||
|
|
||||||
if !recipe.shebang {
|
|
||||||
if let Some(attribute) = recipe
|
|
||||||
.attributes
|
|
||||||
.iter()
|
|
||||||
.find(|attribute| matches!(attribute, Attribute::Extension(_)))
|
|
||||||
{
|
|
||||||
return Err(recipe.name.error(InvalidAttribute {
|
|
||||||
item_kind: "Recipe",
|
|
||||||
item_name: recipe.name.lexeme(),
|
|
||||||
attribute: attribute.clone(),
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn analyze_alias(alias: &Alias<'src, Name<'src>>) -> CompileResult<'src> {
|
fn analyze_alias(alias: &Alias<'src, Name<'src>>) -> CompileResult<'src> {
|
||||||
|
let name = alias.name.lexeme();
|
||||||
|
|
||||||
for attribute in &alias.attributes {
|
for attribute in &alias.attributes {
|
||||||
if *attribute != Attribute::Private {
|
if *attribute != Attribute::Private {
|
||||||
return Err(alias.name.token.error(InvalidAttribute {
|
return Err(alias.name.token.error(AliasInvalidAttribute {
|
||||||
item_kind: "Alias",
|
alias: name,
|
||||||
item_name: alias.name.lexeme(),
|
|
||||||
attribute: attribute.clone(),
|
attribute: attribute.clone(),
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,6 @@ use super::*;
|
|||||||
pub(crate) enum Attribute<'src> {
|
pub(crate) enum Attribute<'src> {
|
||||||
Confirm(Option<StringLiteral<'src>>),
|
Confirm(Option<StringLiteral<'src>>),
|
||||||
Doc(Option<StringLiteral<'src>>),
|
Doc(Option<StringLiteral<'src>>),
|
||||||
Extension(StringLiteral<'src>),
|
|
||||||
Group(StringLiteral<'src>),
|
Group(StringLiteral<'src>),
|
||||||
Linux,
|
Linux,
|
||||||
Macos,
|
Macos,
|
||||||
@ -28,7 +27,7 @@ impl AttributeDiscriminant {
|
|||||||
fn argument_range(self) -> RangeInclusive<usize> {
|
fn argument_range(self) -> RangeInclusive<usize> {
|
||||||
match self {
|
match self {
|
||||||
Self::Confirm | Self::Doc => 0..=1,
|
Self::Confirm | Self::Doc => 0..=1,
|
||||||
Self::Group | Self::Extension => 1..=1,
|
Self::Group => 1..=1,
|
||||||
Self::Linux
|
Self::Linux
|
||||||
| Self::Macos
|
| Self::Macos
|
||||||
| Self::NoCd
|
| Self::NoCd
|
||||||
@ -47,6 +46,8 @@ impl<'src> Attribute<'src> {
|
|||||||
name: Name<'src>,
|
name: Name<'src>,
|
||||||
argument: Option<StringLiteral<'src>>,
|
argument: Option<StringLiteral<'src>>,
|
||||||
) -> CompileResult<'src, Self> {
|
) -> CompileResult<'src, Self> {
|
||||||
|
use AttributeDiscriminant::*;
|
||||||
|
|
||||||
let discriminant = name
|
let discriminant = name
|
||||||
.lexeme()
|
.lexeme()
|
||||||
.parse::<AttributeDiscriminant>()
|
.parse::<AttributeDiscriminant>()
|
||||||
@ -71,19 +72,18 @@ impl<'src> Attribute<'src> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Ok(match discriminant {
|
Ok(match discriminant {
|
||||||
AttributeDiscriminant::Confirm => Self::Confirm(argument),
|
Confirm => Self::Confirm(argument),
|
||||||
AttributeDiscriminant::Doc => Self::Doc(argument),
|
Doc => Self::Doc(argument),
|
||||||
AttributeDiscriminant::Extension => Self::Extension(argument.unwrap()),
|
Group => Self::Group(argument.unwrap()),
|
||||||
AttributeDiscriminant::Group => Self::Group(argument.unwrap()),
|
Linux => Self::Linux,
|
||||||
AttributeDiscriminant::Linux => Self::Linux,
|
Macos => Self::Macos,
|
||||||
AttributeDiscriminant::Macos => Self::Macos,
|
NoCd => Self::NoCd,
|
||||||
AttributeDiscriminant::NoCd => Self::NoCd,
|
NoExitMessage => Self::NoExitMessage,
|
||||||
AttributeDiscriminant::NoExitMessage => Self::NoExitMessage,
|
NoQuiet => Self::NoQuiet,
|
||||||
AttributeDiscriminant::NoQuiet => Self::NoQuiet,
|
PositionalArguments => Self::PositionalArguments,
|
||||||
AttributeDiscriminant::PositionalArguments => Self::PositionalArguments,
|
Private => Self::Private,
|
||||||
AttributeDiscriminant::Private => Self::Private,
|
Unix => Self::Unix,
|
||||||
AttributeDiscriminant::Unix => Self::Unix,
|
Windows => Self::Windows,
|
||||||
AttributeDiscriminant::Windows => Self::Windows,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,8 +93,9 @@ impl<'src> Attribute<'src> {
|
|||||||
|
|
||||||
fn argument(&self) -> Option<&StringLiteral> {
|
fn argument(&self) -> Option<&StringLiteral> {
|
||||||
match self {
|
match self {
|
||||||
Self::Confirm(argument) | Self::Doc(argument) => argument.as_ref(),
|
Self::Confirm(prompt) => prompt.as_ref(),
|
||||||
Self::Extension(argument) | Self::Group(argument) => Some(argument),
|
Self::Doc(doc) => doc.as_ref(),
|
||||||
|
Self::Group(group) => Some(group),
|
||||||
Self::Linux
|
Self::Linux
|
||||||
| Self::Macos
|
| Self::Macos
|
||||||
| Self::NoCd
|
| Self::NoCd
|
||||||
|
@ -32,6 +32,13 @@ impl Display for CompileError<'_> {
|
|||||||
use CompileErrorKind::*;
|
use CompileErrorKind::*;
|
||||||
|
|
||||||
match &*self.kind {
|
match &*self.kind {
|
||||||
|
AliasInvalidAttribute { alias, attribute } => {
|
||||||
|
write!(
|
||||||
|
f,
|
||||||
|
"Alias `{alias}` has invalid attribute `{}`",
|
||||||
|
attribute.name(),
|
||||||
|
)
|
||||||
|
}
|
||||||
AliasShadowsRecipe { alias, recipe_line } => write!(
|
AliasShadowsRecipe { alias, recipe_line } => write!(
|
||||||
f,
|
f,
|
||||||
"Alias `{alias}` defined on line {} shadows recipe `{alias}` defined on line {}",
|
"Alias `{alias}` defined on line {} shadows recipe `{alias}` defined on line {}",
|
||||||
@ -143,9 +150,6 @@ impl Display for CompileError<'_> {
|
|||||||
write!(f, "Variable {variable} is both exported and unexported")
|
write!(f, "Variable {variable} is both exported and unexported")
|
||||||
}
|
}
|
||||||
ExtraLeadingWhitespace => write!(f, "Recipe line has extra leading whitespace"),
|
ExtraLeadingWhitespace => write!(f, "Recipe line has extra leading whitespace"),
|
||||||
ExtraneousAttributes { count } => {
|
|
||||||
write!(f, "Extraneous {}", Count("attribute", *count))
|
|
||||||
}
|
|
||||||
FunctionArgumentCountMismatch {
|
FunctionArgumentCountMismatch {
|
||||||
function,
|
function,
|
||||||
found,
|
found,
|
||||||
@ -172,15 +176,6 @@ impl Display for CompileError<'_> {
|
|||||||
"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"
|
||||||
),
|
),
|
||||||
InvalidAttribute {
|
|
||||||
item_name,
|
|
||||||
item_kind,
|
|
||||||
attribute,
|
|
||||||
} => write!(
|
|
||||||
f,
|
|
||||||
"{item_kind} `{item_name}` has invalid attribute `{}`",
|
|
||||||
attribute.name(),
|
|
||||||
),
|
|
||||||
InvalidEscapeSequence { character } => write!(
|
InvalidEscapeSequence { character } => write!(
|
||||||
f,
|
f,
|
||||||
"`\\{}` is not a valid escape sequence",
|
"`\\{}` is not a valid escape sequence",
|
||||||
|
@ -2,6 +2,10 @@ use super::*;
|
|||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub(crate) enum CompileErrorKind<'src> {
|
pub(crate) enum CompileErrorKind<'src> {
|
||||||
|
AliasInvalidAttribute {
|
||||||
|
alias: &'src str,
|
||||||
|
attribute: Attribute<'src>,
|
||||||
|
},
|
||||||
AliasShadowsRecipe {
|
AliasShadowsRecipe {
|
||||||
alias: &'src str,
|
alias: &'src str,
|
||||||
recipe_line: usize,
|
recipe_line: usize,
|
||||||
@ -59,9 +63,6 @@ pub(crate) enum CompileErrorKind<'src> {
|
|||||||
variable: &'src str,
|
variable: &'src str,
|
||||||
},
|
},
|
||||||
ExtraLeadingWhitespace,
|
ExtraLeadingWhitespace,
|
||||||
ExtraneousAttributes {
|
|
||||||
count: usize,
|
|
||||||
},
|
|
||||||
FunctionArgumentCountMismatch {
|
FunctionArgumentCountMismatch {
|
||||||
function: &'src str,
|
function: &'src str,
|
||||||
found: usize,
|
found: usize,
|
||||||
@ -75,11 +76,6 @@ pub(crate) enum CompileErrorKind<'src> {
|
|||||||
Internal {
|
Internal {
|
||||||
message: String,
|
message: String,
|
||||||
},
|
},
|
||||||
InvalidAttribute {
|
|
||||||
item_kind: &'static str,
|
|
||||||
item_name: &'src str,
|
|
||||||
attribute: Attribute<'src>,
|
|
||||||
},
|
|
||||||
InvalidEscapeSequence {
|
InvalidEscapeSequence {
|
||||||
character: char,
|
character: char,
|
||||||
},
|
},
|
||||||
|
@ -720,15 +720,13 @@ impl Config {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn require_unstable(
|
pub(crate) fn require_unstable(&self, message: &str) -> RunResult<'static> {
|
||||||
&self,
|
if self.unstable {
|
||||||
justfile: &Justfile,
|
|
||||||
unstable_feature: UnstableFeature,
|
|
||||||
) -> RunResult<'static> {
|
|
||||||
if self.unstable || justfile.settings.unstable {
|
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(Error::UnstableFeature { unstable_feature })
|
Err(Error::Unstable {
|
||||||
|
message: message.to_owned(),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,8 +174,8 @@ pub(crate) enum Error<'src> {
|
|||||||
recipe: String,
|
recipe: String,
|
||||||
suggestion: Option<Suggestion<'src>>,
|
suggestion: Option<Suggestion<'src>>,
|
||||||
},
|
},
|
||||||
UnstableFeature {
|
Unstable {
|
||||||
unstable_feature: UnstableFeature,
|
message: String,
|
||||||
},
|
},
|
||||||
WriteJustfile {
|
WriteJustfile {
|
||||||
justfile: PathBuf,
|
justfile: PathBuf,
|
||||||
@ -459,8 +459,8 @@ impl<'src> ColorDisplay for Error<'src> {
|
|||||||
write!(f, "\n{suggestion}")?;
|
write!(f, "\n{suggestion}")?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
UnstableFeature { unstable_feature } => {
|
Unstable { message } => {
|
||||||
write!(f, "{unstable_feature} Invoke `just` with `--unstable`, set the `JUST_UNSTABLE` environment variable, or add `set unstable` to your `justfile` to enable unstable features.")?;
|
write!(f, "{message} Invoke `just` with `--unstable`, set the `JUST_UNSTABLE` environment variable, or add `set unstable` to your `justfile` to enable unstable features.")?;
|
||||||
}
|
}
|
||||||
WriteJustfile { justfile, io_error } => {
|
WriteJustfile { justfile, io_error } => {
|
||||||
let justfile = justfile.display();
|
let justfile = justfile.display();
|
||||||
|
@ -13,7 +13,6 @@ pub(crate) enum Item<'src> {
|
|||||||
relative: StringLiteral<'src>,
|
relative: StringLiteral<'src>,
|
||||||
},
|
},
|
||||||
Module {
|
Module {
|
||||||
attributes: BTreeSet<Attribute<'src>>,
|
|
||||||
absolute: Option<PathBuf>,
|
absolute: Option<PathBuf>,
|
||||||
doc: Option<&'src str>,
|
doc: Option<&'src str>,
|
||||||
name: Name<'src>,
|
name: Name<'src>,
|
||||||
|
@ -13,7 +13,7 @@ struct Invocation<'src: 'run, 'run> {
|
|||||||
pub(crate) struct Justfile<'src> {
|
pub(crate) struct Justfile<'src> {
|
||||||
pub(crate) aliases: Table<'src, Alias<'src>>,
|
pub(crate) aliases: Table<'src, Alias<'src>>,
|
||||||
pub(crate) assignments: Table<'src, Assignment<'src>>,
|
pub(crate) assignments: Table<'src, Assignment<'src>>,
|
||||||
pub(crate) doc: Option<String>,
|
pub(crate) doc: Option<&'src str>,
|
||||||
#[serde(rename = "first", serialize_with = "keyed::serialize_option")]
|
#[serde(rename = "first", serialize_with = "keyed::serialize_option")]
|
||||||
pub(crate) default: Option<Rc<Recipe<'src>>>,
|
pub(crate) default: Option<Rc<Recipe<'src>>>,
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
@ -26,9 +26,9 @@ pub(crate) struct Justfile<'src> {
|
|||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
pub(crate) source: PathBuf,
|
pub(crate) source: PathBuf,
|
||||||
pub(crate) unexports: HashSet<String>,
|
pub(crate) unexports: HashSet<String>,
|
||||||
#[serde(skip)]
|
|
||||||
pub(crate) unstable_features: BTreeSet<UnstableFeature>,
|
|
||||||
pub(crate) warnings: Vec<Warning>,
|
pub(crate) warnings: Vec<Warning>,
|
||||||
|
#[serde(skip)]
|
||||||
|
pub(crate) unstable: BTreeSet<Unstable>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'src> Justfile<'src> {
|
impl<'src> Justfile<'src> {
|
||||||
@ -228,8 +228,12 @@ impl<'src> Justfile<'src> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn check_unstable(&self, config: &Config) -> RunResult<'src> {
|
pub(crate) fn check_unstable(&self, config: &Config) -> RunResult<'src> {
|
||||||
if let Some(&unstable_feature) = self.unstable_features.iter().next() {
|
if !config.unstable && !self.settings.unstable {
|
||||||
config.require_unstable(self, unstable_feature)?;
|
if let Some(unstable) = self.unstable.iter().next() {
|
||||||
|
return Err(Error::Unstable {
|
||||||
|
message: unstable.message(),
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for module in self.modules.values() {
|
for module in self.modules.values() {
|
||||||
|
@ -42,7 +42,7 @@ pub(crate) use {
|
|||||||
shell::Shell, show_whitespace::ShowWhitespace, source::Source, string_kind::StringKind,
|
shell::Shell, show_whitespace::ShowWhitespace, source::Source, string_kind::StringKind,
|
||||||
string_literal::StringLiteral, subcommand::Subcommand, suggestion::Suggestion, table::Table,
|
string_literal::StringLiteral, subcommand::Subcommand, suggestion::Suggestion, table::Table,
|
||||||
thunk::Thunk, token::Token, token_kind::TokenKind, unresolved_dependency::UnresolvedDependency,
|
thunk::Thunk, token::Token, token_kind::TokenKind, unresolved_dependency::UnresolvedDependency,
|
||||||
unresolved_recipe::UnresolvedRecipe, unstable_feature::UnstableFeature, use_color::UseColor,
|
unresolved_recipe::UnresolvedRecipe, unstable::Unstable, use_color::UseColor,
|
||||||
variables::Variables, verbosity::Verbosity, warning::Warning,
|
variables::Variables, verbosity::Verbosity, warning::Warning,
|
||||||
},
|
},
|
||||||
camino::Utf8Path,
|
camino::Utf8Path,
|
||||||
@ -204,7 +204,7 @@ mod token_kind;
|
|||||||
mod unindent;
|
mod unindent;
|
||||||
mod unresolved_dependency;
|
mod unresolved_dependency;
|
||||||
mod unresolved_recipe;
|
mod unresolved_recipe;
|
||||||
mod unstable_feature;
|
mod unstable;
|
||||||
mod use_color;
|
mod use_color;
|
||||||
mod variables;
|
mod variables;
|
||||||
mod verbosity;
|
mod verbosity;
|
||||||
|
@ -321,14 +321,6 @@ impl<'run, 'src> Parser<'run, 'src> {
|
|||||||
self.accept(ByteOrderMark)?;
|
self.accept(ByteOrderMark)?;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let mut attributes = self.parse_attributes()?;
|
|
||||||
let mut take_attributes = || {
|
|
||||||
attributes
|
|
||||||
.take()
|
|
||||||
.map(|(_token, attributes)| attributes)
|
|
||||||
.unwrap_or_default()
|
|
||||||
};
|
|
||||||
|
|
||||||
let next = self.next()?;
|
let next = self.next()?;
|
||||||
|
|
||||||
if let Some(comment) = self.accept(Comment)? {
|
if let Some(comment) = self.accept(Comment)? {
|
||||||
@ -342,7 +334,7 @@ impl<'run, 'src> Parser<'run, 'src> {
|
|||||||
} else if self.next_is(Identifier) {
|
} else if self.next_is(Identifier) {
|
||||||
match Keyword::from_lexeme(next.lexeme()) {
|
match Keyword::from_lexeme(next.lexeme()) {
|
||||||
Some(Keyword::Alias) if self.next_are(&[Identifier, Identifier, ColonEquals]) => {
|
Some(Keyword::Alias) if self.next_are(&[Identifier, Identifier, ColonEquals]) => {
|
||||||
items.push(Item::Alias(self.parse_alias(take_attributes())?));
|
items.push(Item::Alias(self.parse_alias(BTreeSet::new())?));
|
||||||
}
|
}
|
||||||
Some(Keyword::Export) if self.next_are(&[Identifier, Identifier, ColonEquals]) => {
|
Some(Keyword::Export) if self.next_are(&[Identifier, Identifier, ColonEquals]) => {
|
||||||
self.presume_keyword(Keyword::Export)?;
|
self.presume_keyword(Keyword::Export)?;
|
||||||
@ -396,7 +388,6 @@ impl<'run, 'src> Parser<'run, 'src> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
items.push(Item::Module {
|
items.push(Item::Module {
|
||||||
attributes: take_attributes(),
|
|
||||||
absolute: None,
|
absolute: None,
|
||||||
doc,
|
doc,
|
||||||
name,
|
name,
|
||||||
@ -421,7 +412,7 @@ impl<'run, 'src> Parser<'run, 'src> {
|
|||||||
items.push(Item::Recipe(self.parse_recipe(
|
items.push(Item::Recipe(self.parse_recipe(
|
||||||
doc,
|
doc,
|
||||||
false,
|
false,
|
||||||
take_attributes(),
|
BTreeSet::new(),
|
||||||
)?));
|
)?));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -431,17 +422,23 @@ impl<'run, 'src> Parser<'run, 'src> {
|
|||||||
items.push(Item::Recipe(self.parse_recipe(
|
items.push(Item::Recipe(self.parse_recipe(
|
||||||
doc,
|
doc,
|
||||||
true,
|
true,
|
||||||
take_attributes(),
|
BTreeSet::new(),
|
||||||
)?));
|
)?));
|
||||||
|
} else if let Some(attributes) = self.parse_attributes()? {
|
||||||
|
let next_keyword = Keyword::from_lexeme(self.next()?.lexeme());
|
||||||
|
match next_keyword {
|
||||||
|
Some(Keyword::Alias) if self.next_are(&[Identifier, Identifier, ColonEquals]) => {
|
||||||
|
items.push(Item::Alias(self.parse_alias(attributes)?));
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
let quiet = self.accepted(At)?;
|
||||||
|
let doc = pop_doc_comment(&mut items, eol_since_last_comment);
|
||||||
|
items.push(Item::Recipe(self.parse_recipe(doc, quiet, attributes)?));
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return Err(self.unexpected_token()?);
|
return Err(self.unexpected_token()?);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some((token, attributes)) = attributes {
|
|
||||||
return Err(token.error(CompileErrorKind::ExtraneousAttributes {
|
|
||||||
count: attributes.len(),
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.next_token == self.tokens.len() {
|
if self.next_token == self.tokens.len() {
|
||||||
@ -992,16 +989,10 @@ impl<'run, 'src> Parser<'run, 'src> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Parse recipe attributes
|
/// Parse recipe attributes
|
||||||
fn parse_attributes(
|
fn parse_attributes(&mut self) -> CompileResult<'src, Option<BTreeSet<Attribute<'src>>>> {
|
||||||
&mut self,
|
|
||||||
) -> CompileResult<'src, Option<(Token<'src>, BTreeSet<Attribute<'src>>)>> {
|
|
||||||
let mut attributes = BTreeMap::new();
|
let mut attributes = BTreeMap::new();
|
||||||
|
|
||||||
let mut token = None;
|
while self.accepted(BracketL)? {
|
||||||
|
|
||||||
while let Some(bracket) = self.accept(BracketL)? {
|
|
||||||
token.get_or_insert(bracket);
|
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let name = self.parse_name()?;
|
let name = self.parse_name()?;
|
||||||
|
|
||||||
@ -1038,7 +1029,7 @@ impl<'run, 'src> Parser<'run, 'src> {
|
|||||||
if attributes.is_empty() {
|
if attributes.is_empty() {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
} else {
|
} else {
|
||||||
Ok(Some((token.unwrap(), attributes.into_keys().collect())))
|
Ok(Some(attributes.into_keys().collect()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -368,16 +368,7 @@ impl<'src, D> Recipe<'src, D> {
|
|||||||
io_error: error,
|
io_error: error,
|
||||||
})?;
|
})?;
|
||||||
let mut path = tempdir.path().to_path_buf();
|
let mut path = tempdir.path().to_path_buf();
|
||||||
|
path.push(shebang.script_filename(self.name()));
|
||||||
let extension = self.attributes.iter().find_map(|attribute| {
|
|
||||||
if let Attribute::Extension(extension) = attribute {
|
|
||||||
Some(extension.cooked.as_str())
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
path.push(shebang.script_filename(self.name(), extension));
|
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut f = fs::File::create(&path).map_err(|error| Error::TempdirIo {
|
let mut f = fs::File::create(&path).map_err(|error| Error::TempdirIo {
|
||||||
|
@ -38,14 +38,12 @@ impl<'line> Shebang<'line> {
|
|||||||
.unwrap_or(self.interpreter)
|
.unwrap_or(self.interpreter)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn script_filename(&self, recipe: &str, extension: Option<&str>) -> String {
|
pub(crate) fn script_filename(&self, recipe: &str) -> String {
|
||||||
let extension = extension.unwrap_or_else(|| match self.interpreter_filename() {
|
match self.interpreter_filename() {
|
||||||
"cmd" | "cmd.exe" => ".bat",
|
"cmd" | "cmd.exe" => format!("{recipe}.bat"),
|
||||||
"powershell" | "powershell.exe" | "pwsh" | "pwsh.exe" => ".ps1",
|
"powershell" | "powershell.exe" | "pwsh" | "pwsh.exe" => format!("{recipe}.ps1"),
|
||||||
_ => "",
|
_ => recipe.to_owned(),
|
||||||
});
|
}
|
||||||
|
|
||||||
format!("{recipe}{extension}")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn include_shebang_line(&self) -> bool {
|
pub(crate) fn include_shebang_line(&self) -> bool {
|
||||||
@ -140,9 +138,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn powershell_script_filename() {
|
fn powershell_script_filename() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Shebang::new("#!powershell")
|
Shebang::new("#!powershell").unwrap().script_filename("foo"),
|
||||||
.unwrap()
|
|
||||||
.script_filename("foo", None),
|
|
||||||
"foo.ps1"
|
"foo.ps1"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -150,7 +146,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn pwsh_script_filename() {
|
fn pwsh_script_filename() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Shebang::new("#!pwsh").unwrap().script_filename("foo", None),
|
Shebang::new("#!pwsh").unwrap().script_filename("foo"),
|
||||||
"foo.ps1"
|
"foo.ps1"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -160,7 +156,7 @@ mod tests {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
Shebang::new("#!powershell.exe")
|
Shebang::new("#!powershell.exe")
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.script_filename("foo", None),
|
.script_filename("foo"),
|
||||||
"foo.ps1"
|
"foo.ps1"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -168,9 +164,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn pwsh_exe_script_filename() {
|
fn pwsh_exe_script_filename() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Shebang::new("#!pwsh.exe")
|
Shebang::new("#!pwsh.exe").unwrap().script_filename("foo"),
|
||||||
.unwrap()
|
|
||||||
.script_filename("foo", None),
|
|
||||||
"foo.ps1"
|
"foo.ps1"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -178,7 +172,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn cmd_script_filename() {
|
fn cmd_script_filename() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Shebang::new("#!cmd").unwrap().script_filename("foo", None),
|
Shebang::new("#!cmd").unwrap().script_filename("foo"),
|
||||||
"foo.bat"
|
"foo.bat"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -186,19 +180,14 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn cmd_exe_script_filename() {
|
fn cmd_exe_script_filename() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Shebang::new("#!cmd.exe")
|
Shebang::new("#!cmd.exe").unwrap().script_filename("foo"),
|
||||||
.unwrap()
|
|
||||||
.script_filename("foo", None),
|
|
||||||
"foo.bat"
|
"foo.bat"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn plain_script_filename() {
|
fn plain_script_filename() {
|
||||||
assert_eq!(
|
assert_eq!(Shebang::new("#!bar").unwrap().script_filename("foo"), "foo");
|
||||||
Shebang::new("#!bar").unwrap().script_filename("foo", None),
|
|
||||||
"foo"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -222,26 +211,4 @@ mod tests {
|
|||||||
fn include_shebang_line_other_windows() {
|
fn include_shebang_line_other_windows() {
|
||||||
assert!(!Shebang::new("#!foo -c").unwrap().include_shebang_line());
|
assert!(!Shebang::new("#!foo -c").unwrap().include_shebang_line());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn filename_with_extension() {
|
|
||||||
assert_eq!(
|
|
||||||
Shebang::new("#!bar")
|
|
||||||
.unwrap()
|
|
||||||
.script_filename("foo", Some(".sh")),
|
|
||||||
"foo.sh"
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
Shebang::new("#!pwsh.exe")
|
|
||||||
.unwrap()
|
|
||||||
.script_filename("foo", Some(".sh")),
|
|
||||||
"foo.sh"
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
Shebang::new("#!cmd.exe")
|
|
||||||
.unwrap()
|
|
||||||
.script_filename("foo", Some(".sh")),
|
|
||||||
"foo.sh"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -79,7 +79,7 @@ impl Subcommand {
|
|||||||
justfile.run(config, &search, overrides, &[])?;
|
justfile.run(config, &search, overrides, &[])?;
|
||||||
}
|
}
|
||||||
Dump => Self::dump(config, ast, justfile)?,
|
Dump => Self::dump(config, ast, justfile)?,
|
||||||
Format => Self::format(config, &search, src, ast, justfile)?,
|
Format => Self::format(config, &search, src, ast)?,
|
||||||
Groups => Self::groups(config, justfile),
|
Groups => Self::groups(config, justfile),
|
||||||
List { path } => Self::list(config, justfile, path)?,
|
List { path } => Self::list(config, justfile, path)?,
|
||||||
Show { path } => Self::show(config, justfile, path)?,
|
Show { path } => Self::show(config, justfile, path)?,
|
||||||
@ -337,14 +337,8 @@ impl Subcommand {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn format(
|
fn format(config: &Config, search: &Search, src: &str, ast: &Ast) -> RunResult<'static> {
|
||||||
config: &Config,
|
config.require_unstable("The `--fmt` command is currently unstable.")?;
|
||||||
search: &Search,
|
|
||||||
src: &str,
|
|
||||||
ast: &Ast,
|
|
||||||
justfile: &Justfile,
|
|
||||||
) -> RunResult<'static> {
|
|
||||||
config.require_unstable(justfile, UnstableFeature::FormatSubcommand)?;
|
|
||||||
|
|
||||||
let formatted = ast.to_string();
|
let formatted = ast.to_string();
|
||||||
|
|
||||||
@ -452,7 +446,7 @@ impl Subcommand {
|
|||||||
signature_widths: &BTreeMap<&str, usize>,
|
signature_widths: &BTreeMap<&str, usize>,
|
||||||
) {
|
) {
|
||||||
if let Some(doc) = doc {
|
if let Some(doc) = doc {
|
||||||
if !doc.is_empty() && doc.lines().count() <= 1 {
|
if doc.lines().count() <= 1 {
|
||||||
print!(
|
print!(
|
||||||
"{:padding$}{} {}",
|
"{:padding$}{} {}",
|
||||||
"",
|
"",
|
||||||
@ -545,13 +539,13 @@ impl Subcommand {
|
|||||||
ordered.insert(0, None);
|
ordered.insert(0, None);
|
||||||
}
|
}
|
||||||
|
|
||||||
let no_groups = groups.contains_key(&None) && groups.len() == 1;
|
|
||||||
|
|
||||||
for (i, group) in ordered.into_iter().enumerate() {
|
for (i, group) in ordered.into_iter().enumerate() {
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
println!();
|
println!();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let no_groups = groups.contains_key(&None) && groups.len() == 1;
|
||||||
|
|
||||||
if !no_groups {
|
if !no_groups {
|
||||||
print!("{list_prefix}");
|
print!("{list_prefix}");
|
||||||
if let Some(group) = &group {
|
if let Some(group) = &group {
|
||||||
@ -611,16 +605,12 @@ impl Subcommand {
|
|||||||
Self::list_module(config, submodule, depth + 1);
|
Self::list_module(config, submodule, depth + 1);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (i, submodule) in module.modules(config).into_iter().enumerate() {
|
for submodule in module.modules(config) {
|
||||||
if !no_groups && !groups.is_empty() && i == 0 {
|
|
||||||
println!();
|
|
||||||
}
|
|
||||||
|
|
||||||
print!("{list_prefix}{} ...", submodule.name());
|
print!("{list_prefix}{} ...", submodule.name());
|
||||||
format_doc(
|
format_doc(
|
||||||
config,
|
config,
|
||||||
submodule.name(),
|
submodule.name(),
|
||||||
submodule.doc.as_deref(),
|
submodule.doc,
|
||||||
max_signature_width,
|
max_signature_width,
|
||||||
&signature_widths,
|
&signature_widths,
|
||||||
);
|
);
|
||||||
|
12
src/unstable.rs
Normal file
12
src/unstable.rs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#[derive(Copy, Clone, Debug, PartialEq, Ord, Eq, PartialOrd)]
|
||||||
|
pub(crate) enum Unstable {
|
||||||
|
Modules,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Unstable {
|
||||||
|
pub(crate) fn message(self) -> String {
|
||||||
|
match self {
|
||||||
|
Self::Modules => "Modules are currently unstable.".into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,14 +0,0 @@
|
|||||||
use super::*;
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Ord, Eq, PartialOrd)]
|
|
||||||
pub(crate) enum UnstableFeature {
|
|
||||||
FormatSubcommand,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Display for UnstableFeature {
|
|
||||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
|
||||||
match self {
|
|
||||||
Self::FormatSubcommand => write!(f, "The `--fmt` command is currently unstable."),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -193,40 +193,3 @@ fn doc_multiline() {
|
|||||||
)
|
)
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn extension() {
|
|
||||||
Test::new()
|
|
||||||
.justfile(
|
|
||||||
"
|
|
||||||
[extension: '.txt']
|
|
||||||
baz:
|
|
||||||
#!/bin/sh
|
|
||||||
echo $0
|
|
||||||
",
|
|
||||||
)
|
|
||||||
.stdout_regex(r"*baz\.txt\n")
|
|
||||||
.run();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn extension_on_linewise_error() {
|
|
||||||
Test::new()
|
|
||||||
.justfile(
|
|
||||||
"
|
|
||||||
[extension: '.txt']
|
|
||||||
baz:
|
|
||||||
",
|
|
||||||
)
|
|
||||||
.stderr(
|
|
||||||
"
|
|
||||||
error: Recipe `baz` has invalid attribute `extension`
|
|
||||||
——▶ justfile:2:1
|
|
||||||
│
|
|
||||||
2 │ baz:
|
|
||||||
│ ^^^
|
|
||||||
",
|
|
||||||
)
|
|
||||||
.status(EXIT_FAILURE)
|
|
||||||
.run();
|
|
||||||
}
|
|
||||||
|
@ -86,6 +86,7 @@ fn recipes_in_submodules_can_be_chosen() {
|
|||||||
.args(["--unstable", "--choose"])
|
.args(["--unstable", "--choose"])
|
||||||
.env("JUST_CHOOSER", "head -n10")
|
.env("JUST_CHOOSER", "head -n10")
|
||||||
.write("bar.just", "baz:\n echo BAZ")
|
.write("bar.just", "baz:\n echo BAZ")
|
||||||
|
.test_round_trip(false)
|
||||||
.justfile(
|
.justfile(
|
||||||
"
|
"
|
||||||
mod bar
|
mod bar
|
||||||
|
@ -864,6 +864,7 @@ fn source_file() {
|
|||||||
|
|
||||||
Test::new()
|
Test::new()
|
||||||
.args(["--evaluate", "x"])
|
.args(["--evaluate", "x"])
|
||||||
|
.test_round_trip(false)
|
||||||
.justfile(
|
.justfile(
|
||||||
"
|
"
|
||||||
import 'foo.just'
|
import 'foo.just'
|
||||||
@ -874,7 +875,8 @@ fn source_file() {
|
|||||||
.run();
|
.run();
|
||||||
|
|
||||||
Test::new()
|
Test::new()
|
||||||
.args(["foo", "bar"])
|
.args(["--unstable", "foo", "bar"])
|
||||||
|
.test_round_trip(false)
|
||||||
.justfile(
|
.justfile(
|
||||||
"
|
"
|
||||||
mod foo
|
mod foo
|
||||||
@ -888,7 +890,8 @@ fn source_file() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn source_directory() {
|
fn source_directory() {
|
||||||
Test::new()
|
Test::new()
|
||||||
.args(["foo", "bar"])
|
.args(["--unstable", "foo", "bar"])
|
||||||
|
.test_round_trip(false)
|
||||||
.justfile(
|
.justfile(
|
||||||
"
|
"
|
||||||
mod foo
|
mod foo
|
||||||
@ -981,7 +984,9 @@ import-outer: import-inner
|
|||||||
echo '{{ module_directory() }}'
|
echo '{{ module_directory() }}'
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
|
.test_round_trip(false)
|
||||||
.args([
|
.args([
|
||||||
|
"--unstable",
|
||||||
"outer",
|
"outer",
|
||||||
"import-outer",
|
"import-outer",
|
||||||
"baz",
|
"baz",
|
||||||
|
@ -17,6 +17,7 @@ fn import_succeeds() {
|
|||||||
@echo A
|
@echo A
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
|
.test_round_trip(false)
|
||||||
.arg("a")
|
.arg("a")
|
||||||
.stdout("B\nA\n")
|
.stdout("B\nA\n")
|
||||||
.run();
|
.run();
|
||||||
@ -33,6 +34,7 @@ fn missing_import_file_error() {
|
|||||||
@echo A
|
@echo A
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
|
.test_round_trip(false)
|
||||||
.arg("a")
|
.arg("a")
|
||||||
.status(EXIT_FAILURE)
|
.status(EXIT_FAILURE)
|
||||||
.stderr(
|
.stderr(
|
||||||
@ -58,6 +60,7 @@ fn missing_optional_imports_are_ignored() {
|
|||||||
@echo A
|
@echo A
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
|
.test_round_trip(false)
|
||||||
.arg("a")
|
.arg("a")
|
||||||
.stdout("A\n")
|
.stdout("A\n")
|
||||||
.run();
|
.run();
|
||||||
@ -76,6 +79,7 @@ fn trailing_spaces_after_import_are_ignored() {
|
|||||||
@echo A
|
@echo A
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
|
.test_round_trip(false)
|
||||||
.stdout("A\n")
|
.stdout("A\n")
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
@ -95,6 +99,7 @@ fn import_after_recipe() {
|
|||||||
import './import.justfile'
|
import './import.justfile'
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
|
.test_round_trip(false)
|
||||||
.stdout("A\n")
|
.stdout("A\n")
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
@ -121,6 +126,7 @@ fn import_recipes_are_not_default() {
|
|||||||
"import.justfile": "bar:",
|
"import.justfile": "bar:",
|
||||||
})
|
})
|
||||||
.justfile("import './import.justfile'")
|
.justfile("import './import.justfile'")
|
||||||
|
.test_round_trip(false)
|
||||||
.status(EXIT_FAILURE)
|
.status(EXIT_FAILURE)
|
||||||
.stderr("error: Justfile contains no default recipe.\n")
|
.stderr("error: Justfile contains no default recipe.\n")
|
||||||
.run();
|
.run();
|
||||||
@ -137,6 +143,7 @@ fn listed_recipes_in_imports_are_in_load_order() {
|
|||||||
)
|
)
|
||||||
.write("import.justfile", "bar:")
|
.write("import.justfile", "bar:")
|
||||||
.args(["--list", "--unsorted"])
|
.args(["--list", "--unsorted"])
|
||||||
|
.test_round_trip(false)
|
||||||
.stdout(
|
.stdout(
|
||||||
"
|
"
|
||||||
Available recipes:
|
Available recipes:
|
||||||
@ -183,6 +190,7 @@ fn recipes_in_import_are_overridden_by_recipes_in_parent() {
|
|||||||
set allow-duplicate-recipes
|
set allow-duplicate-recipes
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
|
.test_round_trip(false)
|
||||||
.arg("a")
|
.arg("a")
|
||||||
.stdout("ROOT\n")
|
.stdout("ROOT\n")
|
||||||
.run();
|
.run();
|
||||||
@ -208,6 +216,7 @@ fn variables_in_import_are_overridden_by_variables_in_parent() {
|
|||||||
@echo {{f}}
|
@echo {{f}}
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
|
.test_round_trip(false)
|
||||||
.arg("a")
|
.arg("a")
|
||||||
.stdout("bar\n")
|
.stdout("bar\n")
|
||||||
.run();
|
.run();
|
||||||
@ -223,6 +232,7 @@ fn import_paths_beginning_with_tilde_are_expanded_to_homdir() {
|
|||||||
import '~/mod.just'
|
import '~/mod.just'
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
|
.test_round_trip(false)
|
||||||
.arg("foo")
|
.arg("foo")
|
||||||
.stdout("FOOBAR\n")
|
.stdout("FOOBAR\n")
|
||||||
.env("HOME", "foobar")
|
.env("HOME", "foobar")
|
||||||
@ -238,6 +248,7 @@ fn imports_dump_correctly() {
|
|||||||
import './import.justfile'
|
import './import.justfile'
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
|
.test_round_trip(false)
|
||||||
.arg("--dump")
|
.arg("--dump")
|
||||||
.stdout("import './import.justfile'\n")
|
.stdout("import './import.justfile'\n")
|
||||||
.run();
|
.run();
|
||||||
@ -252,6 +263,7 @@ fn optional_imports_dump_correctly() {
|
|||||||
import? './import.justfile'
|
import? './import.justfile'
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
|
.test_round_trip(false)
|
||||||
.arg("--dump")
|
.arg("--dump")
|
||||||
.stdout("import? './import.justfile'\n")
|
.stdout("import? './import.justfile'\n")
|
||||||
.run();
|
.run();
|
||||||
@ -267,6 +279,7 @@ fn imports_in_root_run_in_justfile_directory() {
|
|||||||
import 'foo/import.justfile'
|
import 'foo/import.justfile'
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
|
.test_round_trip(false)
|
||||||
.arg("bar")
|
.arg("bar")
|
||||||
.stdout("BAZ")
|
.stdout("BAZ")
|
||||||
.run();
|
.run();
|
||||||
@ -279,6 +292,8 @@ fn imports_in_submodules_run_in_submodule_directory() {
|
|||||||
.write("foo/mod.just", "import 'import.just'")
|
.write("foo/mod.just", "import 'import.just'")
|
||||||
.write("foo/import.just", "bar:\n @cat baz")
|
.write("foo/import.just", "bar:\n @cat baz")
|
||||||
.write("foo/baz", "BAZ")
|
.write("foo/baz", "BAZ")
|
||||||
|
.test_round_trip(false)
|
||||||
|
.arg("--unstable")
|
||||||
.arg("foo")
|
.arg("foo")
|
||||||
.arg("bar")
|
.arg("bar")
|
||||||
.stdout("BAZ")
|
.stdout("BAZ")
|
||||||
@ -291,6 +306,7 @@ fn nested_import_paths_are_relative_to_containing_submodule() {
|
|||||||
.justfile("import 'foo/import.just'")
|
.justfile("import 'foo/import.just'")
|
||||||
.write("foo/import.just", "import 'bar.just'")
|
.write("foo/import.just", "import 'bar.just'")
|
||||||
.write("foo/bar.just", "bar:\n @echo BAR")
|
.write("foo/bar.just", "bar:\n @echo BAR")
|
||||||
|
.test_round_trip(false)
|
||||||
.arg("bar")
|
.arg("bar")
|
||||||
.stdout("BAR\n")
|
.stdout("BAR\n")
|
||||||
.run();
|
.run();
|
||||||
@ -303,6 +319,8 @@ fn recipes_in_nested_imports_run_in_parent_module() {
|
|||||||
.write("foo/import.just", "import 'bar/import.just'")
|
.write("foo/import.just", "import 'bar/import.just'")
|
||||||
.write("foo/bar/import.just", "bar:\n @cat baz")
|
.write("foo/bar/import.just", "bar:\n @cat baz")
|
||||||
.write("baz", "BAZ")
|
.write("baz", "BAZ")
|
||||||
|
.test_round_trip(false)
|
||||||
|
.arg("--unstable")
|
||||||
.arg("bar")
|
.arg("bar")
|
||||||
.stdout("BAZ")
|
.stdout("BAZ")
|
||||||
.run();
|
.run();
|
||||||
@ -321,6 +339,7 @@ fn shebang_recipes_in_imports_in_root_run_in_justfile_directory() {
|
|||||||
import 'foo/import.justfile'
|
import 'foo/import.justfile'
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
|
.test_round_trip(false)
|
||||||
.arg("bar")
|
.arg("bar")
|
||||||
.stdout("BAZ")
|
.stdout("BAZ")
|
||||||
.run();
|
.run();
|
||||||
@ -338,6 +357,7 @@ fn recipes_imported_in_root_run_in_command_line_provided_working_directory() {
|
|||||||
"--justfile",
|
"--justfile",
|
||||||
"subdir/a.justfile",
|
"subdir/a.justfile",
|
||||||
])
|
])
|
||||||
|
.test_round_trip(false)
|
||||||
.stdout("BAZBAZ")
|
.stdout("BAZBAZ")
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ use super::*;
|
|||||||
fn case(justfile: &str, value: Value) {
|
fn case(justfile: &str, value: Value) {
|
||||||
Test::new()
|
Test::new()
|
||||||
.justfile(justfile)
|
.justfile(justfile)
|
||||||
.args(["--dump", "--dump-format", "json"])
|
.args(["--dump", "--dump-format", "json", "--unstable"])
|
||||||
.stdout(format!("{}\n", serde_json::to_string(&value).unwrap()))
|
.stdout(format!("{}\n", serde_json::to_string(&value).unwrap()))
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
@ -1110,7 +1110,8 @@ fn module() {
|
|||||||
.tree(tree! {
|
.tree(tree! {
|
||||||
"foo.just": "bar:",
|
"foo.just": "bar:",
|
||||||
})
|
})
|
||||||
.args(["--dump", "--dump-format", "json"])
|
.args(["--dump", "--dump-format", "json", "--unstable"])
|
||||||
|
.test_round_trip(false)
|
||||||
.stdout(format!(
|
.stdout(format!(
|
||||||
"{}\n",
|
"{}\n",
|
||||||
serde_json::to_string(&json!({
|
serde_json::to_string(&json!({
|
||||||
|
@ -12,7 +12,8 @@ fn modules_unsorted() {
|
|||||||
mod bar
|
mod bar
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
.args(["--list", "--unsorted"])
|
.test_round_trip(false)
|
||||||
|
.args(["--unstable", "--list", "--unsorted"])
|
||||||
.stdout(
|
.stdout(
|
||||||
"
|
"
|
||||||
Available recipes:
|
Available recipes:
|
||||||
@ -155,7 +156,8 @@ fn list_submodule() {
|
|||||||
mod foo
|
mod foo
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
.args(["--list", "foo"])
|
.test_round_trip(false)
|
||||||
|
.args(["--unstable", "--list", "foo"])
|
||||||
.stdout(
|
.stdout(
|
||||||
"
|
"
|
||||||
Available recipes:
|
Available recipes:
|
||||||
@ -175,7 +177,8 @@ fn list_nested_submodule() {
|
|||||||
mod foo
|
mod foo
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
.args(["--list", "foo", "bar"])
|
.test_round_trip(false)
|
||||||
|
.args(["--unstable", "--list", "foo", "bar"])
|
||||||
.stdout(
|
.stdout(
|
||||||
"
|
"
|
||||||
Available recipes:
|
Available recipes:
|
||||||
@ -192,7 +195,8 @@ fn list_nested_submodule() {
|
|||||||
mod foo
|
mod foo
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
.args(["--list", "foo::bar"])
|
.test_round_trip(false)
|
||||||
|
.args(["--unstable", "--list", "foo::bar"])
|
||||||
.stdout(
|
.stdout(
|
||||||
"
|
"
|
||||||
Available recipes:
|
Available recipes:
|
||||||
@ -205,7 +209,7 @@ fn list_nested_submodule() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn list_invalid_path() {
|
fn list_invalid_path() {
|
||||||
Test::new()
|
Test::new()
|
||||||
.args(["--list", "$hello"])
|
.args(["--unstable", "--list", "$hello"])
|
||||||
.stderr("error: Invalid module path `$hello`\n")
|
.stderr("error: Invalid module path `$hello`\n")
|
||||||
.status(1)
|
.status(1)
|
||||||
.run();
|
.run();
|
||||||
@ -214,7 +218,7 @@ fn list_invalid_path() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn list_unknown_submodule() {
|
fn list_unknown_submodule() {
|
||||||
Test::new()
|
Test::new()
|
||||||
.args(["--list", "hello"])
|
.args(["--unstable", "--list", "hello"])
|
||||||
.stderr("error: Justfile does not contain submodule `hello`\n")
|
.stderr("error: Justfile does not contain submodule `hello`\n")
|
||||||
.status(1)
|
.status(1)
|
||||||
.run();
|
.run();
|
||||||
@ -232,7 +236,8 @@ fn list_with_groups_in_modules() {
|
|||||||
",
|
",
|
||||||
)
|
)
|
||||||
.write("bar.just", "[group('BAZ')]\nbaz:")
|
.write("bar.just", "[group('BAZ')]\nbaz:")
|
||||||
.args(["--list", "--list-submodules"])
|
.test_round_trip(false)
|
||||||
|
.args(["--unstable", "--list", "--list-submodules"])
|
||||||
.stdout(
|
.stdout(
|
||||||
"
|
"
|
||||||
Available recipes:
|
Available recipes:
|
||||||
@ -256,7 +261,8 @@ fn list_displays_recipes_in_submodules() {
|
|||||||
mod foo
|
mod foo
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
.args(["--list", "--list-submodules"])
|
.test_round_trip(false)
|
||||||
|
.args(["--unstable", "--list", "--list-submodules"])
|
||||||
.stdout(
|
.stdout(
|
||||||
"
|
"
|
||||||
Available recipes:
|
Available recipes:
|
||||||
@ -279,7 +285,8 @@ fn modules_are_space_separated_in_output() {
|
|||||||
mod bar
|
mod bar
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
.args(["--list", "--list-submodules"])
|
.test_round_trip(false)
|
||||||
|
.args(["--unstable", "--list", "--list-submodules"])
|
||||||
.stdout(
|
.stdout(
|
||||||
"
|
"
|
||||||
Available recipes:
|
Available recipes:
|
||||||
@ -312,7 +319,8 @@ barbarbar:
|
|||||||
",
|
",
|
||||||
)
|
)
|
||||||
.justfile("mod foo")
|
.justfile("mod foo")
|
||||||
.args(["--list", "--list-submodules"])
|
.test_round_trip(false)
|
||||||
|
.args(["--unstable", "--list", "--list-submodules"])
|
||||||
.stdout(
|
.stdout(
|
||||||
"
|
"
|
||||||
Available recipes:
|
Available recipes:
|
||||||
@ -333,7 +341,8 @@ fn nested_modules_are_properly_indented() {
|
|||||||
mod foo
|
mod foo
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
.args(["--list", "--list-submodules"])
|
.test_round_trip(false)
|
||||||
|
.args(["--unstable", "--list", "--list-submodules"])
|
||||||
.stdout(
|
.stdout(
|
||||||
"
|
"
|
||||||
Available recipes:
|
Available recipes:
|
||||||
@ -355,7 +364,8 @@ fn module_doc_rendered() {
|
|||||||
mod foo
|
mod foo
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
.args(["--list"])
|
.test_round_trip(false)
|
||||||
|
.args(["--unstable", "--list"])
|
||||||
.stdout(
|
.stdout(
|
||||||
"
|
"
|
||||||
Available recipes:
|
Available recipes:
|
||||||
@ -383,7 +393,8 @@ fn module_doc_aligned() {
|
|||||||
@echo Hi
|
@echo Hi
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
.args(["--list"])
|
.test_round_trip(false)
|
||||||
|
.args(["--unstable", "--list"])
|
||||||
.stdout(
|
.stdout(
|
||||||
"
|
"
|
||||||
Available recipes:
|
Available recipes:
|
||||||
@ -394,47 +405,3 @@ fn module_doc_aligned() {
|
|||||||
)
|
)
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn space_before_submodules_following_groups() {
|
|
||||||
Test::new()
|
|
||||||
.write("foo.just", "")
|
|
||||||
.justfile(
|
|
||||||
"
|
|
||||||
mod foo
|
|
||||||
|
|
||||||
[group: 'baz']
|
|
||||||
bar:
|
|
||||||
",
|
|
||||||
)
|
|
||||||
.args(["--list"])
|
|
||||||
.stdout(
|
|
||||||
"
|
|
||||||
Available recipes:
|
|
||||||
[baz]
|
|
||||||
bar
|
|
||||||
|
|
||||||
foo ...
|
|
||||||
",
|
|
||||||
)
|
|
||||||
.run();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn no_space_before_submodules_not_following_groups() {
|
|
||||||
Test::new()
|
|
||||||
.write("foo.just", "")
|
|
||||||
.justfile(
|
|
||||||
"
|
|
||||||
mod foo
|
|
||||||
",
|
|
||||||
)
|
|
||||||
.args(["--list"])
|
|
||||||
.stdout(
|
|
||||||
"
|
|
||||||
Available recipes:
|
|
||||||
foo ...
|
|
||||||
",
|
|
||||||
)
|
|
||||||
.run();
|
|
||||||
}
|
|
||||||
|
164
tests/modules.rs
164
tests/modules.rs
@ -1,16 +1,16 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn modules_are_stable() {
|
fn modules_are_unstable() {
|
||||||
Test::new()
|
Test::new()
|
||||||
.justfile(
|
.justfile(
|
||||||
"
|
"
|
||||||
mod foo
|
mod foo
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
.write("foo.just", "@bar:\n echo ok")
|
.write("foo.just", "")
|
||||||
.args(["foo", "bar"])
|
.stderr_regex("error: Modules are currently unstable..*")
|
||||||
.stdout("ok\n")
|
.status(EXIT_FAILURE)
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23,6 +23,8 @@ fn default_recipe_in_submodule_must_have_no_arguments() {
|
|||||||
mod foo
|
mod foo
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
|
.test_round_trip(false)
|
||||||
|
.arg("--unstable")
|
||||||
.arg("foo")
|
.arg("foo")
|
||||||
.stderr("error: Recipe `foo` cannot be used as default recipe since it requires at least 1 argument.\n")
|
.stderr("error: Recipe `foo` cannot be used as default recipe since it requires at least 1 argument.\n")
|
||||||
.status(EXIT_FAILURE)
|
.status(EXIT_FAILURE)
|
||||||
@ -38,6 +40,8 @@ fn module_recipes_can_be_run_as_subcommands() {
|
|||||||
mod foo
|
mod foo
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
|
.test_round_trip(false)
|
||||||
|
.arg("--unstable")
|
||||||
.arg("foo")
|
.arg("foo")
|
||||||
.arg("foo")
|
.arg("foo")
|
||||||
.stdout("FOO\n")
|
.stdout("FOO\n")
|
||||||
@ -53,6 +57,8 @@ fn module_recipes_can_be_run_with_path_syntax() {
|
|||||||
mod foo
|
mod foo
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
|
.test_round_trip(false)
|
||||||
|
.arg("--unstable")
|
||||||
.arg("foo::foo")
|
.arg("foo::foo")
|
||||||
.stdout("FOO\n")
|
.stdout("FOO\n")
|
||||||
.run();
|
.run();
|
||||||
@ -68,6 +74,8 @@ fn nested_module_recipes_can_be_run_with_path_syntax() {
|
|||||||
mod foo
|
mod foo
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
|
.test_round_trip(false)
|
||||||
|
.arg("--unstable")
|
||||||
.arg("foo::bar::baz")
|
.arg("foo::bar::baz")
|
||||||
.stdout("BAZ\n")
|
.stdout("BAZ\n")
|
||||||
.run();
|
.run();
|
||||||
@ -76,18 +84,21 @@ fn nested_module_recipes_can_be_run_with_path_syntax() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn invalid_path_syntax() {
|
fn invalid_path_syntax() {
|
||||||
Test::new()
|
Test::new()
|
||||||
|
.test_round_trip(false)
|
||||||
.arg(":foo::foo")
|
.arg(":foo::foo")
|
||||||
.stderr("error: Justfile does not contain recipe `:foo::foo`.\n")
|
.stderr("error: Justfile does not contain recipe `:foo::foo`.\n")
|
||||||
.status(EXIT_FAILURE)
|
.status(EXIT_FAILURE)
|
||||||
.run();
|
.run();
|
||||||
|
|
||||||
Test::new()
|
Test::new()
|
||||||
|
.test_round_trip(false)
|
||||||
.arg("foo::foo:")
|
.arg("foo::foo:")
|
||||||
.stderr("error: Justfile does not contain recipe `foo::foo:`.\n")
|
.stderr("error: Justfile does not contain recipe `foo::foo:`.\n")
|
||||||
.status(EXIT_FAILURE)
|
.status(EXIT_FAILURE)
|
||||||
.run();
|
.run();
|
||||||
|
|
||||||
Test::new()
|
Test::new()
|
||||||
|
.test_round_trip(false)
|
||||||
.arg("foo:::foo")
|
.arg("foo:::foo")
|
||||||
.stderr("error: Justfile does not contain recipe `foo:::foo`.\n")
|
.stderr("error: Justfile does not contain recipe `foo:::foo`.\n")
|
||||||
.status(EXIT_FAILURE)
|
.status(EXIT_FAILURE)
|
||||||
@ -97,6 +108,7 @@ fn invalid_path_syntax() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn missing_recipe_after_invalid_path() {
|
fn missing_recipe_after_invalid_path() {
|
||||||
Test::new()
|
Test::new()
|
||||||
|
.test_round_trip(false)
|
||||||
.arg(":foo::foo")
|
.arg(":foo::foo")
|
||||||
.arg("bar")
|
.arg("bar")
|
||||||
.stderr("error: Justfile does not contain recipe `:foo::foo`.\n")
|
.stderr("error: Justfile does not contain recipe `:foo::foo`.\n")
|
||||||
@ -114,6 +126,8 @@ fn assignments_are_evaluated_in_modules() {
|
|||||||
bar := 'PARENT'
|
bar := 'PARENT'
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
|
.test_round_trip(false)
|
||||||
|
.arg("--unstable")
|
||||||
.arg("foo")
|
.arg("foo")
|
||||||
.arg("foo")
|
.arg("foo")
|
||||||
.stdout("CHILD\n")
|
.stdout("CHILD\n")
|
||||||
@ -129,6 +143,8 @@ fn module_subcommand_runs_default_recipe() {
|
|||||||
mod foo
|
mod foo
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
|
.test_round_trip(false)
|
||||||
|
.arg("--unstable")
|
||||||
.arg("foo")
|
.arg("foo")
|
||||||
.stdout("FOO\n")
|
.stdout("FOO\n")
|
||||||
.run();
|
.run();
|
||||||
@ -144,6 +160,8 @@ fn modules_can_contain_other_modules() {
|
|||||||
mod foo
|
mod foo
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
|
.test_round_trip(false)
|
||||||
|
.arg("--unstable")
|
||||||
.arg("foo")
|
.arg("foo")
|
||||||
.arg("bar")
|
.arg("bar")
|
||||||
.arg("baz")
|
.arg("baz")
|
||||||
@ -161,6 +179,8 @@ fn circular_module_imports_are_detected() {
|
|||||||
mod foo
|
mod foo
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
|
.test_round_trip(false)
|
||||||
|
.arg("--unstable")
|
||||||
.arg("foo")
|
.arg("foo")
|
||||||
.arg("bar")
|
.arg("bar")
|
||||||
.arg("baz")
|
.arg("baz")
|
||||||
@ -187,6 +207,8 @@ foo:
|
|||||||
mod foo
|
mod foo
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
|
.test_round_trip(false)
|
||||||
|
.arg("--unstable")
|
||||||
.arg("foo")
|
.arg("foo")
|
||||||
.arg("foo")
|
.arg("foo")
|
||||||
.stdout("FOO\n")
|
.stdout("FOO\n")
|
||||||
@ -207,7 +229,9 @@ foo:
|
|||||||
set allow-duplicate-recipes
|
set allow-duplicate-recipes
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
|
.test_round_trip(false)
|
||||||
.status(EXIT_FAILURE)
|
.status(EXIT_FAILURE)
|
||||||
|
.arg("--unstable")
|
||||||
.arg("foo")
|
.arg("foo")
|
||||||
.arg("foo")
|
.arg("foo")
|
||||||
.stderr(
|
.stderr(
|
||||||
@ -241,7 +265,9 @@ fn modules_conflict_with_recipes() {
|
|||||||
│ ^^^
|
│ ^^^
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
|
.test_round_trip(false)
|
||||||
.status(EXIT_FAILURE)
|
.status(EXIT_FAILURE)
|
||||||
|
.arg("--unstable")
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -265,7 +291,9 @@ fn modules_conflict_with_aliases() {
|
|||||||
│ ^^^
|
│ ^^^
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
|
.test_round_trip(false)
|
||||||
.status(EXIT_FAILURE)
|
.status(EXIT_FAILURE)
|
||||||
|
.arg("--unstable")
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -281,6 +309,7 @@ fn modules_conflict_with_other_modules() {
|
|||||||
bar:
|
bar:
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
|
.test_round_trip(false)
|
||||||
.status(EXIT_FAILURE)
|
.status(EXIT_FAILURE)
|
||||||
.stderr(
|
.stderr(
|
||||||
"
|
"
|
||||||
@ -291,6 +320,7 @@ fn modules_conflict_with_other_modules() {
|
|||||||
│ ^^^
|
│ ^^^
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
|
.arg("--unstable")
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -303,6 +333,8 @@ fn modules_are_dumped_correctly() {
|
|||||||
mod foo
|
mod foo
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
|
.test_round_trip(false)
|
||||||
|
.arg("--unstable")
|
||||||
.arg("--dump")
|
.arg("--dump")
|
||||||
.stdout("mod foo\n")
|
.stdout("mod foo\n")
|
||||||
.run();
|
.run();
|
||||||
@ -317,6 +349,8 @@ fn optional_modules_are_dumped_correctly() {
|
|||||||
mod? foo
|
mod? foo
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
|
.test_round_trip(false)
|
||||||
|
.arg("--unstable")
|
||||||
.arg("--dump")
|
.arg("--dump")
|
||||||
.stdout("mod? foo\n")
|
.stdout("mod? foo\n")
|
||||||
.run();
|
.run();
|
||||||
@ -331,6 +365,8 @@ fn modules_can_be_in_subdirectory() {
|
|||||||
mod foo
|
mod foo
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
|
.test_round_trip(false)
|
||||||
|
.arg("--unstable")
|
||||||
.arg("foo")
|
.arg("foo")
|
||||||
.arg("foo")
|
.arg("foo")
|
||||||
.stdout("FOO\n")
|
.stdout("FOO\n")
|
||||||
@ -346,6 +382,8 @@ fn modules_in_subdirectory_can_be_named_justfile() {
|
|||||||
mod foo
|
mod foo
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
|
.test_round_trip(false)
|
||||||
|
.arg("--unstable")
|
||||||
.arg("foo")
|
.arg("foo")
|
||||||
.arg("foo")
|
.arg("foo")
|
||||||
.stdout("FOO\n")
|
.stdout("FOO\n")
|
||||||
@ -361,6 +399,8 @@ fn modules_in_subdirectory_can_be_named_justfile_with_any_case() {
|
|||||||
mod foo
|
mod foo
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
|
.test_round_trip(false)
|
||||||
|
.arg("--unstable")
|
||||||
.arg("foo")
|
.arg("foo")
|
||||||
.arg("foo")
|
.arg("foo")
|
||||||
.stdout("FOO\n")
|
.stdout("FOO\n")
|
||||||
@ -376,6 +416,8 @@ fn modules_in_subdirectory_can_have_leading_dot() {
|
|||||||
mod foo
|
mod foo
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
|
.test_round_trip(false)
|
||||||
|
.arg("--unstable")
|
||||||
.arg("foo")
|
.arg("foo")
|
||||||
.arg("foo")
|
.arg("foo")
|
||||||
.stdout("FOO\n")
|
.stdout("FOO\n")
|
||||||
@ -392,6 +434,8 @@ fn modules_require_unambiguous_file() {
|
|||||||
mod foo
|
mod foo
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
|
.test_round_trip(false)
|
||||||
|
.arg("--unstable")
|
||||||
.status(EXIT_FAILURE)
|
.status(EXIT_FAILURE)
|
||||||
.stderr(
|
.stderr(
|
||||||
"
|
"
|
||||||
@ -414,6 +458,8 @@ fn missing_module_file_error() {
|
|||||||
mod foo
|
mod foo
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
|
.test_round_trip(false)
|
||||||
|
.arg("--unstable")
|
||||||
.status(EXIT_FAILURE)
|
.status(EXIT_FAILURE)
|
||||||
.stderr(
|
.stderr(
|
||||||
"
|
"
|
||||||
@ -438,6 +484,8 @@ fn missing_optional_modules_do_not_trigger_error() {
|
|||||||
@echo BAR
|
@echo BAR
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
|
.test_round_trip(false)
|
||||||
|
.arg("--unstable")
|
||||||
.stdout("BAR\n")
|
.stdout("BAR\n")
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
@ -453,6 +501,8 @@ fn missing_optional_modules_do_not_conflict() {
|
|||||||
",
|
",
|
||||||
)
|
)
|
||||||
.write("baz.just", "baz:\n @echo BAZ")
|
.write("baz.just", "baz:\n @echo BAZ")
|
||||||
|
.test_round_trip(false)
|
||||||
|
.arg("--unstable")
|
||||||
.arg("foo")
|
.arg("foo")
|
||||||
.arg("baz")
|
.arg("baz")
|
||||||
.stdout("BAZ\n")
|
.stdout("BAZ\n")
|
||||||
@ -471,7 +521,8 @@ fn root_dotenv_is_available_to_submodules() {
|
|||||||
)
|
)
|
||||||
.write("foo.just", "foo:\n @echo $DOTENV_KEY")
|
.write("foo.just", "foo:\n @echo $DOTENV_KEY")
|
||||||
.write(".env", "DOTENV_KEY=dotenv-value")
|
.write(".env", "DOTENV_KEY=dotenv-value")
|
||||||
.args(["foo", "foo"])
|
.test_round_trip(false)
|
||||||
|
.args(["--unstable", "foo", "foo"])
|
||||||
.stdout("dotenv-value\n")
|
.stdout("dotenv-value\n")
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
@ -491,7 +542,8 @@ fn dotenv_settings_in_submodule_are_ignored() {
|
|||||||
"set dotenv-load := false\nfoo:\n @echo $DOTENV_KEY",
|
"set dotenv-load := false\nfoo:\n @echo $DOTENV_KEY",
|
||||||
)
|
)
|
||||||
.write(".env", "DOTENV_KEY=dotenv-value")
|
.write(".env", "DOTENV_KEY=dotenv-value")
|
||||||
.args(["foo", "foo"])
|
.test_round_trip(false)
|
||||||
|
.args(["--unstable", "foo", "foo"])
|
||||||
.stdout("dotenv-value\n")
|
.stdout("dotenv-value\n")
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
@ -505,6 +557,8 @@ fn modules_may_specify_path() {
|
|||||||
mod foo 'commands/foo.just'
|
mod foo 'commands/foo.just'
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
|
.test_round_trip(false)
|
||||||
|
.arg("--unstable")
|
||||||
.arg("foo")
|
.arg("foo")
|
||||||
.arg("foo")
|
.arg("foo")
|
||||||
.stdout("FOO\n")
|
.stdout("FOO\n")
|
||||||
@ -520,6 +574,8 @@ fn modules_may_specify_path_to_directory() {
|
|||||||
mod foo 'commands/bar'
|
mod foo 'commands/bar'
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
|
.test_round_trip(false)
|
||||||
|
.arg("--unstable")
|
||||||
.arg("foo")
|
.arg("foo")
|
||||||
.arg("foo")
|
.arg("foo")
|
||||||
.stdout("FOO\n")
|
.stdout("FOO\n")
|
||||||
@ -535,6 +591,8 @@ fn modules_with_paths_are_dumped_correctly() {
|
|||||||
mod foo 'commands/foo.just'
|
mod foo 'commands/foo.just'
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
|
.test_round_trip(false)
|
||||||
|
.arg("--unstable")
|
||||||
.arg("--dump")
|
.arg("--dump")
|
||||||
.stdout("mod foo 'commands/foo.just'\n")
|
.stdout("mod foo 'commands/foo.just'\n")
|
||||||
.run();
|
.run();
|
||||||
@ -549,6 +607,8 @@ fn optional_modules_with_paths_are_dumped_correctly() {
|
|||||||
mod? foo 'commands/foo.just'
|
mod? foo 'commands/foo.just'
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
|
.test_round_trip(false)
|
||||||
|
.arg("--unstable")
|
||||||
.arg("--dump")
|
.arg("--dump")
|
||||||
.stdout("mod? foo 'commands/foo.just'\n")
|
.stdout("mod? foo 'commands/foo.just'\n")
|
||||||
.run();
|
.run();
|
||||||
@ -563,6 +623,7 @@ fn recipes_may_be_named_mod() {
|
|||||||
@echo FOO
|
@echo FOO
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
|
.test_round_trip(false)
|
||||||
.arg("mod")
|
.arg("mod")
|
||||||
.arg("bar")
|
.arg("bar")
|
||||||
.stdout("FOO\n")
|
.stdout("FOO\n")
|
||||||
@ -579,6 +640,8 @@ fn submodule_linewise_recipes_run_in_submodule_directory() {
|
|||||||
mod foo
|
mod foo
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
|
.test_round_trip(false)
|
||||||
|
.arg("--unstable")
|
||||||
.arg("foo")
|
.arg("foo")
|
||||||
.arg("foo")
|
.arg("foo")
|
||||||
.stdout("BAR")
|
.stdout("BAR")
|
||||||
@ -595,6 +658,8 @@ fn submodule_shebang_recipes_run_in_submodule_directory() {
|
|||||||
mod foo
|
mod foo
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
|
.test_round_trip(false)
|
||||||
|
.arg("--unstable")
|
||||||
.arg("foo")
|
.arg("foo")
|
||||||
.arg("foo")
|
.arg("foo")
|
||||||
.stdout("BAR")
|
.stdout("BAR")
|
||||||
@ -611,6 +676,8 @@ fn module_paths_beginning_with_tilde_are_expanded_to_homdir() {
|
|||||||
mod foo '~/mod.just'
|
mod foo '~/mod.just'
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
|
.test_round_trip(false)
|
||||||
|
.arg("--unstable")
|
||||||
.arg("foo")
|
.arg("foo")
|
||||||
.arg("foo")
|
.arg("foo")
|
||||||
.stdout("FOOBAR\n")
|
.stdout("FOOBAR\n")
|
||||||
@ -630,6 +697,8 @@ fn recipes_with_same_name_are_both_run() {
|
|||||||
@echo ROOT
|
@echo ROOT
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
|
.test_round_trip(false)
|
||||||
|
.arg("--unstable")
|
||||||
.arg("foo::bar")
|
.arg("foo::bar")
|
||||||
.arg("bar")
|
.arg("bar")
|
||||||
.stdout("MODULE\nROOT\n")
|
.stdout("MODULE\nROOT\n")
|
||||||
@ -639,7 +708,7 @@ fn recipes_with_same_name_are_both_run() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn submodule_recipe_not_found_error_message() {
|
fn submodule_recipe_not_found_error_message() {
|
||||||
Test::new()
|
Test::new()
|
||||||
.args(["foo::bar"])
|
.args(["--unstable", "foo::bar"])
|
||||||
.stderr("error: Justfile does not contain submodule `foo`\n")
|
.stderr("error: Justfile does not contain submodule `foo`\n")
|
||||||
.status(1)
|
.status(1)
|
||||||
.run();
|
.run();
|
||||||
@ -654,7 +723,8 @@ fn submodule_recipe_not_found_spaced_error_message() {
|
|||||||
mod foo
|
mod foo
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
.args(["foo", "baz"])
|
.test_round_trip(false)
|
||||||
|
.args(["--unstable", "foo", "baz"])
|
||||||
.stderr("error: Justfile does not contain recipe `foo baz`.\nDid you mean `bar`?\n")
|
.stderr("error: Justfile does not contain recipe `foo baz`.\nDid you mean `bar`?\n")
|
||||||
.status(1)
|
.status(1)
|
||||||
.run();
|
.run();
|
||||||
@ -669,7 +739,8 @@ fn submodule_recipe_not_found_colon_separated_error_message() {
|
|||||||
mod foo
|
mod foo
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
.args(["foo::baz"])
|
.test_round_trip(false)
|
||||||
|
.args(["--unstable", "foo::baz"])
|
||||||
.stderr("error: Justfile does not contain recipe `foo::baz`.\nDid you mean `bar`?\n")
|
.stderr("error: Justfile does not contain recipe `foo::baz`.\nDid you mean `bar`?\n")
|
||||||
.status(1)
|
.status(1)
|
||||||
.run();
|
.run();
|
||||||
@ -687,7 +758,7 @@ fn colon_separated_path_does_not_run_recipes() {
|
|||||||
@echo BAR
|
@echo BAR
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
.args(["foo::bar"])
|
.args(["--unstable", "foo::bar"])
|
||||||
.stderr("error: Expected submodule at `foo` but found recipe.\n")
|
.stderr("error: Expected submodule at `foo` but found recipe.\n")
|
||||||
.status(1)
|
.status(1)
|
||||||
.run();
|
.run();
|
||||||
@ -708,7 +779,8 @@ fn expected_submodule_but_found_recipe_in_submodule_error() {
|
|||||||
Test::new()
|
Test::new()
|
||||||
.justfile("mod foo")
|
.justfile("mod foo")
|
||||||
.write("foo.just", "bar:")
|
.write("foo.just", "bar:")
|
||||||
.args(["foo::bar::baz"])
|
.test_round_trip(false)
|
||||||
|
.args(["--unstable", "foo::bar::baz"])
|
||||||
.stderr("error: Expected submodule at `foo::bar` but found recipe.\n")
|
.stderr("error: Expected submodule at `foo::bar` but found recipe.\n")
|
||||||
.status(1)
|
.status(1)
|
||||||
.run();
|
.run();
|
||||||
@ -733,74 +805,8 @@ fn comments_can_follow_modules() {
|
|||||||
mod foo # this is foo
|
mod foo # this is foo
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
.args(["foo", "foo"])
|
.test_round_trip(false)
|
||||||
|
.args(["--unstable", "foo", "foo"])
|
||||||
.stdout("FOO\n")
|
.stdout("FOO\n")
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn doc_comment_on_module() {
|
|
||||||
Test::new()
|
|
||||||
.write("foo.just", "")
|
|
||||||
.justfile(
|
|
||||||
"
|
|
||||||
# Comment
|
|
||||||
mod foo
|
|
||||||
",
|
|
||||||
)
|
|
||||||
.test_round_trip(false)
|
|
||||||
.arg("--list")
|
|
||||||
.stdout("Available recipes:\n foo ... # Comment\n")
|
|
||||||
.run();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn doc_attribute_on_module() {
|
|
||||||
Test::new()
|
|
||||||
.write("foo.just", "")
|
|
||||||
.justfile(
|
|
||||||
r#"
|
|
||||||
# Suppressed comment
|
|
||||||
[doc: "Comment"]
|
|
||||||
mod foo
|
|
||||||
"#,
|
|
||||||
)
|
|
||||||
.test_round_trip(false)
|
|
||||||
.arg("--list")
|
|
||||||
.stdout("Available recipes:\n foo ... # Comment\n")
|
|
||||||
.run();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn bad_module_attribute_fails() {
|
|
||||||
Test::new()
|
|
||||||
.write("foo.just", "")
|
|
||||||
.justfile(
|
|
||||||
r#"
|
|
||||||
[no-cd]
|
|
||||||
mod foo
|
|
||||||
"#,
|
|
||||||
)
|
|
||||||
.test_round_trip(false)
|
|
||||||
.arg("--list")
|
|
||||||
.stderr("error: Module `foo` has invalid attribute `no-cd`\n ——▶ justfile:2:5\n │\n2 │ mod foo\n │ ^^^\n")
|
|
||||||
.status(EXIT_FAILURE)
|
|
||||||
.run();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn empty_doc_attribute_on_module() {
|
|
||||||
Test::new()
|
|
||||||
.write("foo.just", "")
|
|
||||||
.justfile(
|
|
||||||
r#"
|
|
||||||
# Suppressed comment
|
|
||||||
[doc]
|
|
||||||
mod foo
|
|
||||||
"#,
|
|
||||||
)
|
|
||||||
.test_round_trip(false)
|
|
||||||
.arg("--list")
|
|
||||||
.stdout("Available recipes:\n foo ...\n")
|
|
||||||
.run();
|
|
||||||
}
|
|
||||||
|
@ -80,7 +80,7 @@ error: Expected identifier, but found ']'
|
|||||||
}
|
}
|
||||||
|
|
||||||
test! {
|
test! {
|
||||||
name: extraneous_attribute_before_comment,
|
name: unattached_attribute_before_comment,
|
||||||
justfile: r#"
|
justfile: r#"
|
||||||
[no-exit-message]
|
[no-exit-message]
|
||||||
# This is a doc comment
|
# This is a doc comment
|
||||||
@ -88,31 +88,25 @@ hello:
|
|||||||
@exit 100
|
@exit 100
|
||||||
"#,
|
"#,
|
||||||
stderr: r#"
|
stderr: r#"
|
||||||
error: Extraneous attribute
|
error: Expected '@', '[', or identifier, but found comment
|
||||||
——▶ justfile:1:1
|
——▶ justfile:2:1
|
||||||
│
|
│
|
||||||
1 │ [no-exit-message]
|
2 │ # This is a doc comment
|
||||||
│ ^
|
│ ^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
"#,
|
"#,
|
||||||
|
|
||||||
status: EXIT_FAILURE,
|
status: EXIT_FAILURE,
|
||||||
}
|
}
|
||||||
|
|
||||||
test! {
|
test! {
|
||||||
name: extraneous_attribute_before_empty_line,
|
name: unattached_attribute_before_empty_line,
|
||||||
justfile: r#"
|
justfile: r#"
|
||||||
[no-exit-message]
|
[no-exit-message]
|
||||||
|
|
||||||
hello:
|
hello:
|
||||||
@exit 100
|
@exit 100
|
||||||
"#,
|
"#,
|
||||||
stderr: "
|
stderr: "error: Expected '@', '[', or identifier, but found end of line\n ——▶ justfile:2:1\n │\n2 │ \n │ ^\n",
|
||||||
error: Extraneous attribute
|
|
||||||
——▶ justfile:1:1
|
|
||||||
│
|
|
||||||
1 │ [no-exit-message]
|
|
||||||
│ ^
|
|
||||||
",
|
|
||||||
status: EXIT_FAILURE,
|
status: EXIT_FAILURE,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ fn shell_expanded_strings_are_dumped_correctly() {
|
|||||||
",
|
",
|
||||||
)
|
)
|
||||||
.env("JUST_TEST_VARIABLE", "FOO")
|
.env("JUST_TEST_VARIABLE", "FOO")
|
||||||
.args(["--dump"])
|
.args(["--dump", "--unstable"])
|
||||||
.stdout("x := x'$JUST_TEST_VARIABLE'\n")
|
.stdout("x := x'$JUST_TEST_VARIABLE'\n")
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
@ -114,8 +114,9 @@ fn shell_expanded_strings_can_be_used_in_mod_paths() {
|
|||||||
)
|
)
|
||||||
.write("mod.just", "@bar:\n echo BAR")
|
.write("mod.just", "@bar:\n echo BAR")
|
||||||
.env("JUST_TEST_VARIABLE", "mod.just")
|
.env("JUST_TEST_VARIABLE", "mod.just")
|
||||||
.args(["foo", "bar"])
|
.args(["--unstable", "foo", "bar"])
|
||||||
.stdout("BAR\n")
|
.stdout("BAR\n")
|
||||||
|
.test_round_trip(false)
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,7 +110,8 @@ fn show_recipe_at_path() {
|
|||||||
mod foo
|
mod foo
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
.args(["--show", "foo::bar"])
|
.test_round_trip(false)
|
||||||
|
.args(["--unstable", "--show", "foo::bar"])
|
||||||
.stdout("bar:\n @echo MODULE\n")
|
.stdout("bar:\n @echo MODULE\n")
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
@ -133,7 +134,8 @@ fn show_space_separated_path() {
|
|||||||
mod foo
|
mod foo
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
.args(["--show", "foo bar"])
|
.test_round_trip(false)
|
||||||
|
.args(["--unstable", "--show", "foo bar"])
|
||||||
.stdout("bar:\n @echo MODULE\n")
|
.stdout("bar:\n @echo MODULE\n")
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
@ -65,6 +65,8 @@ fn submodule_recipes() {
|
|||||||
bar:
|
bar:
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
|
.test_round_trip(false)
|
||||||
|
.arg("--unstable")
|
||||||
.arg("--summary")
|
.arg("--summary")
|
||||||
.stdout("bar foo::foo foo::bar::bar foo::bar::baz::baz foo::bar::baz::biz::biz\n")
|
.stdout("bar foo::foo foo::bar::bar foo::bar::baz::baz foo::bar::baz::biz::biz\n")
|
||||||
.run();
|
.run();
|
||||||
@ -79,6 +81,7 @@ fn summary_implies_unstable() {
|
|||||||
mod foo
|
mod foo
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
|
.test_round_trip(false)
|
||||||
.arg("--summary")
|
.arg("--summary")
|
||||||
.stdout("foo::foo\n")
|
.stdout("foo::foo\n")
|
||||||
.run();
|
.run();
|
||||||
|
@ -169,7 +169,6 @@ impl Test {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused)]
|
|
||||||
pub(crate) fn test_round_trip(mut self, test_round_trip: bool) -> Self {
|
pub(crate) fn test_round_trip(mut self, test_round_trip: bool) -> Self {
|
||||||
self.test_round_trip = test_round_trip;
|
self.test_round_trip = test_round_trip;
|
||||||
self
|
self
|
||||||
|
@ -2,9 +2,14 @@ use super::*;
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn set_unstable_true_with_env_var() {
|
fn set_unstable_true_with_env_var() {
|
||||||
|
let justfile = r#"
|
||||||
|
default:
|
||||||
|
echo 'foo'
|
||||||
|
"#;
|
||||||
|
|
||||||
for val in ["true", "some-arbitrary-string"] {
|
for val in ["true", "some-arbitrary-string"] {
|
||||||
Test::new()
|
Test::new()
|
||||||
.justfile("")
|
.justfile(justfile)
|
||||||
.args(["--fmt"])
|
.args(["--fmt"])
|
||||||
.env("JUST_UNSTABLE", val)
|
.env("JUST_UNSTABLE", val)
|
||||||
.status(EXIT_SUCCESS)
|
.status(EXIT_SUCCESS)
|
||||||
@ -15,9 +20,13 @@ fn set_unstable_true_with_env_var() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn set_unstable_false_with_env_var() {
|
fn set_unstable_false_with_env_var() {
|
||||||
|
let justfile = r#"
|
||||||
|
default:
|
||||||
|
echo 'foo'
|
||||||
|
"#;
|
||||||
for val in ["0", "", "false"] {
|
for val in ["0", "", "false"] {
|
||||||
Test::new()
|
Test::new()
|
||||||
.justfile("")
|
.justfile(justfile)
|
||||||
.args(["--fmt"])
|
.args(["--fmt"])
|
||||||
.env("JUST_UNSTABLE", val)
|
.env("JUST_UNSTABLE", val)
|
||||||
.status(EXIT_FAILURE)
|
.status(EXIT_FAILURE)
|
||||||
@ -28,8 +37,12 @@ fn set_unstable_false_with_env_var() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn set_unstable_false_with_env_var_unset() {
|
fn set_unstable_false_with_env_var_unset() {
|
||||||
|
let justfile = r#"
|
||||||
|
default:
|
||||||
|
echo 'foo'
|
||||||
|
"#;
|
||||||
Test::new()
|
Test::new()
|
||||||
.justfile("")
|
.justfile(justfile)
|
||||||
.args(["--fmt"])
|
.args(["--fmt"])
|
||||||
.status(EXIT_FAILURE)
|
.status(EXIT_FAILURE)
|
||||||
.stderr_regex("error: The `--fmt` command is currently unstable.*")
|
.stderr_regex("error: The `--fmt` command is currently unstable.*")
|
||||||
@ -39,16 +52,19 @@ fn set_unstable_false_with_env_var_unset() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn set_unstable_with_setting() {
|
fn set_unstable_with_setting() {
|
||||||
Test::new()
|
Test::new()
|
||||||
.justfile("set unstable")
|
.justfile(
|
||||||
.arg("--fmt")
|
"
|
||||||
.stderr_regex("Wrote justfile to .*")
|
set unstable
|
||||||
|
|
||||||
|
mod foo
|
||||||
|
",
|
||||||
|
)
|
||||||
|
.write("foo.just", "@bar:\n echo BAR")
|
||||||
|
.args(["foo", "bar"])
|
||||||
|
.stdout("BAR\n")
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
// This test should be re-enabled if we get a new unstable feature which is
|
|
||||||
// encountered in source files. (As opposed to, for example, the unstable
|
|
||||||
// `--fmt` subcommand, which is encountered on the command line.)
|
|
||||||
#[cfg(any())]
|
|
||||||
#[test]
|
#[test]
|
||||||
fn unstable_setting_does_not_affect_submodules() {
|
fn unstable_setting_does_not_affect_submodules() {
|
||||||
Test::new()
|
Test::new()
|
||||||
|
Loading…
Reference in New Issue
Block a user