Skip to content

Commit

Permalink
JSON output for index entries (#293)
Browse files Browse the repository at this point in the history
Mainly intended for seeing all the values, at the cost of readability.
  • Loading branch information
Byron committed Jan 24, 2022
1 parent f790a55 commit 3fc1622
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 22 deletions.
2 changes: 1 addition & 1 deletion git-repository/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ test = true
[features]
default = ["max-performance", "one-stop-shop"]
unstable = ["git-index"]
serde1 = ["git-pack/serde1", "git-object/serde1", "git-protocol/serde1", "git-transport/serde1", "git-ref/serde1", "git-odb/serde1"]
serde1 = ["git-pack/serde1", "git-object/serde1", "git-protocol/serde1", "git-transport/serde1", "git-ref/serde1", "git-odb/serde1", "git-index/serde1"]
# enable when https://github.com/RustCrypto/asm-hashes/issues/17 is fixed
# max-performance = ["git-features/parallel", "git-features/zlib-ng-compat", "git-features/fast-sha1"]
max-performance = ["git-features/parallel", "git-features/zlib-ng-compat", "git-pack/pack-cache-lru-static", "git-pack/pack-cache-lru-dynamic"]
Expand Down
107 changes: 87 additions & 20 deletions gitoxide-core/src/index.rs
Original file line number Diff line number Diff line change
@@ -1,38 +1,105 @@
use git_repository as git;
use git_repository::bstr::ByteSlice;
use std::io::Write;
use std::path::Path;

pub mod entries {
use git_repository as git;

pub struct Options {
pub object_hash: git::hash::Kind,
pub format: crate::OutputFormat,
}
}

#[allow(unused)]
pub fn entries(
index_path: impl AsRef<Path>,
mut out: impl std::io::Write,
object_hash: git::hash::Kind,
entries::Options { object_hash, format }: entries::Options,
) -> anyhow::Result<()> {
use crate::OutputFormat::*;
let file = git::index::File::at(
index_path.as_ref(),
git::index::decode::Options {
object_hash,
..Default::default()
},
)?;
for entry in file.entries() {
writeln!(
out,
"{} {}{:?} {} {}",
match entry.flags.stage() {
0 => "BASE ",
1 => "OURS ",
2 => "THEIRS ",
_ => "UNKNOWN",
},
if entry.flags.is_empty() {
"".to_string()
} else {
format!("{:?} ", entry.flags)
},
entry.mode,
entry.id,
entry.path(&file.state)
)?;

#[cfg(feature = "serde1")]
if let Json = format {
out.write_all(b"[\n")?;
}

let mut entries = file.entries().iter().peekable();
while let Some(entry) = entries.next() {
match format {
Human => human_entry(&mut out, &file, entry)?,
#[cfg(feature = "serde1")]
Json => json_entry_oneline(&mut out, &file, entry, entries.peek().is_none())?,
}
}

#[cfg(feature = "serde1")]
if let Json = format {
out.write_all(b"]\n")?;
}
Ok(())
}

#[cfg(feature = "serde1")]
fn json_entry_oneline(
mut out: &mut impl Write,
file: &git::index::File,
entry: &git::index::Entry,
is_last: bool,
) -> anyhow::Result<()> {
#[cfg_attr(feature = "serde1", derive(serde::Serialize))]
struct Entry<'a> {
stat: &'a git::index::entry::Stat,
hex_id: String,
flags: u32,
mode: u32,
path: std::borrow::Cow<'a, str>,
}

serde_json::to_writer(
&mut out,
&Entry {
stat: &entry.stat,
hex_id: entry.id.to_hex().to_string(),
flags: entry.flags.bits(),
mode: entry.mode.bits(),
path: entry.path(&file.state).to_str_lossy(),
},
)?;

if is_last {
out.write_all(b"\n")?;
} else {
out.write_all(b",\n")?;
}
Ok(())
}

fn human_entry(out: &mut impl Write, file: &git::index::File, entry: &git::index::Entry) -> std::io::Result<()> {
writeln!(
out,
"{} {}{:?} {} {}",
match entry.flags.stage() {
0 => "BASE ",
1 => "OURS ",
2 => "THEIRS ",
_ => "UNKNOWN",
},
if entry.flags.is_empty() {
"".to_string()
} else {
format!("{:?} ", entry.flags)
},
entry.mode,
entry.id,
entry.path(&file.state)
)
}
4 changes: 3 additions & 1 deletion src/plumbing/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,9 @@ pub fn main() -> Result<()> {
progress,
progress_keep_open,
None,
move |_progress, out, _err| core::index::entries(index_path, out, object_hash),
move |_progress, out, _err| {
core::index::entries(index_path, out, core::index::entries::Options { object_hash, format })
},
),
},
Subcommands::Repository(subcommands) => match subcommands {
Expand Down

0 comments on commit 3fc1622

Please sign in to comment.