2019-04-11 15:23:14 -07:00
|
|
|
use crate::common::*;
|
2018-03-05 13:21:35 -08:00
|
|
|
|
2017-11-16 23:30:08 -08:00
|
|
|
#[derive(Debug)]
|
2019-12-07 03:09:21 -08:00
|
|
|
pub(crate) enum RuntimeError<'src> {
|
2018-12-08 14:29:41 -08:00
|
|
|
ArgumentCountMismatch {
|
2020-02-10 20:07:06 -08:00
|
|
|
recipe: &'src str,
|
2019-12-07 03:09:21 -08:00
|
|
|
parameters: Vec<&'src Parameter<'src>>,
|
2020-02-10 20:07:06 -08:00
|
|
|
found: usize,
|
|
|
|
min: usize,
|
|
|
|
max: usize,
|
2018-11-06 00:41:33 -08:00
|
|
|
},
|
2018-12-08 14:29:41 -08:00
|
|
|
Backtick {
|
2020-02-10 20:07:06 -08:00
|
|
|
token: Token<'src>,
|
2018-12-08 14:29:41 -08:00
|
|
|
output_error: OutputError,
|
|
|
|
},
|
|
|
|
Code {
|
2020-02-10 20:07:06 -08:00
|
|
|
recipe: &'src str,
|
2018-12-08 14:29:41 -08:00
|
|
|
line_number: Option<usize>,
|
2020-02-10 20:07:06 -08:00
|
|
|
code: i32,
|
2018-12-08 14:29:41 -08:00
|
|
|
},
|
|
|
|
Cygpath {
|
2020-02-10 20:07:06 -08:00
|
|
|
recipe: &'src str,
|
2018-12-08 14:29:41 -08:00
|
|
|
output_error: OutputError,
|
|
|
|
},
|
|
|
|
Dotenv {
|
|
|
|
dotenv_error: dotenv::Error,
|
|
|
|
},
|
|
|
|
FunctionCall {
|
2019-12-07 03:09:21 -08:00
|
|
|
function: Name<'src>,
|
2020-02-10 20:07:06 -08:00
|
|
|
message: String,
|
2018-12-08 14:29:41 -08:00
|
|
|
},
|
|
|
|
Internal {
|
|
|
|
message: String,
|
|
|
|
},
|
|
|
|
IoError {
|
2020-02-10 20:07:06 -08:00
|
|
|
recipe: &'src str,
|
2018-12-08 14:29:41 -08:00
|
|
|
io_error: io::Error,
|
|
|
|
},
|
|
|
|
Shebang {
|
2020-02-10 20:07:06 -08:00
|
|
|
recipe: &'src str,
|
|
|
|
command: String,
|
2018-12-08 14:29:41 -08:00
|
|
|
argument: Option<String>,
|
|
|
|
io_error: io::Error,
|
|
|
|
},
|
|
|
|
Signal {
|
2020-02-10 20:07:06 -08:00
|
|
|
recipe: &'src str,
|
2018-12-08 14:29:41 -08:00
|
|
|
line_number: Option<usize>,
|
2020-02-10 20:07:06 -08:00
|
|
|
signal: i32,
|
2018-12-08 14:29:41 -08:00
|
|
|
},
|
|
|
|
TmpdirIoError {
|
2020-02-10 20:07:06 -08:00
|
|
|
recipe: &'src str,
|
2018-12-08 14:29:41 -08:00
|
|
|
io_error: io::Error,
|
|
|
|
},
|
|
|
|
UnknownOverrides {
|
2019-12-07 03:09:21 -08:00
|
|
|
overrides: Vec<&'src str>,
|
2018-12-08 14:29:41 -08:00
|
|
|
},
|
|
|
|
UnknownRecipes {
|
2020-02-10 20:07:06 -08:00
|
|
|
recipes: Vec<&'src str>,
|
2020-04-26 14:19:21 -07:00
|
|
|
suggestion: Option<Suggestion<'src>>,
|
2018-12-08 14:29:41 -08:00
|
|
|
},
|
|
|
|
Unknown {
|
2020-02-10 20:07:06 -08:00
|
|
|
recipe: &'src str,
|
2018-12-08 14:29:41 -08:00
|
|
|
line_number: Option<usize>,
|
|
|
|
},
|
Gargantuan refactor (#522)
- 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.
2019-11-09 21:43:20 -08:00
|
|
|
NoRecipes,
|
|
|
|
DefaultRecipeRequiresArguments {
|
2020-02-10 20:07:06 -08:00
|
|
|
recipe: &'src str,
|
Gargantuan refactor (#522)
- 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.
2019-11-09 21:43:20 -08:00
|
|
|
min_arguments: usize,
|
|
|
|
},
|
2017-11-16 23:30:08 -08:00
|
|
|
}
|
|
|
|
|
2019-12-07 03:09:21 -08:00
|
|
|
impl<'src> Error for RuntimeError<'src> {
|
Gargantuan refactor (#522)
- 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.
2019-11-09 21:43:20 -08:00
|
|
|
fn code(&self) -> i32 {
|
2017-11-16 23:30:08 -08:00
|
|
|
match *self {
|
2020-01-15 02:16:13 -08:00
|
|
|
Self::Code { code, .. }
|
|
|
|
| Self::Backtick {
|
2018-12-08 14:29:41 -08:00
|
|
|
output_error: OutputError::Code(code),
|
|
|
|
..
|
Gargantuan refactor (#522)
- 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.
2019-11-09 21:43:20 -08:00
|
|
|
} => code,
|
|
|
|
_ => EXIT_FAILURE,
|
2017-11-16 23:30:08 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-07 03:09:21 -08:00
|
|
|
impl<'src> RuntimeError<'src> {
|
2019-11-13 19:32:50 -08:00
|
|
|
fn context(&self) -> Option<Token> {
|
|
|
|
use RuntimeError::*;
|
|
|
|
match self {
|
|
|
|
FunctionCall { function, .. } => Some(function.token()),
|
|
|
|
Backtick { token, .. } => Some(*token),
|
|
|
|
_ => None,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-07 03:09:21 -08:00
|
|
|
impl<'src> Display for RuntimeError<'src> {
|
2019-04-11 15:23:14 -07:00
|
|
|
fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
|
2017-11-16 23:30:08 -08:00
|
|
|
use RuntimeError::*;
|
2019-04-11 15:23:14 -07:00
|
|
|
|
2018-12-08 14:29:41 -08:00
|
|
|
let color = if f.alternate() {
|
|
|
|
Color::always()
|
|
|
|
} else {
|
|
|
|
Color::never()
|
|
|
|
};
|
2017-11-16 23:30:08 -08:00
|
|
|
let message = color.message();
|
Gargantuan refactor (#522)
- 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.
2019-11-09 21:43:20 -08:00
|
|
|
write!(f, "{}", message.prefix())?;
|
2017-11-16 23:30:08 -08:00
|
|
|
|
2019-11-13 19:32:50 -08:00
|
|
|
match self {
|
2018-12-08 14:29:41 -08:00
|
|
|
UnknownRecipes {
|
2019-11-13 19:32:50 -08:00
|
|
|
recipes,
|
|
|
|
suggestion,
|
2018-12-08 14:29:41 -08:00
|
|
|
} => {
|
|
|
|
write!(
|
|
|
|
f,
|
2019-10-09 01:40:40 -07:00
|
|
|
"Justfile does not contain {} {}.",
|
|
|
|
Count("recipe", recipes.len()),
|
|
|
|
List::or_ticked(recipes),
|
2018-12-08 14:29:41 -08:00
|
|
|
)?;
|
2017-11-16 23:30:08 -08:00
|
|
|
if let Some(suggestion) = *suggestion {
|
2020-04-26 14:19:21 -07:00
|
|
|
write!(f, "\n{}", suggestion)?;
|
2017-11-16 23:30:08 -08:00
|
|
|
}
|
2020-02-10 20:07:06 -08:00
|
|
|
},
|
2019-11-13 19:32:50 -08:00
|
|
|
UnknownOverrides { overrides } => {
|
2018-12-08 14:29:41 -08:00
|
|
|
write!(
|
|
|
|
f,
|
2019-10-09 01:40:40 -07:00
|
|
|
"{} {} overridden on the command line but not present in justfile",
|
|
|
|
Count("Variable", overrides.len()),
|
|
|
|
List::and_ticked(overrides),
|
2018-12-08 14:29:41 -08:00
|
|
|
)?;
|
2020-02-10 20:07:06 -08:00
|
|
|
},
|
2018-12-08 14:29:41 -08:00
|
|
|
ArgumentCountMismatch {
|
|
|
|
recipe,
|
2019-11-13 19:32:50 -08:00
|
|
|
parameters,
|
2018-12-08 14:29:41 -08:00
|
|
|
found,
|
|
|
|
min,
|
|
|
|
max,
|
|
|
|
} => {
|
2017-11-16 23:30:08 -08:00
|
|
|
if min == max {
|
|
|
|
let expected = min;
|
2018-12-08 14:29:41 -08:00
|
|
|
write!(
|
|
|
|
f,
|
2019-10-09 01:40:40 -07:00
|
|
|
"Recipe `{}` got {} {} but {}takes {}",
|
2018-12-08 14:29:41 -08:00
|
|
|
recipe,
|
|
|
|
found,
|
2019-11-13 19:32:50 -08:00
|
|
|
Count("argument", *found),
|
2018-12-08 14:29:41 -08:00
|
|
|
if expected < found { "only " } else { "" },
|
|
|
|
expected
|
|
|
|
)?;
|
2017-11-16 23:30:08 -08:00
|
|
|
} else if found < min {
|
2018-12-08 14:29:41 -08:00
|
|
|
write!(
|
|
|
|
f,
|
2019-10-09 01:40:40 -07:00
|
|
|
"Recipe `{}` got {} {} but takes at least {}",
|
2018-12-08 14:29:41 -08:00
|
|
|
recipe,
|
|
|
|
found,
|
2019-11-13 19:32:50 -08:00
|
|
|
Count("argument", *found),
|
2018-12-08 14:29:41 -08:00
|
|
|
min
|
|
|
|
)?;
|
2017-11-16 23:30:08 -08:00
|
|
|
} else if found > max {
|
2018-12-08 14:29:41 -08:00
|
|
|
write!(
|
|
|
|
f,
|
2019-10-09 01:40:40 -07:00
|
|
|
"Recipe `{}` got {} {} but takes at most {}",
|
2018-12-08 14:29:41 -08:00
|
|
|
recipe,
|
|
|
|
found,
|
2019-11-13 19:32:50 -08:00
|
|
|
Count("argument", *found),
|
2018-12-08 14:29:41 -08:00
|
|
|
max
|
|
|
|
)?;
|
2017-11-16 23:30:08 -08:00
|
|
|
}
|
2018-11-03 14:51:06 -07:00
|
|
|
write!(f, "\nusage:\n just {}", recipe)?;
|
|
|
|
for param in parameters {
|
|
|
|
if color.stderr().active() {
|
|
|
|
write!(f, " {:#}", param)?;
|
|
|
|
} else {
|
|
|
|
write!(f, " {}", param)?;
|
|
|
|
}
|
|
|
|
}
|
2020-02-10 20:07:06 -08:00
|
|
|
},
|
2018-12-08 14:29:41 -08:00
|
|
|
Code {
|
|
|
|
recipe,
|
|
|
|
line_number,
|
|
|
|
code,
|
2020-02-10 20:07:06 -08:00
|
|
|
} =>
|
2017-11-16 23:30:08 -08:00
|
|
|
if let Some(n) = line_number {
|
2018-12-08 14:29:41 -08:00
|
|
|
write!(
|
|
|
|
f,
|
|
|
|
"Recipe `{}` failed on line {} with exit code {}",
|
|
|
|
recipe, n, code
|
|
|
|
)?;
|
2017-11-16 23:30:08 -08:00
|
|
|
} else {
|
|
|
|
write!(f, "Recipe `{}` failed with exit code {}", recipe, code)?;
|
2020-02-10 20:07:06 -08:00
|
|
|
},
|
2018-12-08 14:29:41 -08:00
|
|
|
Cygpath {
|
|
|
|
recipe,
|
2019-11-13 19:32:50 -08:00
|
|
|
output_error,
|
|
|
|
} => match output_error {
|
2017-11-16 23:30:08 -08:00
|
|
|
OutputError::Code(code) => {
|
2018-12-08 14:29:41 -08:00
|
|
|
write!(
|
|
|
|
f,
|
2020-02-10 20:07:06 -08:00
|
|
|
"Cygpath failed with exit code {} while translating recipe `{}` shebang interpreter \
|
|
|
|
path",
|
2018-12-08 14:29:41 -08:00
|
|
|
code, recipe
|
|
|
|
)?;
|
2020-02-10 20:07:06 -08:00
|
|
|
},
|
2017-11-16 23:30:08 -08:00
|
|
|
OutputError::Signal(signal) => {
|
2018-12-08 14:29:41 -08:00
|
|
|
write!(
|
|
|
|
f,
|
2020-02-10 20:07:06 -08:00
|
|
|
"Cygpath terminated by signal {} while translating recipe `{}` shebang interpreter \
|
|
|
|
path",
|
2018-12-08 14:29:41 -08:00
|
|
|
signal, recipe
|
|
|
|
)?;
|
2020-02-10 20:07:06 -08:00
|
|
|
},
|
2017-11-16 23:30:08 -08:00
|
|
|
OutputError::Unknown => {
|
2018-12-08 14:29:41 -08:00
|
|
|
write!(
|
|
|
|
f,
|
2020-02-10 20:07:06 -08:00
|
|
|
"Cygpath experienced an unknown failure while translating recipe `{}` shebang \
|
|
|
|
interpreter path",
|
2018-12-08 14:29:41 -08:00
|
|
|
recipe
|
|
|
|
)?;
|
2020-02-10 20:07:06 -08:00
|
|
|
},
|
2019-11-13 19:32:50 -08:00
|
|
|
OutputError::Io(io_error) => {
|
2017-11-16 23:30:08 -08:00
|
|
|
match io_error.kind() {
|
|
|
|
io::ErrorKind::NotFound => write!(
|
2018-12-08 14:29:41 -08:00
|
|
|
f,
|
2020-02-10 20:07:06 -08:00
|
|
|
"Could not find `cygpath` executable to translate recipe `{}` shebang interpreter \
|
|
|
|
path:\n{}",
|
2018-12-08 14:29:41 -08:00
|
|
|
recipe, io_error
|
|
|
|
),
|
2017-11-16 23:30:08 -08:00
|
|
|
io::ErrorKind::PermissionDenied => write!(
|
2018-12-08 14:29:41 -08:00
|
|
|
f,
|
2020-02-10 20:07:06 -08:00
|
|
|
"Could not run `cygpath` executable to translate recipe `{}` shebang interpreter \
|
|
|
|
path:\n{}",
|
2018-12-08 14:29:41 -08:00
|
|
|
recipe, io_error
|
|
|
|
),
|
2017-11-16 23:30:08 -08:00
|
|
|
_ => write!(f, "Could not run `cygpath` executable:\n{}", io_error),
|
|
|
|
}?;
|
2020-02-10 20:07:06 -08:00
|
|
|
},
|
2019-11-13 19:32:50 -08:00
|
|
|
OutputError::Utf8(utf8_error) => {
|
2018-12-08 14:29:41 -08:00
|
|
|
write!(
|
|
|
|
f,
|
2020-02-10 20:07:06 -08:00
|
|
|
"Cygpath successfully translated recipe `{}` shebang interpreter path, but output was \
|
|
|
|
not utf8: {}",
|
2018-12-08 14:29:41 -08:00
|
|
|
recipe, utf8_error
|
|
|
|
)?;
|
2020-02-10 20:07:06 -08:00
|
|
|
},
|
2017-11-16 23:30:08 -08:00
|
|
|
},
|
2019-11-13 19:32:50 -08:00
|
|
|
Dotenv { dotenv_error } => {
|
2018-08-27 18:36:40 -07:00
|
|
|
writeln!(f, "Failed to load .env: {}", dotenv_error)?;
|
2020-02-10 20:07:06 -08:00
|
|
|
},
|
2019-11-13 19:32:50 -08:00
|
|
|
FunctionCall { function, message } => {
|
2019-04-15 22:40:02 -07:00
|
|
|
writeln!(
|
|
|
|
f,
|
|
|
|
"Call to function `{}` failed: {}",
|
2019-11-07 10:55:15 -08:00
|
|
|
function.lexeme(),
|
2019-04-15 22:40:02 -07:00
|
|
|
message
|
|
|
|
)?;
|
2020-02-10 20:07:06 -08:00
|
|
|
},
|
2018-12-08 14:29:41 -08:00
|
|
|
Shebang {
|
|
|
|
recipe,
|
2019-11-13 19:32:50 -08:00
|
|
|
command,
|
|
|
|
argument,
|
|
|
|
io_error,
|
2020-02-10 20:07:06 -08:00
|
|
|
} =>
|
2019-11-13 19:32:50 -08:00
|
|
|
if let Some(argument) = argument {
|
2018-12-08 14:29:41 -08:00
|
|
|
write!(
|
|
|
|
f,
|
|
|
|
"Recipe `{}` with shebang `#!{} {}` execution error: {}",
|
|
|
|
recipe, command, argument, io_error
|
|
|
|
)?;
|
2017-11-16 23:30:08 -08:00
|
|
|
} else {
|
2018-12-08 14:29:41 -08:00
|
|
|
write!(
|
|
|
|
f,
|
|
|
|
"Recipe `{}` with shebang `#!{}` execution error: {}",
|
|
|
|
recipe, command, io_error
|
|
|
|
)?;
|
2020-02-10 20:07:06 -08:00
|
|
|
},
|
2018-12-08 14:29:41 -08:00
|
|
|
Signal {
|
|
|
|
recipe,
|
|
|
|
line_number,
|
|
|
|
signal,
|
2020-02-10 20:07:06 -08:00
|
|
|
} =>
|
2017-11-16 23:30:08 -08:00
|
|
|
if let Some(n) = line_number {
|
2018-12-08 14:29:41 -08:00
|
|
|
write!(
|
|
|
|
f,
|
|
|
|
"Recipe `{}` was terminated on line {} by signal {}",
|
|
|
|
recipe, n, signal
|
|
|
|
)?;
|
2017-11-16 23:30:08 -08:00
|
|
|
} else {
|
|
|
|
write!(f, "Recipe `{}` was terminated by signal {}", recipe, signal)?;
|
2020-02-10 20:07:06 -08:00
|
|
|
},
|
2018-12-08 14:29:41 -08:00
|
|
|
Unknown {
|
|
|
|
recipe,
|
|
|
|
line_number,
|
2020-02-10 20:07:06 -08:00
|
|
|
} =>
|
2017-11-16 23:30:08 -08:00
|
|
|
if let Some(n) = line_number {
|
2018-12-08 14:29:41 -08:00
|
|
|
write!(
|
|
|
|
f,
|
|
|
|
"Recipe `{}` failed on line {} for an unknown reason",
|
|
|
|
recipe, n
|
|
|
|
)?;
|
2017-11-16 23:30:08 -08:00
|
|
|
} else {
|
2019-11-13 19:32:50 -08:00
|
|
|
write!(f, "Recipe `{}` failed for an unknown reason", recipe)?;
|
2020-02-10 20:07:06 -08:00
|
|
|
},
|
2019-11-13 19:32:50 -08:00
|
|
|
IoError { recipe, io_error } => {
|
2017-11-16 23:30:08 -08:00
|
|
|
match io_error.kind() {
|
2018-12-08 14:29:41 -08:00
|
|
|
io::ErrorKind::NotFound => writeln!(
|
|
|
|
f,
|
2018-08-27 18:36:40 -07:00
|
|
|
"Recipe `{}` could not be run because just could not find `sh`:{}",
|
2018-12-08 14:29:41 -08:00
|
|
|
recipe, io_error
|
|
|
|
),
|
2018-08-27 18:36:40 -07:00
|
|
|
io::ErrorKind::PermissionDenied => writeln!(
|
2018-12-08 14:29:41 -08:00
|
|
|
f,
|
|
|
|
"Recipe `{}` could not be run because just could not run `sh`:{}",
|
|
|
|
recipe, io_error
|
|
|
|
),
|
|
|
|
_ => writeln!(
|
|
|
|
f,
|
2020-02-10 20:07:06 -08:00
|
|
|
"Recipe `{}` could not be run because of an IO error while launching `sh`:{}",
|
2018-12-08 14:29:41 -08:00
|
|
|
recipe, io_error
|
|
|
|
),
|
2017-11-16 23:30:08 -08:00
|
|
|
}?;
|
2020-02-10 20:07:06 -08:00
|
|
|
},
|
2019-11-13 19:32:50 -08:00
|
|
|
TmpdirIoError { recipe, io_error } => writeln!(
|
2018-12-08 14:29:41 -08:00
|
|
|
f,
|
2020-02-10 20:07:06 -08:00
|
|
|
"Recipe `{}` could not be run because of an IO error while trying to create a temporary \
|
|
|
|
directory or write a file to that directory`:{}",
|
2018-12-08 14:29:41 -08:00
|
|
|
recipe, io_error
|
|
|
|
)?,
|
2019-11-13 19:32:50 -08:00
|
|
|
Backtick { output_error, .. } => match output_error {
|
2017-11-16 23:30:08 -08:00
|
|
|
OutputError::Code(code) => {
|
2018-08-27 18:36:40 -07:00
|
|
|
writeln!(f, "Backtick failed with exit code {}", code)?;
|
2020-02-10 20:07:06 -08:00
|
|
|
},
|
2017-11-16 23:30:08 -08:00
|
|
|
OutputError::Signal(signal) => {
|
2018-08-27 18:36:40 -07:00
|
|
|
writeln!(f, "Backtick was terminated by signal {}", signal)?;
|
2020-02-10 20:07:06 -08:00
|
|
|
},
|
2017-11-16 23:30:08 -08:00
|
|
|
OutputError::Unknown => {
|
2018-08-27 18:36:40 -07:00
|
|
|
writeln!(f, "Backtick failed for an unknown reason")?;
|
2020-02-10 20:07:06 -08:00
|
|
|
},
|
2019-11-13 19:32:50 -08:00
|
|
|
OutputError::Io(io_error) => {
|
2017-11-16 23:30:08 -08:00
|
|
|
match io_error.kind() {
|
|
|
|
io::ErrorKind::NotFound => write!(
|
2018-12-08 14:29:41 -08:00
|
|
|
f,
|
|
|
|
"Backtick could not be run because just could not find `sh`:\n{}",
|
|
|
|
io_error
|
|
|
|
),
|
2017-11-16 23:30:08 -08:00
|
|
|
io::ErrorKind::PermissionDenied => write!(
|
2018-12-08 14:29:41 -08:00
|
|
|
f,
|
|
|
|
"Backtick could not be run because just could not run `sh`:\n{}",
|
|
|
|
io_error
|
|
|
|
),
|
|
|
|
_ => write!(
|
|
|
|
f,
|
2020-02-10 20:07:06 -08:00
|
|
|
"Backtick could not be run because of an IO error while launching `sh`:\n{}",
|
2018-12-08 14:29:41 -08:00
|
|
|
io_error
|
|
|
|
),
|
2017-11-16 23:30:08 -08:00
|
|
|
}?;
|
2020-02-10 20:07:06 -08:00
|
|
|
},
|
2019-11-13 19:32:50 -08:00
|
|
|
OutputError::Utf8(utf8_error) => {
|
2018-12-08 14:29:41 -08:00
|
|
|
writeln!(
|
|
|
|
f,
|
|
|
|
"Backtick succeeded but stdout was not utf8: {}",
|
|
|
|
utf8_error
|
|
|
|
)?;
|
2020-02-10 20:07:06 -08:00
|
|
|
},
|
2017-11-16 23:30:08 -08:00
|
|
|
},
|
Gargantuan refactor (#522)
- 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.
2019-11-09 21:43:20 -08:00
|
|
|
NoRecipes => {
|
|
|
|
writeln!(f, "Justfile contains no recipes.",)?;
|
2020-02-10 20:07:06 -08:00
|
|
|
},
|
Gargantuan refactor (#522)
- 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.
2019-11-09 21:43:20 -08:00
|
|
|
DefaultRecipeRequiresArguments {
|
|
|
|
recipe,
|
|
|
|
min_arguments,
|
|
|
|
} => {
|
|
|
|
writeln!(
|
|
|
|
f,
|
|
|
|
"Recipe `{}` cannot be used as default recipe since it requires at least {} {}.",
|
|
|
|
recipe,
|
|
|
|
min_arguments,
|
2019-11-13 19:32:50 -08:00
|
|
|
Count("argument", *min_arguments),
|
Gargantuan refactor (#522)
- 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.
2019-11-09 21:43:20 -08:00
|
|
|
)?;
|
2020-02-10 20:07:06 -08:00
|
|
|
},
|
2019-11-13 19:32:50 -08:00
|
|
|
Internal { message } => {
|
2018-12-08 14:29:41 -08:00
|
|
|
write!(
|
|
|
|
f,
|
2019-10-09 00:18:53 -07:00
|
|
|
"Internal runtime error, this may indicate a bug in just: {} \
|
2018-12-08 14:29:41 -08:00
|
|
|
consider filing an issue: https://github.com/casey/just/issues/new",
|
|
|
|
message
|
|
|
|
)?;
|
2020-02-10 20:07:06 -08:00
|
|
|
},
|
2017-11-16 23:30:08 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
write!(f, "{}", message.suffix())?;
|
|
|
|
|
2019-11-13 19:32:50 -08:00
|
|
|
if let Some(token) = self.context() {
|
|
|
|
token.write_context(f, Color::fmt(f).error())?;
|
2017-11-16 23:30:08 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
2020-07-19 05:01:46 -07:00
|
|
|
|
|
|
|
impl<'src> From<dotenv::Error> for RuntimeError<'src> {
|
|
|
|
fn from(dotenv_error: dotenv::Error) -> RuntimeError<'src> {
|
|
|
|
RuntimeError::Dotenv { dotenv_error }
|
|
|
|
}
|
|
|
|
}
|