Skip to content

Commit

Permalink
Improve error message on bad working directory
Browse files Browse the repository at this point in the history
Handles two cases:

- working directory doesn't exist.
- working directory cannot be changed into due to on of the following:
    - The process lacks permissions to view the contents.
    - The path points at a non-directory file.

Addresses: casey#2295
  • Loading branch information
artm committed Sep 1, 2024
1 parent aca2239 commit 44c6eee
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 1 deletion.
11 changes: 11 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,11 @@ pub(crate) enum Error<'src> {
MissingModuleFile {
module: Name<'src>,
},
WorkingDirectoryIo {
recipe: &'src str,
working_directory: PathBuf,
io_error: io::Error,
},
NoChoosableRecipes,
NoDefaultRecipe,
NoRecipes,
Expand Down Expand Up @@ -470,6 +475,12 @@ impl<'src> ColorDisplay for Error<'src> {
UnstableFeature { unstable_feature } => {
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.")?;
}
WorkingDirectoryIo { recipe, working_directory, io_error } => {
match io_error.kind() {
io::ErrorKind::NotFound => write!(f, "Recipe `{recipe}` could not be run because just could not find working directory `{}`: {io_error}", working_directory.to_string_lossy()),
_ => write!(f, "Recipe `{recipe}` could not be run because just could not set working directory to `{}`: {io_error}", working_directory.to_string_lossy()),
}?;
},
WriteJustfile { justfile, io_error } => {
let justfile = justfile.display();
write!(f, "Failed to write justfile to `{justfile}`: {io_error}")?;
Expand Down
9 changes: 9 additions & 0 deletions src/recipe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,15 @@ impl<'src, D> Recipe<'src, D> {
}
}
Err(io_error) => {
if let Some(working_directory) = self.working_directory(context) {
if let Err(io_error) = fs::read_dir(working_directory.clone()) {
return Err(Error::WorkingDirectoryIo {
recipe: self.name(),
working_directory,
io_error,
});
}
}
return Err(Error::Io {
recipe: self.name(),
io_error,
Expand Down
60 changes: 59 additions & 1 deletion tests/working_directory.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::*;
use {super::*, fs::Permissions, std::os::unix::fs::PermissionsExt};

const JUSTFILE: &str = r#"
foo := `cat data`
Expand Down Expand Up @@ -331,3 +331,61 @@ file := shell('cat file.txt')
.stdout("FILE\n")
.run();
}

#[test]
fn missing_working_directory_produces_clear_message() {
Test::new()
.justfile(
"
set working-directory := 'missing'
default:
pwd
",
)
.status(1)
.stderr_regex(
".*Recipe `default` could not be run because just could not find working directory `.*/missing`.*",
)
.run();
}

#[test]
fn unusable_working_directory_produces_clear_message() {
Test::new()
.justfile(
"
set working-directory := 'unusable'
default:
pwd
",
)
.tree(tree! {
unusable: {}
})
.chmod("unusable", Permissions::from_mode(0o000))
.status(1)
.stderr_regex(
".*Recipe `default` could not be run because just could not set working directory to `.*/unusable`:.*",
)
.run();
}

#[test]
fn working_directory_is_not_a_directory_produces_clear_message() {
Test::new()
.justfile(
"
set working-directory := 'unusable'
default:
pwd
",
)
.tree(tree! {
unusable: "is not a directory"
})
.status(1)
.stderr_regex(
".*Recipe `default` could not be run because just could not set working directory to `.*/unusable`:.*",
)
.run();
}

0 comments on commit 44c6eee

Please sign in to comment.