impl profile evaluation
This commit is contained in:
157
src/repo/profile/mod.rs
Normal file
157
src/repo/profile/mod.rs
Normal file
@@ -0,0 +1,157 @@
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
fs::{self, File},
|
||||
io::{self, Read},
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
use get::Get;
|
||||
use itertools::Itertools;
|
||||
|
||||
use crate::{atom::Atom, useflag::UseFlag};
|
||||
|
||||
mod make_defaults;
|
||||
mod package;
|
||||
mod package_use;
|
||||
mod packages;
|
||||
mod parsers;
|
||||
mod useflags;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
enum LineBasedFileExpr<T> {
|
||||
Comment,
|
||||
Expr(T),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
enum FlagOperation {
|
||||
Add(UseFlag),
|
||||
Remove(UseFlag),
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum Error {
|
||||
#[error("{0}: io error: {1}")]
|
||||
Io(PathBuf, io::Error),
|
||||
#[error("error evaluating make.defaults settings: {0}")]
|
||||
MakeDefaults(#[from] make_defaults::Error),
|
||||
#[error("error evaluating packages settings: {0}")]
|
||||
Packages(#[from] packages::Error),
|
||||
#[error("error evaluating package settings: {0}")]
|
||||
Package(#[from] package::Error),
|
||||
#[error("error evaluating package.use settings: {0}")]
|
||||
PackageUse(#[from] package_use::Error),
|
||||
#[error("error evaluating use settings: {0}")]
|
||||
Use(#[from] useflags::Error),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Get)]
|
||||
pub struct Profile {
|
||||
#[get(kind = "deref")]
|
||||
path: PathBuf,
|
||||
#[get(kind = "deref")]
|
||||
parents: Vec<Profile>,
|
||||
make_defaults: HashMap<String, String>,
|
||||
#[get(kind = "deref")]
|
||||
packages: Vec<Atom>,
|
||||
#[get(kind = "deref")]
|
||||
package_mask: Vec<Atom>,
|
||||
#[get(kind = "deref")]
|
||||
package_provided: Vec<Atom>,
|
||||
package_use: HashMap<Atom, Vec<UseFlag>>,
|
||||
package_use_force: HashMap<Atom, Vec<UseFlag>>,
|
||||
package_use_mask: HashMap<Atom, Vec<UseFlag>>,
|
||||
package_use_stable_force: HashMap<Atom, Vec<UseFlag>>,
|
||||
package_use_stable_mask: HashMap<Atom, Vec<UseFlag>>,
|
||||
#[get(kind = "deref")]
|
||||
use_force: Vec<UseFlag>,
|
||||
#[get(kind = "deref")]
|
||||
use_mask: Vec<UseFlag>,
|
||||
#[get(kind = "deref")]
|
||||
use_stable_force: Vec<UseFlag>,
|
||||
#[get(kind = "deref")]
|
||||
use_stable_mask: Vec<UseFlag>,
|
||||
}
|
||||
|
||||
impl Profile {
|
||||
pub(super) fn evaluate<P: AsRef<Path>>(path: P) -> Result<Self, Error> {
|
||||
let parents_path = path.as_ref().join("parent");
|
||||
|
||||
let parents = match fs::read_to_string(&parents_path) {
|
||||
Ok(parents) => parents
|
||||
.lines()
|
||||
.map(|line| path.as_ref().join(line))
|
||||
.map(Profile::evaluate)
|
||||
.collect::<Result<_, _>>()?,
|
||||
Err(e) if matches!(e.kind(), io::ErrorKind::NotFound) => Vec::new(),
|
||||
Err(e) => return Err(Error::Io(parents_path, e)),
|
||||
};
|
||||
|
||||
let make_defaults = make_defaults::evaluate(&parents, &path)?;
|
||||
|
||||
let packages = packages::evaluate(&parents, &path)?;
|
||||
|
||||
let package_mask = package::evaluate(&parents, package::Kind::Mask, &path)?;
|
||||
let package_provided = package::evaluate(&parents, package::Kind::Provided, &path)?;
|
||||
|
||||
let package_use = package_use::evaluate(&parents, package_use::Kind::Use, &path)?;
|
||||
let package_use_force = package_use::evaluate(&parents, package_use::Kind::Force, &path)?;
|
||||
let package_use_mask = package_use::evaluate(&parents, package_use::Kind::Mask, &path)?;
|
||||
let package_use_stable_force =
|
||||
package_use::evaluate(&parents, package_use::Kind::StableForce, &path)?;
|
||||
let package_use_stable_mask =
|
||||
package_use::evaluate(&parents, package_use::Kind::StableMask, &path)?;
|
||||
|
||||
let use_force = useflags::evaluate(&parents, useflags::Kind::Force, &path)?;
|
||||
let use_mask = useflags::evaluate(&parents, useflags::Kind::Mask, &path)?;
|
||||
let use_stable_force = useflags::evaluate(&parents, useflags::Kind::StableForce, &path)?;
|
||||
let use_stable_mask = useflags::evaluate(&parents, useflags::Kind::StableMask, &path)?;
|
||||
|
||||
Ok(Self {
|
||||
path: path.as_ref().to_path_buf(),
|
||||
parents,
|
||||
make_defaults,
|
||||
packages,
|
||||
package_mask,
|
||||
package_provided,
|
||||
package_use,
|
||||
package_use_force,
|
||||
package_use_mask,
|
||||
package_use_stable_force,
|
||||
package_use_stable_mask,
|
||||
use_force,
|
||||
use_mask,
|
||||
use_stable_force,
|
||||
use_stable_mask,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn read_config_files<P: AsRef<Path>>(path: P) -> Result<String, io::Error> {
|
||||
let metadata = fs::metadata(&path)?;
|
||||
|
||||
if metadata.is_file() {
|
||||
fs::read_to_string(&path)
|
||||
} else if metadata.is_dir() {
|
||||
let mut buffer = String::new();
|
||||
let paths = fs::read_dir(&path)?
|
||||
.collect::<Result<Vec<_>, _>>()?
|
||||
.into_iter()
|
||||
.map(|entry| entry.path())
|
||||
.filter(|path| path.starts_with("."))
|
||||
.sorted()
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
for path in &paths {
|
||||
let mut file = File::open(path)?;
|
||||
|
||||
file.read_to_string(&mut buffer)?;
|
||||
}
|
||||
|
||||
Ok(buffer)
|
||||
} else {
|
||||
let path = fs::canonicalize(&path)?;
|
||||
|
||||
read_config_files(path)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user