Radish alpha
h
Radicle Heartwood Protocol & Stack
Radicle
Git (anonymous pull)
Log in to clone via SSH
radicle: Move interpretation of output to binary
Lorenz Leutgeb committed 7 months ago
commit 9c8905f829d62a2d269e5f0fdb309273bc9ecc62
parent f00a56c52e7c95a072430f523baacff7633faa18
3 files changed +38 -26
modified crates/radicle-cli/src/git.rs
@@ -132,11 +132,23 @@ pub fn repository() -> Result<Repository, anyhow::Error> {
}

/// Execute a git command by spawning a child process.
+
/// Returns [`Result::Ok`] if the command *exited successfully*.
pub fn git<S: AsRef<std::ffi::OsStr>>(
    repo: &std::path::Path,
    args: impl IntoIterator<Item = S>,
-
) -> Result<String, io::Error> {
-
    radicle::git::run::<_, _, &str, &str>(repo, args, [])
+
) -> anyhow::Result<std::process::Output> {
+
    let output = radicle::git::run::<_, _, &str, &str>(repo, args, [])?;
+

+
    if !output.status.success() {
+
        anyhow::bail!(
+
            "`git` exited with status {}, stderr and stdout follow:\n{}\n{}\n",
+
            output.status,
+
            String::from_utf8_lossy(&output.stderr),
+
            String::from_utf8_lossy(&output.stdout),
+
        )
+
    }
+

+
    Ok(output)
}

/// Configure SSH signing in the given git repo, for the given peer.
modified crates/radicle-remote-helper/src/push.rs
@@ -6,6 +6,7 @@ mod error;
use std::collections::HashMap;
use std::io::IsTerminal;
use std::path::{Path, PathBuf};
+
use std::process::ExitStatus;
use std::str::FromStr;
use std::{assert_eq, io};

@@ -124,6 +125,15 @@ pub enum Error {
    UnknownObjectType { oid: git::Oid },
    #[error(transparent)]
    FindObjects(#[from] git::canonical::error::FindObjectsError),
+

+
    /// Errors for "internal" pushes, i.e., pushes that this process
+
    /// initiates between the working copy and storage.
+
    #[error("internal push failed with exit status {status}, stderr and stdout follow:\n{stderr}\n{stdout}")]
+
    InternalPushFailed {
+
        status: ExitStatus,
+
        stderr: String,
+
        stdout: String,
+
    },
}

/// Push command.
@@ -879,13 +889,15 @@ fn push_ref(

    args.extend([url.to_string(), refspec.to_string()]);

-
    radicle::git::run::<_, _, &str, &str>(repo, args, [])
-
    .map_err(|err| {
-
        Error::Io(std::io::Error::other(format!(
-
            "failed to run `git push {url} {refspec}` in {:?}: {err}",
-
            working.path()
-
        )))
-
    })?;
+
    let output = radicle::git::run::<_, _, &str, &str>(repo, args, [])?;
+

+
    if !output.status.success() {
+
        return Err(Error::InternalPushFailed {
+
            stderr: String::from_utf8_lossy(&output.stderr).to_string(),
+
            stdout: String::from_utf8_lossy(&output.stdout).to_string(),
+
            status: output.status,
+
        });
+
    }

    Ok(())
}
modified crates/radicle/src/git.rs
@@ -754,29 +754,18 @@ pub fn run<P, S, K, V>(
    repo: P,
    args: impl IntoIterator<Item = S>,
    envs: impl IntoIterator<Item = (K, V)>,
-
) -> Result<String, io::Error>
+
) -> io::Result<std::process::Output>
where
    P: AsRef<Path>,
    S: AsRef<std::ffi::OsStr>,
    K: AsRef<std::ffi::OsStr>,
    V: AsRef<std::ffi::OsStr>,
{
-
    let output = Command::new("git")
+
    Command::new("git")
        .current_dir(repo)
        .envs(envs)
        .args(args)
-
        .output()?;
-

-
    if output.status.success() {
-
        let out = if output.stdout.is_empty() {
-
            &output.stderr
-
        } else {
-
            &output.stdout
-
        };
-
        return Ok(String::from_utf8_lossy(out).into());
-
    }
-

-
    Err(io::Error::other(String::from_utf8_lossy(&output.stderr)))
+
        .output()
}

/// Functions that call to the `git` CLI instead of `git2`.
@@ -797,7 +786,7 @@ pub mod process {
        storage: &R,
        oids: impl IntoIterator<Item = Oid>,
        verbosity: Verbosity,
-
    ) -> Result<(), io::Error>
+
    ) -> io::Result<std::process::Output>
    where
        R: ReadRepository,
    {
@@ -810,8 +799,7 @@ pub mod process {
        fetch.push(url::File::new(storage.path()).to_string());
        fetch.extend(oids.into_iter().map(|oid| oid.to_string()));
        // N.b. `.` is used since we're fetching within the working copy
-
        run::<_, _, &str, &str>(working, fetch, [])?;
-
        Ok(())
+
        run::<_, _, &str, &str>(working, fetch, [])
    }
}