test: route integration-test git subprocesses through hermetic helper

Adopt grasp_audit::git_command() at every git call site in tests/ so
the integration suite sees only configuration it supplies itself,
matching the hermeticity grasp-audit's fixtures now enforce. Ambient
settings such as a failing hook from core.hooksPath/init.templateDir
or an init.defaultBranch override previously reached these
subprocesses directly; the nip09 helpers even depended on
init.defaultBranch=main to make their swallowed branch-setup errors
harmless.

This commit is the mechanical conversion only: arguments and error
handling are unchanged (tokio call sites wrap the helper with
tokio::process::Command::from). Load-bearing swallowed exit statuses
are fixed in a follow-up so each change stays independently
reviewable.

Validated: cargo clippy --workspace --all-targets -D warnings;
cargo fmt --all -- --check; full suite runs in the final validation
pass.
This commit is contained in:
DanConwayDev
2026-08-01 16:16:26 +00:00
parent be8dce6e9c
commit 7be865bac8
10 changed files with 65 additions and 65 deletions
+3 -3
View File
@@ -572,7 +572,7 @@ async fn test_archive_read_only_creates_bare_repo() {
.await
.expect("Failed to write new file");
let output = tokio::process::Command::new("git")
let output = tokio::process::Command::from(grasp_audit::git_command())
.args(["add", "."])
.current_dir(temp_dir.path())
.output()
@@ -580,7 +580,7 @@ async fn test_archive_read_only_creates_bare_repo() {
.expect("Failed to git add");
assert!(output.status.success());
let output = tokio::process::Command::new("git")
let output = tokio::process::Command::from(grasp_audit::git_command())
.args(["commit", "-m", "New commit for push test"])
.current_dir(temp_dir.path())
.output()
@@ -590,7 +590,7 @@ async fn test_archive_read_only_creates_bare_repo() {
// Try to push to archive relay (should fail in read-only mode)
let push_url = format!("http://{}/{}/{}.git", archive_domain, npub, identifier);
let output = tokio::process::Command::new("git")
let output = tokio::process::Command::from(grasp_audit::git_command())
.args(["push", &push_url, "main"])
.current_dir(temp_dir.path())
.output()
+21 -21
View File
@@ -27,7 +27,7 @@
//! let server = SmartGitServer::start(temp_dir.path()).await;
//!
//! // Git operations work against server.url()
//! let output = Command::new("git")
//! let output = git_command()
//! .args(["clone", "--depth=1", server.url(), "/tmp/clone"])
//! .output()
//! .unwrap();
@@ -46,9 +46,9 @@
//! The purgatory sync system uses `git fetch --depth=1`, so tests involving purgatory
//! sync should use `SmartGitServer`.
use grasp_audit::git_command;
use std::net::SocketAddr;
use std::path::{Path, PathBuf};
use std::process::Command;
use std::sync::Arc;
use http_body_util::Full;
@@ -100,7 +100,7 @@ impl SimpleGitServer {
let bare_repo_path = temp_dir.path().join("repo.git");
// 2. Create bare clone
let output = Command::new("git")
let output = git_command()
.args(["clone", "--bare"])
.arg(source_repo)
.arg(&bare_repo_path)
@@ -115,7 +115,7 @@ impl SimpleGitServer {
}
// 3. Run git update-server-info to generate info/refs and objects/info/packs
let output = Command::new("git")
let output = git_command()
.args(["update-server-info"])
.current_dir(&bare_repo_path)
.output()
@@ -395,7 +395,7 @@ mod tests {
let server = SimpleGitServer::start(temp_dir.path()).await;
// Run git ls-remote against the server (using tokio::process::Command)
let output = tokio::process::Command::new("git")
let output = tokio::process::Command::from(grasp_audit::git_command())
.args(["ls-remote", server.url()])
.output()
.await
@@ -439,7 +439,7 @@ mod tests {
let dest_dir = tempfile::tempdir().expect("Failed to create dest dir");
// Initialize empty repo (using tokio::process::Command)
let output = tokio::process::Command::new("git")
let output = tokio::process::Command::from(grasp_audit::git_command())
.args(["init"])
.current_dir(dest_dir.path())
.output()
@@ -448,7 +448,7 @@ mod tests {
assert!(output.status.success());
// Add the server as a remote
let output = tokio::process::Command::new("git")
let output = tokio::process::Command::from(grasp_audit::git_command())
.args(["remote", "add", "origin", server.url()])
.current_dir(dest_dir.path())
.output()
@@ -457,7 +457,7 @@ mod tests {
assert!(output.status.success());
// Fetch from the server
let output = tokio::process::Command::new("git")
let output = tokio::process::Command::from(grasp_audit::git_command())
.args(["fetch", "origin"])
.current_dir(dest_dir.path())
.output()
@@ -471,7 +471,7 @@ mod tests {
);
// Verify the commit was fetched
let output = tokio::process::Command::new("git")
let output = tokio::process::Command::from(grasp_audit::git_command())
.args(["rev-parse", "origin/main"])
.current_dir(dest_dir.path())
.output()
@@ -561,7 +561,7 @@ impl SmartGitServer {
let bare_repo_path = temp_dir.path().join("repo.git");
// 2. Create bare clone
let output = Command::new("git")
let output = git_command()
.args(["clone", "--bare"])
.arg(source_repo)
.arg(&bare_repo_path)
@@ -759,7 +759,7 @@ async fn handle_info_refs_upload_pack(
use tokio::process::Command as TokioCommand;
// Spawn git upload-pack --advertise-refs
let mut cmd = TokioCommand::new("git");
let mut cmd = TokioCommand::from(grasp_audit::git_command());
cmd.arg("-c")
.arg("uploadpack.allowReachableSHA1InWant=true")
.arg("-c")
@@ -851,7 +851,7 @@ async fn handle_upload_pack(
let body_bytes = req.collect().await?.to_bytes();
// Spawn git upload-pack
let mut cmd = TokioCommand::new("git");
let mut cmd = TokioCommand::from(grasp_audit::git_command());
cmd.arg("-c")
.arg("uploadpack.allowReachableSHA1InWant=true")
.arg("-c")
@@ -1004,7 +1004,7 @@ mod smart_git_server_tests {
let server = SmartGitServer::start(temp_dir.path()).await;
// Run git ls-remote against the server (using tokio::process::Command)
let output = tokio::process::Command::new("git")
let output = tokio::process::Command::from(grasp_audit::git_command())
.args(["ls-remote", server.url()])
.output()
.await
@@ -1048,7 +1048,7 @@ mod smart_git_server_tests {
let dest_dir = tempfile::tempdir().expect("Failed to create dest dir");
// Initialize empty repo
let output = tokio::process::Command::new("git")
let output = tokio::process::Command::from(grasp_audit::git_command())
.args(["init"])
.current_dir(dest_dir.path())
.output()
@@ -1057,7 +1057,7 @@ mod smart_git_server_tests {
assert!(output.status.success());
// Add the server as a remote
let output = tokio::process::Command::new("git")
let output = tokio::process::Command::from(grasp_audit::git_command())
.args(["remote", "add", "origin", server.url()])
.current_dir(dest_dir.path())
.output()
@@ -1066,7 +1066,7 @@ mod smart_git_server_tests {
assert!(output.status.success());
// Fetch from the server
let output = tokio::process::Command::new("git")
let output = tokio::process::Command::from(grasp_audit::git_command())
.args(["fetch", "origin"])
.current_dir(dest_dir.path())
.output()
@@ -1080,7 +1080,7 @@ mod smart_git_server_tests {
);
// Verify the commit was fetched
let output = tokio::process::Command::new("git")
let output = tokio::process::Command::from(grasp_audit::git_command())
.args(["rev-parse", "origin/main"])
.current_dir(dest_dir.path())
.output()
@@ -1113,7 +1113,7 @@ mod smart_git_server_tests {
let dest_dir = tempfile::tempdir().expect("Failed to create dest dir");
// Initialize empty repo
let output = tokio::process::Command::new("git")
let output = tokio::process::Command::from(grasp_audit::git_command())
.args(["init"])
.current_dir(dest_dir.path())
.output()
@@ -1122,7 +1122,7 @@ mod smart_git_server_tests {
assert!(output.status.success());
// Add the server as a remote
let output = tokio::process::Command::new("git")
let output = tokio::process::Command::from(grasp_audit::git_command())
.args(["remote", "add", "origin", server.url()])
.current_dir(dest_dir.path())
.output()
@@ -1131,7 +1131,7 @@ mod smart_git_server_tests {
assert!(output.status.success());
// Shallow fetch from the server - THIS IS WHAT PURGATORY SYNC USES
let output = tokio::process::Command::new("git")
let output = tokio::process::Command::from(grasp_audit::git_command())
.args(["fetch", "--depth=1", "origin", &commit_hash])
.current_dir(dest_dir.path())
.output()
@@ -1145,7 +1145,7 @@ mod smart_git_server_tests {
);
// Verify the commit was fetched
let output = tokio::process::Command::new("git")
let output = tokio::process::Command::from(grasp_audit::git_command())
.args(["cat-file", "-t", &commit_hash])
.current_dir(dest_dir.path())
.output()
+8 -8
View File
@@ -106,11 +106,11 @@ pub async fn publish_served_repo(client: &AuditClient, test_name: &str) -> (Even
"deterministic commit hash mismatch"
);
let _ = std::process::Command::new("git")
let _ = grasp_audit::git_command()
.args(["branch", "main"])
.current_dir(&clone_path)
.output();
let _ = std::process::Command::new("git")
let _ = grasp_audit::git_command()
.args(["checkout", "main"])
.current_dir(&clone_path)
.output();
@@ -222,11 +222,11 @@ pub async fn publish_served_repo_with_maintainers(
"deterministic commit hash mismatch"
);
let _ = std::process::Command::new("git")
let _ = grasp_audit::git_command()
.args(["branch", "main"])
.current_dir(&clone_path)
.output();
let _ = std::process::Command::new("git")
let _ = grasp_audit::git_command()
.args(["checkout", "main"])
.current_dir(&clone_path)
.output();
@@ -498,11 +498,11 @@ pub async fn publish_served_announcement_for_identifier(
"deterministic commit hash mismatch"
);
let _ = std::process::Command::new("git")
let _ = grasp_audit::git_command()
.args(["branch", "main"])
.current_dir(&clone_path)
.output();
let _ = std::process::Command::new("git")
let _ = grasp_audit::git_command()
.args(["checkout", "main"])
.current_dir(&clone_path)
.output();
@@ -611,11 +611,11 @@ pub async fn publish_served_announcement_with_state_for_identifier(
"deterministic commit hash mismatch"
);
let _ = std::process::Command::new("git")
let _ = grasp_audit::git_command()
.args(["branch", "main"])
.current_dir(&clone_path)
.output();
let _ = std::process::Command::new("git")
let _ = grasp_audit::git_command()
.args(["checkout", "main"])
.current_dir(&clone_path)
.output();
+11 -11
View File
@@ -11,9 +11,9 @@
//! - Use `Tag::custom("name", vec![...])` syntax
//! - Use `EventBuilder::new(kind, content).tags(tags)` syntax
use grasp_audit::git_command;
use nostr_sdk::prelude::*;
use std::path::Path;
use std::process::Command;
use std::time::Duration;
// NOTE: Using rust-nostr Kind variants:
@@ -131,7 +131,7 @@ pub fn create_branch(
/// Get the HEAD commit hash.
fn get_head_commit(path: &Path) -> Result<String, String> {
let output = Command::new("git")
let output = git_command()
.args(["rev-parse", "HEAD"])
.current_dir(path)
.output()
@@ -149,7 +149,7 @@ fn get_head_commit(path: &Path) -> Result<String, String> {
/// Run a git command in the specified directory.
fn run_git(path: &Path, args: &[&str]) -> Result<(), String> {
let output = Command::new("git")
let output = git_command()
.args(args)
.current_dir(path)
.output()
@@ -543,7 +543,7 @@ pub async fn check_ref_at_commit(
) -> Result<bool, String> {
let remote_url = format!("http://{}/{}/{}.git", relay_domain, npub, repo_id);
let output = Command::new("git")
let output = git_command()
.args(["ls-remote", &remote_url, ref_name])
.output()
.map_err(|e| format!("Failed to run git ls-remote: {}", e))?;
@@ -591,7 +591,7 @@ pub fn push_to_relay(
let remote_url = format!("http://{}/{}/{}.git", relay_domain, npub, repo_id);
// Check if origin already exists
let check_output = Command::new("git")
let check_output = git_command()
.args(["remote", "get-url", "origin"])
.current_dir(local_path)
.output()
@@ -606,7 +606,7 @@ pub fn push_to_relay(
}
// Push all refs
let output = Command::new("git")
let output = git_command()
.args(["push", "-u", "origin", "--all"])
.current_dir(local_path)
.output()
@@ -650,7 +650,7 @@ pub fn push_ref_to_relay(
let remote_url = format!("http://{}/{}/{}.git", relay_domain, npub, repo_id);
// Check if origin already exists
let check_output = Command::new("git")
let check_output = git_command()
.args(["remote", "get-url", "origin"])
.current_dir(local_path)
.output()
@@ -658,13 +658,13 @@ pub fn push_ref_to_relay(
if check_output.status.success() {
// Remote exists, update it
let _ = Command::new("git")
let _ = git_command()
.args(["remote", "set-url", "origin", &remote_url])
.current_dir(local_path)
.output();
} else {
// Add new remote
let _ = Command::new("git")
let _ = git_command()
.args(["remote", "add", "origin", &remote_url])
.current_dir(local_path)
.output();
@@ -673,7 +673,7 @@ pub fn push_ref_to_relay(
// Push specific commit to specific ref
// Format: git push origin <commit>:<ref>
let refspec = format!("{}:{}", commit_hash, ref_name);
let output = Command::new("git")
let output = git_command()
.args(["push", "origin", &refspec])
.current_dir(local_path)
.output()
@@ -823,7 +823,7 @@ mod tests {
create_branch(temp_dir.path(), "feature", None).expect("Failed to create branch");
// Verify branch exists
let output = Command::new("git")
let output = git_command()
.args(["rev-parse", "feature"])
.current_dir(temp_dir.path())
.output()
+2 -2
View File
@@ -1234,7 +1234,7 @@ pub async fn push_unique_git_data_to_relay(
let path = git_temp_dir.path();
fn git(path: &std::path::Path, args: &[&str]) {
let status = std::process::Command::new("git")
let status = grasp_audit::git_command()
.args(args)
.current_dir(path)
.env("GIT_AUTHOR_NAME", "Test User")
@@ -1269,7 +1269,7 @@ pub async fn push_unique_git_data_to_relay(
git(path, &["commit", "-m", "State test commit"]);
let commit_hash = {
let out = std::process::Command::new("git")
let out = grasp_audit::git_command()
.args(["rev-parse", "HEAD"])
.current_dir(path)
.output()
+2 -2
View File
@@ -12,15 +12,15 @@ use common::{
publish_served_repo, push_ref_to_relay, TestRelay,
};
use grasp_audit::git_command;
use grasp_audit::{clone_repo, AuditClient, AuditConfig, DETERMINISTIC_COMMIT_HASH};
use nostr_sdk::prelude::*;
use std::fs;
use std::path::Path;
use std::process::Command;
use std::time::Duration;
fn repo_has_ref(repo_path: &Path, ref_name: &str) -> bool {
let output = Command::new("git")
let output = git_command()
.args([
"--git-dir",
repo_path.to_str().expect("repo path utf8"),
+4 -4
View File
@@ -9,13 +9,13 @@ use common::{
publish_served_repo_with_maintainers, publish_served_repo_with_state_event, push_to_relay,
CommitVariant, TestRelay,
};
use grasp_audit::git_command;
use grasp_audit::{AuditClient, AuditConfig};
use ngit_grasp::nostr::lifecycle::{
HoldingStore, DEFAULT_RETENTION, HOLDING_ARCHIVE_PATH_TAG, HOLDING_METADATA_KIND,
};
use nostr_sdk::prelude::*;
use std::path::{Path, PathBuf};
use std::process::Command;
use std::time::Duration;
async fn open_holding(relay: &TestRelay) -> HoldingStore {
@@ -230,7 +230,7 @@ async fn wait_for_event_presence(
}
fn run_git_in_repo(repo_path: &Path, args: &[&str]) -> std::process::Output {
Command::new("git")
git_command()
.args(args)
.current_dir(repo_path)
.output()
@@ -238,7 +238,7 @@ fn run_git_in_repo(repo_path: &Path, args: &[&str]) -> std::process::Output {
}
fn run_git_bare(repo_path: &Path, args: &[&str]) -> std::process::Output {
Command::new("git")
git_command()
.args(["--git-dir", repo_path.to_str().expect("repo path utf8")])
.args(args)
.output()
@@ -992,7 +992,7 @@ async fn reannouncement_restores_events_and_git_archive_happy_path() {
.expect("query restored state"));
assert!(repo_path.is_dir(), "git repo must be restored");
let show_ref = Command::new("git")
let show_ref = git_command()
.args(["--git-dir", repo_path.to_str().unwrap(), "show-ref"])
.output()
.expect("run git show-ref on restored repo");
+4 -4
View File
@@ -13,11 +13,11 @@ use common::{
publish_served_repo_with_state_event_and_maintainers, push_to_relay, CommitVariant, TestRelay,
};
use grasp_audit::git_command;
use grasp_audit::{AuditClient, AuditConfig, DETERMINISTIC_COMMIT_HASH};
use ngit_grasp::nostr::lifecycle::HoldingStore;
use nostr_sdk::prelude::*;
use std::collections::HashSet;
use std::process::Command;
use std::time::Duration;
fn build_state_with_branches(
@@ -53,7 +53,7 @@ fn repo_path(relay: &TestRelay, client: &AuditClient, repo_id: &str) -> std::pat
}
fn list_repo_refs(repo_path: &std::path::Path) -> HashSet<String> {
let output = Command::new("git")
let output = git_command()
.args([
"--git-dir",
repo_path.to_str().expect("repo path"),
@@ -80,7 +80,7 @@ fn assert_valid_empty_bare_repo(repo_path: &std::path::Path) {
repo_path.display()
);
let bare = Command::new("git")
let bare = git_command()
.args([
"--git-dir",
repo_path.to_str().expect("repo path"),
@@ -100,7 +100,7 @@ fn assert_valid_empty_bare_repo(repo_path: &std::path::Path) {
"replacement repo must report itself as bare"
);
let refs = Command::new("git")
let refs = git_command()
.args([
"--git-dir",
repo_path.to_str().expect("repo path"),
+5 -5
View File
@@ -29,9 +29,9 @@
//! announcements are in relay_a's DB), wait briefly for the sync round-trip, then
//! send the owner announcement + git push.
use grasp_audit::git_command;
use std::collections::BTreeMap;
use std::path::Path;
use std::process::Command;
use std::time::Duration;
use nostr_sdk::prelude::*;
@@ -146,7 +146,7 @@ async fn push_counts(relay: &TestRelay) -> (u64, u64) {
}
fn list_remote_refs(clone_url: &str) -> Result<BTreeMap<String, String>, String> {
let output = Command::new("git")
let output = git_command()
.args(["ls-remote", "--refs", clone_url])
.output()
.map_err(|error| format!("Failed to list refs from {clone_url}: {error}"))?;
@@ -203,7 +203,7 @@ async fn assert_remote_refs(
}
fn rename_default_branch(repository: &Path, branch: &str) {
let output = Command::new("git")
let output = git_command()
.args(["branch", "-m", branch])
.current_dir(repository)
.output()
@@ -216,7 +216,7 @@ fn rename_default_branch(repository: &Path, branch: &str) {
}
fn remote_default_branch(clone_url: &str) -> Result<String, String> {
let output = Command::new("git")
let output = git_command()
.args(["ls-remote", "--symref", clone_url, "HEAD"])
.output()
.map_err(|error| format!("Failed to inspect HEAD from {clone_url}: {error}"))?;
@@ -1080,7 +1080,7 @@ async fn test_purgatory_owner_uses_rejected_maintainer_clone_to_sync_git() {
&[&source_relay.domain()],
)
.await;
let commit_output = Command::new("git")
let commit_output = git_command()
.args(["rev-parse", "HEAD"])
.current_dir(maintainer_git.path())
.output()
+5 -5
View File
@@ -19,7 +19,7 @@ async fn test_filter_capability_advertised() {
let server = SmartGitServer::start(temp_dir.path()).await;
// Run git ls-remote to see advertised capabilities
let output = Command::new("git")
let output = Command::from(grasp_audit::git_command())
.env("GIT_TRACE_PACKET", "1")
.args(["ls-remote", server.url()])
.output()
@@ -63,7 +63,7 @@ async fn test_filtered_clone_succeeds() {
let clone_path = clone_dir.path().join("cloned-repo");
// Attempt a filtered clone
let output = Command::new("git")
let output = Command::from(grasp_audit::git_command())
.args([
"clone",
"--filter=blob:none",
@@ -90,7 +90,7 @@ async fn test_filtered_clone_succeeds() {
);
// In a filtered clone, we should be able to list files
let ls_output = Command::new("git")
let ls_output = Command::from(grasp_audit::git_command())
.current_dir(&clone_path)
.args(["ls-files"])
.output()
@@ -126,7 +126,7 @@ async fn test_filtered_fetch_succeeds() {
let clone_dir = TempDir::new().expect("Failed to create clone dir");
let clone_path = clone_dir.path().join("repo");
let clone_output = Command::new("git")
let clone_output = Command::from(grasp_audit::git_command())
.args(["clone", server.url(), clone_path.to_str().unwrap()])
.output()
.await
@@ -139,7 +139,7 @@ async fn test_filtered_fetch_succeeds() {
);
// Now try a filtered fetch
let fetch_output = Command::new("git")
let fetch_output = Command::from(grasp_audit::git_command())
.current_dir(&clone_path)
.args(["fetch", "--filter=blob:none", "origin"])
.output()