Sebastian Thielmake fmt47724c04 years agoHistory
138 lines · 5.2 KB · Rust
RawDownload
use std::path::PathBuf; use crate::{    file::{init, Metadata},    path, source, File, Source,}; /// Easy-instantiation of typical non-repository git configuration files with all configuration defaulting to typical values.////// ### Limitations////// Note that `includeIf` conditions in global files will cause failure as the required information/// to resolve them isn't present without a repository.////// Also note that relevant information to interpolate paths will be obtained from the environment or other/// source on unix.impl File<'static> {    /// Open all global configuration files which involves the following sources:    ///    /// * [system][crate::Source::System]    /// * [git][crate::Source::Git]    /// * [user][crate::Source::User]    ///    /// which excludes repository local configuration, as well as override-configuration from environment variables.    ///    /// Note that the file might [be empty][File::is_void()] in case no configuration file was found.    pub fn from_globals() -> Result<File<'static>, init::from_paths::Error> {        let metas = [source::Kind::System, source::Kind::Global]            .iter()            .flat_map(|kind| kind.sources())            .filter_map(|source| {                let path = source                    .storage_location(&mut |name| std::env::var_os(name))                    .and_then(|p| p.is_file().then(|| p))                    .map(|p| p.into_owned());                 Metadata {                    path,                    source: *source,                    level: 0,                    trust: git_sec::Trust::Full,                }                .into()            });         let home = std::env::var("HOME").ok().map(PathBuf::from);        let options = init::Options {            includes: init::includes::Options::follow_without_conditional(home.as_deref()),            ..Default::default()        };        File::from_paths_metadata(metas, options).map(Option::unwrap_or_default)    }     /// Generates a config from `GIT_CONFIG_*` environment variables and return a possibly empty `File`.    /// A typical use of this is to [`append`][File::append()] this configuration to another one with lower    /// precedence to obtain overrides.    ///    /// See [`git-config`'s documentation] for more information on the environment variables in question.    ///    /// [`git-config`'s documentation]: https://git-scm.com/docs/git-config#Documentation/git-config.txt-GITCONFIGCOUNT    pub fn from_environment_overrides() -> Result<File<'static>, init::from_env::Error> {        let home = std::env::var("HOME").ok().map(PathBuf::from);        let options = init::Options {            includes: init::includes::Options::follow_without_conditional(home.as_deref()),            ..Default::default()        };         File::from_env(options).map(Option::unwrap_or_default)    }} /// An easy way to provide complete configuration for a repository.impl File<'static> {    /// This configuration type includes the following sources, in order of precedence:    ///    /// - globals    /// - repository-local by loading `dir`/config    /// - environment    ///    /// Note that `dir` is the `.git` dir to load the configuration from, not the configuration file.    ///    /// Includes will be resolved within limits as some information like the git installation directory is missing to interpolate    /// paths with as well as git repository information like the branch name.    pub fn from_git_dir(dir: impl Into<std::path::PathBuf>) -> Result<File<'static>, from_git_dir::Error> {        let (mut local, git_dir) = {            let source = Source::Local;            let mut path = dir.into();            path.push(                source                    .storage_location(&mut |n| std::env::var_os(n))                    .expect("location available for local"),            );            let local = Self::from_path_no_includes(&path, source)?;            path.pop();            (local, path)        };         let home = std::env::var("HOME").ok().map(PathBuf::from);        let options = init::Options {            includes: init::includes::Options::follow(                path::interpolate::Context {                    home_dir: home.as_deref(),                    ..Default::default()                },                init::includes::conditional::Context {                    git_dir: Some(git_dir.as_ref()),                    branch_name: None,                },            ),            lossy: false,        };         let mut globals = Self::from_globals()?;        globals.resolve_includes(options)?;        local.resolve_includes(options)?;         globals.append(local).append(Self::from_environment_overrides()?);        Ok(globals)    }} ///pub mod from_git_dir {    use crate::file::init;     /// The error returned by [`File::from_git_dir()`][crate::File::from_git_dir()].    #[derive(Debug, thiserror::Error)]    pub enum Error {        #[error(transparent)]        FromPaths(#[from] init::from_paths::Error),        #[error(transparent)]        FromEnv(#[from] init::from_env::Error),        #[error(transparent)]        Init(#[from] init::Error),        #[error(transparent)]        Includes(#[from] init::includes::Error),    }}