summaryrefslogtreecommitdiff
path: root/src/repo
diff options
context:
space:
mode:
Diffstat (limited to 'src/repo')
-rw-r--r--src/repo/ebuild/meson.build1
-rw-r--r--src/repo/ebuild/mod.rs83
-rw-r--r--src/repo/ebuild/parsers.rs205
-rw-r--r--src/repo/meson.build3
-rw-r--r--src/repo/mod.rs325
5 files changed, 0 insertions, 617 deletions
diff --git a/src/repo/ebuild/meson.build b/src/repo/ebuild/meson.build
deleted file mode 100644
index a7331a8..0000000
--- a/src/repo/ebuild/meson.build
+++ /dev/null
@@ -1 +0,0 @@
-sources += files('mod.rs', 'parsers.rs')
diff --git a/src/repo/ebuild/mod.rs b/src/repo/ebuild/mod.rs
deleted file mode 100644
index 3f52db9..0000000
--- a/src/repo/ebuild/mod.rs
+++ /dev/null
@@ -1,83 +0,0 @@
-use get::Get;
-use std::path::PathBuf;
-
-use crate::{
- atom::{Atom, Name, Slot, Version},
- useflag::{IUseFlag, UseFlag},
-};
-
-mod parsers;
-
-#[derive(Clone, Debug)]
-pub enum Conditional {
- Negative(UseFlag),
- Positive(UseFlag),
-}
-
-#[derive(Clone, Debug)]
-pub enum Depend<T> {
- Element(T),
- AllOf(Vec<Self>),
- AnyOf(Vec<Self>),
- OneOf(Vec<Self>),
- ConditionalGroup(Conditional, Vec<Self>),
-}
-
-#[derive(Debug, Clone)]
-pub enum UriPrefix {
- Mirror,
- Fetch,
-}
-
-#[derive(Debug, Clone, Get)]
-pub struct Uri {
- #[get(kind = "deref")]
- protocol: String,
- #[get(kind = "deref")]
- path: String,
-}
-
-#[derive(Debug, Clone)]
-pub enum SrcUri {
- Filename(PathBuf),
- Uri {
- prefix: Option<UriPrefix>,
- uri: Uri,
- filename: Option<PathBuf>,
- },
-}
-
-#[derive(Debug, Clone, Get)]
-pub struct License(#[get(method = "get", kind = "deref")] String);
-
-#[derive(Debug, Clone, Get)]
-pub struct Eapi(#[get(method = "get", kind = "deref")] String);
-
-#[derive(Debug, Clone, Get)]
-pub struct Eclass(#[get(method = "get", kind = "deref")] String);
-
-#[derive(Debug, Clone, Get)]
-pub struct Ebuild {
- pub(super) name: Name,
- pub(super) version: Version,
- pub(super) slot: Option<Slot>,
- pub(super) homepage: Option<String>,
- #[get(kind = "deref")]
- pub(super) src_uri: Vec<Depend<SrcUri>>,
- pub(super) eapi: Option<Eapi>,
- #[get(kind = "deref")]
- pub(super) inherit: Vec<Eclass>,
- #[get(kind = "deref")]
- pub(super) iuse: Vec<IUseFlag>,
- #[get(kind = "deref")]
- pub(super) license: Vec<Depend<License>>,
- pub(super) description: Option<String>,
- #[get(kind = "deref")]
- pub(super) depend: Vec<Depend<Atom>>,
- #[get(kind = "deref")]
- pub(super) bdepend: Vec<Depend<Atom>>,
- #[get(kind = "deref")]
- pub(super) rdepend: Vec<Depend<Atom>>,
- #[get(kind = "deref")]
- pub(super) idepend: Vec<Depend<Atom>>,
-}
diff --git a/src/repo/ebuild/parsers.rs b/src/repo/ebuild/parsers.rs
deleted file mode 100644
index c80cdf2..0000000
--- a/src/repo/ebuild/parsers.rs
+++ /dev/null
@@ -1,205 +0,0 @@
-use std::path::PathBuf;
-
-use mon::{
- Parser, ParserIter, ascii_alpha1, ascii_alphanumeric, ascii_whitespace1, r#if, one_of, tag,
-};
-
-use crate::{
- Parseable,
- repo::ebuild::{Conditional, Depend, Eapi, Eclass, License, SrcUri, Uri, UriPrefix},
- useflag::UseFlag,
-};
-
-impl<'a> Parseable<'a, &'a str> for UriPrefix {
- type Parser = impl Parser<&'a str, Output = Self>;
-
- fn parser() -> Self::Parser {
- tag("+mirror")
- .map(|_| UriPrefix::Mirror)
- .or(tag("+fetch").map(|_| UriPrefix::Fetch))
- }
-}
-
-impl<'a> Parseable<'a, &'a str> for Uri {
- type Parser = impl Parser<&'a str, Output = Self>;
-
- fn parser() -> Self::Parser {
- let protocol = ascii_alpha1::<&str>()
- .followed_by(tag("://"))
- .map(|output: &str| output.to_string());
- let path = r#if(|c: &char| !c.is_ascii_whitespace())
- .repeated()
- .at_least(1)
- .recognize()
- .map(|output: &str| output.to_string());
-
- protocol
- .and(path)
- .map(|(protocol, path)| Uri { protocol, path })
- }
-}
-
-impl<'a> Parseable<'a, &'a str> for SrcUri {
- type Parser = impl Parser<&'a str, Output = Self>;
-
- fn parser() -> Self::Parser {
- let filename = || {
- r#if(|c: &char| !c.is_ascii_whitespace())
- .repeated()
- .at_least(1)
- .recognize()
- .map(|output: &str| PathBuf::from(output))
- };
-
- let uri = UriPrefix::parser()
- .opt()
- .and(Uri::parser())
- .and(filename().preceded_by(tag(" -> ")).opt())
- .map(|((prefix, uri), filename)| SrcUri::Uri {
- prefix,
- uri,
- filename,
- });
-
- uri.or(filename().map(|path: PathBuf| SrcUri::Filename(path)))
- }
-}
-
-impl<'a> Parseable<'a, &'a str> for License {
- type Parser = impl Parser<&'a str, Output = Self>;
-
- fn parser() -> Self::Parser {
- let start = ascii_alphanumeric().or(one_of("_".chars()));
- let rest = ascii_alphanumeric()
- .or(one_of("+_.-".chars()))
- .repeated()
- .many();
-
- start
- .and(rest)
- .recognize()
- .map(|output: &str| License(output.to_string()))
- }
-}
-
-impl<'a> Parseable<'a, &'a str> for Eapi {
- type Parser = impl Parser<&'a str, Output = Self>;
-
- fn parser() -> Self::Parser {
- let start = ascii_alphanumeric().or(one_of("_".chars()));
- let rest = ascii_alphanumeric()
- .or(one_of("+_.-".chars()))
- .repeated()
- .many();
-
- start
- .and(rest)
- .recognize()
- .map(|output: &str| Eapi(output.to_string()))
- }
-}
-
-// TODO:
-// Cant find information about eclass names in pms so we allow anything except
-// for whitespace.
-impl<'a> Parseable<'a, &'a str> for Eclass {
- type Parser = impl Parser<&'a str, Output = Self>;
-
- fn parser() -> Self::Parser {
- r#if(|c: &char| !c.is_ascii_whitespace())
- .repeated()
- .at_least(1)
- .recognize()
- .map(|output: &str| Eclass(output.to_string()))
- }
-}
-
-impl<'a, T> Parseable<'a, &'a str> for Depend<T>
-where
- T: Parseable<'a, &'a str>,
-{
- type Parser = impl Parser<&'a str, Output = Self>;
-
- fn parser() -> Self::Parser {
- |it| {
- let exprs = || {
- Depend::parser()
- .separated_by_with_trailing(ascii_whitespace1())
- .at_least(1)
- .delimited_by(tag("(").followed_by(ascii_whitespace1()), tag(")"))
- };
-
- let all_of_group = exprs().map(|exprs| Depend::AllOf(exprs));
-
- let any_of_group = exprs()
- .preceded_by(tag("||").followed_by(ascii_whitespace1()))
- .map(|exprs| Depend::AnyOf(exprs));
-
- let one_of_group = exprs()
- .preceded_by(tag("^^").followed_by(ascii_whitespace1()))
- .map(|exprs| Depend::OneOf(exprs));
-
- let conditional_group = Conditional::parser()
- .followed_by(ascii_whitespace1())
- .and(exprs())
- .map(|(conditional, exprs)| Depend::ConditionalGroup(conditional, exprs));
-
- T::parser()
- .map(|e| Depend::Element(e))
- .or(conditional_group)
- .or(any_of_group)
- .or(all_of_group)
- .or(one_of_group)
- .parse(it)
- }
- }
-}
-
-impl<'a> Parseable<'a, &'a str> for Conditional {
- type Parser = impl Parser<&'a str, Output = Self>;
-
- fn parser() -> Self::Parser {
- UseFlag::parser()
- .preceded_by(tag("!"))
- .followed_by(tag("?"))
- .map(Conditional::Negative)
- .or(UseFlag::parser()
- .followed_by(tag("?"))
- .map(Conditional::Positive))
- }
-}
-
-#[cfg(test)]
-mod test {
-
- use mon::{ParserIter, input::InputIter};
-
- use crate::{atom::Atom, repo::ebuild::Depend};
-
- use super::*;
-
- #[test]
- fn test_src_uri() {
- let tests = [
- "https://example.com/foo/bar.tar.gz",
- "https://example.com/foo/bar.tar.gz -> bar.tar.gz",
- ];
-
- for test in tests {
- SrcUri::parser()
- .check_finished(InputIter::new(test))
- .unwrap();
- }
- }
-
- #[test]
- fn test_expr() {
- let it = InputIter::new("flag? ( || ( foo/bar foo/bar ) )");
-
- Depend::<Atom>::parser()
- .separated_by(ascii_whitespace1())
- .many()
- .check_finished(it)
- .unwrap();
- }
-}
diff --git a/src/repo/meson.build b/src/repo/meson.build
deleted file mode 100644
index c1be7a7..0000000
--- a/src/repo/meson.build
+++ /dev/null
@@ -1,3 +0,0 @@
-sources += files('mod.rs')
-
-subdir('ebuild')
diff --git a/src/repo/mod.rs b/src/repo/mod.rs
deleted file mode 100644
index eb68839..0000000
--- a/src/repo/mod.rs
+++ /dev/null
@@ -1,325 +0,0 @@
-use std::{
- fs, io,
- os::unix::ffi::OsStrExt,
- path::{Path, PathBuf},
-};
-
-use get::Get;
-
-use mon::{Parser, ParserIter, ascii_whitespace1, input::InputIter, tag};
-
-use crate::{
- Parseable,
- atom::{self, Atom},
- repo::ebuild::{Depend, Eapi, Ebuild, Eclass, License, SrcUri},
- useflag::IUseFlag,
-};
-
-pub mod ebuild;
-
-#[derive(Debug, thiserror::Error)]
-pub enum Error {
- #[error("io error: {0}")]
- Io(PathBuf, io::Error),
- #[error("error while reading directory: {0:?}: {1}")]
- ReadDir(PathBuf, io::Error),
- #[error("failed to decode path: {0}")]
- Unicode(PathBuf),
- #[error("parser error: {0}")]
- Parser(String),
-}
-
-#[derive(Debug, Clone, Get)]
-pub struct Repo {
- #[get(kind = "deref")]
- path: PathBuf,
-}
-
-#[derive(Debug, Clone, Get)]
-pub struct Category {
- name: atom::Category,
- #[get(kind = "deref")]
- path: PathBuf,
-}
-
-#[derive(Debug)]
-pub struct Categories(PathBuf, fs::ReadDir);
-
-#[derive(Debug)]
-pub struct Ebuilds(PathBuf, fs::ReadDir);
-
-impl Repo {
- pub fn new<P: AsRef<Path>>(path: P) -> Self {
- Self {
- path: path.as_ref().to_path_buf(),
- }
- }
-
- pub fn categories(&self) -> Result<Categories, Error> {
- let path = self.path.as_path().join("metadata/md5-cache");
-
- Ok(Categories(
- path.clone(),
- fs::read_dir(&path).map_err(|e| Error::Io(path, e))?,
- ))
- }
-}
-
-impl Category {
- pub fn ebuilds(&self) -> Result<Ebuilds, Error> {
- Ok(Ebuilds(
- self.path.clone(),
- fs::read_dir(&self.path).map_err(|e| Error::Io(self.path.clone(), e))?,
- ))
- }
-}
-
-impl Iterator for Categories {
- type Item = Result<Category, Error>;
-
- fn next(&mut self) -> Option<Self::Item> {
- loop {
- match self.1.next()? {
- Ok(entry) if entry.path().file_name().unwrap().as_bytes() == b"Manifest.gz" => (),
- Ok(entry) => match read_category(entry.path()) {
- Ok(category) => break Some(Ok(category)),
- Err(e) => break Some(Err(e)),
- },
- Err(e) => break Some(Err(Error::ReadDir(self.0.clone(), e))),
- }
- }
- }
-}
-
-impl Iterator for Ebuilds {
- type Item = Result<Ebuild, Error>;
-
- fn next(&mut self) -> Option<Self::Item> {
- loop {
- match self.1.next()? {
- Ok(entry) if entry.path().file_name().unwrap().as_bytes() == b"Manifest.gz" => (),
- Ok(entry) => match read_ebuild(entry.path()) {
- Ok(ebuild) => break Some(Ok(ebuild)),
- Err(e) => break Some(Err(e)),
- },
- Err(e) => break Some(Err(Error::ReadDir(self.0.clone(), e))),
- }
- }
- }
-}
-
-fn read_category(path: PathBuf) -> Result<Category, Error> {
- let file_name = path
- .as_path()
- .file_name()
- .unwrap()
- .to_str()
- .ok_or(Error::Unicode(path.clone()))?;
-
- let name = atom::Category::parser()
- .parse_finished(InputIter::new(file_name))
- .map_err(|_| Error::Parser(file_name.to_string()))?;
-
- Ok(Category { name, path })
-}
-
-fn read_ebuild(path: PathBuf) -> Result<Ebuild, Error> {
- let file_name = path
- .as_path()
- .file_name()
- .unwrap()
- .to_str()
- .ok_or(Error::Unicode(path.clone()))?;
-
- let (name, version) = atom::Name::parser()
- .and(atom::Version::parser().preceded_by(tag("-")))
- .parse_finished(InputIter::new(file_name))
- .map_err(|_| Error::Parser(file_name.to_string()))?;
-
- let metadata = fs::read_to_string(path.as_path()).map_err(|e| Error::Io(path, e))?;
-
- Ok(Ebuild {
- name,
- version,
- slot: match read_slot(&metadata) {
- Some(Ok(slot)) => Some(slot),
- Some(Err(e)) => return Err(e),
- None => None,
- },
- homepage: read_homepage(&metadata),
- src_uri: match read_src_uri(&metadata) {
- Some(Ok(src_uri)) => src_uri,
- Some(Err(e)) => return Err(e),
- None => Vec::new(),
- },
- eapi: match read_eapi(&metadata) {
- Some(Ok(eapi)) => Some(eapi),
- Some(Err(e)) => return Err(e),
- None => None,
- },
- inherit: match read_inherit(&metadata) {
- Some(Ok(inherit)) => inherit,
- Some(Err(e)) => return Err(e),
- None => Vec::new(),
- },
- iuse: match read_iuse(&metadata) {
- Some(Ok(iuse)) => iuse,
- Some(Err(e)) => return Err(e),
- None => Vec::new(),
- },
- license: match read_license(&metadata) {
- Some(Ok(license)) => license,
- Some(Err(e)) => return Err(e),
- None => Vec::new(),
- },
- description: read_description(&metadata),
- depend: match read_depend(&metadata) {
- Some(Ok(depend)) => depend,
- Some(Err(e)) => return Err(e),
- None => Vec::new(),
- },
- bdepend: match read_bdepend(&metadata) {
- Some(Ok(depend)) => depend,
- Some(Err(e)) => return Err(e),
- None => Vec::new(),
- },
- rdepend: match read_rdepend(&metadata) {
- Some(Ok(depend)) => depend,
- Some(Err(e)) => return Err(e),
- None => Vec::new(),
- },
- idepend: match read_idepend(&metadata) {
- Some(Ok(depend)) => depend,
- Some(Err(e)) => return Err(e),
- None => Vec::new(),
- },
- })
-}
-
-fn read_slot(input: &str) -> Option<Result<atom::Slot, Error>> {
- let line = input.lines().find_map(|line| line.strip_prefix("SLOT="))?;
-
- match atom::Slot::parser().parse_finished(InputIter::new(line)) {
- Ok(slot) => Some(Ok(slot)),
- Err(_) => Some(Err(Error::Parser(line.to_string()))),
- }
-}
-
-fn read_homepage(input: &str) -> Option<String> {
- input
- .lines()
- .find_map(|line| line.strip_prefix("HOMEPAGE=").map(str::to_string))
-}
-
-fn read_src_uri(input: &str) -> Option<Result<Vec<Depend<SrcUri>>, Error>> {
- let line = input
- .lines()
- .find_map(|line| line.strip_prefix("SRC_URI="))?;
-
- match Depend::<SrcUri>::parser()
- .separated_by(ascii_whitespace1())
- .many()
- .parse_finished(InputIter::new(line))
- {
- Ok(slot) => Some(Ok(slot)),
- Err(_) => Some(Err(Error::Parser(line.to_string()))),
- }
-}
-
-fn read_eapi(input: &str) -> Option<Result<Eapi, Error>> {
- let line = input.lines().find_map(|line| line.strip_prefix("EAPI="))?;
-
- match Eapi::parser().parse_finished(InputIter::new(line)) {
- Ok(slot) => Some(Ok(slot)),
- Err(_) => Some(Err(Error::Parser(line.to_string()))),
- }
-}
-
-fn read_inherit(input: &str) -> Option<Result<Vec<Eclass>, Error>> {
- let line = input
- .lines()
- .find_map(|line| line.strip_prefix("INHERIT="))?;
-
- match Eclass::parser()
- .separated_by(ascii_whitespace1())
- .many()
- .parse_finished(InputIter::new(line))
- {
- Ok(inherit) => Some(Ok(inherit)),
- Err(_) => Some(Err(Error::Parser(line.to_string()))),
- }
-}
-
-fn read_iuse(input: &str) -> Option<Result<Vec<IUseFlag>, Error>> {
- let line = input.lines().find_map(|line| line.strip_prefix("IUSE="))?;
-
- match IUseFlag::parser()
- .separated_by(ascii_whitespace1())
- .many()
- .parse_finished(InputIter::new(line))
- {
- Ok(iuse) => Some(Ok(iuse)),
- Err(_) => Some(Err(Error::Parser(line.to_string()))),
- }
-}
-
-fn read_license(input: &str) -> Option<Result<Vec<Depend<License>>, Error>> {
- let line = input
- .lines()
- .find_map(|line| line.strip_suffix("LICENSE="))?;
-
- match Depend::<License>::parser()
- .separated_by(ascii_whitespace1())
- .many()
- .parse_finished(InputIter::new(line))
- {
- Ok(license) => Some(Ok(license)),
- Err(_) => Some(Err(Error::Parser(line.to_string()))),
- }
-}
-
-fn read_description(input: &str) -> Option<String> {
- input
- .lines()
- .find_map(|line| line.strip_prefix("DESCRIPTION=").map(str::to_string))
-}
-
-fn read_depend(input: &str) -> Option<Result<Vec<Depend<Atom>>, Error>> {
- let line = input
- .lines()
- .find_map(|line| line.strip_prefix("DEPEND="))?;
-
- Some(parse_depends(line))
-}
-
-fn read_bdepend(input: &str) -> Option<Result<Vec<Depend<Atom>>, Error>> {
- let line = input
- .lines()
- .find_map(|line| line.strip_prefix("BDEPEND="))?;
-
- Some(parse_depends(line))
-}
-
-fn read_rdepend(input: &str) -> Option<Result<Vec<Depend<Atom>>, Error>> {
- let line = input
- .lines()
- .find_map(|line| line.strip_prefix("RDEPEND="))?;
-
- Some(parse_depends(line))
-}
-
-fn read_idepend(input: &str) -> Option<Result<Vec<Depend<Atom>>, Error>> {
- let line = input
- .lines()
- .find_map(|line| line.strip_prefix("IDEPEND="))?;
-
- Some(parse_depends(line))
-}
-
-fn parse_depends(line: &str) -> Result<Vec<Depend<Atom>>, Error> {
- Depend::<Atom>::parser()
- .separated_by(ascii_whitespace1())
- .many()
- .parse_finished(InputIter::new(line))
- .map_err(|_| Error::Parser(line.to_string()))
-}