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