Watch
0
0
Fork
You've already forked hyperhive
0
hyperhive/hive-c0re/src/lifecycle/git.rs

39 lines
1.6 KiB
Rust

//! Spawning `git` from hive-c0re: the binary lookup and the credential
//! handoff.
use tokio::process::Command;
/// Spawn `git` honoring the `HYPERHIVE_GIT` env var (absolute path baked in
/// by the NixOS module), falling back to bare `git` (PATH lookup) otherwise.
///
/// `kill_on_drop(true)`: if the caller's future is dropped before the child
/// exits — e.g. a `tokio::time::timeout` around startup migration fires — the
/// git child is killed instead of orphaned (left retrying an unreachable
/// forge). No-op on normal completion, where the child has already exited.
#[must_use]
pub fn git_command() -> Command {
let exe = std::env::var("HYPERHIVE_GIT").unwrap_or_else(|_| "git".into());
let mut cmd = Command::new(exe);
cmd.kill_on_drop(true);
cmd
}
/// [`git_command`] carrying HTTP credentials **in its environment**.
///
/// `auth_header` is an `Authorization:` line (see
/// `forge::basic_auth_header`) handed to git as `http.extraHeader`
/// through `GIT_CONFIG_*`, which git reads exactly like a config file. The
/// alternative — userinfo in the remote URL — puts the secret in `argv`, and
/// `/proc/<pid>/cmdline` is world-readable while `/proc/<pid>/environ` is
/// owner-only. Same credential, materially smaller audience.
///
/// `GIT_CONFIG_COUNT` needs git >= 2.31; `HYPERHIVE_GIT` points at a pinned
/// nixpkgs git well past that.
#[must_use]
pub fn git_command_authed(auth_header: &str) -> Command {
let mut cmd = git_command();
cmd.env("GIT_CONFIG_COUNT", "1")
.env("GIT_CONFIG_KEY_0", "http.extraHeader")
.env("GIT_CONFIG_VALUE_0", auth_header);
cmd
}