Skip to content

Commit

Permalink
feat: gix submodule subcommand for simple submodule listing and inf…
Browse files Browse the repository at this point in the history
…ormation retrieval
  • Loading branch information
Byron committed Aug 21, 2023
1 parent f4a9a6b commit 1ccbe16
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 4 deletions.
8 changes: 4 additions & 4 deletions gitoxide-core/src/repository/index/entries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,11 @@ pub(crate) mod function {
recurse_submodules,
}: Options,
) -> anyhow::Result<()> {
use crate::OutputFormat::*;
let mut out = BufWriter::with_capacity(64 * 1024, out);
let mut all_attrs = statistics.then(BTreeSet::new);

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

Expand All @@ -70,13 +69,14 @@ pub(crate) mod function {
)?;

#[cfg(feature = "serde")]
if format == Json {
if format == OutputFormat::Json {
out.write_all(b"]\n")?;
out.flush()?;
if statistics {
serde_json::to_writer_pretty(&mut err, &stats)?;
}
} else if format == Human && statistics {
}
if format == OutputFormat::Human && statistics {
out.flush()?;
writeln!(err, "{stats:#?}")?;
if let Some(attrs) = all_attrs.filter(|a| !a.is_empty()) {
Expand Down
1 change: 1 addition & 0 deletions gitoxide-core/src/repository/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,5 +40,6 @@ pub mod mailmap;
pub mod odb;
pub mod remote;
pub mod revision;
pub mod submodule;
pub mod tree;
pub mod verify;
67 changes: 67 additions & 0 deletions gitoxide-core/src/repository/submodule.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
use crate::OutputFormat;
use anyhow::bail;
use gix::commit::describe::SelectRef;
use gix::prelude::ObjectIdExt;
use gix::{Repository, Submodule};

pub fn list(repo: Repository, mut out: impl std::io::Write, format: OutputFormat) -> anyhow::Result<()> {
if format != OutputFormat::Human {
bail!("Only human output is supported for now")
}

let Some(submodules) = repo.submodules()? else { return Ok(()) };
for sm in submodules {
print_sm(sm, &mut out)?;
}
Ok(())
}

fn print_sm(sm: Submodule<'_>, out: &mut impl std::io::Write) -> anyhow::Result<()> {
let _span = gix::trace::coarse!("print_sm", path = ?sm.path());
let state = sm.state()?;
let mut sm_repo = sm.open()?;
if let Some(repo) = sm_repo.as_mut() {
repo.object_cache_size_if_unset(4 * 1024 * 1024);
};
writeln!(
out,
" {is_active} {path} {config} head:{head_id} index:{index_id} ({worktree}) [{url}]",
is_active = if !sm.is_active()? || !state.repository_exists {
"ⅹ"
} else {
"✓"
},
path = sm.path()?,
config = if state.superproject_configuration {
"config:yes"
} else {
"config:no"
},
head_id = submodule_short_hash(sm.head_id()?, sm_repo.as_ref()),
index_id = submodule_short_hash(sm.index_id()?, sm_repo.as_ref()),
worktree = match sm_repo {
Some(repo) => {
// TODO(name-revision): this is the simple version, `git` gives it
// multiple tries https://github.com/git/git/blob/fac96dfbb1c24369ba7d37a5affd8adfe6c650fd/builtin/submodule--helper.c#L161
// and even uses `git name-rev`/`git describe --contains` which we can't do yet.
repo.head_commit()?
.describe()
.names(SelectRef::AllRefs)
.format()?
.to_string()
}
None => {
"no worktree".to_string()
}
},
url = sm.url()?.to_bstring()
)?;
Ok(())
}

fn submodule_short_hash(id: Option<gix::ObjectId>, repo: Option<&Repository>) -> String {
id.map_or_else(
|| "none".to_string(),
|id| repo.map_or_else(|| id.to_string(), |repo| id.attach(repo).shorten_or_id().to_string()),
)
}
14 changes: 14 additions & 0 deletions src/plumbing/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,20 @@ pub fn main() -> Result<()> {
})?;

match cmd {
Subcommands::Submodule(platform) => match platform
.cmds
.unwrap_or(crate::plumbing::options::submodule::Subcommands::List)
{
crate::plumbing::options::submodule::Subcommands::List => prepare_and_run(
"submodule-list",
trace,
verbose,
progress,
progress_keep_open,
None,
move |_progress, out, _err| core::repository::submodule::list(repository(Mode::Lenient)?, out, format),
),
},
#[cfg(feature = "gitoxide-core-tools-archive")]
Subcommands::Archive(crate::plumbing::options::archive::Platform {
format,
Expand Down
18 changes: 18 additions & 0 deletions src/plumbing/options/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,9 @@ pub enum Subcommands {
Exclude(exclude::Subcommands),
#[clap(subcommand)]
Index(index::Subcommands),
/// Interact with submodules.
#[clap(alias = "submodules")]
Submodule(submodule::Platform),
/// Show which git configuration values are used or planned.
ConfigTree,
Config(config::Platform),
Expand Down Expand Up @@ -708,5 +711,20 @@ pub mod index {
}
}

pub mod submodule {

#[derive(Debug, clap::Parser)]
pub struct Platform {
#[clap(subcommand)]
pub cmds: Option<Subcommands>,
}

#[derive(Debug, clap::Subcommand)]
pub enum Subcommands {
/// Print all direct submodules to standard output
List,
}
}

///
pub mod free;

0 comments on commit 1ccbe16

Please sign in to comment.