mkit_cli/commands/
hash_cmd.rs1use std::io::Write;
4
5use clap::Parser;
6use mkit_core::object::{Blob, Object};
7use mkit_core::serialize;
8use mkit_core::store::ObjectStore;
9use mkit_core::worktree;
10
11use crate::clap_shim;
12use crate::exit;
13use crate::format;
14
15#[derive(Debug, Parser)]
16#[command(name = "mkit hash", about = "Hash a file as a blob and store it.")]
17struct HashOpts {
18 file: String,
20}
21
22#[must_use]
23pub fn run(args: &[String]) -> u8 {
24 let opts = match clap_shim::parse::<HashOpts>("mkit hash", args) {
25 Ok(o) => o,
26 Err(code) => return code,
27 };
28 let path = &opts.file;
29 let cwd = match std::env::current_dir() {
30 Ok(p) => p,
31 Err(e) => return emit_err(&format!("cwd: {e}"), exit::NOINPUT),
32 };
33 let layout = match super::resolve_layout(&cwd) {
34 Ok(layout) => layout,
35 Err(code) => return code,
36 };
37 let store = match ObjectStore::open(&layout) {
38 Ok(s) => s,
39 Err(e) => return emit_err(&format!("not a mkit repo: {e}"), exit::GENERAL_ERROR),
40 };
41 let bytes = match worktree::read_regular_file_bounded(std::path::Path::new(path)) {
46 Ok((_, data)) => data,
47 Err(e) => return emit_err(&format!("read {path}: {e}"), exit::NOINPUT),
48 };
49 let blob = Object::Blob(Blob { data: bytes });
50 let serialized = match serialize::serialize(&blob) {
51 Ok(b) => b,
52 Err(e) => return emit_err(&format!("serialize: {e}"), exit::DATAERR),
53 };
54 match store.write(&serialized) {
55 Ok(h) => {
56 let mut stdout = std::io::stdout().lock();
57 let _ = writeln!(stdout, "{}", format::hex_hash(&h));
58 exit::OK
59 }
60 Err(e) => emit_err(&format!("store: {e}"), exit::CANTCREAT),
61 }
62}
63
64use super::error as emit_err;