Skip to content

Commit

Permalink
Add filepack fingerprint command to print manifest fingerprint (#75)
Browse files Browse the repository at this point in the history
  • Loading branch information
casey authored Oct 17, 2024
1 parent cc88b71 commit d9a763d
Show file tree
Hide file tree
Showing 7 changed files with 98 additions and 26 deletions.
21 changes: 18 additions & 3 deletions src/manifest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,24 @@ impl Manifest {
hasher.finalize().into()
}

pub(crate) fn load(path: &Utf8Path) -> Result<Self> {
serde_json::from_str(&filesystem::read_to_string(path)?)
.context(error::DeserializeManifest { path })
pub(crate) fn load_from_root(path: Option<&Utf8Path>) -> Result<(Utf8PathBuf, Self)> {
let path = if let Some(path) = path {
if filesystem::metadata(path)?.is_dir() {
path.join(Manifest::FILENAME)
} else {
path.into()
}
} else {
current_dir()?.join(Manifest::FILENAME)
};

let json = filesystem::read_to_string_opt(&path)?
.ok_or_else(|| error::ManifestNotFound { path: &path }.build())?;

let manifest =
serde_json::from_str(&json).context(error::DeserializeManifest { path: &path })?;

Ok((path, manifest))
}

pub(crate) fn store(&self, path: &Utf8Path) -> Result<()> {
Expand Down
6 changes: 5 additions & 1 deletion src/subcommand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use {
};

mod create;
mod fingerprint;
mod hash;
mod key;
mod keygen;
Expand All @@ -28,7 +29,9 @@ mod verify;
pub(crate) enum Subcommand {
#[command(about = "Create manifest")]
Create(create::Create),
#[command(about = "Hash file")]
#[command(about = "Print manifest fingerprint")]
Fingerprint(fingerprint::Fingerprint),
#[command(about = "Print file hash")]
Hash(hash::Hash),
#[command(about = "Print master key")]
Key,
Expand All @@ -48,6 +51,7 @@ impl Subcommand {
pub(crate) fn run(self, options: Options) -> Result {
match self {
Self::Create(create) => create.run(options),
Self::Fingerprint(fingerprint) => fingerprint.run(),
Self::Hash(hash) => hash.run(options),
Self::Key => key::run(options),
Self::Keygen => keygen::run(options),
Expand Down
21 changes: 21 additions & 0 deletions src/subcommand/fingerprint.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
use super::*;

#[derive(Parser)]
pub(crate) struct Fingerprint {
#[arg(
help = "Load manifest from <PATH>. May be path to manifest, to directory containing manifest \
named `filepack.json`, or omitted, in which case manifest named `filepack.json` in the current \
directory is loaded."
)]
path: Option<Utf8PathBuf>,
}

impl Fingerprint {
pub(crate) fn run(self) -> Result {
let (_path, manifest) = Manifest::load_from_root(self.path.as_deref())?;

println!("{}", manifest.fingerprint());

Ok(())
}
}
12 changes: 1 addition & 11 deletions src/subcommand/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,7 @@ pub(crate) struct Render {

impl Render {
pub(crate) fn run(self) -> Result {
let path = if let Some(path) = self.root {
if filesystem::metadata(&path)?.is_dir() {
path.join(Manifest::FILENAME)
} else {
path
}
} else {
current_dir()?.join(Manifest::FILENAME)
};

let manifest = Manifest::load(&path)?;
let (path, manifest) = Manifest::load_from_root(self.root.as_deref())?;

let root = path.parent().unwrap();

Expand Down
12 changes: 1 addition & 11 deletions src/subcommand/sign.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,7 @@ pub(crate) struct Sign {

impl Sign {
pub(crate) fn run(self, options: Options) -> Result {
let path = if let Some(path) = self.root {
if filesystem::metadata(&path)?.is_dir() {
path.join(Manifest::FILENAME)
} else {
path
}
} else {
current_dir()?.join(Manifest::FILENAME)
};

let mut manifest = Manifest::load(&path)?;
let (path, mut manifest) = Manifest::load_from_root(self.root.as_deref())?;

let fingerprint = manifest.fingerprint();

Expand Down
51 changes: 51 additions & 0 deletions tests/fingerprint.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
use super::*;

#[test]
fn fingerprint() {
let dir = TempDir::new().unwrap();

dir.child("foo").touch().unwrap();

Command::cargo_bin("filepack")
.unwrap()
.arg("create")
.current_dir(&dir)
.assert()
.success();

let json = r#"{"files":{"foo":{"hash":"af1349b9f5f9a1a6a0404dea36dcc9499bcb25c9adc112b7cc9a93cae41f3262","size":0}}}"#;

dir.child("filepack.json").assert(json.to_owned() + "\n");

let fingerprint = "74ddbe0dcf48c634aca1d90f37defd60b230fc52857ffa4b6c956583e8a4daaf";

assert_eq!(
blake3::hash(json.as_bytes()),
fingerprint.parse::<blake3::Hash>().unwrap(),
);

Command::cargo_bin("filepack")
.unwrap()
.arg("fingerprint")
.current_dir(&dir)
.assert()
.stdout(format!("{fingerprint}\n"))
.success();

Command::cargo_bin("filepack")
.unwrap()
.args(["fingerprint", dir.path().to_str().unwrap()])
.assert()
.stdout(format!("{fingerprint}\n"))
.success();

Command::cargo_bin("filepack")
.unwrap()
.args([
"fingerprint",
dir.path().join("filepack.json").to_str().unwrap(),
])
.assert()
.stdout(format!("{fingerprint}\n"))
.success();
}
1 change: 1 addition & 0 deletions tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ impl Manifest {
}

mod create;
mod fingerprint;
mod hash;
mod key;
mod keygen;
Expand Down

0 comments on commit d9a763d

Please sign in to comment.