164 lines
4.6 KiB
Rust
164 lines
4.6 KiB
Rust
use std::path::{Path, PathBuf};
|
|
use std::process::Command;
|
|
|
|
#[derive(Debug)]
|
|
pub enum Backend {
|
|
Git,
|
|
Mercurial,
|
|
Unknown(String),
|
|
}
|
|
|
|
impl Backend {
|
|
pub fn from_setting(setting: Option<String>) -> Backend {
|
|
// Git is the default setting until further notice
|
|
setting.map_or(Backend::Git, |name| match name.as_ref() {
|
|
"git" => Backend::Git,
|
|
"mercurial" => Backend::Mercurial,
|
|
_ => Backend::Unknown(name.to_string()),
|
|
})
|
|
}
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct Repo {
|
|
pub backend: Backend,
|
|
pub source: String,
|
|
pub dest: PathBuf,
|
|
pub subupdates: bool,
|
|
}
|
|
|
|
impl Repo {
|
|
pub fn new(backend: Backend, source: &str, dest: &Path, subupdates: bool) -> Repo {
|
|
Repo {
|
|
backend,
|
|
source: source.to_string(),
|
|
dest: dest.to_path_buf(),
|
|
subupdates,
|
|
}
|
|
}
|
|
|
|
pub fn branch(&self) -> String {
|
|
match &self.backend {
|
|
Backend::Git => {
|
|
let output = Command::new("git")
|
|
.arg("rev-parse")
|
|
.arg("--abbrev-ref")
|
|
.arg("HEAD")
|
|
.output()
|
|
.expect("WTF");
|
|
if !output.status.success() {
|
|
panic!("Corrupted git repository???");
|
|
}
|
|
String::from_utf8(output.stdout).unwrap().trim().to_string()
|
|
}
|
|
Backend::Mercurial => {
|
|
unreachable!("UNIMPLEMENTED!");
|
|
}
|
|
Backend::Unknown(name) => {
|
|
panic!("Uknown backend: {}. Cannot find ranch", name);
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn clone(&self) -> bool {
|
|
match &self.backend {
|
|
Backend::Git => {
|
|
let output = Command::new("git")
|
|
.arg("clone")
|
|
.arg("--recursive")
|
|
.arg(&self.source)
|
|
.arg(&self.dest)
|
|
.output() // To suppress (capture) output
|
|
.expect("PROCESS ERROR!");
|
|
output.status.success()
|
|
}
|
|
Backend::Mercurial => {
|
|
unreachable!("Unimplemented");
|
|
}
|
|
Backend::Unknown(name) => {
|
|
eprintln!("Unknown DVCS: {}", name);
|
|
false
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn checkout(&self, target: &str) -> bool {
|
|
println!("CHECKOUT TO {}", target);
|
|
match &self.backend {
|
|
Backend::Git => {
|
|
let status = Command::new("git")
|
|
.arg("checkout")
|
|
.arg(target)
|
|
.status()
|
|
.expect("PROCESS ERROR!");
|
|
status.success()
|
|
}
|
|
Backend::Mercurial => {
|
|
unreachable!("UNIMPLEMENTED");
|
|
}
|
|
Backend::Unknown(name) => {
|
|
eprintln!("Unknown DVCS: {}", name);
|
|
false
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn has_updates(&self) -> bool {
|
|
match &self.backend {
|
|
Backend::Git => {
|
|
// Refresh remote
|
|
if !Command::new("git")
|
|
.arg("fetch")
|
|
.arg("--quiet")
|
|
.arg("origin")
|
|
.status()
|
|
.expect("WTF")
|
|
.success()
|
|
{
|
|
// FAILED, no internet??
|
|
eprintln!("Fetching updates failed");
|
|
return false;
|
|
}
|
|
let branch = self.branch();
|
|
if Command::new("git")
|
|
.arg("diff")
|
|
.arg("--quiet")
|
|
.arg(format!("remotes/origin/{}", &branch))
|
|
.status()
|
|
.expect("WTF")
|
|
.success()
|
|
{
|
|
// Command succeeeded, no updates
|
|
return false;
|
|
}
|
|
// Updates
|
|
return true;
|
|
}
|
|
Backend::Mercurial => {
|
|
unreachable!("unimplemented");
|
|
}
|
|
Backend::Unknown(name) => {
|
|
eprintln!("Unknown DVCS:{}!", name);
|
|
false
|
|
}
|
|
}
|
|
}
|
|
/*
|
|
/// Runs an update on the repository in dest. Returns true
|
|
/// when an update was performed, false otherwise
|
|
pub fn update(&self, dest: &str) -> bool {
|
|
match self {
|
|
Backend::Git => {
|
|
|
|
},
|
|
Backend::Mercurial => {
|
|
|
|
},
|
|
Backend::Unknown(name) => {
|
|
eprintln!("Unknown DVCS: {}", name);
|
|
false
|
|
}
|
|
}
|
|
}*/
|
|
}
|