Skip to content

Commit

Permalink
added some missing documentation, minimal CLI changes
Browse files Browse the repository at this point in the history
  • Loading branch information
sokorototo committed Mar 29, 2024
1 parent 9514dd9 commit 4206102
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 107 deletions.
30 changes: 21 additions & 9 deletions vach-cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,8 @@ vach list -i textures.vach
> `pack` is used to pack files and directories into archives. It takes inputs for customizing how the archive should be packaged.
```sh
# The simplest pack command.
# Any pack command must have an output, set using the "-o" or "--output" keys
# This builds only an empty archive
# This builds an empty archive
vach pack -o hello.vach

# You can add files as inputs using the "-i" or "--input" keys
Expand Down Expand Up @@ -127,10 +126,9 @@ vach pack -t -o hello.vach -i hello.txt goodbye.txt

### 2: unpack

>`unpack` is used to unpack archives back into their constituent files.
>`unpack` it's just like `pack` but backwards
```sh
# The simplest unpack command
# Provide an input: "-i" or "--input"
vach unpack -i target.vach

Expand All @@ -151,12 +149,26 @@ vach unpack -k keypair.kp -i source.vach
vach unpack -s keypair.sk -i source.vach
```

### 3: list
### 3: pipe

>`pipe`: Read the data from a _specific_ entry and pipe it to stdout

```sh
# Print to stdout
vach pipe -i target.vach -r npc-dialogue.txt
# Pipe directly into a file
vach pipe -i target.vach -r npc-dialogue.txt >> npc-dialogue.txt
# Pipe into another process' stdin
vach pipe -i presets.vach -r low.json | jq '."TextureResolution"'
```

### 4: list

> Lists all the entries in the archive as a table

```sh
# The simplest list command
# Provide some input: "-i" or "--input"
vach list -i textures.vach
Expand All @@ -170,7 +182,7 @@ vach list -i textures.vach -m TXTRS
vach list -i textures.vach -m TXTRS --sort size-descending
```

### 4: verify
### 5: verify

> Verifies the validity of a file as an archive

Expand All @@ -182,7 +194,7 @@ vach verify -i textures.vach
vach verify -i textures.vach -m TXTRS
```

### 5: keypair
### 6: keypair

> Key-pair generation command

Expand All @@ -197,7 +209,7 @@ vach keypair -s -o keypair.kp
# -> keypair.sk
```

### 6: split
### 7: split

> Splits an existing keypair into it's public and secret components
Expand Down
125 changes: 50 additions & 75 deletions vach-cli/src/commands/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,14 @@ use tabled::{
};
use vach::{
prelude::{ArchiveConfig, Archive, Flags},
archive::{CompressionAlgorithm, RegistryEntry},
archive::RegistryEntry,
};
use indicatif::HumanBytes;

use super::CommandTrait;
use crate::keys::key_names;

pub const VERSION: &str = "0.2.0";

enum Sort {
SizeAscending,
SizeDescending,
Alphabetical,
AlphabeticalReversed,
None,
}
pub const VERSION: &str = "0.2.1";

/// This command lists the entries in an archive in tabulated form
pub struct Evaluator;
Expand All @@ -35,15 +27,6 @@ impl CommandTrait for Evaluator {
},
};

let sort = match args.value_of(key_names::SORT) {
Some("alphabetical") => Sort::Alphabetical,
Some("alphabetical-reversed") => Sort::AlphabeticalReversed,
Some("size-ascending") => Sort::SizeAscending,
Some("size-descending") => Sort::SizeDescending,
Some(sort) => anyhow::bail!("Unknown sort given: {}. Valid sort types are: 'alphabetical' 'alphabetical-descending' 'size-ascending' 'size-descending'", sort),
None => Sort::None,
};

let magic: [u8; vach::MAGIC_LENGTH] = match args.value_of(key_names::MAGIC) {
Some(magic) => magic.as_bytes().try_into()?,
None => *vach::DEFAULT_MAGIC,
Expand All @@ -52,61 +35,53 @@ impl CommandTrait for Evaluator {
let file = File::open(archive_path)?;
let archive = Archive::with_config(file, &ArchiveConfig::new(magic, None))?;

if archive.entries().is_empty() {
println!("{}", archive);
} else {
let mut entries: Vec<(String, RegistryEntry)> = archive
.entries()
.iter()
.map(|(id, entry)| (id.clone(), entry.clone()))
.collect();

// Log some additional info about this archive
println!("{}", archive);

// Sort the entries accordingly
match sort {
Sort::SizeAscending => entries.sort_by(|a, b| a.1.offset.cmp(&b.1.offset)),
Sort::SizeDescending => entries.sort_by(|a, b| b.1.offset.cmp(&a.1.offset)),
Sort::Alphabetical => entries.sort_by(|a, b| a.0.cmp(&b.0)),
Sort::AlphabeticalReversed => entries.sort_by(|a, b| b.0.cmp(&a.0)),
Sort::None => (),
};

let table_entries: Vec<FileTableEntry> = entries
.iter()
.map(|(id, entry)| {
let c_algo = if entry.flags.contains(Flags::LZ4_COMPRESSED) {
Some(CompressionAlgorithm::LZ4)
} else if entry.flags.contains(Flags::BROTLI_COMPRESSED) {
Some(CompressionAlgorithm::Brotli(8))
} else if entry.flags.contains(Flags::SNAPPY_COMPRESSED) {
Some(CompressionAlgorithm::Snappy)
} else {
None
};

let c_algo = match c_algo {
Some(algo) => algo.to_string(),
None => "None".to_string(),
};

FileTableEntry {
id,
size: HumanBytes(entry.offset).to_string(),
flags: entry.flags,
compression: c_algo,
}
})
.collect();

let mut table = Table::new(table_entries);
table
.with(Style::rounded())
.with(Modify::list(Columns::new(..1), Alignment::left()));

println!("{}", table);
}
// log basic metadata
println!("{}", archive);

let mut entries: Vec<(String, RegistryEntry)> = archive
.entries()
.iter()
.map(|(id, entry)| (id.clone(), entry.clone()))
.collect();

// Sort the entries accordingly
match args.value_of(key_names::SORT) {
Some("alphabetical") => entries.sort_by(|a, b| a.0.cmp(&b.0)),
Some("alphabetical-reversed") => entries.sort_by(|a, b| b.0.cmp(&a.0)),
Some("size-ascending") => entries.sort_by(|a, b| a.1.offset.cmp(&b.1.offset)),
Some("size-descending") => entries.sort_by(|a, b| b.1.offset.cmp(&a.1.offset)),
Some(sort) => anyhow::bail!("Unknown sort option provided: {}. Valid sort types are: 'alphabetical' 'alphabetical-descending' 'size-ascending' 'size-descending'", sort),
_ => (),
};

let table_entries: Vec<FileTableEntry> = entries
.iter()
.map(|(id, entry)| {
let c_algo = if entry.flags.contains(Flags::LZ4_COMPRESSED) {
"LZ4"
} else if entry.flags.contains(Flags::BROTLI_COMPRESSED) {
"Brotli"
} else if entry.flags.contains(Flags::SNAPPY_COMPRESSED) {
"Snappy"
} else {
"None"
};

FileTableEntry {
id,
size: HumanBytes(entry.offset).to_string(),
flags: entry.flags,
compression: c_algo,
}
})
.collect();

let mut table = Table::new(table_entries);
table
.with(Style::rounded())
.with(Modify::list(Columns::new(..1), Alignment::left()));

println!("{}", table);

Ok(())
}
Expand All @@ -117,5 +92,5 @@ struct FileTableEntry<'a> {
id: &'a str,
size: String,
flags: Flags,
compression: String,
compression: &'static str,
}
39 changes: 16 additions & 23 deletions vach-cli/src/commands/pack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ impl Read for FileWrapper {
};
let result = file.read(buf);

// Intercepts a file once it's finished reading to drop it, thus avoiding OS filesystem limitations easily
// Meaning we can safely drop the `fs::File` stored in this file wrapper
// Once the file is done reading, we drop the file handle
// TOo avoid hitting OS limitations
if let Ok(0) = result {
self.1.take();
};
Expand Down Expand Up @@ -107,7 +107,7 @@ impl CommandTrait for Evaluator {
};

// Extract the inputs
let mut inputs: Vec<FileWrapper> = vec![];
let mut inputs = vec![];

// Used to filter invalid inputs and excluded inputs
let path_filter = |path: &PathBuf| match path.canonicalize() {
Expand Down Expand Up @@ -188,8 +188,8 @@ impl CommandTrait for Evaluator {
kp = Some(generated);
}

let pbar = ProgressBar::new(inputs.len() as u64 + 5 + if truncate { 3 } else { 0 });
pbar.set_style(
let progress = ProgressBar::new(inputs.len() as u64 + 5 + if truncate { 3 } else { 0 });
progress.set_style(
ProgressStyle::default_bar()
.template(super::PROGRESS_BAR_STYLE)?
.progress_chars("█░-")
Expand All @@ -198,8 +198,8 @@ impl CommandTrait for Evaluator {

// Since it wraps it's internal state in an arc, we can safely clone and send across threads
let callback = |leaf: &Leaf, _: &RegistryEntry| {
pbar.inc(1);
pbar.set_message(leaf.id.clone())
progress.inc(1);
progress.set_message(leaf.id.clone())
};

// Build a builder-config using the above extracted data
Expand Down Expand Up @@ -234,42 +234,35 @@ impl CommandTrait for Evaluator {
// Process the files
for wrapper in &mut inputs {
if !wrapper.0.exists() {
pbar.println(format!("Skipping {}, does not exist!", wrapper.0.to_string_lossy()));

pbar.inc(1);
println!("Skipping {}, does not exist!", wrapper.0.to_string_lossy());
progress.inc(1);

continue;
}

let id = wrapper
.0
.to_string_lossy()
.trim_start_matches("./")
.trim_start_matches(".\\")
.to_string();
println!("Preparing {} for packaging", id);
let id = wrapper.0.to_string_lossy().into_owned();
builder.add(wrapper, &id)?;
}

// Inform of success in input queue
pbar.inc(2);
progress.inc(2);

builder.dump(output_file, &builder_config)?;
pbar.println(format!("Generated a new archive @ {}", output_path));
progress.println(format!("Generated a new archive @ {}", output_path));
drop(builder);

// Truncate original files
if truncate {
for wrapper in inputs {
std::fs::remove_file(&wrapper.0)?;
pbar.finish();
pbar.println(format!("Truncated original file @ {}", wrapper.0.to_string_lossy()));
progress.println(format!("Truncated original file @ {}", wrapper.0.to_string_lossy()));
}

pbar.inc(3);
progress.inc(3);
};

pbar.inc(3);
progress.inc(3);
progress.finish();

Ok(())
}
Expand Down

0 comments on commit 4206102

Please sign in to comment.