Skip to content

Commit

Permalink
share and pass cli arguments for pack verification (#287)
Browse files Browse the repository at this point in the history
  • Loading branch information
Byron committed Jan 3, 2022
1 parent 4b4f9f8 commit db43e47
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 42 deletions.
30 changes: 26 additions & 4 deletions gitoxide-core/src/repository.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,49 @@ pub fn init(directory: Option<PathBuf>) -> Result<git_repository::Path> {
}

pub mod verify {
use crate::pack;
use crate::OutputFormat;
use std::{path::PathBuf, sync::atomic::AtomicBool};

use git_repository::Progress;

use crate::OutputFormat;
/// A general purpose context for many operations provided here
pub struct Context {
/// If set, provide statistics to `out` in the given format
pub output_statistics: Option<OutputFormat>,
/// If set, don't use more than this amount of threads.
/// Otherwise, usually use as many threads as there are logical cores.
/// A value of 0 is interpreted as no-limit
pub thread_limit: Option<usize>,
pub verify_mode: pack::verify::Mode,
pub algorithm: pack::verify::Algorithm,
}

pub const PROGRESS_RANGE: std::ops::RangeInclusive<u8> = 1..=3;

pub fn integrity(
repo: PathBuf,
_format: OutputFormat,
_out: impl std::io::Write,
progress: impl Progress,
should_interrupt: &AtomicBool,
Context {
output_statistics: _,
thread_limit,
verify_mode,
algorithm,
}: Context,
) -> anyhow::Result<()> {
let repo = git_repository::open(repo)?;
// TODO: a way to get the pack cache from a handle
repo.objects.verify_integrity(
progress,
should_interrupt,
git_repository::odb::pack::index::verify::integrity::Options::default(),
git_repository::odb::pack::index::verify::integrity::Options {
verify_mode,
traversal: algorithm.into(),
thread_limit,
// TODO: a way to get the pack cache from a handle
make_pack_lookup_cache: || git_repository::odb::pack::cache::Never,
},
)?;
Ok(())
}
Expand Down
49 changes: 38 additions & 11 deletions src/plumbing/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,34 @@ pub fn main() -> Result<()> {

match cmd {
Subcommands::Repository(subcommands) => match subcommands {
repo::Subcommands::Verify { repository } => prepare_and_run(
repo::Subcommands::Verify {
args:
pack::VerifyOptions {
statistics,
algorithm,
decode,
re_encode,
},
repository,
} => prepare_and_run(
"repository-verify",
verbose,
progress,
progress_keep_open,
core::repository::verify::PROGRESS_RANGE,
move |progress, out, _err| {
core::repository::verify::integrity(repository, format, out, progress, &should_interrupt)
core::repository::verify::integrity(
repository,
out,
progress,
&should_interrupt,
core::repository::verify::Context {
output_statistics: statistics.then(|| format),
algorithm,
verify_mode: verify_mode(decode, re_encode),
thread_limit,
},
)
},
),
},
Expand Down Expand Up @@ -223,23 +243,22 @@ pub fn main() -> Result<()> {
},
),
pack::Subcommands::Verify {
args:
pack::VerifyOptions {
algorithm,
decode,
re_encode,
statistics,
},
path,
algorithm,
decode,
re_encode,
statistics,
} => prepare_and_run(
"pack-verify",
verbose,
progress,
progress_keep_open,
verify::PROGRESS_RANGE,
move |progress, out, err| {
let mode = match (decode, re_encode) {
(true, false) => verify::Mode::HashCrc32Decode,
(true, true) | (false, true) => verify::Mode::HashCrc32DecodeEncode,
(false, false) => verify::Mode::HashCrc32,
};
let mode = verify_mode(decode, re_encode);
let output_statistics = if statistics { Some(format) } else { None };
verify::pack_or_pack_index(
path,
Expand Down Expand Up @@ -396,3 +415,11 @@ pub fn main() -> Result<()> {
}?;
Ok(())
}

fn verify_mode(decode: bool, re_encode: bool) -> verify::Mode {
match (decode, re_encode) {
(true, false) => verify::Mode::HashCrc32Decode,
(true, true) | (false, true) => verify::Mode::HashCrc32DecodeEncode,
(false, false) => verify::Mode::HashCrc32,
}
}
62 changes: 35 additions & 27 deletions src/plumbing/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,40 +210,46 @@ pub mod pack {
/// Verify the integrity of a pack, index or multi-index file
#[clap(setting = AppSettings::DisableVersionFlag)]
Verify {
/// output statistical information about the pack
#[clap(long, short = 's')]
statistics: bool,
/// The algorithm used to verify the pack. They differ in costs.
#[clap(
long,
short = 'a',
default_value = "less-time",
possible_values(core::pack::verify::Algorithm::variants())
)]
algorithm: core::pack::verify::Algorithm,

#[clap(long, conflicts_with("re-encode"))]
/// Decode and parse tags, commits and trees to validate their correctness beyond hashing correctly.
///
/// Malformed objects should not usually occur, but could be injected on purpose or accident.
/// This will reduce overall performance.
decode: bool,

#[clap(long)]
/// Decode and parse tags, commits and trees to validate their correctness, and re-encode them.
///
/// This flag is primarily to test the implementation of encoding, and requires to decode the object first.
/// Encoding an object after decoding it should yield exactly the same bytes.
/// This will reduce overall performance even more, as re-encoding requires to transform zero-copy objects into
/// owned objects, causing plenty of allocation to occour.
re_encode: bool,
#[clap(flatten)]
args: VerifyOptions,

/// The '.pack', '.idx' or 'multi-pack-index' file to validate.
#[clap(parse(from_os_str))]
path: PathBuf,
},
}

#[derive(Debug, clap::Parser)]
pub struct VerifyOptions {
/// output statistical information
#[clap(long, short = 's')]
pub statistics: bool,
/// The algorithm used to verify packs. They differ in costs.
#[clap(
long,
short = 'a',
default_value = "less-time",
possible_values(core::pack::verify::Algorithm::variants())
)]
pub algorithm: core::pack::verify::Algorithm,

#[clap(long, conflicts_with("re-encode"))]
/// Decode and parse tags, commits and trees to validate their correctness beyond hashing correctly.
///
/// Malformed objects should not usually occur, but could be injected on purpose or accident.
/// This will reduce overall performance.
pub decode: bool,

#[clap(long)]
/// Decode and parse tags, commits and trees to validate their correctness, and re-encode them.
///
/// This flag is primarily to test the implementation of encoding, and requires to decode the object first.
/// Encoding an object after decoding it should yield exactly the same bytes.
/// This will reduce overall performance even more, as re-encoding requires to transform zero-copy objects into
/// owned objects, causing plenty of allocation to occour.
pub re_encode: bool,
}

///
pub mod multi_index {
use std::path::PathBuf;
Expand Down Expand Up @@ -330,6 +336,8 @@ pub mod repo {
/// Verify the integrity of the entire repository
#[clap(setting = AppSettings::DisableVersionFlag)]
Verify {
#[clap(flatten)]
args: super::pack::VerifyOptions,
#[clap(short = 'r', long, default_value = ".")]
repository: PathBuf,
},
Expand Down

0 comments on commit db43e47

Please sign in to comment.