Skip to content

Commit

Permalink
support for json in pretty-plumbing and gitoxide (on demand)
Browse files Browse the repository at this point in the history
  • Loading branch information
Byron committed Jul 2, 2020
1 parent b8b979b commit b3780f8
Show file tree
Hide file tree
Showing 9 changed files with 98 additions and 10 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ fast = ["git-features/parallel", "git-features/fast-sha1"]
pretty-cli = ["structopt",
"git-features/progress-prodash",
"git-features/progress-log",
"gitoxide-core/serde1",
"prodash/log-renderer",
"prodash/tui-renderer",
"prodash/localtime",
Expand Down
3 changes: 2 additions & 1 deletion gitoxide-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ doctest = false
test = false

[features]
serde1 = ["git-object/serde1", "git-odb/serde1"]
serde1 = ["git-object/serde1", "git-odb/serde1", "serde_json"]

[dependencies]
git-repository = { version = "0.1.0", path = "../git-repository" }
Expand All @@ -21,3 +21,4 @@ git-odb = { version = "0.1.0", path = "../git-odb" }
git-features = { version = "0.1.0", path = "../git-features" }
anyhow = "1.0.31"
bytesize = "1.0.1"
serde_json = { version = "1.0.56", optional = true }
45 changes: 40 additions & 5 deletions gitoxide-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,48 @@ use bytesize::ByteSize;
use git_features::progress::Progress;
use git_object::Kind;
use git_odb::pack::{self, index};
use std::str::FromStr;
use std::{io, path::Path};

#[derive(Debug, Eq, PartialEq, Hash, Clone, Copy)]
pub enum OutputFormat {
Human,
#[cfg(feature = "serde1")]
Json,
}

impl OutputFormat {
pub fn variants() -> &'static [&'static str] {
&[
"human",
#[cfg(feature = "serde1")]
"json",
]
}
}

impl FromStr for OutputFormat {
type Err = String;

fn from_str(s: &str) -> Result<Self, Self::Err> {
let s_lc = s.to_ascii_lowercase();
Ok(match s_lc.as_str() {
"human" => OutputFormat::Human,
#[cfg(feature = "serde1")]
"json" => OutputFormat::Json,
_ => return Err(format!("Invalid output format: '{}'", s)),
})
}
}

pub fn init() -> Result<()> {
git_repository::init::repository().with_context(|| "Repository initialization failed")
}

pub fn verify_pack_or_pack_index<P>(
path: impl AsRef<Path>,
progress: Option<P>,
output_statistics: bool,
output_statistics: Option<OutputFormat>,
mut out: impl io::Write,
mut err: impl io::Write,
) -> Result<(git_object::Id, Option<index::PackFileChecksumResult>)>
Expand Down Expand Up @@ -69,7 +101,7 @@ where
}
}
idx.verify_checksum_of_index(pack.as_ref(), progress, || -> EitherCache {
if output_statistics {
if output_statistics.is_some() {
// turn off acceleration as we need to see entire chains all the time
EitherCache::Left(pack::cache::DecodeEntryNoop)
} else {
Expand All @@ -80,9 +112,12 @@ where
ext => return Err(anyhow!("Unknown extension {:?}, expecting 'idx' or 'pack'", ext)),
};
if let Some(stats) = res.1.as_ref() {
if output_statistics {
print_statistics(&mut out, stats).ok();
}
match output_statistics {
Some(OutputFormat::Human) => drop(print_statistics(&mut out, stats)),
#[cfg(feature = "serde1")]
Some(OutputFormat::Json) => drop(serde_json::to_writer_pretty(out, stats)),
_ => {}
};
}
Ok(res)
}
Expand Down
6 changes: 5 additions & 1 deletion src/plumbing/lean.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,11 @@ pub fn main() -> Result<()> {
core::verify_pack_or_pack_index(
path,
progress::Log::new("verify-pack").into(),
statistics,
if statistics {
Some(core::OutputFormat::Human)
} else {
None
},
stdout(),
stderr(),
)
Expand Down
19 changes: 18 additions & 1 deletion src/plumbing/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use structopt::StructOpt;
use options::*;

mod options {
use gitoxide_core as core;
use std::path::PathBuf;
use structopt::{clap::AppSettings, StructOpt};

Expand All @@ -27,6 +28,14 @@ mod options {
/// if set, output statistical information about the pack
#[structopt(long, short = "s")]
statistics: bool,
/// Determine the format to use when outputting statistics.
#[structopt(
long,
short = "f",
default_value = "human",
possible_values(core::OutputFormat::variants())
)]
format: core::OutputFormat,

/// if set, verbose progress messages are printed line by line
#[structopt(long, short = "v")]
Expand Down Expand Up @@ -99,12 +108,20 @@ pub fn main() -> Result<()> {
path,
verbose,
progress,
format,
progress_keep_open,
statistics,
} => {
let (handle, progress) = init_progress("verify-pack", verbose, progress, progress_keep_open);
let mut buf = Vec::new();
let res = core::verify_pack_or_pack_index(path, progress, statistics, &mut buf, stderr()).map(|_| ());
let res = core::verify_pack_or_pack_index(
path,
progress,
if statistics { Some(format) } else { None },
&mut buf,
stderr(),
)
.map(|_| ());
// We might have something interesting to show, which would be hidden by the alternate screen if there is a progress TUI
// We know that the printing happens at the end, so this is fine.
drop(handle);
Expand Down
4 changes: 2 additions & 2 deletions tasks.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@
* [x] change exit code depending on verification success or failure
* [x] progress that allows TUI to remain open for people to see more log messages
* [x] support for serde/~~miniserde~~ for all returned data types (features per crate)
* [ ] a way to output things as json (as `--format` flag maybe)
* [x] a way to output things as json (as `--format` flag maybe)
* **stress**
* [ ] first stress test for validation of a big repository, linux maybe, or something smaller but big enough
* **unrelated**
* [ ] Use `argh` in cargo-diet to reduce build times
* [ ] Use `argh` in prodash dashboard example to reduce build times
* [x] Use `argh` in prodash dashboard example to reduce build times

Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"average": {
"kind": "Tree",
"num_deltas": 1,
"decompressed_size": 3456,
"compressed_size": 1725,
"object_size": 9621
},
"objects_per_chain_length": {
"0": 18,
"1": 4,
"2": 3,
"3": 1,
"4": 2,
"5": 1,
"6": 1
},
"total_compressed_entries_size": 51753,
"total_decompressed_entries_size": 103701,
"total_object_size": 288658,
"pack_size": 51875
}
7 changes: 7 additions & 0 deletions tests/stateless-journey.sh
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,13 @@ title "CLI ${kind}"
expect_run $SUCCESSFULLY "$exe_plumbing" verify-pack --statistics "$PACK_INDEX_FILE"
}
)
test "$kind" = pretty_and_fast &&
(with "statistics (JSON)"
it "verifies the pack index successfully and with desired output" && {
WITH_SNAPSHOT="$snapshot/plumbing-verify-pack-index-with-statistics-json-success" \
expect_run $SUCCESSFULLY "$exe_plumbing" verify-pack --statistics --format json "$PACK_INDEX_FILE"
}
)
)
(sandbox
(with "an INvalid pack INDEX file"
Expand Down

0 comments on commit b3780f8

Please sign in to comment.