Skip to content

Commit eca3658

Browse files
committed
feat: open::Options::modify() as general pattern to allow builder methods usage in &mut self.
That way it's easier to configure both the `full` and the `partial` trust instances of discovery options.
1 parent 279ba7c commit eca3658

File tree

3 files changed

+88
-67
lines changed

3 files changed

+88
-67
lines changed

git-repository/src/config/cache/init.rs

Lines changed: 74 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -55,73 +55,82 @@ impl Cache {
5555
..util::base_options(lossy)
5656
};
5757

58-
let config = {
59-
let home_env = &home_env;
60-
let xdg_config_home_env = &xdg_config_home_env;
61-
let git_prefix = &git_prefix;
62-
let metas = [
63-
git_config::source::Kind::GitInstallation,
64-
git_config::source::Kind::System,
65-
git_config::source::Kind::Global,
66-
]
67-
.iter()
68-
.flat_map(|kind| kind.sources())
69-
.filter_map(|source| {
70-
match source {
71-
git_config::Source::GitInstallation if !use_installation => return None,
72-
git_config::Source::System if !use_system => return None,
73-
git_config::Source::Git if !use_git => return None,
74-
git_config::Source::User if !use_user => return None,
75-
_ => {}
76-
}
77-
source
78-
.storage_location(&mut |name| {
79-
match name {
80-
git_ if git_.starts_with("GIT_") => Some(git_prefix),
81-
"XDG_CONFIG_HOME" => Some(xdg_config_home_env),
82-
"HOME" => Some(home_env),
83-
_ => None,
84-
}
85-
.and_then(|perm| std::env::var_os(name).and_then(|val| perm.check_opt(val)))
86-
})
87-
.map(|p| (source, p.into_owned()))
88-
})
89-
.map(|(source, path)| git_config::file::Metadata {
90-
path: Some(path),
91-
source: *source,
92-
level: 0,
93-
trust: git_sec::Trust::Full,
94-
});
58+
let config =
59+
{
60+
let home_env = &home_env;
61+
let xdg_config_home_env = &xdg_config_home_env;
62+
let git_prefix = &git_prefix;
63+
let metas = [
64+
git_config::source::Kind::GitInstallation,
65+
git_config::source::Kind::System,
66+
git_config::source::Kind::Global,
67+
]
68+
.iter()
69+
.flat_map(|kind| kind.sources())
70+
.filter_map(|source| {
71+
match source {
72+
git_config::Source::GitInstallation if !use_installation => return None,
73+
git_config::Source::System if !use_system => return None,
74+
git_config::Source::Git if !use_git => return None,
75+
git_config::Source::User if !use_user => return None,
76+
_ => {}
77+
}
78+
source
79+
.storage_location(&mut |name| {
80+
match name {
81+
git_ if git_.starts_with("GIT_") => Some(git_prefix),
82+
"XDG_CONFIG_HOME" => Some(xdg_config_home_env),
83+
"HOME" => Some(home_env),
84+
_ => None,
85+
}
86+
.and_then(|perm| std::env::var_os(name).and_then(|val| perm.check_opt(val)))
87+
})
88+
.map(|p| (source, p.into_owned()))
89+
})
90+
.map(|(source, path)| git_config::file::Metadata {
91+
path: Some(path),
92+
source: *source,
93+
level: 0,
94+
trust: git_sec::Trust::Full,
95+
});
9596

96-
let err_on_nonexisting_paths = false;
97-
let mut globals = git_config::File::from_paths_metadata_buf(
98-
metas,
99-
&mut buf,
100-
err_on_nonexisting_paths,
101-
git_config::file::init::Options {
102-
includes: git_config::file::includes::Options::no_follow(),
103-
..options
104-
},
105-
)
106-
.map_err(|err| match err {
107-
git_config::file::init::from_paths::Error::Init(err) => Error::from(err),
108-
git_config::file::init::from_paths::Error::Io(err) => err.into(),
109-
})?
110-
.unwrap_or_default();
97+
let err_on_nonexisting_paths = false;
98+
let mut globals = git_config::File::from_paths_metadata_buf(
99+
metas,
100+
&mut buf,
101+
err_on_nonexisting_paths,
102+
git_config::file::init::Options {
103+
includes: git_config::file::includes::Options::no_follow(),
104+
..options
105+
},
106+
)
107+
.map_err(|err| match err {
108+
git_config::file::init::from_paths::Error::Init(err) => Error::from(err),
109+
git_config::file::init::from_paths::Error::Io(err) => err.into(),
110+
})?
111+
.unwrap_or_default();
111112

112-
globals.append(git_dir_config);
113-
globals.resolve_includes(options)?;
114-
if use_env {
115-
globals.append(git_config::File::from_env(options)?.unwrap_or_default());
116-
}
117-
if !cli_config_overrides.is_empty() {
118-
crate::config::overrides::append(&mut globals, cli_config_overrides, git_config::Source::Cli)?;
119-
}
120-
if !api_config_overrides.is_empty() {
121-
crate::config::overrides::append(&mut globals, api_config_overrides, git_config::Source::Api)?;
122-
}
123-
globals
124-
};
113+
globals.append(git_dir_config);
114+
globals.resolve_includes(options)?;
115+
if use_env {
116+
globals.append(git_config::File::from_env(options)?.unwrap_or_default());
117+
}
118+
if !cli_config_overrides.is_empty() {
119+
crate::config::overrides::append(&mut globals, cli_config_overrides, git_config::Source::Cli)
120+
.map_err(|err| Error::ConfigOverrides {
121+
err,
122+
source: git_config::Source::Cli,
123+
})?;
124+
}
125+
if !api_config_overrides.is_empty() {
126+
crate::config::overrides::append(&mut globals, api_config_overrides, git_config::Source::Api)
127+
.map_err(|err| Error::ConfigOverrides {
128+
err,
129+
source: git_config::Source::Api,
130+
})?;
131+
}
132+
globals
133+
};
125134

126135
let hex_len = util::parse_core_abbrev(&config, object_hash).with_leniency(lenient_config)?;
127136

git-repository/src/config/mod.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,12 @@ pub enum Error {
6767
DecodeBoolean { key: String, value: BString },
6868
#[error(transparent)]
6969
PathInterpolation(#[from] git_config::path::interpolate::Error),
70-
#[error("Configuration overrides at open or init time could not be applied.")]
71-
ConfigOverrides(#[from] overrides::Error),
70+
#[error("{source:?} configuration overrides at open or init time could not be applied.")]
71+
ConfigOverrides {
72+
#[source]
73+
err: overrides::Error,
74+
source: git_config::Source,
75+
},
7276
#[error("Invalid value for 'core.logAllRefUpdates': \"{value}\"")]
7377
LogAllRefUpdates { value: BString },
7478
}

git-repository/src/open.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,14 @@ impl Options {
134134
}
135135
}
136136

137+
/// Generic modification
138+
impl Options {
139+
/// An adapter to allow calling any builder method on this instance despite only having a mutable reference.
140+
pub fn modify(&mut self, f: impl FnOnce(Self) -> Self) {
141+
*self = f(std::mem::take(self));
142+
}
143+
}
144+
137145
/// Builder methods
138146
impl Options {
139147
/// Apply the given configuration `values` like `init.defaultBranch=special` or `core.bool-implicit-true` in memory to as early

0 commit comments

Comments
 (0)