gix_config/file/init/
comfort.rs1use std::borrow::Cow;
2
3use crate::{
4 file::{init, Metadata},
5 path, source, File, Source,
6};
7
8impl File<'static> {
18 pub fn from_globals() -> Result<File<'static>, init::from_paths::Error> {
28 let metas = [
29 source::Kind::GitInstallation,
30 source::Kind::System,
31 source::Kind::Global,
32 ]
33 .iter()
34 .flat_map(|kind| kind.sources())
35 .filter_map(|source| {
36 let path = source
37 .storage_location(&mut gix_path::env::var)
38 .and_then(|p| p.is_file().then_some(p))
39 .map(Cow::into_owned);
40
41 Metadata {
42 path,
43 source: *source,
44 level: 0,
45 trust: gix_sec::Trust::Full,
46 }
47 .into()
48 });
49
50 let home = gix_path::env::home_dir();
51 let options = init::Options {
52 includes: init::includes::Options::follow_without_conditional(home.as_deref()),
53 ..Default::default()
54 };
55 File::from_paths_metadata(metas, options).map(Option::unwrap_or_default)
56 }
57
58 pub fn from_environment_overrides() -> Result<File<'static>, init::from_env::Error> {
66 let home = gix_path::env::home_dir();
67 let options = init::Options {
68 includes: init::includes::Options::follow_without_conditional(home.as_deref()),
69 ..Default::default()
70 };
71
72 File::from_env(options).map(Option::unwrap_or_default)
73 }
74}
75
76impl File<'static> {
78 pub fn from_git_dir(dir: std::path::PathBuf) -> Result<File<'static>, from_git_dir::Error> {
90 let (mut local, git_dir) = {
91 let source = Source::Local;
92 let mut path = dir;
93 path.push(
94 source
95 .storage_location(&mut gix_path::env::var)
96 .expect("location available for local"),
97 );
98 let local = Self::from_path_no_includes(path.clone(), source)?;
99 path.pop();
100 (local, path)
101 };
102
103 let worktree = match local.boolean("extensions.worktreeConfig") {
104 Some(Ok(worktree_config)) => worktree_config.then(|| {
105 let source = Source::Worktree;
106 let path = git_dir.join(
107 source
108 .storage_location(&mut gix_path::env::var)
109 .expect("location available for worktree"),
110 );
111 Self::from_path_no_includes(path, source)
112 }),
113 _ => None,
114 }
115 .transpose()?;
116
117 let home = gix_path::env::home_dir();
118 let options = init::Options {
119 includes: init::includes::Options::follow(
120 path::interpolate::Context {
121 home_dir: home.as_deref(),
122 ..Default::default()
123 },
124 init::includes::conditional::Context {
125 git_dir: Some(git_dir.as_ref()),
126 branch_name: None,
127 },
128 ),
129 ..Default::default()
130 };
131
132 let mut globals = Self::from_globals()?;
133 globals.resolve_includes(options)?;
134 local.resolve_includes(options)?;
135
136 globals.append(local);
137 if let Some(mut worktree) = worktree {
138 worktree.resolve_includes(options)?;
139 globals.append(worktree);
140 }
141 globals.append(Self::from_environment_overrides()?);
142
143 Ok(globals)
144 }
145}
146
147pub mod from_git_dir {
149 use crate::file::init;
150
151 #[derive(Debug, thiserror::Error)]
153 pub enum Error {
154 #[error(transparent)]
155 FromPaths(#[from] init::from_paths::Error),
156 #[error(transparent)]
157 FromEnv(#[from] init::from_env::Error),
158 #[error(transparent)]
159 Init(#[from] init::Error),
160 #[error(transparent)]
161 Includes(#[from] init::includes::Error),
162 }
163}