aefdcea7d0
- Instead of changing the current directory with `env::set_current_dir` to be implicitly inherited by subprocesses, we now use `Command::current_dir` to set it explicitly. This feels much better, since we aren't dependent on the implicit state of the process's current directory. - Subcommand execution is much improved. - Added a ton of tests for config parsing, config execution, working dir, and search dir. - Error messages are improved. Many more will be colored. - The Config is now onwed, instead of borrowing from the arguments and the `clap::ArgMatches` object. This is a huge ergonomic improvement, especially in tests, and I don't think anyone will notice. - `--edit` now uses `$VISUAL`, `$EDITOR`, or `vim`, in that order, matching git, which I think is what most people will expect. - Added a cute `tmptree!{}` macro, for creating temporary directories populated with directories and files for tests. - Admitted that grammer is LL(k) and I don't know what `k` is.
84 lines
1.7 KiB
Markdown
84 lines
1.7 KiB
Markdown
justfile grammar
|
|
================
|
|
|
|
Justfiles are processed by a mildly context-sensitive tokenizer
|
|
and a recursive descent parser. The grammar is LL(k), for an
|
|
unknown but hopefully reasonable value of k.
|
|
|
|
tokens
|
|
------
|
|
|
|
```
|
|
BACKTICK = `[^`\n\r]*`
|
|
COMMENT = #([^!].*)?$
|
|
DEDENT = emitted when indentation decreases
|
|
EOF = emitted at the end of the file
|
|
INDENT = emitted when indentation increases
|
|
LINE = emitted before a recipe line
|
|
NAME = [a-zA-Z_][a-zA-Z0-9_-]*
|
|
NEWLINE = \n|\r\n
|
|
RAW_STRING = '[^'\r\n]*'
|
|
STRING = "[^"]*" # also processes \n \r \t \" \\ escapes
|
|
TEXT = recipe text, only matches in a recipe body
|
|
```
|
|
|
|
grammar syntax
|
|
--------------
|
|
|
|
```
|
|
| alternation
|
|
() grouping
|
|
_? option (0 or 1 times)
|
|
_* repetition (0 or more times)
|
|
_+ repetition (1 or more times)
|
|
```
|
|
|
|
grammar
|
|
-------
|
|
|
|
```
|
|
justfile : item* EOF
|
|
|
|
item : recipe
|
|
| alias
|
|
| assignment
|
|
| export
|
|
| eol
|
|
|
|
eol : NEWLINE
|
|
| COMMENT NEWLINE
|
|
|
|
alias : 'alias' NAME ':=' NAME
|
|
|
|
assignment : NAME ':=' expression eol
|
|
|
|
export : 'export' assignment
|
|
|
|
expression : value '+' expression
|
|
| value
|
|
|
|
value : NAME '(' sequence? ')'
|
|
| STRING
|
|
| RAW_STRING
|
|
| BACKTICK
|
|
| NAME
|
|
| '(' expression ')'
|
|
|
|
sequence : expression ',' sequence
|
|
| expression ','?
|
|
|
|
recipe : '@'? NAME parameter* ('+' parameter)? ':' dependencies? body?
|
|
|
|
parameter : NAME
|
|
| NAME '=' value
|
|
|
|
dependencies : NAME+
|
|
|
|
body : INDENT line+ DEDENT
|
|
|
|
line : LINE (TEXT | interpolation)+ NEWLINE
|
|
| NEWLINE
|
|
|
|
interpolation : '{{' expression '}}'
|
|
```
|