| |
|
| |
/// Helper functions for writing adapters.
|
| |
pub mod helper {
|
| + |
use std::{path::Path, process::Command};
|
| + |
|
| + |
use radicle::prelude::{Profile, RepoId};
|
| + |
use radicle_git_ext::Oid;
|
| + |
|
| |
use super::{MessageError, Request, Response, RunId, RunResult};
|
| |
|
| + |
/// Exit code to indicate we didn't get one from the process.
|
| + |
pub const NO_EXIT: i32 = 999;
|
| + |
|
| |
/// Read a request from stdin.
|
| |
pub fn read_request() -> Result<Request, MessageHelperError> {
|
| |
let req =
|
| |
Ok(())
|
| |
}
|
| |
|
| + |
/// Get sources from the local node.
|
| + |
pub fn get_sources(repoid: RepoId, commit: Oid, src: &Path) -> Result<(), MessageHelperError> {
|
| + |
let profile = Profile::load().map_err(MessageHelperError::Profile)?;
|
| + |
let storage = profile.storage.path();
|
| + |
let repo_path = storage.join(repoid.canonical());
|
| + |
|
| + |
git_clone(&repo_path, src)?;
|
| + |
git_checkout(commit, src)?;
|
| + |
|
| + |
Ok(())
|
| + |
}
|
| + |
|
| + |
/// Run `git clone` for the repository.
|
| + |
fn git_clone(repo_path: &Path, src: &Path) -> Result<(), MessageHelperError> {
|
| + |
runcmd(
|
| + |
&[
|
| + |
"git",
|
| + |
"clone",
|
| + |
&repo_path.to_string_lossy(),
|
| + |
&src.to_string_lossy(),
|
| + |
],
|
| + |
Path::new("."),
|
| + |
)?;
|
| + |
Ok(())
|
| + |
}
|
| + |
|
| + |
// Check out the requested commit.
|
| + |
fn git_checkout(commit: Oid, src: &Path) -> Result<(), MessageHelperError> {
|
| + |
runcmd(&["git", "config", "advice.detachedHead", "false"], src)?;
|
| + |
runcmd(&["git", "checkout", &commit.to_string()], src)?;
|
| + |
Ok(())
|
| + |
}
|
| + |
|
| + |
/// Run a program.
|
| + |
pub fn runcmd(argv: &[&str], cwd: &Path) -> Result<i32, MessageHelperError> {
|
| + |
assert!(!argv.is_empty());
|
| + |
|
| + |
let output = Command::new("bash")
|
| + |
.arg("-c")
|
| + |
.arg(r#""$@" 2>&1"#)
|
| + |
.arg("--")
|
| + |
.args(argv)
|
| + |
.current_dir(cwd)
|
| + |
.output()
|
| + |
.map_err(|err| MessageHelperError::Command("bash", err))?;
|
| + |
|
| + |
let exit = output.status.code().unwrap_or(NO_EXIT);
|
| + |
Ok(exit)
|
| + |
}
|
| + |
|
| |
/// Possible errors from this module.
|
| |
#[derive(Debug, thiserror::Error)]
|
| |
pub enum MessageHelperError {
|
| |
/// Error writing response to stdout.
|
| |
#[error("failed to write response to stdout: {0:?}")]
|
| |
WriteResponse(Response, #[source] Box<MessageError>),
|
| + |
|
| + |
/// Can't load Radicle profile.
|
| + |
#[error("failed to load Radicle profile")]
|
| + |
Profile(#[source] radicle::profile::Error),
|
| + |
|
| + |
/// Can't run command and capture its output.
|
| + |
#[error("failed to run command {0}")]
|
| + |
Command(&'static str, #[source] std::io::Error),
|
| |
}
|
| |
}
|