diff --git a/indexer/src/main.rs b/indexer/src/main.rs index 5b39092..f8c1933 100644 --- a/indexer/src/main.rs +++ b/indexer/src/main.rs @@ -7,6 +7,7 @@ mod archread; mod man; mod open; mod pkg; +mod sys_alpine; mod sys_arch; mod sys_deb; mod sys_freebsd1; @@ -41,6 +42,12 @@ fn main() { (@arg arch: --arch +takes_value "Architecture") (@arg FILE: +required "Package file") ) + (@subcommand alpine => + (about: "Index an Alpine Linux repository") + (@arg sys: --sys +required +takes_value "System short-name") + (@arg mirror: --mirror +required +takes_value "Mirror URL") + (@arg repo: --repo +required +takes_value "Repository name") + ) (@subcommand arch => (about: "Index an Arch Linux repository") (@arg sys: --sys +required +takes_value "System short-name") @@ -127,6 +134,14 @@ fn main() { }); } + if let Some(matches) = arg.subcommand_matches("alpine") { + let sys = sysbyshort(&mut db, matches.value_of("sys").unwrap()); + sys_alpine::sync(&mut db, sys, + matches.value_of("mirror").unwrap(), + matches.value_of("repo").unwrap() + ); + } + if let Some(matches) = arg.subcommand_matches("arch") { let sys = sysbyshort(&mut db, matches.value_of("sys").unwrap()); sys_arch::sync(&mut db, sys, diff --git a/indexer/src/sys_alpine.rs b/indexer/src/sys_alpine.rs new file mode 100644 index 0000000..241ca3e --- /dev/null +++ b/indexer/src/sys_alpine.rs @@ -0,0 +1,99 @@ +use std::str::FromStr; +use std::io::{Read,BufRead,BufReader}; +use postgres; + +use crate::archive; +use crate::open; +use crate::pkg; + +// https://git.alpinelinux.org/apk-tools/tree/doc/apk-repositories.5.scd +// https://git.alpinelinux.org/apk-tools/tree/src/package.c#n874 (apk_pkg_write_index_entry) + +pub fn read_index(pg: &mut T, sys: i32, mirror: &str, repo: &str, lst: R) { + let rd = BufReader::new(lst); + + let mut name = None; + let mut version = None; + let mut builddate = None; + let mut arch = None; + let mut lineno: u32 = 0; + + for line in rd.lines() { + lineno += 1; + let line = match line { + Err(e) => { error!("Can't read package index: {}", e); return }, + Ok(x) => x, + }; + + if line.starts_with("P:") { + name = Some(line[2..].to_string()); + } else if line.starts_with("V:") { + version = Some(line[2..].to_string()); + } else if line.starts_with("t:") { + builddate = i64::from_str(&line[2..]).ok(); + } else if line.starts_with("A:") { + arch = Some(line[2..].to_string()); + } + if line != "" { + continue; + } + + if name.is_none() || version.is_none() { + warn!("Package without name or version on line {}", lineno); + return; + } + + let pname = name.as_ref().unwrap(); + let pver = version.as_ref().unwrap(); + if pname == "man-pages" || pname.ends_with("-doc") { + let p = format!("{}/{}/x86_64/{}-{}.apk", mirror, repo, pname, pver); + pkg::pkg(pg, pkg::PkgOpt{ + force: false, + sys: sys, + cat: repo, + pkg: pname, + ver: pver, + date: builddate.map(pkg::Date::Found).unwrap_or(pkg::Date::Max), + arch: arch.as_deref(), + file: open::Path{ + path: &p, + cache: false, + canbelocal: false, + }, + }); + } + + name = None; + version = None; + builddate = None; + arch = None; + } +} + + +pub fn sync(pg: &mut T, sys: i32, mirror: &str, repo: &str) { + info!("Reading packages from {} {}", mirror, repo); + + let path = format!("{}/{}/x86_64/APKINDEX.tar.gz", mirror, repo); + let path = open::Path{ path: &path, cache: true, canbelocal: false }; + let mut index = match path.open() { + Err(e) => { error!("Can't read package index: {}", e); return }, + Ok(x) => x, + }; + + let ent = match archive::Archive::open_archive(&mut index) { + Err(e) => { error!("Can't read package index: {}", e); return }, + Ok(x) => x, + }; + + let r = archive::walk(ent, |x| { + if x.path() == Some("APKINDEX") { + read_index(pg, sys, mirror, repo, x); + } + Ok(true) + }); + + if let Err(e) = r { + error!("Error reading package index: {}", e); + } +} diff --git a/www/images/alpine.png b/www/images/alpine.png new file mode 100644 index 0000000..ccc839b Binary files /dev/null and b/www/images/alpine.png differ diff --git a/www/man.css b/www/man.css index 3e86d9f..1a2cecb 100644 --- a/www/man.css +++ b/www/man.css @@ -49,6 +49,7 @@ i.grayedout { color: #aaa; font-size: 13px; } #systems li { display: block; float: left; width: 300px; min-height: 80px; margin: 15px 10px; padding-left: 60px } #systems span { display: block; margin-left: -55px; float: left; width: 50px; height: 50px; background-repeat: no-repeat; } +#systems a span { margin-top: 10px } #systems b { font-size: 24px; display: block } #pkglist .charselect { float: right }