More rust I guess...
This commit is contained in:
parent
1fb5e7d6b9
commit
64efc98ee2
|
@ -1,9 +1,11 @@
|
||||||
use std::path::{Path,PathBuf};
|
use std::path::{Path,PathBuf};
|
||||||
use md5;
|
use md5;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::io::Error;
|
use std::io::{Error,ErrorKind};
|
||||||
use ofborg::clone;
|
use ofborg::clone;
|
||||||
use ofborg::clone::GitClonable;
|
use ofborg::clone::GitClonable;
|
||||||
|
use std::ffi::OsStr;
|
||||||
|
use std::process::Command;
|
||||||
|
|
||||||
pub struct CachedCloner {
|
pub struct CachedCloner {
|
||||||
root: PathBuf
|
root: PathBuf
|
||||||
|
@ -20,6 +22,13 @@ pub struct CachedProject {
|
||||||
clone_url: String
|
clone_url: String
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct CachedProjectCo {
|
||||||
|
root: PathBuf,
|
||||||
|
id: String,
|
||||||
|
clone_url: String,
|
||||||
|
local_reference: PathBuf,
|
||||||
|
}
|
||||||
|
|
||||||
impl CachedCloner {
|
impl CachedCloner {
|
||||||
pub fn project(&self, name: String, clone_url: String) -> CachedProject {
|
pub fn project(&self, name: String, clone_url: String) -> CachedProject {
|
||||||
// <root>/repo/<hash>/clone
|
// <root>/repo/<hash>/clone
|
||||||
|
@ -39,28 +48,111 @@ impl CachedCloner {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CachedProject {
|
impl CachedProject {
|
||||||
pub fn checkout_ref(&self,
|
pub fn clone_for(&self, use_category: String, id: String) -> Result<CachedProjectCo, Error> {
|
||||||
name: String,
|
self.prefetch_cache()?;
|
||||||
git_ref: String,
|
|
||||||
) -> Result<String, Error> {
|
|
||||||
let repo_cache_path = 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> {
|
fn prefetch_cache(&self) -> Result<PathBuf, Error> {
|
||||||
fs::create_dir_all(&self.root)?;
|
fs::create_dir_all(&self.root)?;
|
||||||
|
|
||||||
self.clone_repo()?;
|
self.clone_repo()?;
|
||||||
|
self.fetch_repo()?;
|
||||||
|
|
||||||
return Ok(self.clone_to());
|
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 {
|
fn clone_from(&self) -> String {
|
||||||
return self.clone_url.clone()
|
return self.clone_url.clone()
|
||||||
}
|
}
|
||||||
|
@ -73,55 +165,13 @@ impl clone::GitClonable for CachedProject {
|
||||||
|
|
||||||
fn lock_path(&self) -> PathBuf {
|
fn lock_path(&self) -> PathBuf {
|
||||||
let mut clone_path = self.root.clone();
|
let mut clone_path = self.root.clone();
|
||||||
clone_path.set_file_name("clone.lock");
|
clone_path.push("clone.lock");
|
||||||
return clone_path
|
return clone_path
|
||||||
}
|
}
|
||||||
|
|
||||||
fn extra_clone_args(&self) -> Vec<String> {
|
fn extra_clone_args(&self) -> Vec<&OsStr> {
|
||||||
return vec!()
|
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::fs;
|
||||||
use std::io::{Error,ErrorKind};
|
use std::io::{Error,ErrorKind};
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
|
use std::ffi::OsStr;
|
||||||
|
|
||||||
pub struct Lock {
|
pub struct Lock {
|
||||||
lock: Option<fs::File>
|
lock: Option<fs::File>
|
||||||
|
@ -15,15 +15,15 @@ impl Lock {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub trait GitClonable {
|
pub trait GitClonable {
|
||||||
fn clone_from(&self) -> String;
|
fn clone_from(&self) -> String;
|
||||||
fn clone_to(&self) -> PathBuf;
|
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_path(&self) -> PathBuf;
|
||||||
|
|
||||||
fn lock(&self) -> Result<Lock, Error> {
|
fn lock(&self) -> Result<Lock, Error> {
|
||||||
|
println!("Locking {:?}", self.lock_path());
|
||||||
let lock = fs::File::create(self.lock_path())?;
|
let lock = fs::File::create(self.lock_path())?;
|
||||||
lock.lock_exclusive()?;
|
lock.lock_exclusive()?;
|
||||||
return Ok(Lock{
|
return Ok(Lock{
|
||||||
|
@ -60,7 +60,6 @@ pub trait GitClonable {
|
||||||
let result = Command::new("git")
|
let result = Command::new("git")
|
||||||
.arg("fetch")
|
.arg("fetch")
|
||||||
.arg("origin")
|
.arg("origin")
|
||||||
.args(self.extra_clone_args())
|
|
||||||
.current_dir(self.clone_to())
|
.current_dir(self.clone_to())
|
||||||
.status()?;
|
.status()?;
|
||||||
|
|
||||||
|
@ -72,4 +71,48 @@ pub trait GitClonable {
|
||||||
return Err(Error::new(ErrorKind::Other, "Failed to fetch"));
|
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(),
|
let project = cloner.project("NixOS/nixpkgs".to_string(),
|
||||||
"https://github.com/nixos/nixpkgs.git".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(),
|
let refpath = co.checkout_ref("origin/master".as_ref());
|
||||||
"origin/master".to_string()
|
co.fetch_pr(31228).unwrap();
|
||||||
);
|
co.merge_commit("7214d0f6f7a6467205761f87973140727154e1b3".as_ref()).unwrap();
|
||||||
|
|
||||||
match refpath {
|
match refpath {
|
||||||
Ok(path) => {
|
Ok(path) => {
|
||||||
|
|
Loading…
Reference in a new issue