Sebastian Thielmake fmt47724c04 years agoHistory
147 lines · 4.3 KB · Rust
RawDownload
use std::{fs, path::Path, str::FromStr}; use git_config::{    file::{includes, init},    path, File,};use tempfile::tempdir; use crate::file::{cow_str, init::from_paths::escape_backslashes}; mod gitdir;mod onbranch; #[test]fn include_and_includeif_correct_inclusion_order_and_delayed_resolve_include() -> crate::Result {    let dir = tempdir()?;    let config_path = dir.path().join("root");    let first_include_path = dir.path().join("first-incl");    let second_include_path = dir.path().join("second-incl");    let include_if_path = dir.path().join("incl-if");    fs::write(        first_include_path.as_path(),        "; first include beginning[section]  value = first-incl-path# first include end no nl",    )?;     fs::write(        second_include_path.as_path(),        "; second include beginning[section]  value = second-incl-path ; post value comment# second include end",    )?;     fs::write(        include_if_path.as_path(),        "# includeIf beginning[section]  value = incl-if-path; include if end no nl",    )?;     let root_config = format!(        r#" ; root beginning# root pre base[section]    value = base # base comment; root post base    [include]  path = {}  path = {} ; paths are multi-values# root past first include[section]  value = base-past-first-include# root before include-if no-nl[includeIf "gitdir:root/"]  path = {}[section]  value = base-past-includeIf[include]  path = {}# root past last include[section]  value = base-past-second-include ; root last include"#,        escape_backslashes(&first_include_path),        escape_backslashes(&first_include_path),        escape_backslashes(&include_if_path),        escape_backslashes(&second_include_path),    );    fs::write(config_path.as_path(), &root_config)?;     let dir = config_path.join(".git");    for delayed_resolve in [false, true] {        let meta = git_config::file::Metadata::try_from_path(&config_path, git_config::Source::Api)?;        let options = options_with_git_dir(&dir);        let config = if delayed_resolve {            let mut config = File::from_bytes_owned(&mut root_config.as_bytes().into(), meta, Default::default())?;            config.resolve_includes(options)?;            config        } else {            File::from_paths_metadata(Some(meta), options)?.expect("non-empty")        };         assert_eq!(            config.strings("section", None, "value"),            Some(vec![                cow_str("base"),                cow_str("first-incl-path"),                cow_str("first-incl-path"),                cow_str("base-past-first-include"),                cow_str("incl-if-path"),                cow_str("base-past-includeIf"),                cow_str("second-incl-path"),                cow_str("base-past-second-include"),            ]),            "include order isn't changed also in relation to the root configuratino, delayed_resolve = {}",            delayed_resolve,        );        assert_eq!(config.sections().count(), 11);         let config_string = config.to_string();        let deserialized = File::from_str(&config_string)?;        assert_eq!(config, config, "equality comparisons work");        assert_eq!(            deserialized.sections().count(),            config.sections().count(),            "sections must match to have a chance for equality"        );        assert_eq!(config, deserialized, "we can round-trip the information at least");        assert_eq!(            deserialized.to_string(),            config_string,            "serialization works exactly as before"        );    }    Ok(())} fn options_with_git_dir(git_dir: &Path) -> init::Options<'_> {    init::Options {        includes: includes::Options::follow(            path::interpolate::Context {                home_dir: Some(git_dir.parent().unwrap()),                ..Default::default()            },            includes::conditional::Context {                git_dir: Some(git_dir),                ..Default::default()            },        ),        ..Default::default()    }} fn create_symlink(from: impl AsRef<Path>, to: impl AsRef<Path>) {    std::fs::create_dir_all(from.as_ref().parent().unwrap()).unwrap();    #[cfg(not(windows))]    std::os::unix::fs::symlink(to, from).unwrap();    #[cfg(windows)]    std::os::windows::fs::symlink_file(to, from).unwrap();}