From 60c3de341887dc6992a278f88bde058e591fc593 Mon Sep 17 00:00:00 2001
From: Sebastian Thiel <sebastian.thiel@icloud.com>
Date: Sat, 11 Jan 2025 17:34:50 +0100
Subject: [PATCH] feat: add `gix env` to print paths relevant to the Git
 installation.

---
 gitoxide-core/src/lib.rs    | 40 +++++++++++++++++++++++++++++++++++++
 src/plumbing/main.rs        |  9 +++++++++
 src/plumbing/options/mod.rs |  1 +
 3 files changed, 50 insertions(+)

diff --git a/gitoxide-core/src/lib.rs b/gitoxide-core/src/lib.rs
index 9ff7ab73760..24e4c510dbd 100644
--- a/gitoxide-core/src/lib.rs
+++ b/gitoxide-core/src/lib.rs
@@ -30,6 +30,7 @@
 #![deny(rust_2018_idioms)]
 #![forbid(unsafe_code)]
 
+use anyhow::bail;
 use std::str::FromStr;
 
 #[derive(Debug, Eq, PartialEq, Hash, Clone, Copy)]
@@ -82,6 +83,45 @@ pub mod repository;
 mod discover;
 pub use discover::discover;
 
+pub fn env(mut out: impl std::io::Write, format: OutputFormat) -> anyhow::Result<()> {
+    if format != OutputFormat::Human {
+        bail!("JSON output isn't supported");
+    };
+
+    let width = 15;
+    writeln!(
+        out,
+        "{field:>width$}: {}",
+        std::path::Path::new(gix::path::env::shell()).display(),
+        field = "shell",
+    )?;
+    writeln!(
+        out,
+        "{field:>width$}: {:?}",
+        gix::path::env::installation_config_prefix(),
+        field = "config prefix",
+    )?;
+    writeln!(
+        out,
+        "{field:>width$}: {:?}",
+        gix::path::env::installation_config(),
+        field = "config",
+    )?;
+    writeln!(
+        out,
+        "{field:>width$}: {}",
+        gix::path::env::exe_invocation().display(),
+        field = "git exe",
+    )?;
+    writeln!(
+        out,
+        "{field:>width$}: {:?}",
+        gix::path::env::system_prefix(),
+        field = "system prefix",
+    )?;
+    Ok(())
+}
+
 #[cfg(all(feature = "async-client", feature = "blocking-client"))]
 compile_error!("Cannot set both 'blocking-client' and 'async-client' features as they are mutually exclusive");
 
diff --git a/src/plumbing/main.rs b/src/plumbing/main.rs
index 625f9733268..577b23208d6 100644
--- a/src/plumbing/main.rs
+++ b/src/plumbing/main.rs
@@ -146,6 +146,15 @@ pub fn main() -> Result<()> {
     }
 
     match cmd {
+        Subcommands::Env => prepare_and_run(
+            "env",
+            trace,
+            verbose,
+            progress,
+            progress_keep_open,
+            None,
+            move |_progress, out, _err| core::env(out, format),
+        ),
         Subcommands::Merge(merge::Platform { cmd }) => match cmd {
             merge::SubCommands::File {
                 resolve_with,
diff --git a/src/plumbing/options/mod.rs b/src/plumbing/options/mod.rs
index a1f37b08e13..5439b600f42 100644
--- a/src/plumbing/options/mod.rs
+++ b/src/plumbing/options/mod.rs
@@ -145,6 +145,7 @@ pub enum Subcommands {
     Corpus(corpus::Platform),
     MergeBase(merge_base::Command),
     Merge(merge::Platform),
+    Env,
     Diff(diff::Platform),
     Log(log::Platform),
     Worktree(worktree::Platform),