diff --git a/indexer/src/main.rs b/indexer/src/main.rs index ee6976a..5399e09 100644 --- a/indexer/src/main.rs +++ b/indexer/src/main.rs @@ -21,6 +21,7 @@ mod sys_arch; mod sys_deb; mod sys_freebsd1; mod sys_freebsd2; +mod sys_rpmdir; // Convenience function to get a system id by short-name. Panics if the system doesn't exist. @@ -73,6 +74,12 @@ fn main() { (@arg sys: --sys +required +takes_value "System short-name") (@arg mirror: --mirror +required +takes_value "Mirror URL") ) + (@subcommand rpmdir => + (about: "Index a bare RPM directory") + (@arg sys: --sys +required +takes_value "System short-name") + (@arg cat: --cat +required +takes_value "Category to set for all packages") + (@arg mirror: --mirror +required +takes_value "Mirror URL") + ) ).get_matches(); unsafe { pkg::DRY_RUN = arg.is_present("dry") }; @@ -154,5 +161,13 @@ fn main() { ).unwrap_or_else(|e| error!("{}", e)); } + if let Some(matches) = arg.subcommand_matches("rpmdir") { + sys_rpmdir::sync(&db, + sysbyshort(&db, matches.value_of("sys").unwrap()), + matches.value_of("cat").unwrap(), + matches.value_of("mirror").unwrap() + ).unwrap_or_else(|e| error!("{}", e)); + } + trace!("Exiting"); } diff --git a/indexer/src/sys_rpmdir.rs b/indexer/src/sys_rpmdir.rs new file mode 100644 index 0000000..730aea6 --- /dev/null +++ b/indexer/src/sys_rpmdir.rs @@ -0,0 +1,45 @@ +use std::io::Result; +use regex::Regex; +use postgres; + +use open; +use pkg; + +pub fn sync(pg: &postgres::GenericConnection, sys: i32, cat: &str, mirror: &str) -> Result<()> { + let pkgs : Vec = open::Path{path: mirror, cache: true, canbelocal: false} + .dirlist()?.into_iter() + .filter_map(|(n,d)| if d { None } else { Some(n) }) + .collect(); + + lazy_static!( + // --..rpm + // As far as I can tell, rpm requires that , and cannot contain a + // dash, so this parsing should be reliable. + static ref RE: Regex = Regex::new(r"^(.+)-([^-]+-[^-]+)\.([^\.-]+)\.rpm$").unwrap(); + ); + + for pkg in pkgs { + let cap = match RE.captures(&pkg) { + Some(x) => x, + None => { warn!("Unknown file in directory listing: {}", pkg); continue }, + }; + let (name, ver, arch) = (&cap[1], &cap[2], &cap[3]); + + let path = format!("{}{}", mirror, pkg); + pkg::pkg(pg, pkg::PkgOpt{ + force: false, + sys: sys, + cat: cat, + pkg: name, + ver: ver, + date: pkg::Date::Max, + arch: Some(arch), + file: open::Path{ + path: &path, + cache: false, + canbelocal: false, + }, + }); + } + Ok(()) +}