1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
use anyhow::Result;
use move_command_line_common::files::MOVE_EXTENSION;
use sha2::{Digest, Sha256};
use std::path::{Path, PathBuf};
use crate::source_package::{layout::SourcePackageLayout, parsed_manifest::PackageDigest};
pub fn compute_digest(paths: &[PathBuf]) -> Result<PackageDigest> {
let mut hashed_files = Vec::new();
let mut hash = |path: &Path| {
let contents = std::fs::read(path)?;
hashed_files.push(format!("{:X}", Sha256::digest(&contents)));
Ok(())
};
let mut maybe_hash_file = |path: &Path| -> Result<()> {
match path.extension() {
Some(x) if MOVE_EXTENSION == x => hash(path),
_ if path.ends_with(SourcePackageLayout::Manifest.path()) => hash(path),
_ => Ok(()),
}
};
for path in paths {
if path.is_file() {
maybe_hash_file(path)?;
} else {
for entry in walkdir::WalkDir::new(path)
.follow_links(true)
.into_iter()
.filter_map(|e| e.ok())
{
if entry.file_type().is_file() {
maybe_hash_file(entry.path())?
}
}
}
}
hashed_files.sort();
let mut hasher = Sha256::new();
for file_hash in hashed_files.into_iter() {
hasher.update(file_hash.as_bytes());
}
Ok(PackageDigest::from(format!("{:X}", hasher.finalize())))
}