summaryrefslogtreecommitdiffstats
path: root/vendor/gix-pathspec/src/defaults.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/gix-pathspec/src/defaults.rs')
-rw-r--r--vendor/gix-pathspec/src/defaults.rs70
1 files changed, 70 insertions, 0 deletions
diff --git a/vendor/gix-pathspec/src/defaults.rs b/vendor/gix-pathspec/src/defaults.rs
new file mode 100644
index 000000000..81be53b38
--- /dev/null
+++ b/vendor/gix-pathspec/src/defaults.rs
@@ -0,0 +1,70 @@
+use std::ffi::OsString;
+
+use crate::{Defaults, MagicSignature, SearchMode};
+
+///
+pub mod from_environment {
+ /// The error returned by [Defaults::from_environment()](super::Defaults::from_environment()).
+ #[derive(Debug, thiserror::Error)]
+ #[allow(missing_docs)]
+ pub enum Error {
+ #[error(transparent)]
+ ParseValue(#[from] gix_config_value::Error),
+ #[error("Glob and no-glob settings are mutually exclusive")]
+ MixedGlobAndNoGlob,
+ }
+}
+
+impl Defaults {
+ /// Initialize this instance using information from the environment as
+ /// [per the official documentation](https://git-scm.com/book/en/v2/Git-Internals-Environment-Variables) *(look for `PATHSPECS`)*,
+ /// calling `var(variable_name)` for each variable that should be obtained.
+ ///
+ /// Used environment variables are `GIT_GLOB_PATHSPECS`, `GIT_NOGLOB_PATHSPECS`, `GIT_LITERAL_PATHSPECS` and `GIT_ICASE_PATHSPECS`.
+ /// Note that there are lot of failure modes, and instead of offering lenient parsing, the caller may ignore errors and
+ /// use other defaults instead.
+ ///
+ /// ### Deviation
+ ///
+ /// Instead of failing if `GIT_LITERAL_PATHSPECS` is used with glob globals, we ignore these. Also our implementation allows global
+ /// `icase` settings in combination with this setting.
+ pub fn from_environment(var: &mut dyn FnMut(&str) -> Option<OsString>) -> Result<Self, from_environment::Error> {
+ let mut env_bool = |name: &str| -> Result<Option<bool>, gix_config_value::Error> {
+ var(name)
+ .map(|val| gix_config_value::Boolean::try_from(val).map(|b| b.0))
+ .transpose()
+ };
+
+ let literal = env_bool("GIT_LITERAL_PATHSPECS")?.unwrap_or_default();
+ let signature = env_bool("GIT_ICASE_PATHSPECS")?
+ .and_then(|val| val.then_some(MagicSignature::ICASE))
+ .unwrap_or_default();
+ if literal {
+ return Ok(Defaults {
+ signature,
+ search_mode: SearchMode::Literal,
+ literal,
+ });
+ }
+ let glob = env_bool("GIT_GLOB_PATHSPECS")?;
+ let mut search_mode = glob
+ .and_then(|glob| glob.then_some(SearchMode::PathAwareGlob))
+ .unwrap_or_default();
+ search_mode = env_bool("GIT_NOGLOB_PATHSPECS")?
+ .map(|no_glob| {
+ if glob.unwrap_or_default() && no_glob {
+ Err(from_environment::Error::MixedGlobAndNoGlob)
+ } else {
+ Ok(SearchMode::Literal)
+ }
+ })
+ .transpose()?
+ .unwrap_or(search_mode);
+
+ Ok(Defaults {
+ signature,
+ search_mode,
+ literal,
+ })
+ }
+}