use crate::error::*;
use skellige::prelude::*;
const TMPDIR: &str = "abs";
const REPO_BASE: &str = "https://git.archlinux.org/svntogit";
pub const PACKAGES: &str = "packages";
pub const COMMUNITY: &str = "community";
#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub enum Repo {
Packages,
Community,
}
impl Repo {
fn from<T: AsRef<str>>(repo: T) -> RelicResult<Repo> {
match repo.as_ref() {
PACKAGES => Ok(Repo::Packages),
COMMUNITY => Ok(Repo::Community),
_ => Err(RelicError::repo_not_found(repo.as_ref())),
}
}
}
pub fn kernel_ver() -> RelicResult<String> {
let tmpdir = user::temp_dir(TMPDIR)?;
defer!(sys::remove_all(&tmpdir).unwrap());
let src = download("linux", &tmpdir)?;
lazy_static! {
static ref RX: Regex = Regex::new(r"(?m)^pkgver=((\d+\.\d+\.\d+)|(\d+\.\d+)|(\d+)).*").unwrap();
}
Ok(sys::extract_string(src.mash("PKGBUILD"), &RX)?)
}
pub fn find<T: AsRef<str>>(pkg: T) -> RelicResult<Repo> {
for name in &vec![PACKAGES, COMMUNITY] {
let url = format!("{}/{}.git", REPO_BASE, name);
let branch = format!("packages/{}", pkg.as_ref());
if git::remote_branch_exists(url, branch).is_ok() {
return Repo::from(name);
}
}
Err(RelicError::package_not_found(pkg))
}
pub fn download<T: AsRef<str>, U: AsRef<Path>>(pkg: T, dst: U) -> RelicResult<PathBuf> {
for name in &vec![PACKAGES, COMMUNITY] {
let url = format!("{}/{}.git", REPO_BASE, name);
let branch = format!("packages/{}", pkg.as_ref());
let tmpdir = user::temp_dir(TMPDIR)?;
defer!(sys::remove_all(&tmpdir).unwrap());
if git::Repo::new(&tmpdir)?.url(url).branch(branch).branch_only(true).clone().is_ok() {
let dir = sys::mkdir(&dst)?;
sys::copy(tmpdir.mash("trunk/*"), &dir)?;
return Ok(dir);
}
}
Err(RelicError::package_not_found(pkg))
}
#[cfg(test)]
mod tests {
use crate::prelude::*;
fn setup<T: AsRef<Path>>(path: T) -> PathBuf {
let temp = PathBuf::from("tests/temp").abs().unwrap();
sys::mkdir(&temp).unwrap();
temp.mash(path.as_ref())
}
#[test]
fn test_kernel_ver() {
assert!(abs::kernel_ver().is_ok());
let rx = Regex::new(r"(?m)^pkgver=((\d+\.\d+\.\d+)|(\d+\.\d+)|(\d+)).*").unwrap();
let caps = rx.captures("pkgver=6.arch").unwrap();
assert_eq!(caps.get(1).unwrap().as_str(), "6");
let caps = rx.captures("pkgver=5.5.arch").unwrap();
assert_eq!(caps.get(1).unwrap().as_str(), "5.5");
let caps = rx.captures("pkgver=5.4.14.arch").unwrap();
assert_eq!(caps.get(1).unwrap().as_str(), "5.4.14");
}
#[test]
fn test_repo() {
assert!(abs::find("foobar").is_err());
assert!(abs::Repo::from("foobar").is_err());
assert_eq!(abs::find("pkgfile").unwrap(), abs::Repo::Packages);
assert_eq!(abs::find("acme").unwrap(), abs::Repo::Community);
assert_eq!(abs::find("linux").unwrap(), abs::Repo::Packages);
}
#[test]
fn test_source() {
let tmpdir = setup("abs_source");
assert!(sys::remove_all(&tmpdir).is_ok());
assert!(abs::download("pkgfile", &tmpdir).is_ok());
assert_eq!(tmpdir.is_dir(), true);
assert_eq!(tmpdir.mash("PKGBUILD").exists(), true);
assert!(abs::download("foobar", &tmpdir).is_err());
assert!(sys::remove_all(&tmpdir).is_ok());
}
}