pub struct Options<'a> {
    pub max_depth: u8,
    pub err_on_max_depth_exceeded: bool,
    pub err_on_interpolation_failure: bool,
    pub err_on_missing_config_path: bool,
    pub interpolate: Context<'a>,
    pub conditional: Context<'a>,
}
Expand description

Options to handle includes, like include.path or includeIf.<condition>.path,

Fields§

§max_depth: u8

The maximum allowed length of the file include chain built by following nested resolve_includes where base level is depth = 0.

§err_on_max_depth_exceeded: bool

When max depth is exceeded while following nested includes, return an error if true or silently stop following resolve_includes.

Setting this value to false allows to read configuration with cycles, which otherwise always results in an error.

§err_on_interpolation_failure: bool

If true, default false, failing to interpolate paths will result in an error.

Interpolation also happens if paths in conditional includes can’t be interpolated.

§err_on_missing_config_path: bool

If true, default true, configuration not originating from a path will cause errors when trying to resolve relative include paths (which would require the including configuration’s path).

§interpolate: Context<'a>

Used during path interpolation, both for include paths before trying to read the file, and for paths used in conditional gitdir includes.

§conditional: Context<'a>

Additional context for conditional includes to work.

Implementations§

Provide options to never follow include directives at all.

Examples found in repository?
src/file/includes/types.rs (line 113)
112
113
114
    fn default() -> Self {
        Self::no_follow()
    }
More examples
Hide additional examples
src/file/includes/mod.rs (line 110)
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
fn append_followed_includes_recursively(
    section_ids_and_include_paths: Vec<(SectionId, crate::Path<'_>)>,
    target_config: &mut File<'static>,
    depth: u8,
    options: init::Options<'_>,
    buf: &mut Vec<u8>,
) -> Result<(), Error> {
    for (section_id, config_path) in section_ids_and_include_paths {
        let meta = OwnShared::clone(&target_config.sections[&section_id].meta);
        let target_config_path = meta.path.as_deref();
        let config_path = match resolve_path(config_path, target_config_path, options.includes)? {
            Some(p) => p,
            None => continue,
        };
        if !config_path.is_file() {
            continue;
        }

        buf.clear();
        std::io::copy(&mut std::fs::File::open(&config_path)?, buf)?;
        let config_meta = Metadata {
            path: Some(config_path),
            trust: meta.trust,
            level: meta.level + 1,
            source: meta.source,
        };
        let no_follow_options = init::Options {
            includes: includes::Options::no_follow(),
            ..options
        };

        let mut include_config =
            File::from_bytes_owned(buf, config_meta, no_follow_options).map_err(|err| match err {
                init::Error::Parse(err) => Error::Parse(err),
                init::Error::Interpolate(err) => Error::Interpolate(err),
                init::Error::Includes(_) => unreachable!("BUG: {:?} not possible due to no-follow options", err),
            })?;
        resolve_includes_recursive(&mut include_config, depth + 1, buf, options)?;

        target_config.append_or_insert(include_config, Some(section_id));
    }
    Ok(())
}

Provide options to follow includes like git does, provided the required conditional and interpolate contexts to support gitdir and onbranch based includeIf directives as well as standard include.path resolution. Note that the follow-mode is git-style, following at most 10 indirections while producing an error if the depth is exceeded.

Examples found in repository?
src/file/init/comfort.rs (lines 115-124)
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
    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 worktree = match local.boolean("extensions", None, "worktreeConfig") {
            Some(Ok(worktree_config)) => worktree_config.then(|| {
                let source = Source::Worktree;
                let path = git_dir.join(
                    source
                        .storage_location(&mut |n| std::env::var_os(n))
                        .expect("location available for worktree"),
                );
                Self::from_path_no_includes(path, source)
            }),
            _ => None,
        }
        .transpose()?;

        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);
        if let Some(mut worktree) = worktree {
            worktree.resolve_includes(options)?;
            globals.append(worktree);
        }
        globals.append(Self::from_environment_overrides()?);

        Ok(globals)
    }

For use with follow type options, cause failure if an include path couldn’t be interpolated or the depth limit is exceeded.

Like follow, but without information to resolve includeIf directories as well as default configuration to allow resolving ~username/ path. home_dir is required to resolve ~/ paths if set. Note that %(prefix) paths cannot be interpolated with this configuration, use follow() instead for complete control.

Examples found in repository?
src/file/init/comfort.rs (line 48)
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
    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)
    }

Set the context used for interpolation when interpolating paths to include as well as the paths in gitdir conditional includes.

Trait Implementations§

Returns a copy of the value. Read more
Performs copy-assignment from source. Read more
Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

The resulting type after obtaining ownership.
Creates owned data from borrowed data, usually by cloning. Read more
Uses borrowed data to replace owned data, usually by cloning. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.