fix(cli): canonicalize build --output path
This fixes a potential issue with the new lock file hashing mechanism, in which two different path literals pointing to the same location would hash to separate lock files, allowing a race condition.
This commit is contained in:
parent
82486d4b0a
commit
93d793d249
2 changed files with 17 additions and 7 deletions
|
|
@ -955,11 +955,21 @@ impl Build {
|
|||
} else {
|
||||
let output_path = if let Some(ref path) = self.output {
|
||||
let path = Path::new(path);
|
||||
if path.is_absolute() {
|
||||
let full_path = if path.is_absolute() {
|
||||
path.to_path_buf()
|
||||
} else {
|
||||
current_dir.join(path)
|
||||
}
|
||||
};
|
||||
let parent_path = full_path
|
||||
.parent()
|
||||
.context("Output path must have a parent")?;
|
||||
let name = full_path
|
||||
.file_name()
|
||||
.context("Ouput path must have a filename")?;
|
||||
fs::create_dir_all(parent_path).context("Failed to create output path")?;
|
||||
let mut canon_path = parent_path.canonicalize().context("Invalid output path")?;
|
||||
canon_path.push(name);
|
||||
canon_path
|
||||
} else {
|
||||
let file_name = grammar_path
|
||||
.file_stem()
|
||||
|
|
|
|||
|
|
@ -1098,11 +1098,11 @@ impl Loader {
|
|||
|
||||
// Ensure the dynamic library exists before trying to load it. This can
|
||||
// happen in race conditions where we couldn't acquire the lock because
|
||||
// another process was compiling but it still haven't finished by the
|
||||
// another process was compiling but it still hasn't finished by the
|
||||
// time we reach this point, so the output file still doesn't exist.
|
||||
//
|
||||
// Instead of complaining about library load failure in `load_language`,
|
||||
// inform the user about the precise issue.
|
||||
// Instead of allowing the `load_language` call below to fail, return a
|
||||
// clearer error to the user here.
|
||||
if !output_path.exists() {
|
||||
let msg = format!(
|
||||
"Dynamic library `{}` not found after build attempt. \
|
||||
|
|
@ -1110,10 +1110,10 @@ impl Loader {
|
|||
output_path.display()
|
||||
);
|
||||
|
||||
return Err(LoaderError::IO(IoError::new(
|
||||
Err(LoaderError::IO(IoError::new(
|
||||
std::io::Error::new(std::io::ErrorKind::NotFound, msg),
|
||||
Some(output_path.as_path()),
|
||||
)));
|
||||
)))?;
|
||||
}
|
||||
|
||||
Self::load_language(&output_path, &language_fn_name)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue