feat(fogtix): proper command descriptions + new rebuild command

This commit is contained in:
Alain Zscheile 2022-10-16 01:44:58 +02:00
parent edec390b13
commit 0de72adc10

View file

@ -13,18 +13,25 @@ struct Args {
#[derive(clap::Subcommand)]
enum Command {
/// creates an empty snapshot
Init {
/// the empty snapshot to create
#[arg(short)]
snapshot: String,
},
/// re-executes a changeset of a snapshot based upon the saved anchor
Rebuild {
#[arg(short)]
snapshot: String,
},
/// removes a snapshot
Remove {
/// the snapshot to remove
#[arg(short)]
snapshot: String,
},
/// creates a snapshot based upon another (which is used as anchor)
Snapshot {
/// the snapshot to anchor this snapshot on
#[arg(short)]
@ -35,12 +42,14 @@ enum Command {
snapshot: String,
},
/// prints the snapshot data
ShowRes {
/// the snapshot to view
#[arg(short)]
snapshot: String,
},
/// duplicates a snapshot (doesn't create a relation between the original and new one)
Fork {
/// the snapshot to clone
#[arg(short)]
@ -51,6 +60,7 @@ enum Command {
snapshot: String,
},
/// commits/appends a change to a snapshot
Commit {
/// the snapshot to edit
#[arg(short)]
@ -61,6 +71,8 @@ enum Command {
bytecode_file: String,
},
/// merges/injects an augmention snapshot into another snapshot
/// and ensures that diverging changes fulfill baseline commutation requirements
Merge {
/// the snapshot to edit
#[arg(short)]
@ -108,6 +120,18 @@ fn data_ser(din: Vec<u64>, dout: &mut Vec<u8>) {
dout.extend(din.into_iter().flat_map(|i| i.to_be_bytes()));
}
fn anchor_from_meta(m: &[u8; 256]) -> IoResult<&str> {
let anchor = &m[..m
.iter()
.enumerate()
.find(|&(_, &i)| i == 0)
.map(|(n, _)| n)
.unwrap_or(m.len())];
core::str::from_utf8(anchor).map_err(|_e| {
std::io::Error::new(std::io::ErrorKind::InvalidData, "unable to parse anchor")
})
}
#[allow(non_snake_case)]
fn main() {
let args = <Args as clap::Parser>::parse();
@ -138,6 +162,45 @@ fn main() {
}
}
Command::Rebuild { snapshot } => {
let snapshots = repo.snapshots().unwrap();
let changes = repo.changes().unwrap();
let changes = changes
.massget()
.expect("unable to acquire changes dir read lock");
snapshots
.update_thin(&snapshot, |snap| {
snap.data.clear();
// retrieve base data; manually because `update_thin` holds the lock already
let mut data = {
let sn = snapshots.0.open(anchor_from_meta(&snap.meta)?)?;
data_deser(&byr_core::ThinSnapshot::read_from_stream(sn)?.data)?
};
for i in &snap.changelist.0 {
let olddata = data.clone();
let bytecode = changes.get(i)?;
BytecodeWrapper(&bytecode[..]).run(&mut data).map_err(|e| {
std::io::Error::new(std::io::ErrorKind::InvalidInput, e.to_string())
})?;
if olddata == data {
return Err(std::io::Error::new(
std::io::ErrorKind::InvalidData,
format!(
"change {} is a NOP",
yzb64::base64::display::Base64Display::from(
&i[..],
&*yzb64::B64_ENGINE
),
),
));
}
}
data_ser(data, &mut snap.data);
Ok(())
})
.expect("unable to update snapshot");
}
Command::Snapshot { anchor, snapshot } => {
if anchor.len() > 256 {
eprintln!("ERROR: anchor name too long");
@ -243,14 +306,7 @@ fn main() {
snap.data.shrink_to_fit();
// retrieve base data; manually because `update_thin` holds the lock already
let mut data = {
let sn = snapshots.0.open(core::str::from_utf8(&snap.meta).map_err(
|_e| {
std::io::Error::new(
std::io::ErrorKind::InvalidData,
"unable to parse anchor",
)
},
)?)?;
let sn = snapshots.0.open(anchor_from_meta(&snap.meta)?)?;
data_deser(&byr_core::ThinSnapshot::read_from_stream(sn)?.data)?
};