Skip to content

Commit

Permalink
fix symlinked directories in checkpoint update (#38)
Browse files Browse the repository at this point in the history
* fix symlinked directories in checkpoint update

* version bump and changelog

* change target reason naming clarity
  • Loading branch information
pnordahl authored Nov 26, 2024
1 parent 2c73baa commit ebdb4a0
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 9 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Change Log

## [3.5.7] - 2024-11-26

### Fixed
- Issue preventing symlinked directories from working with `checkpoint update --pending`
- (internal) Naming of change target reason `uses_target` to `uses ` for clarity

## [3.5.6] - 2024-11-23

### Changed
Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ description = "A tool for effective polyglot, multi-project monorepo development
license = "MIT"
homepage = "https://github.com/pnordahl/monorail"
repository = "https://github.com/pnordahl/monorail"
version = "3.5.6"
version = "3.5.7"
authors = ["Patrick Nordahl <[email protected]>"]
edition = "2021"
keywords = ["monorail", "monorepo", "build", "cli", "build-tool"]
Expand Down
8 changes: 4 additions & 4 deletions src/app/analyze.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@ impl PartialOrd for AnalyzedChangeTarget {
pub(crate) enum AnalyzedChangeTargetReason {
#[serde(rename = "target")]
Target,
#[serde(rename = "uses_target")]
UsesTarget,
#[serde(rename = "uses")]
Uses,
#[serde(rename = "ignores")]
Ignores,
}
Expand Down Expand Up @@ -290,7 +290,7 @@ fn analyze_change<'a>(
update_change_targets(
&mut change_targets,
&target2,
AnalyzedChangeTargetReason::UsesTarget,
AnalyzedChangeTargetReason::Uses,
);
trace!(target = &target2, "Added uses target");
} else {
Expand Down Expand Up @@ -499,7 +499,7 @@ mod tests {
},
AnalyzedChangeTarget {
path: target3.to_string(),
reason: AnalyzedChangeTargetReason::UsesTarget,
reason: AnalyzedChangeTargetReason::Uses,
},
]),
}];
Expand Down
33 changes: 30 additions & 3 deletions src/core/file.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::collections::{HashMap, VecDeque};
use std::os::unix::fs::PermissionsExt;
use std::path;
use std::result::Result;
use std::{io, path};

use sha2::Digest;
use tokio::io::AsyncReadExt;
Expand Down Expand Up @@ -56,13 +56,33 @@ pub(crate) fn contains_file(p: &path::Path) -> Result<(), MonorailError> {
// TODO: configure buffer size based on file size?
// TODO: pass in open file instead of path?
pub(crate) async fn get_file_checksum(p: &path::Path) -> Result<String, MonorailError> {
let md = match tokio::fs::metadata(p).await {
Ok(md) => md,
Err(_) => {
// non-existent/failed to stat files have an empty checksum
return Ok(String::new());
}
};
let mut file = match tokio::fs::File::open(p).await {
Ok(file) => file,
Err(e) if e.kind() == io::ErrorKind::NotFound => return Ok("".to_string()),
Err(e) => {
// TODO: once io::ErrorKind::IsADirectory, use that
// empty directories have no checksum; this is required here
// because opening a normal directory would return an error
if md.is_dir() {
return Ok(String::new());
}
return Err(MonorailError::from(e));
}
};

// check for symlink directory; this is because File::open won't fail to
// open the symlink, but attempting to read it will fail
if md.is_dir() {
return Ok(String::new());
}

// hash the file
let mut hasher = sha2::Sha256::new();

let mut buffer = [0u8; 64 * 1024];
Expand Down Expand Up @@ -234,11 +254,18 @@ mod tests {

// files that don't exist have an empty checksum
let p = &repo_path.join("test.txt");
assert_eq!(get_file_checksum(p).await.unwrap(), "".to_string());
assert_eq!(get_file_checksum(p).await.unwrap(), String::new());

// write file and compare checksums
let checksum = write_with_checksum(p, &[1, 2, 3]).await.unwrap();
assert_eq!(get_file_checksum(p).await.unwrap(), checksum);

// empty directories have an empty checksum
tokio::fs::create_dir_all(repo_path.join("link"))
.await
.unwrap();
let p = &repo_path.join("link");
assert_eq!(get_file_checksum(p).await.unwrap(), String::new());
}

#[test]
Expand Down

0 comments on commit ebdb4a0

Please sign in to comment.