aboutsummaryrefslogtreecommitdiff
path: root/src/gentoo
diff options
context:
space:
mode:
authorpablu <me@pablu.de>2026-05-06 17:04:31 +0200
committerpablu <me@pablu.de>2026-05-06 17:04:31 +0200
commit3346222550bc18edc457d9b509f00d0eba9d0f4f (patch)
tree5769f6b3aa3c70082e5229ad9d2ed77ca97e7a0a /src/gentoo
initial working
Diffstat (limited to 'src/gentoo')
-rw-r--r--src/gentoo/mod.rs7
-rw-r--r--src/gentoo/package.rs20
-rw-r--r--src/gentoo/portage.rs85
-rw-r--r--src/gentoo/useflags.rs16
4 files changed, 128 insertions, 0 deletions
diff --git a/src/gentoo/mod.rs b/src/gentoo/mod.rs
new file mode 100644
index 0000000..ff343bc
--- /dev/null
+++ b/src/gentoo/mod.rs
@@ -0,0 +1,7 @@
+pub mod package;
+pub mod portage;
+pub mod useflags;
+
+pub use package::Package;
+pub use portage::Portage;
+pub use useflags::UseFlag;
diff --git a/src/gentoo/package.rs b/src/gentoo/package.rs
new file mode 100644
index 0000000..0fe9a6c
--- /dev/null
+++ b/src/gentoo/package.rs
@@ -0,0 +1,20 @@
+use crate::gentoo::UseFlag;
+
+#[derive(Debug, Clone)]
+#[allow(dead_code)]
+pub struct Package {
+ pub name: String,
+ pub use_flags: Vec<UseFlag>,
+ pub version: String,
+}
+
+#[allow(dead_code)]
+impl Package {
+ pub fn new(name: String, version: String, use_flags: Vec<UseFlag>) -> Self {
+ Package {
+ name: name,
+ use_flags: use_flags,
+ version: version,
+ }
+ }
+}
diff --git a/src/gentoo/portage.rs b/src/gentoo/portage.rs
new file mode 100644
index 0000000..40b03c0
--- /dev/null
+++ b/src/gentoo/portage.rs
@@ -0,0 +1,85 @@
+use std::fs;
+
+use crate::gentoo::{Package, UseFlag};
+
+#[derive(Debug)]
+pub struct Portage {
+ pub installed_packages: Vec<Package>,
+}
+
+fn split_pkg(input: &str) -> (&str, Option<&str>) {
+ let bytes = input.as_bytes();
+
+ for i in (0..bytes.len()).rev() {
+ if bytes[i] == b'-' {
+ if let Some(next) = bytes.get(i + 1) {
+ if next.is_ascii_digit() {
+ let name = &input[..i];
+ let version = &input[i + 1..];
+ return (name, Some(version));
+ }
+ }
+ }
+ }
+
+ (input, None)
+}
+
+impl Portage {
+ pub fn new() -> Self {
+ Self {
+ installed_packages: vec![],
+ }
+ }
+
+ pub fn load_installed_packages(&mut self) -> Result<(), std::io::Error> {
+ let categories = fs::read_dir("/var/db/pkg")?;
+
+ for category in categories {
+ let category = category.unwrap();
+ let cat_name = category.file_name();
+ let pkgs = fs::read_dir(category.path())?;
+ for pkg in pkgs {
+ let pkg = pkg.unwrap();
+ let pkg_name = pkg.file_name();
+ let pkg_name = pkg_name.to_str().unwrap();
+ let (pkg_name, pkg_version) = split_pkg(pkg_name);
+
+ let use_flags_file = fs::read(pkg.path().join("USE"))?;
+ let use_flags: Vec<&str> = str::from_utf8(&use_flags_file)
+ .unwrap()
+ .trim()
+ .split(' ')
+ .collect();
+
+ let iuse_flags_file = fs::read(pkg.path().join("IUSE"))?;
+ let iuse_flags: Vec<&str> = str::from_utf8(&iuse_flags_file)
+ .unwrap()
+ .trim()
+ .split(' ')
+ .collect();
+
+ let use_flags: Vec<UseFlag> = iuse_flags
+ .iter()
+ .filter(|x| !x.trim().is_empty())
+ .map(|&iuse| {
+ let is_default = iuse.starts_with("+");
+ let iuse = iuse.strip_prefix("+").unwrap_or(iuse);
+
+ let is_active = use_flags.contains(&iuse);
+
+ UseFlag::new(iuse.into(), is_active, is_default)
+ })
+ .collect();
+
+ self.installed_packages.push(Package::new(
+ format!("{}/{}", cat_name.to_str().unwrap(), pkg_name),
+ pkg_version.unwrap().into(),
+ use_flags,
+ ));
+ }
+ }
+
+ Ok(())
+ }
+}
diff --git a/src/gentoo/useflags.rs b/src/gentoo/useflags.rs
new file mode 100644
index 0000000..0b7d981
--- /dev/null
+++ b/src/gentoo/useflags.rs
@@ -0,0 +1,16 @@
+#[derive(Debug, Clone)]
+pub struct UseFlag {
+ pub name: String,
+ pub enabled: bool,
+ pub default: bool,
+}
+
+impl UseFlag {
+ pub fn new(name: String, enabled: bool, default: bool) -> Self {
+ UseFlag {
+ name,
+ enabled,
+ default,
+ }
+ }
+}