use std::collections::HashSet;
use pkgcraft::pkg::{Package, ebuild::EbuildPkg};
use pkgcraft::restrict::Scope;
use url::Url;
use crate::report::ReportKind::HomepageInvalid;
use crate::scan::ScannerRun;
use crate::source::SourceKind;
super::register! {
kind: super::CheckKind::Homepage,
reports: &[HomepageInvalid],
scope: Scope::Version,
sources: &[SourceKind::EbuildPkg],
context: &[],
create,
}
pub(super) fn create(_run: &ScannerRun) -> super::Runner {
Box::new(Check {
allowed_protocols: ["http", "https"].into_iter().map(Into::into).collect(),
missing_categories: ["acct-group", "acct-user", "virtual"]
.iter()
.map(|x| x.to_string())
.collect(),
})
}
struct Check {
allowed_protocols: HashSet<String>,
missing_categories: HashSet<String>,
}
impl super::CheckRun for Check {
fn run_ebuild_pkg(&self, pkg: &EbuildPkg, run: &ScannerRun) {
let allowed_missing = self.missing_categories.contains(pkg.category());
if pkg.homepage().is_empty() {
if !allowed_missing {
HomepageInvalid.version(pkg).message("missing").report(run);
}
} else if allowed_missing {
HomepageInvalid.version(pkg).message("unneeded").report(run);
}
for value in pkg.homepage() {
match Url::parse(value) {
Ok(url) => {
let protocol = url.scheme();
if !self.allowed_protocols.contains(protocol) {
HomepageInvalid
.version(pkg)
.message(format!("unsupported protocol: {url}"))
.report(run);
}
}
Err(e) => {
HomepageInvalid
.version(pkg)
.message(format!("{e}: {value}"))
.report(run);
}
}
}
}
}
#[cfg(test)]
mod tests {
use pkgcraft::test::{test_data, test_data_patched};
use crate::scan::Scanner;
use crate::test::{assert_unordered_reports, glob_reports};
use super::*;
#[test]
fn check() {
let scanner = Scanner::new().reports([CHECK]);
let data = test_data();
let repo = data.ebuild_repo("qa-primary").unwrap();
let dir = repo.path().join(CHECK);
let unneeded = repo.path().join("virtual/HomepageInvalid");
let expected = glob_reports!("{dir}/*/reports.json", "{unneeded}/reports.json");
let reports = scanner.run(repo, repo).unwrap();
assert_unordered_reports!(reports, expected);
let data = test_data_patched();
let repo = data.ebuild_repo("qa-primary").unwrap();
let reports = scanner.run(repo, repo).unwrap();
assert_unordered_reports!(reports, []);
}
}