Add file paths to error messages (#1737)
This commit is contained in:
parent
f745316e88
commit
7337447d42
@ -42,6 +42,7 @@ impl<'src: 'run, 'run> AssignmentResolver<'src, 'run> {
|
|||||||
column: 0,
|
column: 0,
|
||||||
length: 0,
|
length: 0,
|
||||||
kind: TokenKind::Unspecified,
|
kind: TokenKind::Unspecified,
|
||||||
|
path: "".as_ref(),
|
||||||
};
|
};
|
||||||
return Err(CompileError::new(token, Internal { message }));
|
return Err(CompileError::new(token, Internal { message }));
|
||||||
}
|
}
|
||||||
|
@ -60,6 +60,10 @@ impl Color {
|
|||||||
self.redirect(Stream::Stdout)
|
self.redirect(Stream::Stdout)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn context(self) -> Self {
|
||||||
|
self.restyle(Style::new().fg(Blue).bold())
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn doc(self) -> Self {
|
pub(crate) fn doc(self) -> Self {
|
||||||
self.restyle(Style::new().fg(Blue))
|
self.restyle(Style::new().fg(Blue))
|
||||||
}
|
}
|
||||||
|
@ -15,8 +15,8 @@ impl Compiler {
|
|||||||
paths.push(root.into());
|
paths.push(root.into());
|
||||||
|
|
||||||
while let Some(current) = paths.pop() {
|
while let Some(current) = paths.pop() {
|
||||||
let src = loader.load(¤t)?;
|
let (relative, src) = loader.load(root, ¤t)?;
|
||||||
let tokens = Lexer::lex(src)?;
|
let tokens = Lexer::lex(relative, src)?;
|
||||||
let mut ast = Parser::parse(&tokens)?;
|
let mut ast = Parser::parse(&tokens)?;
|
||||||
|
|
||||||
srcs.insert(current.clone(), src);
|
srcs.insert(current.clone(), src);
|
||||||
@ -56,9 +56,9 @@ impl Compiler {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub(crate) fn test_compile(src: &str) -> CompileResult<Justfile> {
|
pub(crate) fn test_compile(src: &str) -> CompileResult<Justfile> {
|
||||||
let tokens = Lexer::lex(src)?;
|
let tokens = Lexer::test_lex(src)?;
|
||||||
let ast = Parser::parse(&tokens)?;
|
let ast = Parser::parse(&tokens)?;
|
||||||
let root = PathBuf::from("<ROOT>");
|
let root = PathBuf::from("justfile");
|
||||||
let mut asts: HashMap<PathBuf, Ast> = HashMap::new();
|
let mut asts: HashMap<PathBuf, Ast> = HashMap::new();
|
||||||
asts.insert(root.clone(), ast);
|
asts.insert(root.clone(), ast);
|
||||||
Analyzer::analyze(&asts, &root)
|
Analyzer::analyze(&asts, &root)
|
||||||
|
68
src/lexer.rs
68
src/lexer.rs
@ -9,38 +9,45 @@ use {super::*, CompileErrorKind::*, TokenKind::*};
|
|||||||
/// slight against regular expressions, the lexer was just idiosyncratically
|
/// slight against regular expressions, the lexer was just idiosyncratically
|
||||||
/// bad.
|
/// bad.
|
||||||
pub(crate) struct Lexer<'src> {
|
pub(crate) struct Lexer<'src> {
|
||||||
/// Source text
|
|
||||||
src: &'src str,
|
|
||||||
/// Char iterator
|
/// Char iterator
|
||||||
chars: Chars<'src>,
|
chars: Chars<'src>,
|
||||||
/// Tokens
|
|
||||||
tokens: Vec<Token<'src>>,
|
|
||||||
/// Current token start
|
|
||||||
token_start: Position,
|
|
||||||
/// Current token end
|
|
||||||
token_end: Position,
|
|
||||||
/// Next character to be lexed
|
|
||||||
next: Option<char>,
|
|
||||||
/// Next indent will start a recipe body
|
|
||||||
recipe_body_pending: bool,
|
|
||||||
/// Inside recipe body
|
|
||||||
recipe_body: bool,
|
|
||||||
/// Indentation stack
|
/// Indentation stack
|
||||||
indentation: Vec<&'src str>,
|
indentation: Vec<&'src str>,
|
||||||
/// Interpolation token start stack
|
/// Interpolation token start stack
|
||||||
interpolation_stack: Vec<Token<'src>>,
|
interpolation_stack: Vec<Token<'src>>,
|
||||||
|
/// Next character to be lexed
|
||||||
|
next: Option<char>,
|
||||||
/// Current open delimiters
|
/// Current open delimiters
|
||||||
open_delimiters: Vec<(Delimiter, usize)>,
|
open_delimiters: Vec<(Delimiter, usize)>,
|
||||||
|
/// Path to source file
|
||||||
|
path: &'src Path,
|
||||||
|
/// Inside recipe body
|
||||||
|
recipe_body: bool,
|
||||||
|
/// Next indent will start a recipe body
|
||||||
|
recipe_body_pending: bool,
|
||||||
|
/// Source text
|
||||||
|
src: &'src str,
|
||||||
|
/// Tokens
|
||||||
|
tokens: Vec<Token<'src>>,
|
||||||
|
/// Current token end
|
||||||
|
token_end: Position,
|
||||||
|
/// Current token start
|
||||||
|
token_start: Position,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'src> Lexer<'src> {
|
impl<'src> Lexer<'src> {
|
||||||
/// Lex `text`
|
/// Lex `src`
|
||||||
pub(crate) fn lex(src: &'src str) -> CompileResult<Vec<Token<'src>>> {
|
pub(crate) fn lex(path: &'src Path, src: &'src str) -> CompileResult<'src, Vec<Token<'src>>> {
|
||||||
Lexer::new(src).tokenize()
|
Lexer::new(path, src).tokenize()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new Lexer to lex `text`
|
#[cfg(test)]
|
||||||
fn new(src: &'src str) -> Lexer<'src> {
|
pub(crate) fn test_lex(src: &'src str) -> CompileResult<'src, Vec<Token<'src>>> {
|
||||||
|
Lexer::new("justfile".as_ref(), src).tokenize()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a new Lexer to lex `src`
|
||||||
|
fn new(path: &'src Path, src: &'src str) -> Lexer<'src> {
|
||||||
let mut chars = src.chars();
|
let mut chars = src.chars();
|
||||||
let next = chars.next();
|
let next = chars.next();
|
||||||
|
|
||||||
@ -62,6 +69,7 @@ impl<'src> Lexer<'src> {
|
|||||||
chars,
|
chars,
|
||||||
next,
|
next,
|
||||||
src,
|
src,
|
||||||
|
path,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,6 +197,7 @@ impl<'src> Lexer<'src> {
|
|||||||
src: self.src,
|
src: self.src,
|
||||||
length: self.token_end.offset - self.token_start.offset,
|
length: self.token_end.offset - self.token_start.offset,
|
||||||
kind,
|
kind,
|
||||||
|
path: self.path,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Set `token_start` to point after the lexed token
|
// Set `token_start` to point after the lexed token
|
||||||
@ -205,6 +214,7 @@ impl<'src> Lexer<'src> {
|
|||||||
column: self.token_end.column,
|
column: self.token_end.column,
|
||||||
length: 0,
|
length: 0,
|
||||||
kind: Unspecified,
|
kind: Unspecified,
|
||||||
|
path: self.path,
|
||||||
};
|
};
|
||||||
CompileError::new(
|
CompileError::new(
|
||||||
token,
|
token,
|
||||||
@ -240,6 +250,7 @@ impl<'src> Lexer<'src> {
|
|||||||
line: self.token_start.line,
|
line: self.token_start.line,
|
||||||
column: self.token_start.column,
|
column: self.token_start.column,
|
||||||
length,
|
length,
|
||||||
|
path: self.path,
|
||||||
};
|
};
|
||||||
|
|
||||||
CompileError::new(token, kind)
|
CompileError::new(token, kind)
|
||||||
@ -920,7 +931,7 @@ mod tests {
|
|||||||
text.to_owned()
|
text.to_owned()
|
||||||
};
|
};
|
||||||
|
|
||||||
let have = Lexer::lex(&text).unwrap();
|
let have = Lexer::test_lex(&text).unwrap();
|
||||||
|
|
||||||
let have_kinds = have
|
let have_kinds = have
|
||||||
.iter()
|
.iter()
|
||||||
@ -1028,7 +1039,7 @@ mod tests {
|
|||||||
length: usize,
|
length: usize,
|
||||||
kind: CompileErrorKind,
|
kind: CompileErrorKind,
|
||||||
) {
|
) {
|
||||||
match Lexer::lex(src) {
|
match Lexer::test_lex(src) {
|
||||||
Ok(_) => panic!("Lexing succeeded but expected"),
|
Ok(_) => panic!("Lexing succeeded but expected"),
|
||||||
Err(have) => {
|
Err(have) => {
|
||||||
let want = CompileError {
|
let want = CompileError {
|
||||||
@ -1039,6 +1050,7 @@ mod tests {
|
|||||||
line,
|
line,
|
||||||
column,
|
column,
|
||||||
length,
|
length,
|
||||||
|
path: "justfile".as_ref(),
|
||||||
},
|
},
|
||||||
kind: Box::new(kind),
|
kind: Box::new(kind),
|
||||||
};
|
};
|
||||||
@ -2321,7 +2333,9 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn presume_error() {
|
fn presume_error() {
|
||||||
let compile_error = Lexer::new("!").presume('-').unwrap_err();
|
let compile_error = Lexer::new("justfile".as_ref(), "!")
|
||||||
|
.presume('-')
|
||||||
|
.unwrap_err();
|
||||||
assert_matches!(
|
assert_matches!(
|
||||||
compile_error.token,
|
compile_error.token,
|
||||||
Token {
|
Token {
|
||||||
@ -2331,6 +2345,7 @@ mod tests {
|
|||||||
length: 0,
|
length: 0,
|
||||||
src: "!",
|
src: "!",
|
||||||
kind: Unspecified,
|
kind: Unspecified,
|
||||||
|
path: _,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
assert_matches!(&*compile_error.kind,
|
assert_matches!(&*compile_error.kind,
|
||||||
@ -2342,9 +2357,12 @@ mod tests {
|
|||||||
Error::Compile { compile_error }
|
Error::Compile { compile_error }
|
||||||
.color_display(Color::never())
|
.color_display(Color::never())
|
||||||
.to_string(),
|
.to_string(),
|
||||||
"error: Internal error, this may indicate a bug in just: \
|
"error: Internal error, this may indicate a bug in just: Lexer presumed character `-`
|
||||||
Lexer presumed character `-`\nconsider filing an issue: \
|
consider filing an issue: https://github.com/casey/just/issues/new
|
||||||
https://github.com/casey/just/issues/new\n |\n1 | !\n | ^"
|
--> justfile:1:1
|
||||||
|
|
|
||||||
|
1 | !
|
||||||
|
| ^"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,22 +1,34 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
pub(crate) struct Loader {
|
pub(crate) struct Loader {
|
||||||
arena: Arena<String>,
|
srcs: Arena<String>,
|
||||||
|
paths: Arena<PathBuf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Loader {
|
impl Loader {
|
||||||
pub(crate) fn new() -> Self {
|
pub(crate) fn new() -> Self {
|
||||||
Loader {
|
Loader {
|
||||||
arena: Arena::new(),
|
srcs: Arena::new(),
|
||||||
|
paths: Arena::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn load<'src>(&'src self, path: &Path) -> RunResult<&'src str> {
|
pub(crate) fn load<'src>(
|
||||||
|
&'src self,
|
||||||
|
root: &Path,
|
||||||
|
path: &Path,
|
||||||
|
) -> RunResult<(&'src Path, &'src str)> {
|
||||||
let src = fs::read_to_string(path).map_err(|io_error| Error::Load {
|
let src = fs::read_to_string(path).map_err(|io_error| Error::Load {
|
||||||
path: path.to_owned(),
|
path: path.to_owned(),
|
||||||
io_error,
|
io_error,
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
Ok(self.arena.alloc(src))
|
let relative = if let Ok(path) = path.strip_prefix(root.parent().unwrap()) {
|
||||||
|
path
|
||||||
|
} else {
|
||||||
|
path
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok((self.paths.alloc(relative.into()), self.srcs.alloc(src)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
15
src/name.rs
15
src/name.rs
@ -4,10 +4,11 @@ use super::*;
|
|||||||
/// it its own type for clarity.
|
/// it its own type for clarity.
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd)]
|
||||||
pub(crate) struct Name<'src> {
|
pub(crate) struct Name<'src> {
|
||||||
pub(crate) offset: usize,
|
pub(crate) column: usize,
|
||||||
pub(crate) length: usize,
|
pub(crate) length: usize,
|
||||||
pub(crate) line: usize,
|
pub(crate) line: usize,
|
||||||
pub(crate) column: usize,
|
pub(crate) offset: usize,
|
||||||
|
pub(crate) path: &'src Path,
|
||||||
pub(crate) src: &'src str,
|
pub(crate) src: &'src str,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -20,11 +21,12 @@ impl<'src> Name<'src> {
|
|||||||
/// Turn this name back into a token
|
/// Turn this name back into a token
|
||||||
pub(crate) fn token(&self) -> Token<'src> {
|
pub(crate) fn token(&self) -> Token<'src> {
|
||||||
Token {
|
Token {
|
||||||
|
column: self.column,
|
||||||
kind: TokenKind::Identifier,
|
kind: TokenKind::Identifier,
|
||||||
offset: self.offset,
|
|
||||||
length: self.length,
|
length: self.length,
|
||||||
line: self.line,
|
line: self.line,
|
||||||
column: self.column,
|
offset: self.offset,
|
||||||
|
path: self.path,
|
||||||
src: self.src,
|
src: self.src,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -32,10 +34,11 @@ impl<'src> Name<'src> {
|
|||||||
pub(crate) fn from_identifier(token: Token<'src>) -> Name {
|
pub(crate) fn from_identifier(token: Token<'src>) -> Name {
|
||||||
assert_eq!(token.kind, TokenKind::Identifier);
|
assert_eq!(token.kind, TokenKind::Identifier);
|
||||||
Name {
|
Name {
|
||||||
offset: token.offset,
|
column: token.column,
|
||||||
length: token.length,
|
length: token.length,
|
||||||
line: token.line,
|
line: token.line,
|
||||||
column: token.column,
|
offset: token.offset,
|
||||||
|
path: token.path,
|
||||||
src: token.src,
|
src: token.src,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -927,7 +927,7 @@ mod tests {
|
|||||||
|
|
||||||
fn test(text: &str, want: Tree) {
|
fn test(text: &str, want: Tree) {
|
||||||
let unindented = unindent(text);
|
let unindented = unindent(text);
|
||||||
let tokens = Lexer::lex(&unindented).expect("lexing failed");
|
let tokens = Lexer::test_lex(&unindented).expect("lexing failed");
|
||||||
let justfile = Parser::parse(&tokens).expect("parsing failed");
|
let justfile = Parser::parse(&tokens).expect("parsing failed");
|
||||||
let have = justfile.tree();
|
let have = justfile.tree();
|
||||||
if have != want {
|
if have != want {
|
||||||
@ -964,7 +964,7 @@ mod tests {
|
|||||||
length: usize,
|
length: usize,
|
||||||
kind: CompileErrorKind,
|
kind: CompileErrorKind,
|
||||||
) {
|
) {
|
||||||
let tokens = Lexer::lex(src).expect("Lexing failed in parse test...");
|
let tokens = Lexer::test_lex(src).expect("Lexing failed in parse test...");
|
||||||
|
|
||||||
match Parser::parse(&tokens) {
|
match Parser::parse(&tokens) {
|
||||||
Ok(_) => panic!("Parsing unexpectedly succeeded"),
|
Ok(_) => panic!("Parsing unexpectedly succeeded"),
|
||||||
@ -977,6 +977,7 @@ mod tests {
|
|||||||
line,
|
line,
|
||||||
column,
|
column,
|
||||||
length,
|
length,
|
||||||
|
path: "justfile".as_ref(),
|
||||||
},
|
},
|
||||||
kind: Box::new(kind),
|
kind: Box::new(kind),
|
||||||
};
|
};
|
||||||
|
@ -57,11 +57,11 @@ pub(crate) fn analysis_error(
|
|||||||
length: usize,
|
length: usize,
|
||||||
kind: CompileErrorKind,
|
kind: CompileErrorKind,
|
||||||
) {
|
) {
|
||||||
let tokens = Lexer::lex(src).expect("Lexing failed in parse test...");
|
let tokens = Lexer::test_lex(src).expect("Lexing failed in parse test...");
|
||||||
|
|
||||||
let ast = Parser::parse(&tokens).expect("Parsing failed in analysis test...");
|
let ast = Parser::parse(&tokens).expect("Parsing failed in analysis test...");
|
||||||
|
|
||||||
let root = PathBuf::from("<ROOT>");
|
let root = PathBuf::from("justfile");
|
||||||
let mut asts: HashMap<PathBuf, Ast> = HashMap::new();
|
let mut asts: HashMap<PathBuf, Ast> = HashMap::new();
|
||||||
asts.insert(root.clone(), ast);
|
asts.insert(root.clone(), ast);
|
||||||
|
|
||||||
@ -76,6 +76,7 @@ pub(crate) fn analysis_error(
|
|||||||
line,
|
line,
|
||||||
column,
|
column,
|
||||||
length,
|
length,
|
||||||
|
path: "justfile".as_ref(),
|
||||||
},
|
},
|
||||||
kind: Box::new(kind),
|
kind: Box::new(kind),
|
||||||
};
|
};
|
||||||
|
39
src/token.rs
39
src/token.rs
@ -2,12 +2,13 @@ use super::*;
|
|||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone, Copy)]
|
#[derive(Debug, PartialEq, Clone, Copy)]
|
||||||
pub(crate) struct Token<'src> {
|
pub(crate) struct Token<'src> {
|
||||||
pub(crate) offset: usize,
|
pub(crate) column: usize,
|
||||||
|
pub(crate) kind: TokenKind,
|
||||||
pub(crate) length: usize,
|
pub(crate) length: usize,
|
||||||
pub(crate) line: usize,
|
pub(crate) line: usize,
|
||||||
pub(crate) column: usize,
|
pub(crate) offset: usize,
|
||||||
|
pub(crate) path: &'src Path,
|
||||||
pub(crate) src: &'src str,
|
pub(crate) src: &'src str,
|
||||||
pub(crate) kind: TokenKind,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'src> Token<'src> {
|
impl<'src> Token<'src> {
|
||||||
@ -52,9 +53,35 @@ impl<'src> ColorDisplay for Token<'src> {
|
|||||||
i += c.len_utf8();
|
i += c.len_utf8();
|
||||||
}
|
}
|
||||||
let line_number_width = line_number.to_string().len();
|
let line_number_width = line_number.to_string().len();
|
||||||
writeln!(f, "{0:1$} |", "", line_number_width)?;
|
writeln!(
|
||||||
writeln!(f, "{line_number} | {space_line}")?;
|
f,
|
||||||
write!(f, "{0:1$} |", "", line_number_width)?;
|
"{:width$}{} {}:{}:{}",
|
||||||
|
"",
|
||||||
|
color.context().paint("-->"),
|
||||||
|
self.path.display(),
|
||||||
|
line_number,
|
||||||
|
self.column.ordinal(),
|
||||||
|
width = line_number_width
|
||||||
|
)?;
|
||||||
|
writeln!(
|
||||||
|
f,
|
||||||
|
"{:width$} {}",
|
||||||
|
"",
|
||||||
|
color.context().paint("|"),
|
||||||
|
width = line_number_width
|
||||||
|
)?;
|
||||||
|
writeln!(
|
||||||
|
f,
|
||||||
|
"{} {space_line}",
|
||||||
|
color.context().paint(&format!("{line_number} |"))
|
||||||
|
)?;
|
||||||
|
write!(
|
||||||
|
f,
|
||||||
|
"{:width$} {}",
|
||||||
|
"",
|
||||||
|
color.context().paint("|"),
|
||||||
|
width = line_number_width
|
||||||
|
)?;
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
" {0:1$}{2}{3:^<4$}{5}",
|
" {0:1$}{2}{3:^<4$}{5}",
|
||||||
|
@ -33,6 +33,7 @@ fn duplicate_attributes_are_disallowed() {
|
|||||||
.stderr(
|
.stderr(
|
||||||
"
|
"
|
||||||
error: Recipe attribute `no-exit-message` first used on line 1 is duplicated on line 2
|
error: Recipe attribute `no-exit-message` first used on line 1 is duplicated on line 2
|
||||||
|
--> justfile:2:2
|
||||||
|
|
|
|
||||||
2 | [no-exit-message]
|
2 | [no-exit-message]
|
||||||
| ^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^
|
||||||
@ -72,6 +73,7 @@ fn multiple_attributes_one_line_error_message() {
|
|||||||
.stderr(
|
.stderr(
|
||||||
"
|
"
|
||||||
error: Expected ']' or ',', but found identifier
|
error: Expected ']' or ',', but found identifier
|
||||||
|
--> justfile:1:17
|
||||||
|
|
|
|
||||||
1 | [macos, windows linux]
|
1 | [macos, windows linux]
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
@ -95,6 +97,7 @@ fn multiple_attributes_one_line_duplicate_check() {
|
|||||||
.stderr(
|
.stderr(
|
||||||
"
|
"
|
||||||
error: Recipe attribute `linux` first used on line 1 is duplicated on line 2
|
error: Recipe attribute `linux` first used on line 1 is duplicated on line 2
|
||||||
|
--> justfile:2:2
|
||||||
|
|
|
|
||||||
2 | [linux]
|
2 | [linux]
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
@ -27,6 +27,7 @@ fn non_leading_byte_order_mark_produces_error() {
|
|||||||
.stderr(
|
.stderr(
|
||||||
"
|
"
|
||||||
error: Expected \'@\', '!', \'[\', comment, end of file, end of line, or identifier, but found byte order mark
|
error: Expected \'@\', '!', \'[\', comment, end of file, end of line, or identifier, but found byte order mark
|
||||||
|
--> justfile:3:1
|
||||||
|
|
|
|
||||||
3 | \u{feff}
|
3 | \u{feff}
|
||||||
| ^
|
| ^
|
||||||
@ -42,6 +43,7 @@ fn dont_mention_byte_order_mark_in_errors() {
|
|||||||
.stderr(
|
.stderr(
|
||||||
"
|
"
|
||||||
error: Expected '@', '!', '[', comment, end of file, end of line, or identifier, but found '{'
|
error: Expected '@', '!', '[', comment, end of file, end of line, or identifier, but found '{'
|
||||||
|
--> justfile:1:1
|
||||||
|
|
|
|
||||||
1 | {
|
1 | {
|
||||||
| ^
|
| ^
|
||||||
|
@ -61,6 +61,7 @@ test! {
|
|||||||
stdout: "",
|
stdout: "",
|
||||||
stderr: "
|
stderr: "
|
||||||
error: Variable `b` not defined
|
error: Variable `b` not defined
|
||||||
|
--> justfile:1:9
|
||||||
|
|
|
|
||||||
1 | a := if b == '' { '' } else { '' }
|
1 | a := if b == '' { '' } else { '' }
|
||||||
| ^
|
| ^
|
||||||
@ -79,6 +80,7 @@ test! {
|
|||||||
stdout: "",
|
stdout: "",
|
||||||
stderr: "
|
stderr: "
|
||||||
error: Variable `b` not defined
|
error: Variable `b` not defined
|
||||||
|
--> justfile:1:15
|
||||||
|
|
|
|
||||||
1 | a := if '' == b { '' } else { '' }
|
1 | a := if '' == b { '' } else { '' }
|
||||||
| ^
|
| ^
|
||||||
@ -97,6 +99,7 @@ test! {
|
|||||||
stdout: "",
|
stdout: "",
|
||||||
stderr: "
|
stderr: "
|
||||||
error: Variable `b` not defined
|
error: Variable `b` not defined
|
||||||
|
--> justfile:1:20
|
||||||
|
|
|
|
||||||
1 | a := if '' == '' { b } else { '' }
|
1 | a := if '' == '' { b } else { '' }
|
||||||
| ^
|
| ^
|
||||||
@ -115,6 +118,7 @@ test! {
|
|||||||
stdout: "",
|
stdout: "",
|
||||||
stderr: "
|
stderr: "
|
||||||
error: Variable `b` not defined
|
error: Variable `b` not defined
|
||||||
|
--> justfile:1:32
|
||||||
|
|
|
|
||||||
1 | a := if '' == '' { '' } else { b }
|
1 | a := if '' == '' { '' } else { b }
|
||||||
| ^
|
| ^
|
||||||
@ -133,6 +137,7 @@ test! {
|
|||||||
stdout: "",
|
stdout: "",
|
||||||
stderr: "
|
stderr: "
|
||||||
error: Expected '!=', '==', '=~', '+', or '/', but found identifier
|
error: Expected '!=', '==', '=~', '+', or '/', but found identifier
|
||||||
|
--> justfile:1:12
|
||||||
|
|
|
|
||||||
1 | a := if '' a '' { '' } else { b }
|
1 | a := if '' a '' { '' } else { b }
|
||||||
| ^
|
| ^
|
||||||
@ -177,6 +182,7 @@ test! {
|
|||||||
stdout: "",
|
stdout: "",
|
||||||
stderr: "
|
stderr: "
|
||||||
error: Expected keyword `else` but found `end of line`
|
error: Expected keyword `else` but found `end of line`
|
||||||
|
--> justfile:1:54
|
||||||
|
|
|
|
||||||
1 | TEST := if path_exists('/bin/bash') == 'true' {'yes'}
|
1 | TEST := if path_exists('/bin/bash') == 'true' {'yes'}
|
||||||
| ^
|
| ^
|
||||||
@ -192,6 +198,7 @@ test! {
|
|||||||
stdout: "",
|
stdout: "",
|
||||||
stderr: "
|
stderr: "
|
||||||
error: Expected keyword `else` but found identifier `els`
|
error: Expected keyword `else` but found identifier `els`
|
||||||
|
--> justfile:1:55
|
||||||
|
|
|
|
||||||
1 | TEST := if path_exists('/bin/bash') == 'true' {'yes'} els {'no'}
|
1 | TEST := if path_exists('/bin/bash') == 'true' {'yes'} els {'no'}
|
||||||
| ^^^
|
| ^^^
|
||||||
|
@ -5,6 +5,7 @@ test! {
|
|||||||
justfile: "(]",
|
justfile: "(]",
|
||||||
stderr: "
|
stderr: "
|
||||||
error: Mismatched closing delimiter `]`. (Did you mean to close the `(` on line 1?)
|
error: Mismatched closing delimiter `]`. (Did you mean to close the `(` on line 1?)
|
||||||
|
--> justfile:1:2
|
||||||
|
|
|
|
||||||
1 | (]
|
1 | (]
|
||||||
| ^
|
| ^
|
||||||
@ -17,6 +18,7 @@ test! {
|
|||||||
justfile: "]",
|
justfile: "]",
|
||||||
stderr: "
|
stderr: "
|
||||||
error: Unexpected closing delimiter `]`
|
error: Unexpected closing delimiter `]`
|
||||||
|
--> justfile:1:1
|
||||||
|
|
|
|
||||||
1 | ]
|
1 | ]
|
||||||
| ^
|
| ^
|
||||||
@ -96,6 +98,7 @@ test! {
|
|||||||
stdout: "",
|
stdout: "",
|
||||||
stderr: "
|
stderr: "
|
||||||
error: Unterminated interpolation
|
error: Unterminated interpolation
|
||||||
|
--> justfile:2:8
|
||||||
|
|
|
|
||||||
2 | echo {{ (
|
2 | echo {{ (
|
||||||
| ^^
|
| ^^
|
||||||
|
@ -5,6 +5,7 @@ test! {
|
|||||||
justfile: "[private]\n[linux]\nalias t := test\n\ntest:\n",
|
justfile: "[private]\n[linux]\nalias t := test\n\ntest:\n",
|
||||||
stderr: "
|
stderr: "
|
||||||
error: Alias t has an invalid attribute `linux`
|
error: Alias t has an invalid attribute `linux`
|
||||||
|
--> justfile:3:7
|
||||||
|
|
|
|
||||||
3 | alias t := test
|
3 | alias t := test
|
||||||
| ^
|
| ^
|
||||||
@ -17,6 +18,7 @@ test! {
|
|||||||
justfile: "foo := if '' == '' { '' } arlo { '' }",
|
justfile: "foo := if '' == '' { '' } arlo { '' }",
|
||||||
stderr: "
|
stderr: "
|
||||||
error: Expected keyword `else` but found identifier `arlo`
|
error: Expected keyword `else` but found identifier `arlo`
|
||||||
|
--> justfile:1:27
|
||||||
|
|
|
|
||||||
1 | foo := if '' == '' { '' } arlo { '' }
|
1 | foo := if '' == '' { '' } arlo { '' }
|
||||||
| ^^^^
|
| ^^^^
|
||||||
@ -29,6 +31,7 @@ test! {
|
|||||||
justfile: "&~",
|
justfile: "&~",
|
||||||
stderr: "
|
stderr: "
|
||||||
error: Expected character `&`
|
error: Expected character `&`
|
||||||
|
--> justfile:1:2
|
||||||
|
|
|
|
||||||
1 | &~
|
1 | &~
|
||||||
| ^
|
| ^
|
||||||
@ -51,3 +54,61 @@ fn argument_count_mismatch() {
|
|||||||
.status(EXIT_FAILURE)
|
.status(EXIT_FAILURE)
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn file_path_is_indented_if_justfile_is_long() {
|
||||||
|
Test::new()
|
||||||
|
.justfile("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nfoo")
|
||||||
|
.status(EXIT_FAILURE)
|
||||||
|
.stderr(
|
||||||
|
"
|
||||||
|
error: Expected '*', ':', '$', identifier, or '+', but found end of file
|
||||||
|
--> justfile:20:4
|
||||||
|
|
|
||||||
|
20 | foo
|
||||||
|
| ^
|
||||||
|
",
|
||||||
|
)
|
||||||
|
.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn file_paths_are_relative() {
|
||||||
|
Test::new()
|
||||||
|
.justfile("!include foo/bar.just")
|
||||||
|
.write("foo/bar.just", "baz")
|
||||||
|
.args(["--unstable"])
|
||||||
|
.status(EXIT_FAILURE)
|
||||||
|
.stderr(format!(
|
||||||
|
"
|
||||||
|
error: Expected '*', ':', '$', identifier, or '+', but found end of file
|
||||||
|
--> foo{}bar.just:1:4
|
||||||
|
|
|
||||||
|
1 | baz
|
||||||
|
| ^
|
||||||
|
",
|
||||||
|
MAIN_SEPARATOR
|
||||||
|
))
|
||||||
|
.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn file_paths_not_in_subdir_are_absolute() {
|
||||||
|
Test::new()
|
||||||
|
.write("foo/justfile", "!include ../bar.just")
|
||||||
|
.write("bar.just", "baz")
|
||||||
|
.no_justfile()
|
||||||
|
.args(["--unstable", "--justfile", "foo/justfile"])
|
||||||
|
.status(EXIT_FAILURE)
|
||||||
|
.stderr_regex(format!(
|
||||||
|
"
|
||||||
|
error: Expected '*', ':', '$', identifier, or '+', but found end of file
|
||||||
|
--> {}.*{}bar.just:1:4
|
||||||
|
|
|
||||||
|
1 | baz
|
||||||
|
| ^
|
||||||
|
",
|
||||||
|
MAIN_SEPARATOR, MAIN_SEPARATOR
|
||||||
|
))
|
||||||
|
.run();
|
||||||
|
}
|
||||||
|
@ -146,6 +146,7 @@ fn print_error_from_parent_if_recipe_not_found_in_current() {
|
|||||||
.stderr(
|
.stderr(
|
||||||
"
|
"
|
||||||
error: Variable `bar` not defined
|
error: Variable `bar` not defined
|
||||||
|
--> justfile:2:9
|
||||||
|
|
|
|
||||||
2 | echo {{bar}}
|
2 | echo {{bar}}
|
||||||
| ^^^
|
| ^^^
|
||||||
|
@ -85,9 +85,10 @@ foo:
|
|||||||
/bin/echo '{{we}}'
|
/bin/echo '{{we}}'
|
||||||
"#,
|
"#,
|
||||||
stdout: "",
|
stdout: "",
|
||||||
stderr: format!("{} {}\n{}\n{}\n{}\n",
|
stderr: format!("{} {}\n{}\n{}\n{}\n{}\n",
|
||||||
"error: Call to function `without_extension` failed:",
|
"error: Call to function `without_extension` failed:",
|
||||||
"Could not extract parent from ``",
|
"Could not extract parent from ``",
|
||||||
|
" --> justfile:1:8",
|
||||||
" |",
|
" |",
|
||||||
"1 | we := without_extension(\'\')",
|
"1 | we := without_extension(\'\')",
|
||||||
" | ^^^^^^^^^^^^^^^^^").as_str(),
|
" | ^^^^^^^^^^^^^^^^^").as_str(),
|
||||||
@ -104,8 +105,9 @@ foo:
|
|||||||
/bin/echo '{{we}}'
|
/bin/echo '{{we}}'
|
||||||
"#,
|
"#,
|
||||||
stdout: "",
|
stdout: "",
|
||||||
stderr: format!("{}\n{}\n{}\n{}\n",
|
stderr: format!("{}\n{}\n{}\n{}\n{}\n",
|
||||||
"error: Call to function `extension` failed: Could not extract extension from ``",
|
"error: Call to function `extension` failed: Could not extract extension from ``",
|
||||||
|
" --> justfile:1:8",
|
||||||
" |",
|
" |",
|
||||||
"1 | we := extension(\'\')",
|
"1 | we := extension(\'\')",
|
||||||
" | ^^^^^^^^^").as_str(),
|
" | ^^^^^^^^^").as_str(),
|
||||||
@ -122,8 +124,9 @@ foo:
|
|||||||
/bin/echo '{{we}}'
|
/bin/echo '{{we}}'
|
||||||
"#,
|
"#,
|
||||||
stdout: "",
|
stdout: "",
|
||||||
stderr: format!("{}\n{}\n{}\n{}\n",
|
stderr: format!("{}\n{}\n{}\n{}\n{}\n",
|
||||||
"error: Call to function `extension` failed: Could not extract extension from `foo`",
|
"error: Call to function `extension` failed: Could not extract extension from `foo`",
|
||||||
|
" --> justfile:1:8",
|
||||||
" |",
|
" |",
|
||||||
"1 | we := extension(\'foo\')",
|
"1 | we := extension(\'foo\')",
|
||||||
" | ^^^^^^^^^").as_str(),
|
" | ^^^^^^^^^").as_str(),
|
||||||
@ -140,8 +143,9 @@ foo:
|
|||||||
/bin/echo '{{we}}'
|
/bin/echo '{{we}}'
|
||||||
"#,
|
"#,
|
||||||
stdout: "",
|
stdout: "",
|
||||||
stderr: format!("{}\n{}\n{}\n{}\n",
|
stderr: format!("{}\n{}\n{}\n{}\n{}\n",
|
||||||
"error: Call to function `file_stem` failed: Could not extract file stem from ``",
|
"error: Call to function `file_stem` failed: Could not extract file stem from ``",
|
||||||
|
" --> justfile:1:8",
|
||||||
" |",
|
" |",
|
||||||
"1 | we := file_stem(\'\')",
|
"1 | we := file_stem(\'\')",
|
||||||
" | ^^^^^^^^^").as_str(),
|
" | ^^^^^^^^^").as_str(),
|
||||||
@ -158,8 +162,9 @@ foo:
|
|||||||
/bin/echo '{{we}}'
|
/bin/echo '{{we}}'
|
||||||
"#,
|
"#,
|
||||||
stdout: "",
|
stdout: "",
|
||||||
stderr: format!("{}\n{}\n{}\n{}\n",
|
stderr: format!("{}\n{}\n{}\n{}\n{}\n",
|
||||||
"error: Call to function `file_name` failed: Could not extract file name from ``",
|
"error: Call to function `file_name` failed: Could not extract file name from ``",
|
||||||
|
" --> justfile:1:8",
|
||||||
" |",
|
" |",
|
||||||
"1 | we := file_name(\'\')",
|
"1 | we := file_name(\'\')",
|
||||||
" | ^^^^^^^^^").as_str(),
|
" | ^^^^^^^^^").as_str(),
|
||||||
@ -176,9 +181,10 @@ foo:
|
|||||||
/bin/echo '{{we}}'
|
/bin/echo '{{we}}'
|
||||||
"#,
|
"#,
|
||||||
stdout: "",
|
stdout: "",
|
||||||
stderr: format!("{} {}\n{}\n{}\n{}\n",
|
stderr: format!("{} {}\n{}\n{}\n{}\n{}\n",
|
||||||
"error: Call to function `parent_directory` failed:",
|
"error: Call to function `parent_directory` failed:",
|
||||||
"Could not extract parent directory from ``",
|
"Could not extract parent directory from ``",
|
||||||
|
" --> justfile:1:8",
|
||||||
" |",
|
" |",
|
||||||
"1 | we := parent_directory(\'\')",
|
"1 | we := parent_directory(\'\')",
|
||||||
" | ^^^^^^^^^^^^^^^^").as_str(),
|
" | ^^^^^^^^^^^^^^^^").as_str(),
|
||||||
@ -195,9 +201,10 @@ foo:
|
|||||||
/bin/echo '{{we}}'
|
/bin/echo '{{we}}'
|
||||||
"#,
|
"#,
|
||||||
stdout: "",
|
stdout: "",
|
||||||
stderr: format!("{} {}\n{}\n{}\n{}\n",
|
stderr: format!("{} {}\n{}\n{}\n{}\n{}\n",
|
||||||
"error: Call to function `parent_directory` failed:",
|
"error: Call to function `parent_directory` failed:",
|
||||||
"Could not extract parent directory from `/`",
|
"Could not extract parent directory from `/`",
|
||||||
|
" --> justfile:1:8",
|
||||||
" |",
|
" |",
|
||||||
"1 | we := parent_directory(\'/\')",
|
"1 | we := parent_directory(\'/\')",
|
||||||
" | ^^^^^^^^^^^^^^^^").as_str(),
|
" | ^^^^^^^^^^^^^^^^").as_str(),
|
||||||
@ -225,6 +232,7 @@ test! {
|
|||||||
args: ("a"),
|
args: ("a"),
|
||||||
stdout: "",
|
stdout: "",
|
||||||
stderr: "error: Call to function `env_var` failed: environment variable `ZADDY` not present
|
stderr: "error: Call to function `env_var` failed: environment variable `ZADDY` not present
|
||||||
|
--> justfile:2:10
|
||||||
|
|
|
|
||||||
2 | echo {{env_var('ZADDY')}}
|
2 | echo {{env_var('ZADDY')}}
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
@ -395,6 +403,7 @@ test! {
|
|||||||
foo\\
|
foo\\
|
||||||
^
|
^
|
||||||
error: incomplete escape sequence, reached end of pattern prematurely
|
error: incomplete escape sequence, reached end of pattern prematurely
|
||||||
|
--> justfile:2:11
|
||||||
|
|
|
|
||||||
2 | echo {{ replace_regex('barbarbar', 'foo\\', 'foo') }}
|
2 | echo {{ replace_regex('barbarbar', 'foo\\', 'foo') }}
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
@ -498,6 +507,7 @@ fn join_argument_count_error() {
|
|||||||
.stderr(
|
.stderr(
|
||||||
"
|
"
|
||||||
error: Function `join` called with 1 argument but takes 2 or more
|
error: Function `join` called with 1 argument but takes 2 or more
|
||||||
|
--> justfile:1:6
|
||||||
|
|
|
|
||||||
1 | x := join(\'a\')
|
1 | x := join(\'a\')
|
||||||
| ^^^^
|
| ^^^^
|
||||||
@ -534,7 +544,15 @@ fn error_errors_with_message() {
|
|||||||
.justfile("x := error ('Thing Not Supported')")
|
.justfile("x := error ('Thing Not Supported')")
|
||||||
.args(["--evaluate"])
|
.args(["--evaluate"])
|
||||||
.status(1)
|
.status(1)
|
||||||
.stderr("error: Call to function `error` failed: Thing Not Supported\n |\n1 | x := error ('Thing Not Supported')\n | ^^^^^\n")
|
.stderr(
|
||||||
|
"
|
||||||
|
error: Call to function `error` failed: Thing Not Supported
|
||||||
|
--> justfile:1:6
|
||||||
|
|
|
||||||
|
1 | x := error ('Thing Not Supported')
|
||||||
|
| ^^^^^
|
||||||
|
",
|
||||||
|
)
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,6 +58,7 @@ fn include_directive_with_no_path() {
|
|||||||
.stderr(
|
.stderr(
|
||||||
"
|
"
|
||||||
error: !include directive has no argument
|
error: !include directive has no argument
|
||||||
|
--> justfile:1:9
|
||||||
|
|
|
|
||||||
1 | !include
|
1 | !include
|
||||||
| ^
|
| ^
|
||||||
|
@ -20,7 +20,7 @@ pub(crate) use {
|
|||||||
fs,
|
fs,
|
||||||
io::Write,
|
io::Write,
|
||||||
iter,
|
iter,
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf, MAIN_SEPARATOR},
|
||||||
process::{Command, Stdio},
|
process::{Command, Stdio},
|
||||||
str,
|
str,
|
||||||
},
|
},
|
||||||
|
@ -72,6 +72,7 @@ test! {
|
|||||||
",
|
",
|
||||||
stderr: "
|
stderr: "
|
||||||
error: Unknown setting `foo`
|
error: Unknown setting `foo`
|
||||||
|
--> justfile:1:5
|
||||||
|
|
|
|
||||||
1 | set foo
|
1 | set foo
|
||||||
| ^^^
|
| ^^^
|
||||||
@ -86,6 +87,7 @@ test! {
|
|||||||
",
|
",
|
||||||
stderr: "
|
stderr: "
|
||||||
error: Unknown setting `if`
|
error: Unknown setting `if`
|
||||||
|
--> justfile:1:5
|
||||||
|
|
|
|
||||||
1 | set if := 'foo'
|
1 | set if := 'foo'
|
||||||
| ^^
|
| ^^
|
||||||
@ -106,6 +108,7 @@ test! {
|
|||||||
justfile: "alias foo := bar\nalias foo := baz\n",
|
justfile: "alias foo := bar\nalias foo := baz\n",
|
||||||
stderr: "
|
stderr: "
|
||||||
error: Alias `foo` first defined on line 1 is redefined on line 2
|
error: Alias `foo` first defined on line 1 is redefined on line 2
|
||||||
|
--> justfile:2:7
|
||||||
|
|
|
|
||||||
2 | alias foo := baz
|
2 | alias foo := baz
|
||||||
| ^^^
|
| ^^^
|
||||||
@ -118,6 +121,7 @@ test! {
|
|||||||
justfile: "alias foo := bar\n",
|
justfile: "alias foo := bar\n",
|
||||||
stderr: "
|
stderr: "
|
||||||
error: Alias `foo` has an unknown target `bar`
|
error: Alias `foo` has an unknown target `bar`
|
||||||
|
--> justfile:1:7
|
||||||
|
|
|
|
||||||
1 | alias foo := bar
|
1 | alias foo := bar
|
||||||
| ^^^
|
| ^^^
|
||||||
@ -130,6 +134,7 @@ test! {
|
|||||||
justfile: "bar:\n echo bar\nalias foo := bar\nfoo:\n echo foo",
|
justfile: "bar:\n echo bar\nalias foo := bar\nfoo:\n echo foo",
|
||||||
stderr: "
|
stderr: "
|
||||||
error: Alias `foo` defined on line 3 shadows recipe `foo` defined on line 4
|
error: Alias `foo` defined on line 3 shadows recipe `foo` defined on line 4
|
||||||
|
--> justfile:3:7
|
||||||
|
|
|
|
||||||
3 | alias foo := bar
|
3 | alias foo := bar
|
||||||
| ^^^
|
| ^^^
|
||||||
@ -264,6 +269,7 @@ test! {
|
|||||||
justfile: "bar:\nhello:\nfoo: bar baaaaaaaz hello",
|
justfile: "bar:\nhello:\nfoo: bar baaaaaaaz hello",
|
||||||
stderr: "
|
stderr: "
|
||||||
error: Recipe `foo` has unknown dependency `baaaaaaaz`
|
error: Recipe `foo` has unknown dependency `baaaaaaaz`
|
||||||
|
--> justfile:3:10
|
||||||
|
|
|
|
||||||
3 | foo: bar baaaaaaaz hello
|
3 | foo: bar baaaaaaaz hello
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
@ -290,6 +296,7 @@ test! {
|
|||||||
justfile: "b := a\na := `exit 100`\nbar:\n echo '{{`exit 200`}}'",
|
justfile: "b := a\na := `exit 100`\nbar:\n echo '{{`exit 200`}}'",
|
||||||
stderr: "
|
stderr: "
|
||||||
error: Backtick failed with exit code 100
|
error: Backtick failed with exit code 100
|
||||||
|
--> justfile:2:6
|
||||||
|
|
|
|
||||||
2 | a := `exit 100`
|
2 | a := `exit 100`
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
@ -302,6 +309,7 @@ test! {
|
|||||||
justfile: "b := a\na := `echo hello`\nbar:\n echo '{{`exit 200`}}'",
|
justfile: "b := a\na := `echo hello`\nbar:\n echo '{{`exit 200`}}'",
|
||||||
stderr: "
|
stderr: "
|
||||||
error: Backtick failed with exit code 200
|
error: Backtick failed with exit code 200
|
||||||
|
--> justfile:4:10
|
||||||
|
|
|
|
||||||
4 | echo '{{`exit 200`}}'
|
4 | echo '{{`exit 200`}}'
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
@ -314,6 +322,7 @@ test! {
|
|||||||
justfile: "f:\n 無{{`exit 200`}}",
|
justfile: "f:\n 無{{`exit 200`}}",
|
||||||
stderr: "
|
stderr: "
|
||||||
error: Backtick failed with exit code 200
|
error: Backtick failed with exit code 200
|
||||||
|
--> justfile:2:7
|
||||||
|
|
|
|
||||||
2 | 無{{`exit 200`}}
|
2 | 無{{`exit 200`}}
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
@ -328,6 +337,7 @@ test! {
|
|||||||
\techo {{`exit 200`}}
|
\techo {{`exit 200`}}
|
||||||
",
|
",
|
||||||
stderr: " error: Backtick failed with exit code 200
|
stderr: " error: Backtick failed with exit code 200
|
||||||
|
--> justfile:2:9
|
||||||
|
|
|
|
||||||
2 | echo {{`exit 200`}}
|
2 | echo {{`exit 200`}}
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
@ -342,6 +352,7 @@ test! {
|
|||||||
\techo {{\t`exit 200`}}
|
\techo {{\t`exit 200`}}
|
||||||
",
|
",
|
||||||
stderr: "error: Backtick failed with exit code 200
|
stderr: "error: Backtick failed with exit code 200
|
||||||
|
--> justfile:2:10
|
||||||
|
|
|
|
||||||
2 | echo {{ `exit 200`}}
|
2 | echo {{ `exit 200`}}
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
@ -357,6 +368,7 @@ test! {
|
|||||||
",
|
",
|
||||||
stderr: "
|
stderr: "
|
||||||
error: Backtick failed with exit code 200
|
error: Backtick failed with exit code 200
|
||||||
|
--> justfile:2:10
|
||||||
|
|
|
|
||||||
2 | echo {{ `exit 200`}}
|
2 | echo {{ `exit 200`}}
|
||||||
| ^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^
|
||||||
@ -372,6 +384,7 @@ test! {
|
|||||||
",
|
",
|
||||||
stderr: "
|
stderr: "
|
||||||
error: Backtick failed with exit code 200
|
error: Backtick failed with exit code 200
|
||||||
|
--> justfile:2:13
|
||||||
|
|
|
|
||||||
2 | echo 😬{{`exit 200`}}
|
2 | echo 😬{{`exit 200`}}
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
@ -387,6 +400,7 @@ test! {
|
|||||||
",
|
",
|
||||||
stderr: "
|
stderr: "
|
||||||
error: Backtick failed with exit code 200
|
error: Backtick failed with exit code 200
|
||||||
|
--> justfile:2:24
|
||||||
|
|
|
|
||||||
2 | echo 😬鎌鼬{{ `exit 200 # abc`}} 😬鎌鼬
|
2 | echo 😬鎌鼬{{ `exit 200 # abc`}} 😬鎌鼬
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
@ -410,6 +424,7 @@ test! {
|
|||||||
",
|
",
|
||||||
stderr: "
|
stderr: "
|
||||||
error: Backtick failed with exit code 200
|
error: Backtick failed with exit code 200
|
||||||
|
--> justfile:10:10
|
||||||
|
|
|
|
||||||
10 | echo '{{`exit 200`}}'
|
10 | echo '{{`exit 200`}}'
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
@ -426,6 +441,7 @@ test! {
|
|||||||
stdout: "",
|
stdout: "",
|
||||||
stderr: "
|
stderr: "
|
||||||
error: Backtick failed with exit code 123
|
error: Backtick failed with exit code 123
|
||||||
|
--> justfile:4:9
|
||||||
|
|
|
|
||||||
4 | echo {{`exit 123`}}
|
4 | echo {{`exit 123`}}
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
@ -442,6 +458,7 @@ test! {
|
|||||||
stderr: "
|
stderr: "
|
||||||
echo hello
|
echo hello
|
||||||
error: Backtick failed with exit code 123
|
error: Backtick failed with exit code 123
|
||||||
|
--> justfile:3:9
|
||||||
|
|
|
|
||||||
3 | echo {{`exit 123`}}
|
3 | echo {{`exit 123`}}
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
@ -458,6 +475,7 @@ a := `exit 222`",
|
|||||||
stdout: "",
|
stdout: "",
|
||||||
stderr: "
|
stderr: "
|
||||||
error: Backtick failed with exit code 222
|
error: Backtick failed with exit code 222
|
||||||
|
--> justfile:4:6
|
||||||
|
|
|
|
||||||
4 | a := `exit 222`
|
4 | a := `exit 222`
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
@ -573,6 +591,7 @@ test! {
|
|||||||
"#,
|
"#,
|
||||||
stdout: "",
|
stdout: "",
|
||||||
stderr: "error: Unknown start of token:
|
stderr: "error: Unknown start of token:
|
||||||
|
--> justfile:10:1
|
||||||
|
|
|
|
||||||
10 | ???
|
10 | ???
|
||||||
| ^
|
| ^
|
||||||
@ -677,8 +696,7 @@ test! {
|
|||||||
justfile: "b := a\na := `exit 100`\nbar:\n echo '{{`exit 200`}}'",
|
justfile: "b := a\na := `exit 100`\nbar:\n echo '{{`exit 200`}}'",
|
||||||
args: ("--color", "always"),
|
args: ("--color", "always"),
|
||||||
stdout: "",
|
stdout: "",
|
||||||
stderr: "\u{1b}[1;31merror\u{1b}[0m: \u{1b}[1mBacktick failed with exit code 100\u{1b}[0m
|
stderr: "\u{1b}[1;31merror\u{1b}[0m: \u{1b}[1mBacktick failed with exit code 100\u{1b}[0m\n \u{1b}[1;34m-->\u{1b}[0m justfile:2:6\n \u{1b}[1;34m|\u{1b}[0m\n\u{1b}[1;34m2 |\u{1b}[0m a := `exit 100`\n \u{1b}[1;34m|\u{1b}[0m \u{1b}[1;31m^^^^^^^^^^\u{1b}[0m\n",
|
||||||
|\n2 | a := `exit 100`\n | \u{1b}[1;31m^^^^^^^^^^\u{1b}[0m\n",
|
|
||||||
status: 100,
|
status: 100,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -688,6 +706,7 @@ test! {
|
|||||||
args: ("--color", "never"),
|
args: ("--color", "never"),
|
||||||
stdout: "",
|
stdout: "",
|
||||||
stderr: "error: Backtick failed with exit code 100
|
stderr: "error: Backtick failed with exit code 100
|
||||||
|
--> justfile:2:6
|
||||||
|
|
|
|
||||||
2 | a := `exit 100`
|
2 | a := `exit 100`
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
@ -701,6 +720,7 @@ test! {
|
|||||||
args: ("--color", "auto"),
|
args: ("--color", "auto"),
|
||||||
stdout: "",
|
stdout: "",
|
||||||
stderr: "error: Backtick failed with exit code 100
|
stderr: "error: Backtick failed with exit code 100
|
||||||
|
--> justfile:2:6
|
||||||
|
|
|
|
||||||
2 | a := `exit 100`
|
2 | a := `exit 100`
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
@ -739,6 +759,7 @@ test! {
|
|||||||
stdout: "",
|
stdout: "",
|
||||||
stderr: "error: Found a mix of tabs and spaces in leading whitespace: `␉␠`
|
stderr: "error: Found a mix of tabs and spaces in leading whitespace: `␉␠`
|
||||||
Leading whitespace may consist of tabs or spaces, but not both
|
Leading whitespace may consist of tabs or spaces, but not both
|
||||||
|
--> justfile:2:1
|
||||||
|
|
|
|
||||||
2 | echo hello
|
2 | echo hello
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
@ -751,6 +772,7 @@ test! {
|
|||||||
justfile: "bar:\n\t\techo hello\n\t\t\techo goodbye",
|
justfile: "bar:\n\t\techo hello\n\t\t\techo goodbye",
|
||||||
stdout: "",
|
stdout: "",
|
||||||
stderr: "error: Recipe line has extra leading whitespace
|
stderr: "error: Recipe line has extra leading whitespace
|
||||||
|
--> justfile:3:3
|
||||||
|
|
|
|
||||||
3 | echo goodbye
|
3 | echo goodbye
|
||||||
| ^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^
|
||||||
@ -764,6 +786,7 @@ test! {
|
|||||||
stdout: "",
|
stdout: "",
|
||||||
stderr: "error: Recipe line has inconsistent leading whitespace. \
|
stderr: "error: Recipe line has inconsistent leading whitespace. \
|
||||||
Recipe started with `␉␉` but found line with `␉␠`
|
Recipe started with `␉␉` but found line with `␉␠`
|
||||||
|
--> justfile:3:1
|
||||||
|
|
|
|
||||||
3 | echo goodbye
|
3 | echo goodbye
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
@ -776,6 +799,7 @@ test! {
|
|||||||
justfile: "bar:\nhello baz arg='foo' bar:",
|
justfile: "bar:\nhello baz arg='foo' bar:",
|
||||||
stdout: "",
|
stdout: "",
|
||||||
stderr: "error: Non-default parameter `bar` follows default parameter
|
stderr: "error: Non-default parameter `bar` follows default parameter
|
||||||
|
--> justfile:2:21
|
||||||
|
|
|
|
||||||
2 | hello baz arg='foo' bar:
|
2 | hello baz arg='foo' bar:
|
||||||
| ^^^
|
| ^^^
|
||||||
@ -788,6 +812,7 @@ test! {
|
|||||||
justfile: "bar:\nhello baz +arg bar:",
|
justfile: "bar:\nhello baz +arg bar:",
|
||||||
stdout: "",
|
stdout: "",
|
||||||
stderr: "error: Parameter `bar` follows variadic parameter
|
stderr: "error: Parameter `bar` follows variadic parameter
|
||||||
|
--> justfile:2:16
|
||||||
|
|
|
|
||||||
2 | hello baz +arg bar:
|
2 | hello baz +arg bar:
|
||||||
| ^^^
|
| ^^^
|
||||||
@ -800,6 +825,7 @@ test! {
|
|||||||
justfile: "bar:\nhello baz *arg bar:",
|
justfile: "bar:\nhello baz *arg bar:",
|
||||||
stdout: "",
|
stdout: "",
|
||||||
stderr: "error: Parameter `bar` follows variadic parameter
|
stderr: "error: Parameter `bar` follows variadic parameter
|
||||||
|
--> justfile:2:16
|
||||||
|
|
|
|
||||||
2 | hello baz *arg bar:
|
2 | hello baz *arg bar:
|
||||||
| ^^^
|
| ^^^
|
||||||
@ -1172,6 +1198,7 @@ bar:"#,
|
|||||||
args: ("bar"),
|
args: ("bar"),
|
||||||
stdout: "",
|
stdout: "",
|
||||||
stderr: r#"error: Call to unknown function `foo`
|
stderr: r#"error: Call to unknown function `foo`
|
||||||
|
--> justfile:1:8
|
||||||
|
|
|
|
||||||
1 | foo := foo() + "hello"
|
1 | foo := foo() + "hello"
|
||||||
| ^^^
|
| ^^^
|
||||||
@ -1188,6 +1215,7 @@ test! {
|
|||||||
args: ("b"),
|
args: ("b"),
|
||||||
stdout: "",
|
stdout: "",
|
||||||
stderr: "error: Dependency `a` got 0 arguments but takes 1 argument
|
stderr: "error: Dependency `a` got 0 arguments but takes 1 argument
|
||||||
|
--> justfile:2:4
|
||||||
|
|
|
|
||||||
2 | b: a
|
2 | b: a
|
||||||
| ^
|
| ^
|
||||||
@ -1204,6 +1232,7 @@ test! {
|
|||||||
args: ("b"),
|
args: ("b"),
|
||||||
stdout: "",
|
stdout: "",
|
||||||
stderr: "error: Dependency `a` got 0 arguments but takes at least 1 argument
|
stderr: "error: Dependency `a` got 0 arguments but takes at least 1 argument
|
||||||
|
--> justfile:2:4
|
||||||
|
|
|
|
||||||
2 | b: a
|
2 | b: a
|
||||||
| ^
|
| ^
|
||||||
@ -1220,6 +1249,7 @@ test! {
|
|||||||
args: ("b"),
|
args: ("b"),
|
||||||
stdout: "",
|
stdout: "",
|
||||||
stderr: "error: Dependency `a` got 3 arguments but takes at most 2 arguments
|
stderr: "error: Dependency `a` got 3 arguments but takes at most 2 arguments
|
||||||
|
--> justfile:2:5
|
||||||
|
|
|
|
||||||
2 | b: (a '0' '1' '2')
|
2 | b: (a '0' '1' '2')
|
||||||
| ^
|
| ^
|
||||||
@ -1233,6 +1263,7 @@ test! {
|
|||||||
args: ("a"),
|
args: ("a"),
|
||||||
stdout: "",
|
stdout: "",
|
||||||
stderr: "error: Recipe `a` has duplicate parameter `foo`
|
stderr: "error: Recipe `a` has duplicate parameter `foo`
|
||||||
|
--> justfile:1:7
|
||||||
|
|
|
|
||||||
1 | a foo foo:
|
1 | a foo foo:
|
||||||
| ^^^
|
| ^^^
|
||||||
@ -1246,6 +1277,7 @@ test! {
|
|||||||
args: ("b"),
|
args: ("b"),
|
||||||
stdout: "",
|
stdout: "",
|
||||||
stderr: "error: Recipe `b` first defined on line 1 is redefined on line 2
|
stderr: "error: Recipe `b` first defined on line 1 is redefined on line 2
|
||||||
|
--> justfile:2:1
|
||||||
|
|
|
|
||||||
2 | b:
|
2 | b:
|
||||||
| ^
|
| ^
|
||||||
@ -1259,6 +1291,7 @@ test! {
|
|||||||
args: ("foo"),
|
args: ("foo"),
|
||||||
stdout: "",
|
stdout: "",
|
||||||
stderr: "error: Variable `a` has multiple definitions
|
stderr: "error: Variable `a` has multiple definitions
|
||||||
|
--> justfile:2:1
|
||||||
|
|
|
|
||||||
2 | a := 'hello'
|
2 | a := 'hello'
|
||||||
| ^
|
| ^
|
||||||
@ -1273,6 +1306,7 @@ test! {
|
|||||||
stdout: "",
|
stdout: "",
|
||||||
stderr: "error: Expected '&&', comment, end of file, end of line, \
|
stderr: "error: Expected '&&', comment, end of file, end of line, \
|
||||||
identifier, or '(', but found string
|
identifier, or '(', but found string
|
||||||
|
--> justfile:1:6
|
||||||
|
|
|
|
||||||
1 | foo: 'bar'
|
1 | foo: 'bar'
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
@ -1286,6 +1320,7 @@ test! {
|
|||||||
args: ("foo"),
|
args: ("foo"),
|
||||||
stdout: "",
|
stdout: "",
|
||||||
stderr: "error: Expected '*', ':', '$', identifier, or '+', but found string
|
stderr: "error: Expected '*', ':', '$', identifier, or '+', but found string
|
||||||
|
--> justfile:1:5
|
||||||
|
|
|
|
||||||
1 | foo 'bar'
|
1 | foo 'bar'
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
@ -1299,6 +1334,7 @@ test! {
|
|||||||
args: ("a"),
|
args: ("a"),
|
||||||
stdout: "",
|
stdout: "",
|
||||||
stderr: "error: Recipe `a` depends on itself
|
stderr: "error: Recipe `a` depends on itself
|
||||||
|
--> justfile:1:4
|
||||||
|
|
|
|
||||||
1 | a: a
|
1 | a: a
|
||||||
| ^
|
| ^
|
||||||
@ -1312,6 +1348,7 @@ test! {
|
|||||||
args: ("a"),
|
args: ("a"),
|
||||||
stdout: "",
|
stdout: "",
|
||||||
stderr: "error: Recipe `d` has circular dependency `a -> b -> c -> d -> a`
|
stderr: "error: Recipe `d` has circular dependency `a -> b -> c -> d -> a`
|
||||||
|
--> justfile:4:4
|
||||||
|
|
|
|
||||||
4 | d: a
|
4 | d: a
|
||||||
| ^
|
| ^
|
||||||
@ -1325,6 +1362,7 @@ test! {
|
|||||||
args: ("a"),
|
args: ("a"),
|
||||||
stdout: "",
|
stdout: "",
|
||||||
stderr: "error: Variable `z` is defined in terms of itself
|
stderr: "error: Variable `z` is defined in terms of itself
|
||||||
|
--> justfile:1:1
|
||||||
|
|
|
|
||||||
1 | z := z
|
1 | z := z
|
||||||
| ^
|
| ^
|
||||||
@ -1338,6 +1376,7 @@ test! {
|
|||||||
args: ("a"),
|
args: ("a"),
|
||||||
stdout: "",
|
stdout: "",
|
||||||
stderr: "error: Variable `x` depends on its own value: `x -> y -> z -> x`
|
stderr: "error: Variable `x` depends on its own value: `x -> y -> z -> x`
|
||||||
|
--> justfile:1:1
|
||||||
|
|
|
|
||||||
1 | x := y
|
1 | x := y
|
||||||
| ^
|
| ^
|
||||||
@ -1357,6 +1396,7 @@ test! {
|
|||||||
args: ("a"),
|
args: ("a"),
|
||||||
stdout: "",
|
stdout: "",
|
||||||
stderr: "error: Variable `x` depends on its own value: `x -> y -> x`
|
stderr: "error: Variable `x` depends on its own value: `x -> y -> x`
|
||||||
|
--> justfile:2:1
|
||||||
|
|
|
|
||||||
2 | x := y
|
2 | x := y
|
||||||
| ^
|
| ^
|
||||||
@ -1461,6 +1501,7 @@ foo *a +b:
|
|||||||
",
|
",
|
||||||
stdout: "",
|
stdout: "",
|
||||||
stderr: "error: Expected \':\' or \'=\', but found \'+\'
|
stderr: "error: Expected \':\' or \'=\', but found \'+\'
|
||||||
|
--> justfile:1:8
|
||||||
|
|
|
|
||||||
1 | foo *a +b:
|
1 | foo *a +b:
|
||||||
| ^
|
| ^
|
||||||
@ -1476,6 +1517,7 @@ foo +a *b:
|
|||||||
",
|
",
|
||||||
stdout: "",
|
stdout: "",
|
||||||
stderr: "error: Expected \':\' or \'=\', but found \'*\'
|
stderr: "error: Expected \':\' or \'=\', but found \'*\'
|
||||||
|
--> justfile:1:8
|
||||||
|
|
|
|
||||||
1 | foo +a *b:
|
1 | foo +a *b:
|
||||||
| ^
|
| ^
|
||||||
@ -1509,6 +1551,7 @@ a: x y
|
|||||||
",
|
",
|
||||||
stdout: "",
|
stdout: "",
|
||||||
stderr: "error: Recipe `a` has unknown dependency `y`
|
stderr: "error: Recipe `a` has unknown dependency `y`
|
||||||
|
--> justfile:3:6
|
||||||
|
|
|
|
||||||
3 | a: x y
|
3 | a: x y
|
||||||
| ^
|
| ^
|
||||||
@ -1666,6 +1709,7 @@ X := "\'"
|
|||||||
"#,
|
"#,
|
||||||
stdout: "",
|
stdout: "",
|
||||||
stderr: r#"error: `\'` is not a valid escape sequence
|
stderr: r#"error: `\'` is not a valid escape sequence
|
||||||
|
--> justfile:1:6
|
||||||
|
|
|
|
||||||
1 | X := "\'"
|
1 | X := "\'"
|
||||||
| ^^^^
|
| ^^^^
|
||||||
@ -1680,6 +1724,7 @@ test! {
|
|||||||
",
|
",
|
||||||
stdout: "",
|
stdout: "",
|
||||||
stderr: r#"error: Variable `bar` not defined
|
stderr: r#"error: Variable `bar` not defined
|
||||||
|
--> justfile:1:7
|
||||||
|
|
|
|
||||||
1 | foo x=bar:
|
1 | foo x=bar:
|
||||||
| ^^^
|
| ^^^
|
||||||
@ -1694,6 +1739,7 @@ foo x=bar():
|
|||||||
",
|
",
|
||||||
stdout: "",
|
stdout: "",
|
||||||
stderr: r#"error: Call to unknown function `bar`
|
stderr: r#"error: Call to unknown function `bar`
|
||||||
|
--> justfile:1:7
|
||||||
|
|
|
|
||||||
1 | foo x=bar():
|
1 | foo x=bar():
|
||||||
| ^^^
|
| ^^^
|
||||||
@ -1750,6 +1796,7 @@ test! {
|
|||||||
",
|
",
|
||||||
stderr: r#"
|
stderr: r#"
|
||||||
error: Unterminated interpolation
|
error: Unterminated interpolation
|
||||||
|
--> justfile:2:8
|
||||||
|
|
|
|
||||||
2 | echo {{
|
2 | echo {{
|
||||||
| ^^
|
| ^^
|
||||||
@ -1765,6 +1812,7 @@ test! {
|
|||||||
",
|
",
|
||||||
stderr: r#"
|
stderr: r#"
|
||||||
error: Unterminated interpolation
|
error: Unterminated interpolation
|
||||||
|
--> justfile:2:8
|
||||||
|
|
|
|
||||||
2 | echo {{
|
2 | echo {{
|
||||||
| ^^
|
| ^^
|
||||||
@ -1779,6 +1827,7 @@ assembly_source_files = %(wildcard src/arch/$(arch)/*.s)
|
|||||||
",
|
",
|
||||||
stderr: r#"
|
stderr: r#"
|
||||||
error: Unknown start of token:
|
error: Unknown start of token:
|
||||||
|
--> justfile:1:25
|
||||||
|
|
|
|
||||||
1 | assembly_source_files = %(wildcard src/arch/$(arch)/*.s)
|
1 | assembly_source_files = %(wildcard src/arch/$(arch)/*.s)
|
||||||
| ^
|
| ^
|
||||||
@ -1877,6 +1926,7 @@ test! {
|
|||||||
",
|
",
|
||||||
stderr: "
|
stderr: "
|
||||||
error: Expected '*', ':', '$', identifier, or '+', but found '='
|
error: Expected '*', ':', '$', identifier, or '+', but found '='
|
||||||
|
--> justfile:1:5
|
||||||
|
|
|
|
||||||
1 | foo = 'bar'
|
1 | foo = 'bar'
|
||||||
| ^
|
| ^
|
||||||
@ -2074,6 +2124,7 @@ test! {
|
|||||||
stdout: "",
|
stdout: "",
|
||||||
stderr: "
|
stderr: "
|
||||||
error: Variable `a` not defined
|
error: Variable `a` not defined
|
||||||
|
--> justfile:3:9
|
||||||
|
|
|
|
||||||
3 | bar a b=a:
|
3 | bar a b=a:
|
||||||
| ^
|
| ^
|
||||||
|
@ -72,6 +72,7 @@ fn newline_escape_deps_invalid_esc() {
|
|||||||
.stderr(
|
.stderr(
|
||||||
"
|
"
|
||||||
error: `\\ ` is not a valid escape sequence
|
error: `\\ ` is not a valid escape sequence
|
||||||
|
--> justfile:1:11
|
||||||
|
|
|
|
||||||
1 | default: a\\ b
|
1 | default: a\\ b
|
||||||
| ^
|
| ^
|
||||||
@ -92,6 +93,7 @@ fn newline_escape_unpaired_linefeed() {
|
|||||||
.stderr(
|
.stderr(
|
||||||
"
|
"
|
||||||
error: Unpaired carriage return
|
error: Unpaired carriage return
|
||||||
|
--> justfile:1:9
|
||||||
|
|
|
|
||||||
1 | default:\\\ra
|
1 | default:\\\ra
|
||||||
| ^
|
| ^
|
||||||
|
@ -53,6 +53,7 @@ hello:
|
|||||||
"#,
|
"#,
|
||||||
stderr: r#"
|
stderr: r#"
|
||||||
error: Unknown attribute `unknown-attribute`
|
error: Unknown attribute `unknown-attribute`
|
||||||
|
--> justfile:2:2
|
||||||
|
|
|
|
||||||
2 | [unknown-attribute]
|
2 | [unknown-attribute]
|
||||||
| ^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^
|
||||||
@ -70,6 +71,7 @@ hello:
|
|||||||
"#,
|
"#,
|
||||||
stderr: r#"
|
stderr: r#"
|
||||||
error: Expected identifier, but found ']'
|
error: Expected identifier, but found ']'
|
||||||
|
--> justfile:2:2
|
||||||
|
|
|
|
||||||
2 | []
|
2 | []
|
||||||
| ^
|
| ^
|
||||||
@ -87,6 +89,7 @@ hello:
|
|||||||
"#,
|
"#,
|
||||||
stderr: r#"
|
stderr: r#"
|
||||||
error: Expected '@', '[', or identifier, but found comment
|
error: Expected '@', '[', or identifier, but found comment
|
||||||
|
--> justfile:2:1
|
||||||
|
|
|
|
||||||
2 | # This is a doc comment
|
2 | # This is a doc comment
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
@ -103,7 +106,7 @@ test! {
|
|||||||
hello:
|
hello:
|
||||||
@exit 100
|
@exit 100
|
||||||
"#,
|
"#,
|
||||||
stderr: "error: Expected '@', '[', or identifier, but found end of line\n |\n2 | \n | ^\n",
|
stderr: "error: Expected '@', '[', or identifier, but found end of line\n --> justfile:2:1\n |\n2 | \n | ^\n",
|
||||||
status: EXIT_FAILURE,
|
status: EXIT_FAILURE,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ fn bugfix() {
|
|||||||
#[cfg(not(windows))]
|
#[cfg(not(windows))]
|
||||||
const RECURSION_LIMIT_REACHED: &str = "
|
const RECURSION_LIMIT_REACHED: &str = "
|
||||||
error: Parsing recursion depth exceeded
|
error: Parsing recursion depth exceeded
|
||||||
|
--> justfile:1:265
|
||||||
|
|
|
|
||||||
1 | foo: (x ((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
|
1 | foo: (x ((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
|
||||||
| ^
|
| ^
|
||||||
@ -24,6 +25,7 @@ error: Parsing recursion depth exceeded
|
|||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
const RECURSION_LIMIT_REACHED: &str = "
|
const RECURSION_LIMIT_REACHED: &str = "
|
||||||
error: Parsing recursion depth exceeded
|
error: Parsing recursion depth exceeded
|
||||||
|
--> justfile:1:57
|
||||||
|
|
|
|
||||||
1 | foo: (x ((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
|
1 | foo: (x ((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
|
||||||
| ^
|
| ^
|
||||||
|
@ -30,6 +30,7 @@ test! {
|
|||||||
args: ("--show", "f"),
|
args: ("--show", "f"),
|
||||||
stderr: "
|
stderr: "
|
||||||
error: Alias `f` has an unknown target `foo`
|
error: Alias `f` has an unknown target `foo`
|
||||||
|
--> justfile:1:7
|
||||||
|
|
|
|
||||||
1 | alias f := foo
|
1 | alias f := foo
|
||||||
| ^
|
| ^
|
||||||
|
@ -48,6 +48,7 @@ fn no_rhs_once() {
|
|||||||
.stderr(
|
.stderr(
|
||||||
"
|
"
|
||||||
error: Expected backtick, identifier, '(', '/', or string, but found end of file
|
error: Expected backtick, identifier, '(', '/', or string, but found end of file
|
||||||
|
--> justfile:1:11
|
||||||
|
|
|
|
||||||
1 | x := 'a' /
|
1 | x := 'a' /
|
||||||
| ^
|
| ^
|
||||||
@ -69,6 +70,7 @@ fn default_un_parenthesized() {
|
|||||||
.stderr(
|
.stderr(
|
||||||
"
|
"
|
||||||
error: Expected '*', ':', '$', identifier, or '+', but found '/'
|
error: Expected '*', ':', '$', identifier, or '+', but found '/'
|
||||||
|
--> justfile:1:11
|
||||||
|
|
|
|
||||||
1 | foo x='a' / 'b':
|
1 | foo x='a' / 'b':
|
||||||
| ^
|
| ^
|
||||||
@ -90,6 +92,7 @@ fn no_lhs_un_parenthesized() {
|
|||||||
.stderr(
|
.stderr(
|
||||||
"
|
"
|
||||||
error: Expected backtick, identifier, '(', or string, but found '/'
|
error: Expected backtick, identifier, '(', or string, but found '/'
|
||||||
|
--> justfile:1:7
|
||||||
|
|
|
|
||||||
1 | foo x=/ 'a' / 'b':
|
1 | foo x=/ 'a' / 'b':
|
||||||
| ^
|
| ^
|
||||||
|
@ -88,6 +88,7 @@ a:"#,
|
|||||||
args: ("a"),
|
args: ("a"),
|
||||||
stdout: "",
|
stdout: "",
|
||||||
stderr: "error: `\\q` is not a valid escape sequence
|
stderr: "error: `\\q` is not a valid escape sequence
|
||||||
|
--> justfile:1:6
|
||||||
|
|
|
|
||||||
1 | x := \"\\q\"
|
1 | x := \"\\q\"
|
||||||
| ^^^^
|
| ^^^^
|
||||||
@ -108,6 +109,7 @@ a:
|
|||||||
args: ("a"),
|
args: ("a"),
|
||||||
stdout: "",
|
stdout: "",
|
||||||
stderr: "error: Variable `foo` not defined
|
stderr: "error: Variable `foo` not defined
|
||||||
|
--> justfile:6:11
|
||||||
|
|
|
|
||||||
6 | echo '{{foo}}'
|
6 | echo '{{foo}}'
|
||||||
| ^^^
|
| ^^^
|
||||||
@ -128,6 +130,7 @@ a:
|
|||||||
args: ("a"),
|
args: ("a"),
|
||||||
stdout: "",
|
stdout: "",
|
||||||
stderr: "error: Variable `bar` not defined
|
stderr: "error: Variable `bar` not defined
|
||||||
|
--> justfile:3:13
|
||||||
|
|
|
|
||||||
3 | whatever' + bar
|
3 | whatever' + bar
|
||||||
| ^^^
|
| ^^^
|
||||||
@ -165,6 +168,7 @@ a:
|
|||||||
args: ("a"),
|
args: ("a"),
|
||||||
stdout: "",
|
stdout: "",
|
||||||
stderr: "error: Variable `b` not defined
|
stderr: "error: Variable `b` not defined
|
||||||
|
--> justfile:5:10
|
||||||
|
|
|
|
||||||
5 | echo {{b}}
|
5 | echo {{b}}
|
||||||
| ^
|
| ^
|
||||||
@ -181,6 +185,7 @@ test! {
|
|||||||
stdout: "",
|
stdout: "",
|
||||||
stderr: "
|
stderr: "
|
||||||
error: Unterminated string
|
error: Unterminated string
|
||||||
|
--> justfile:1:6
|
||||||
|
|
|
|
||||||
1 | a b= ':
|
1 | a b= ':
|
||||||
| ^
|
| ^
|
||||||
@ -197,6 +202,7 @@ test! {
|
|||||||
stdout: "",
|
stdout: "",
|
||||||
stderr: r#"
|
stderr: r#"
|
||||||
error: Unterminated string
|
error: Unterminated string
|
||||||
|
--> justfile:1:6
|
||||||
|
|
|
|
||||||
1 | a b= ":
|
1 | a b= ":
|
||||||
| ^
|
| ^
|
||||||
@ -212,6 +218,7 @@ test! {
|
|||||||
",
|
",
|
||||||
stderr: r#"
|
stderr: r#"
|
||||||
error: Unterminated backtick
|
error: Unterminated backtick
|
||||||
|
--> justfile:1:8
|
||||||
|
|
|
|
||||||
1 | foo a= `echo blaaaaaah:
|
1 | foo a= `echo blaaaaaah:
|
||||||
| ^
|
| ^
|
||||||
@ -228,6 +235,7 @@ test! {
|
|||||||
stdout: "",
|
stdout: "",
|
||||||
stderr: "
|
stderr: "
|
||||||
error: Unterminated string
|
error: Unterminated string
|
||||||
|
--> justfile:1:6
|
||||||
|
|
|
|
||||||
1 | a b= ''':
|
1 | a b= ''':
|
||||||
| ^^^
|
| ^^^
|
||||||
@ -244,6 +252,7 @@ test! {
|
|||||||
stdout: "",
|
stdout: "",
|
||||||
stderr: r#"
|
stderr: r#"
|
||||||
error: Unterminated string
|
error: Unterminated string
|
||||||
|
--> justfile:1:6
|
||||||
|
|
|
|
||||||
1 | a b= """:
|
1 | a b= """:
|
||||||
| ^^^
|
| ^^^
|
||||||
@ -259,6 +268,7 @@ test! {
|
|||||||
",
|
",
|
||||||
stderr: r#"
|
stderr: r#"
|
||||||
error: Unterminated backtick
|
error: Unterminated backtick
|
||||||
|
--> justfile:1:8
|
||||||
|
|
|
|
||||||
1 | foo a= ```echo blaaaaaah:
|
1 | foo a= ```echo blaaaaaah:
|
||||||
| ^^^
|
| ^^^
|
||||||
@ -374,6 +384,7 @@ test! {
|
|||||||
",
|
",
|
||||||
stderr: "
|
stderr: "
|
||||||
error: Backticks may not start with `#!`
|
error: Backticks may not start with `#!`
|
||||||
|
--> justfile:1:6
|
||||||
|
|
|
|
||||||
1 | x := `#!/usr/bin/env sh`
|
1 | x := `#!/usr/bin/env sh`
|
||||||
| ^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -47,6 +47,7 @@ test! {
|
|||||||
",
|
",
|
||||||
stderr: "
|
stderr: "
|
||||||
error: Recipe `foo` depends on itself
|
error: Recipe `foo` depends on itself
|
||||||
|
--> justfile:1:9
|
||||||
|
|
|
|
||||||
1 | foo: && foo
|
1 | foo: && foo
|
||||||
| ^^^
|
| ^^^
|
||||||
@ -61,6 +62,7 @@ test! {
|
|||||||
",
|
",
|
||||||
stderr: "
|
stderr: "
|
||||||
error: Recipe `foo` has unknown dependency `bar`
|
error: Recipe `foo` has unknown dependency `bar`
|
||||||
|
--> justfile:1:9
|
||||||
|
|
|
|
||||||
1 | foo: && bar
|
1 | foo: && bar
|
||||||
| ^^^
|
| ^^^
|
||||||
@ -77,6 +79,7 @@ test! {
|
|||||||
",
|
",
|
||||||
stderr: "
|
stderr: "
|
||||||
error: Variable `y` not defined
|
error: Variable `y` not defined
|
||||||
|
--> justfile:3:14
|
||||||
|
|
|
|
||||||
3 | foo: && (bar y)
|
3 | foo: && (bar y)
|
||||||
| ^
|
| ^
|
||||||
|
@ -7,6 +7,7 @@ fn parameter_default_unknown_variable_in_expression() {
|
|||||||
.stderr(
|
.stderr(
|
||||||
"
|
"
|
||||||
error: Variable `b` not defined
|
error: Variable `b` not defined
|
||||||
|
--> justfile:1:8
|
||||||
|
|
|
|
||||||
1 | foo a=(b+''):
|
1 | foo a=(b+''):
|
||||||
| ^
|
| ^
|
||||||
@ -27,6 +28,7 @@ fn unknown_variable_in_unary_call() {
|
|||||||
.stderr(
|
.stderr(
|
||||||
"
|
"
|
||||||
error: Variable `a` not defined
|
error: Variable `a` not defined
|
||||||
|
--> justfile:1:15
|
||||||
|
|
|
|
||||||
1 | foo x=env_var(a):
|
1 | foo x=env_var(a):
|
||||||
| ^
|
| ^
|
||||||
@ -47,6 +49,7 @@ fn unknown_first_variable_in_binary_call() {
|
|||||||
.stderr(
|
.stderr(
|
||||||
"
|
"
|
||||||
error: Variable `a` not defined
|
error: Variable `a` not defined
|
||||||
|
--> justfile:1:26
|
||||||
|
|
|
|
||||||
1 | foo x=env_var_or_default(a, b):
|
1 | foo x=env_var_or_default(a, b):
|
||||||
| ^
|
| ^
|
||||||
@ -67,6 +70,7 @@ fn unknown_second_variable_in_binary_call() {
|
|||||||
.stderr(
|
.stderr(
|
||||||
"
|
"
|
||||||
error: Variable `b` not defined
|
error: Variable `b` not defined
|
||||||
|
--> justfile:1:30
|
||||||
|
|
|
|
||||||
1 | foo x=env_var_or_default('', b):
|
1 | foo x=env_var_or_default('', b):
|
||||||
| ^
|
| ^
|
||||||
@ -87,6 +91,7 @@ fn unknown_variable_in_ternary_call() {
|
|||||||
.stderr(
|
.stderr(
|
||||||
"
|
"
|
||||||
error: Variable `a` not defined
|
error: Variable `a` not defined
|
||||||
|
--> justfile:1:15
|
||||||
|
|
|
|
||||||
1 | foo x=replace(a, b, c):
|
1 | foo x=replace(a, b, c):
|
||||||
| ^
|
| ^
|
||||||
|
Loading…
Reference in New Issue
Block a user