radicle: Move interpretation of output to binary
`radicle::run` interprets the `Output` returned by the `git` process. However, depending on the application we have different requirements for interpreting the output, e.g., how to handle errors. Make `radicle:
:run` not interpret `Output`, but move this logic to the respective binary crates (`radicle-remote-helper` and `radicle-cli`).
This commit is contained in:
parent
0a8317c35f
commit
a0f6cbf5f1
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -888,13 +898,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(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -761,29 +761,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`.
|
||||
|
|
@ -804,7 +793,7 @@ pub mod process {
|
|||
storage: &R,
|
||||
oids: impl IntoIterator<Item = Oid>,
|
||||
verbosity: Verbosity,
|
||||
) -> Result<(), io::Error>
|
||||
) -> io::Result<std::process::Output>
|
||||
where
|
||||
R: ReadRepository,
|
||||
{
|
||||
|
|
@ -817,8 +806,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, [])
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
