use std::path::{Path, PathBuf};
use super::database_path::resolve_with_home;
use super::Config;
pub(crate) fn anchor_relative_paths(config: &mut Config, config_dir: &Path, home: Option<&Path>) {
let anchor = |p: &mut PathBuf| {
if let Some(resolved) = resolve_with_home(Some(p), Some(config_dir), home) {
*p = resolved;
}
};
if let Some(c) = config.classification.as_mut() {
c.rules_files.iter_mut().for_each(anchor);
}
if let Some(dir) = config.output.as_mut().and_then(|o| o.directory.as_mut()) {
anchor(dir);
}
if let Some(dir) = config.cache.as_mut().and_then(|c| c.directory.as_mut()) {
anchor(dir);
}
if let Some(dir) = config.dora.as_mut().and_then(|d| d.datadog_dir.as_mut()) {
anchor(dir);
}
}
#[cfg(test)]
mod tests {
use super::*;
fn parse(yaml: &str) -> Config {
serde_yaml::from_str(yaml).expect("parse config")
}
#[test]
fn relative_paths_anchor_to_the_config_dir() {
let mut cfg = parse(
"classification:\n rules_files: [rules.yaml, /etc/r.yaml, \"~/r.yaml\"]\n\
output:\n directory: out\ncache:\n directory: .cache\n\
dora:\n datadog_dir: incidents\n",
);
anchor_relative_paths(&mut cfg, Path::new("/cfg"), Some(Path::new("/home/u")));
let rules = &cfg.classification.as_ref().expect("section").rules_files;
assert_eq!(
rules,
&[
PathBuf::from("/cfg/rules.yaml"),
PathBuf::from("/etc/r.yaml"),
PathBuf::from("/home/u/r.yaml"),
]
);
let out = cfg.output.and_then(|o| o.directory);
assert_eq!(out, Some(PathBuf::from("/cfg/out")));
let cache = cfg.cache.and_then(|c| c.directory);
assert_eq!(cache, Some(PathBuf::from("/cfg/.cache")));
let dd = cfg.dora.and_then(|d| d.datadog_dir);
assert_eq!(dd, Some(PathBuf::from("/cfg/incidents")));
}
#[test]
fn repository_paths_stay_as_written() {
let mut cfg =
parse("repositories:\n - path: .\n - path: .\n name: \"\"\n - path: repos/a\n");
anchor_relative_paths(&mut cfg, Path::new("/cfg"), None);
let paths: Vec<&Path> = cfg.repositories.iter().map(|r| r.path.as_path()).collect();
assert_eq!(
paths,
vec![Path::new("."), Path::new("."), Path::new("repos/a")]
);
let names: Vec<Option<&str>> = cfg.repositories.iter().map(|r| r.name.as_deref()).collect();
assert_eq!(names, vec![None, Some(""), None]);
let stored: Vec<String> = cfg
.repositories
.iter()
.map(|r| crate::report::repo_name(r.name.as_deref(), &r.path))
.collect();
assert_eq!(stored, vec![".", ".", "a"]);
}
#[test]
fn path_dot_resolves_the_github_slug_as_before() {
let dir = tempfile::tempdir().expect("tempdir");
let repo = git2::Repository::init(dir.path()).expect("git init");
repo.remote("origin", "https://github.com/acme/widget.git")
.expect("remote");
let cfg_path = dir.path().join("config.yaml");
std::fs::write(
&cfg_path,
"repositories:\n - path: .\ngithub:\n org: acme\n",
)
.expect("write config");
let cfg = Config::load(&cfg_path).expect("load");
let r = &cfg.repositories[0];
assert_eq!(
(r.path.as_path(), r.name.as_deref()),
(Path::new("."), None)
);
let github = cfg.github.as_ref().expect("github section");
let from_cwd =
crate::collect::github::repo_resolver::owner_repo_from_remote(Path::new("."));
assert_eq!(
crate::collect::github::resolve_github_repos(github, &cfg.repositories),
from_cwd.into_iter().collect::<Vec<_>>()
);
}
}