From 789a68ff36fffd3d25b203dc25de20c06ae16d93 Mon Sep 17 00:00:00 2001 From: John Turner Date: Sat, 13 Dec 2025 05:36:26 +0000 Subject: [PATCH] read arch.list --- src/repo/meson.build | 2 +- src/repo/mod.rs | 29 +++++++++++++++++++++++ src/repo/parsers.rs | 20 ++++++++++++++++ tests/profile/mockrepo/profiles/arch.list | 2 ++ tests/profile/read_mock_profile.rs | 8 +++++++ 5 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 src/repo/parsers.rs create mode 100644 tests/profile/mockrepo/profiles/arch.list diff --git a/src/repo/meson.build b/src/repo/meson.build index d59b73e..e706ad9 100644 --- a/src/repo/meson.build +++ b/src/repo/meson.build @@ -1,4 +1,4 @@ -sources += files('mod.rs') +sources += files('mod.rs', 'parsers.rs') subdir('ebuild') subdir('profile') diff --git a/src/repo/mod.rs b/src/repo/mod.rs index 250825b..0443afc 100644 --- a/src/repo/mod.rs +++ b/src/repo/mod.rs @@ -19,6 +19,7 @@ use crate::{ }; pub mod ebuild; +mod parsers; pub mod profile; #[derive(Debug, thiserror::Error)] @@ -37,6 +38,9 @@ pub enum Error { Profile(profile::Error), } +#[derive(Debug, Clone, PartialEq, Eq, Get)] +pub struct Arch(#[get(method = "get", kind = "deref")] String); + #[derive(Debug, Clone, Get)] pub struct Repo { #[get(kind = "deref")] @@ -45,6 +49,8 @@ pub struct Repo { name: String, #[get(kind = "deref")] package_mask: Vec, + #[get(kind = "deref")] + arch_list: Vec, } #[derive(Debug, Clone, Get)] @@ -80,10 +86,19 @@ impl Repo { Err(e) => return Err(Error::Io(package_mask_path, e)), }; + let arch_list_path = path.as_ref().join("profiles/arch.list"); + let arch_list = match fs::read_to_string(&arch_list_path).map(|s| read_arch_list(&s)) { + Ok(Ok(arch_list)) => arch_list, + Ok(Err(e)) => return Err(e), + Err(e) if matches!(e.kind(), io::ErrorKind::NotFound) => Vec::new(), + Err(e) => return Err(Error::Io(arch_list_path, e)), + }; + Ok(Self { path: path.as_ref().to_path_buf(), name, package_mask, + arch_list, }) } @@ -366,6 +381,20 @@ fn read_package_mask(input: &str) -> Result, Error> { .collect()) } +fn read_arch_list(input: &str) -> Result, Error> { + Ok(LineBasedFileExpr::::parser() + .separated_by_with_opt_trailing(ascii_whitespace1()) + .many() + .parse_finished(InputIter::new(input)) + .map_err(|it| Error::Parser(it.rest().to_string()))? + .into_iter() + .filter_map(|expr| match expr { + LineBasedFileExpr::Comment => None, + LineBasedFileExpr::Expr(arch) => Some(arch), + }) + .collect()) +} + fn parse_depends(line: &str) -> Result>, Error> { Depend::::parser() .separated_by(ascii_whitespace1()) diff --git a/src/repo/parsers.rs b/src/repo/parsers.rs new file mode 100644 index 0000000..ccef666 --- /dev/null +++ b/src/repo/parsers.rs @@ -0,0 +1,20 @@ +use mon::{Parser, ParserIter, ascii_alphanumeric, one_of}; + +use crate::{Parseable, repo::Arch}; + +impl<'a> Parseable<'a, &'a str> for Arch { + type Parser = impl Parser<&'a str, Output = Self>; + + fn parser() -> Self::Parser { + let start = ascii_alphanumeric(); + let rest = ascii_alphanumeric() + .or(one_of("-".chars())) + .repeated() + .many(); + + start + .and(rest) + .recognize() + .map(|output: &str| Arch(output.to_string())) + } +} diff --git a/tests/profile/mockrepo/profiles/arch.list b/tests/profile/mockrepo/profiles/arch.list new file mode 100644 index 0000000..afe9227 --- /dev/null +++ b/tests/profile/mockrepo/profiles/arch.list @@ -0,0 +1,2 @@ +amd64 +aarch64 \ No newline at end of file diff --git a/tests/profile/read_mock_profile.rs b/tests/profile/read_mock_profile.rs index da50216..440dce2 100644 --- a/tests/profile/read_mock_profile.rs +++ b/tests/profile/read_mock_profile.rs @@ -18,6 +18,14 @@ fn main() { assert_eq!(global_package_mask, vec!["app-editors/vim"]); + assert_eq!( + repo.arch_list() + .iter() + .map(|arch| arch.get()) + .collect::>(), + vec!["amd64", "aarch64"] + ); + let profile = repo .evaluate_profile("gentoo-desktop") .expect("failed to evaluate profile");