More rust I guess...
This commit is contained in:
parent
1fb5e7d6b9
commit
64efc98ee2
|
@ -1,9 +1,11 @@
|
|||
use std::path::{Path,PathBuf};
|
||||
use md5;
|
||||
use std::fs;
|
||||
use std::io::Error;
|
||||
use std::io::{Error,ErrorKind};
|
||||
use ofborg::clone;
|
||||
use ofborg::clone::GitClonable;
|
||||
use std::ffi::OsStr;
|
||||
use std::process::Command;
|
||||
|
||||
pub struct CachedCloner {
|
||||
root: PathBuf
|
||||
|
@ -20,6 +22,13 @@ pub struct CachedProject {
|
|||
clone_url: String
|
||||
}
|
||||
|
||||
pub struct CachedProjectCo {
|
||||
root: PathBuf,
|
||||
id: String,
|
||||
clone_url: String,
|
||||
local_reference: PathBuf,
|
||||
}
|
||||
|
||||
impl CachedCloner {
|
||||
pub fn project(&self, name: String, clone_url: String) -> CachedProject {
|
||||
// <root>/repo/<hash>/clone
|
||||
|
@ -39,28 +48,111 @@ impl CachedCloner {
|
|||
}
|
||||
|
||||
impl CachedProject {
|
||||
pub fn checkout_ref(&self,
|
||||
name: String,
|
||||
git_ref: String,
|
||||
) -> Result<String, Error> {
|
||||
let repo_cache_path = self.prefetch_cache()?;
|
||||
pub fn clone_for(&self, use_category: String, id: String) -> Result<CachedProjectCo, Error> {
|
||||
self.prefetch_cache()?;
|
||||
|
||||
// let build_dir = self.build_dir();
|
||||
let mut new_root = self.root.clone();
|
||||
new_root.push(use_category);
|
||||
|
||||
return Ok(repo_cache_path.to_str().unwrap().to_string())
|
||||
return Ok(CachedProjectCo{
|
||||
root: new_root,
|
||||
id: id,
|
||||
clone_url: self.clone_from().clone(),
|
||||
local_reference: self.clone_to().clone(),
|
||||
})
|
||||
}
|
||||
|
||||
fn prefetch_cache(&self) -> Result<PathBuf, Error> {
|
||||
fs::create_dir_all(&self.root)?;
|
||||
|
||||
self.clone_repo()?;
|
||||
self.fetch_repo()?;
|
||||
|
||||
return Ok(self.clone_to());
|
||||
}
|
||||
}
|
||||
|
||||
impl clone::GitClonable for CachedProject {
|
||||
impl CachedProjectCo {
|
||||
pub fn checkout_ref(&self, git_ref: &OsStr) -> Result<String, Error> {
|
||||
self.clone_repo()?;
|
||||
self.fetch_repo()?;
|
||||
self.clean()?;
|
||||
self.checkout(git_ref)?;
|
||||
|
||||
// let build_dir = self.build_dir();
|
||||
|
||||
return Ok(self.clone_to().to_str().unwrap().to_string())
|
||||
}
|
||||
|
||||
pub fn fetch_pr(&self, pr_id: i64) -> Result<(),Error> {
|
||||
let mut lock = self.lock()?;
|
||||
|
||||
let result = Command::new("git")
|
||||
.arg("fetch")
|
||||
.arg("origin")
|
||||
.arg(format!("+refs/pull/{}/head:pr", pr_id))
|
||||
.current_dir(self.clone_to())
|
||||
.status()?;
|
||||
|
||||
lock.unlock();
|
||||
|
||||
if result.success() {
|
||||
return Ok(())
|
||||
} else {
|
||||
return Err(Error::new(ErrorKind::Other, "Failed to fetch PR"));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn merge_commit(&self, commit: &OsStr) -> Result<(), Error> {
|
||||
let mut lock = self.lock()?;
|
||||
|
||||
let result = Command::new("git")
|
||||
.arg("merge")
|
||||
.arg("--no-gpg-sign")
|
||||
.arg("-m")
|
||||
.arg("Automatic merge for GrahamCOfBorg")
|
||||
.arg(commit)
|
||||
.current_dir(self.clone_to())
|
||||
.status()?;
|
||||
|
||||
lock.unlock();
|
||||
|
||||
if result.success() {
|
||||
return Ok(())
|
||||
} else {
|
||||
return Err(Error::new(ErrorKind::Other, "Failed to merge"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl clone::GitClonable for CachedProjectCo {
|
||||
fn clone_from(&self) -> String {
|
||||
return self.clone_url.clone()
|
||||
}
|
||||
|
||||
fn clone_to(&self) -> PathBuf {
|
||||
let mut clone_path = self.root.clone();
|
||||
clone_path.push(&self.id);
|
||||
return clone_path
|
||||
}
|
||||
|
||||
fn lock_path(&self) -> PathBuf {
|
||||
let mut lock_path = self.root.clone();
|
||||
lock_path.push(format!("{}.lock", self.id));
|
||||
return lock_path
|
||||
}
|
||||
|
||||
fn extra_clone_args(&self) -> Vec<&OsStr> {
|
||||
let local_ref = self.local_reference.as_ref();
|
||||
return vec![
|
||||
OsStr::new("--shared"),
|
||||
OsStr::new("--reference-if-able"),
|
||||
local_ref,
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
impl clone::GitClonable for CachedProject {
|
||||
fn clone_from(&self) -> String {
|
||||
return self.clone_url.clone()
|
||||
}
|
||||
|
@ -73,55 +165,13 @@ impl clone::GitClonable for CachedProject {
|
|||
|
||||
fn lock_path(&self) -> PathBuf {
|
||||
let mut clone_path = self.root.clone();
|
||||
clone_path.set_file_name("clone.lock");
|
||||
clone_path.push("clone.lock");
|
||||
return clone_path
|
||||
}
|
||||
|
||||
fn extra_clone_args(&self) -> Vec<String> {
|
||||
return vec!()
|
||||
fn extra_clone_args(&self) -> Vec<&OsStr> {
|
||||
return vec![
|
||||
OsStr::new("--bare"),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
fn try_clone_repo(&self) -> Result<(), Error> {
|
||||
|
||||
|
||||
let result = Command::new("git")
|
||||
.arg("clone")
|
||||
.arg("--bare")
|
||||
.arg(&self.clone_url)
|
||||
.arg(&self.clone_path())
|
||||
.status()?;
|
||||
|
||||
if result.success() {
|
||||
return Ok(())
|
||||
} else {
|
||||
return Err(Error::new(ErrorKind::Other, "Failed to clone"));
|
||||
}
|
||||
}
|
||||
|
||||
fn try_fetch(&self) -> Result<(), Error> {
|
||||
let result = Command::new("git")
|
||||
.arg("fetch")
|
||||
.arg("origin")
|
||||
.current_dir(self.clone_path())
|
||||
.status()?;
|
||||
|
||||
if result.success() {
|
||||
return Ok(())
|
||||
} else {
|
||||
return Err(Error::new(ErrorKind::Other, "Failed to fetch"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
impl locks::Lockable for CachedProject {
|
||||
fn lock_path(&self) -> PathBuf {
|
||||
let mut clone_path = self.root.clone();
|
||||
clone_path.set_file_name("clone.lock");
|
||||
return clone_path
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
|
|
@ -3,7 +3,7 @@ use fs2::FileExt;
|
|||
use std::fs;
|
||||
use std::io::{Error,ErrorKind};
|
||||
use std::process::Command;
|
||||
|
||||
use std::ffi::OsStr;
|
||||
|
||||
pub struct Lock {
|
||||
lock: Option<fs::File>
|
||||
|
@ -15,15 +15,15 @@ impl Lock {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
pub trait GitClonable {
|
||||
fn clone_from(&self) -> String;
|
||||
fn clone_to(&self) -> PathBuf;
|
||||
fn extra_clone_args(&self) -> Vec<String>;
|
||||
fn extra_clone_args(&self) -> Vec<&OsStr>;
|
||||
|
||||
fn lock_path(&self) -> PathBuf;
|
||||
|
||||
fn lock(&self) -> Result<Lock, Error> {
|
||||
println!("Locking {:?}", self.lock_path());
|
||||
let lock = fs::File::create(self.lock_path())?;
|
||||
lock.lock_exclusive()?;
|
||||
return Ok(Lock{
|
||||
|
@ -60,7 +60,6 @@ pub trait GitClonable {
|
|||
let result = Command::new("git")
|
||||
.arg("fetch")
|
||||
.arg("origin")
|
||||
.args(self.extra_clone_args())
|
||||
.current_dir(self.clone_to())
|
||||
.status()?;
|
||||
|
||||
|
@ -72,4 +71,48 @@ pub trait GitClonable {
|
|||
return Err(Error::new(ErrorKind::Other, "Failed to fetch"));
|
||||
}
|
||||
}
|
||||
|
||||
fn clean(&self) -> Result<(), Error> {
|
||||
let mut lock = self.lock()?;
|
||||
|
||||
Command::new("git")
|
||||
.arg("am")
|
||||
.arg("--abort")
|
||||
.current_dir(self.clone_to())
|
||||
.status()?;
|
||||
|
||||
Command::new("git")
|
||||
.arg("merge")
|
||||
.arg("--abort")
|
||||
.current_dir(self.clone_to())
|
||||
.status()?;
|
||||
|
||||
Command::new("git")
|
||||
.arg("reset")
|
||||
.arg("--hard")
|
||||
.current_dir(self.clone_to())
|
||||
.status()?;
|
||||
|
||||
lock.unlock();
|
||||
|
||||
return Ok(())
|
||||
}
|
||||
|
||||
fn checkout(&self, git_ref: &OsStr) -> Result<(), Error> {
|
||||
let mut lock = self.lock()?;
|
||||
|
||||
let result = Command::new("git")
|
||||
.arg("checkout")
|
||||
.arg(git_ref)
|
||||
.current_dir(self.clone_to())
|
||||
.status()?;
|
||||
|
||||
lock.unlock();
|
||||
|
||||
if result.success() {
|
||||
return Ok(())
|
||||
} else {
|
||||
return Err(Error::new(ErrorKind::Other, "Failed to checkout"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,10 +18,12 @@ fn main() {
|
|||
let project = cloner.project("NixOS/nixpkgs".to_string(),
|
||||
"https://github.com/nixos/nixpkgs.git".to_string()
|
||||
);
|
||||
let co = project.clone_for("builder".to_string(),
|
||||
"1234".to_string()).unwrap();
|
||||
|
||||
let refpath = project.checkout_ref("builder-1234".to_string(),
|
||||
"origin/master".to_string()
|
||||
);
|
||||
let refpath = co.checkout_ref("origin/master".as_ref());
|
||||
co.fetch_pr(31228).unwrap();
|
||||
co.merge_commit("7214d0f6f7a6467205761f87973140727154e1b3".as_ref()).unwrap();
|
||||
|
||||
match refpath {
|
||||
Ok(path) => {
|
||||
|
|
Loading…
Reference in a new issue