/src/gitoxide/gix-pathspec/src/defaults.rs
Line | Count | Source |
1 | | use std::ffi::OsString; |
2 | | |
3 | | use crate::{Defaults, MagicSignature, SearchMode}; |
4 | | |
5 | | /// |
6 | | pub mod from_environment { |
7 | | /// The error returned by [Defaults::from_environment()](super::Defaults::from_environment()). |
8 | | #[derive(Debug, thiserror::Error)] |
9 | | #[allow(missing_docs)] |
10 | | pub enum Error { |
11 | | #[error(transparent)] |
12 | | ParseValue(#[from] gix_config_value::Error), |
13 | | #[error("Glob and no-glob settings are mutually exclusive")] |
14 | | MixedGlobAndNoGlob, |
15 | | } |
16 | | } |
17 | | |
18 | | impl Defaults { |
19 | | /// Initialize this instance using information from the environment as |
20 | | /// [per the official documentation](https://git-scm.com/book/en/v2/Git-Internals-Environment-Variables) *(look for `PATHSPECS`)*, |
21 | | /// calling `var(variable_name)` for each variable that should be obtained. |
22 | | /// |
23 | | /// Used environment variables are `GIT_GLOB_PATHSPECS`, `GIT_NOGLOB_PATHSPECS`, `GIT_LITERAL_PATHSPECS` and `GIT_ICASE_PATHSPECS`. |
24 | | /// Note that there are lot of failure modes, and instead of offering lenient parsing, the caller may ignore errors and |
25 | | /// use other defaults instead. |
26 | | /// |
27 | | /// ### Deviation |
28 | | /// |
29 | | /// Instead of failing if `GIT_LITERAL_PATHSPECS` is used with glob globals, we ignore these. Also our implementation allows global |
30 | | /// `icase` settings in combination with this setting. |
31 | 0 | pub fn from_environment(var: &mut dyn FnMut(&str) -> Option<OsString>) -> Result<Self, from_environment::Error> { |
32 | 0 | let mut env_bool = |name: &str| -> Result<Option<bool>, gix_config_value::Error> { |
33 | 0 | var(name) |
34 | 0 | .map(|val| gix_config_value::Boolean::try_from(val).map(|b| b.0)) |
35 | 0 | .transpose() |
36 | 0 | }; |
37 | | |
38 | 0 | let literal = env_bool("GIT_LITERAL_PATHSPECS")?.unwrap_or_default(); |
39 | 0 | let signature = env_bool("GIT_ICASE_PATHSPECS")? |
40 | 0 | .and_then(|val| val.then_some(MagicSignature::ICASE)) |
41 | 0 | .unwrap_or_default(); |
42 | 0 | if literal { |
43 | 0 | return Ok(Defaults { |
44 | 0 | signature, |
45 | 0 | search_mode: SearchMode::Literal, |
46 | 0 | literal, |
47 | 0 | }); |
48 | 0 | } |
49 | 0 | let glob = env_bool("GIT_GLOB_PATHSPECS")?; |
50 | 0 | let mut search_mode = glob |
51 | 0 | .and_then(|glob| glob.then_some(SearchMode::PathAwareGlob)) |
52 | 0 | .unwrap_or_default(); |
53 | 0 | search_mode = env_bool("GIT_NOGLOB_PATHSPECS")? |
54 | 0 | .map(|no_glob| { |
55 | 0 | if glob.unwrap_or_default() && no_glob { |
56 | 0 | Err(from_environment::Error::MixedGlobAndNoGlob) |
57 | | } else { |
58 | 0 | Ok(SearchMode::Literal) |
59 | | } |
60 | 0 | }) |
61 | 0 | .transpose()? |
62 | 0 | .unwrap_or(search_mode); |
63 | | |
64 | 0 | Ok(Defaults { |
65 | 0 | signature, |
66 | 0 | search_mode, |
67 | 0 | literal, |
68 | 0 | }) |
69 | 0 | } |
70 | | } |