Wrap Git errors display in a helper
This commit is contained in:
parent
db6ba6c6aa
commit
c1317da7af
68
src/main.rs
68
src/main.rs
|
@ -134,12 +134,12 @@ fn mirror_repo(
|
||||||
repo_path.push(name);
|
repo_path.push(name);
|
||||||
// Ensure the repository is cloned and up to date.
|
// Ensure the repository is cloned and up to date.
|
||||||
if !repo_path.exists() {
|
if !repo_path.exists() {
|
||||||
if !clone(src_url, path, name) {
|
if let Some(e) = check_git_return(&clone(src_url, path, name), MirrorResult::CloneFailed) {
|
||||||
return Ok(MirrorResult::CloneFailed)
|
return Ok(e)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if !fetch(&repo_path) {
|
if let Some(e) = check_git_return(&fetch(&repo_path), MirrorResult::FetchFailed) {
|
||||||
return Ok(MirrorResult::FetchFailed)
|
return Ok(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Ensure the mirror remote is available.
|
// Ensure the mirror remote is available.
|
||||||
|
@ -148,28 +148,48 @@ fn mirror_repo(
|
||||||
None => return Ok(MirrorResult::RemotesError)
|
None => return Ok(MirrorResult::RemotesError)
|
||||||
};
|
};
|
||||||
if !remotes.contains(&MIRROR_REMOTE_NAME.to_string()) {
|
if !remotes.contains(&MIRROR_REMOTE_NAME.to_string()) {
|
||||||
if !add_mirror_remote(&repo_path, dest_url) {
|
if let Some(e) = check_git_return(
|
||||||
return Ok(MirrorResult::RemotesError)
|
&add_mirror_remote(&repo_path, dest_url),
|
||||||
|
MirrorResult::RemotesError
|
||||||
|
) {
|
||||||
|
return Ok(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Push to the mirror repo.
|
// Push to the mirror repo.
|
||||||
if !push(&repo_path) {
|
if let Some(e) = check_git_return(&push(&repo_path), MirrorResult::PushFailed) {
|
||||||
return Ok(MirrorResult::PushFailed)
|
return Ok(e)
|
||||||
}
|
}
|
||||||
Ok(MirrorResult::Success)
|
Ok(MirrorResult::Success)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Common type for wrappers around Git commands: success and optional stdout.
|
||||||
|
type GitCmdReturn = (bool, Option<String>);
|
||||||
|
|
||||||
|
/// Check a GitCmdReturn.
|
||||||
|
///
|
||||||
|
/// Print errors if the command failed and return `Some(on_error)`, or return None if the command
|
||||||
|
/// completed successfully.
|
||||||
|
fn check_git_return(cmd_return: &GitCmdReturn, on_error: MirrorResult) -> Option<MirrorResult> {
|
||||||
|
match cmd_return {
|
||||||
|
(false, output_opt) => {
|
||||||
|
if let Some(output) = output_opt {
|
||||||
|
eprintln!("Git output:\n{}", output);
|
||||||
|
}
|
||||||
|
Some(on_error)
|
||||||
|
}
|
||||||
|
_ => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Run a git mirror clone command.
|
/// Run a git mirror clone command.
|
||||||
fn clone(url: &str, path: &path::Path, name: &str) -> bool {
|
fn clone(url: &str, path: &path::Path, name: &str) -> GitCmdReturn {
|
||||||
let args = vec!("clone", "--mirror", url, name);
|
let args = vec!("clone", "--mirror", url, name);
|
||||||
let (success, _) = run_git_command_in(args, path);
|
run_git_command_in(args, path)
|
||||||
success
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Update a local repository.
|
/// Update a local repository.
|
||||||
fn fetch(path: &path::Path) -> bool {
|
fn fetch(path: &path::Path) -> GitCmdReturn {
|
||||||
let (success, _) = run_git_command_in(vec!("fetch"), path);
|
run_git_command_in(vec!("fetch"), path)
|
||||||
success
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return a vector of remote names on success.
|
/// Return a vector of remote names on success.
|
||||||
|
@ -182,35 +202,35 @@ fn get_remotes(path: &path::Path) -> Option<Vec<String>> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the mirror remote `url` in the repository at `path`.
|
/// Set the mirror remote `url` in the repository at `path`.
|
||||||
fn add_mirror_remote(path: &path::Path, url: &str) -> bool {
|
fn add_mirror_remote(path: &path::Path, url: &str) -> GitCmdReturn {
|
||||||
let args = vec!("remote", "add", MIRROR_REMOTE_NAME, url);
|
let args = vec!("remote", "add", MIRROR_REMOTE_NAME, url);
|
||||||
let (success, _) = run_git_command_in(args, path);
|
run_git_command_in(args, path)
|
||||||
success
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Run a git mirror push command.
|
/// Run a git mirror push command.
|
||||||
fn push(path: &path::Path) -> bool {
|
fn push(path: &path::Path) -> GitCmdReturn {
|
||||||
let args = vec!("push", "--mirror", MIRROR_REMOTE_NAME);
|
let args = vec!("push", "--mirror", MIRROR_REMOTE_NAME);
|
||||||
let (success, _) = run_git_command_in(args, path);
|
run_git_command_in(args, path)
|
||||||
success
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Run a git command with supplied arguments, return true on successful completion.
|
/// Run a git command with supplied arguments, return true on successful completion.
|
||||||
fn run_git_command(args: Vec<&str>) -> (bool, Option<String>) {
|
fn run_git_command(args: Vec<&str>) -> GitCmdReturn {
|
||||||
let mut command = process::Command::new("git");
|
let mut command = process::Command::new("git");
|
||||||
command.args(&args);
|
command.args(&args);
|
||||||
match command.output() {
|
match command.output() {
|
||||||
Ok(output) => {
|
Ok(output) => {
|
||||||
let success = output.status.success();
|
let success = output.status.success();
|
||||||
let stdout = String::from_utf8(output.stdout).ok();
|
let text = String::from_utf8(
|
||||||
(success, stdout)
|
if success { output.stdout } else { output.stderr }
|
||||||
|
).ok();
|
||||||
|
(success, text)
|
||||||
}
|
}
|
||||||
Err(e) => { eprintln!("Failed to run Git: {}", e); (false, None) }
|
Err(e) => { eprintln!("Failed to run Git: {}", e); (false, None) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Call `run_git_command` but with a work directory specified.
|
/// Call `run_git_command` but with a work directory specified.
|
||||||
fn run_git_command_in(args: Vec<&str>, path: &path::Path) -> (bool, Option<String>) {
|
fn run_git_command_in(args: Vec<&str>, path: &path::Path) -> GitCmdReturn {
|
||||||
let path = match path.to_str() {
|
let path = match path.to_str() {
|
||||||
Some(path) => path,
|
Some(path) => path,
|
||||||
None => { eprintln!("Invalid path: {:?}", path); return (false, None) }
|
None => { eprintln!("Invalid path: {:?}", path); return (false, None) }
|
||||||
|
|
Reference in a new issue