11#![ allow( clippy:: result_large_err) ]
2+ use gix_attributes:: Source ;
3+ use gix_glob:: pattern:: Case ;
24use std:: { borrow:: Cow , path:: PathBuf , time:: Duration } ;
35
46use gix_lock:: acquire:: Fail ;
@@ -154,33 +156,30 @@ impl Cache {
154156 . unwrap_or ( default) )
155157 }
156158
157- fn assemble_attribute_globals (
158- me : & Cache ,
159- _git_dir : & std:: path:: Path ,
160- ) -> Result < gix_attributes:: Search , checkout_options:: Error > {
161- let _attributes_file = match me
162- . trusted_file_path ( "core" , None , Core :: ATTRIBUTES_FILE . name )
163- . transpose ( ) ?
164- {
165- Some ( attributes) => Some ( attributes. into_owned ( ) ) ,
166- None => me. xdg_config_path ( "attributes" ) . ok ( ) . flatten ( ) ,
167- } ;
168- // TODO: implement gix_attributes::Search::from_git_dir(), similar to what's done for `Ignore`.
169- Ok ( Default :: default ( ) )
170- }
171-
172159 let thread_limit = self . apply_leniency (
173160 self . resolved
174161 . integer_filter_by_key ( "checkout.workers" , & mut self . filter_config_section . clone ( ) )
175162 . map ( |value| Checkout :: WORKERS . try_from_workers ( value) ) ,
176163 ) ?;
164+ let capabilities = gix_worktree:: fs:: Capabilities {
165+ precompose_unicode : boolean ( self , "core.precomposeUnicode" , & Core :: PRECOMPOSE_UNICODE , false ) ?,
166+ ignore_case : boolean ( self , "core.ignoreCase" , & Core :: IGNORE_CASE , false ) ?,
167+ executable_bit : boolean ( self , "core.fileMode" , & Core :: FILE_MODE , true ) ?,
168+ symlink : boolean ( self , "core.symlinks" , & Core :: SYMLINKS , true ) ?,
169+ } ;
170+ let case = if capabilities. ignore_case {
171+ Case :: Fold
172+ } else {
173+ Case :: Sensitive
174+ } ;
177175 Ok ( gix_worktree:: index:: checkout:: Options {
178- fs : gix_worktree:: fs:: Capabilities {
179- precompose_unicode : boolean ( self , "core.precomposeUnicode" , & Core :: PRECOMPOSE_UNICODE , false ) ?,
180- ignore_case : boolean ( self , "core.ignoreCase" , & Core :: IGNORE_CASE , false ) ?,
181- executable_bit : boolean ( self , "core.fileMode" , & Core :: FILE_MODE , true ) ?,
182- symlink : boolean ( self , "core.symlinks" , & Core :: SYMLINKS , true ) ?,
183- } ,
176+ attributes : self . assemble_attribute_globals (
177+ git_dir,
178+ case,
179+ gix_worktree:: fs:: cache:: state:: attributes:: Source :: AttributeListThenWorktree ,
180+ self . attributes ,
181+ ) ?,
182+ fs : capabilities,
184183 thread_limit,
185184 destination_is_initially_empty : false ,
186185 overwrite_existing : false ,
@@ -193,23 +192,64 @@ impl Cache {
193192 . map ( |v| Core :: CHECK_STAT . try_into_checkstat ( v) ) ,
194193 ) ?
195194 . unwrap_or ( true ) ,
196- attribute_globals : assemble_attribute_globals ( self , git_dir) ?,
197195 } )
198196 }
197+
198+ // TODO: at least one test, maybe related to core.attributesFile configuration.
199+ fn assemble_attribute_globals (
200+ & self ,
201+ git_dir : & std:: path:: Path ,
202+ case : gix_glob:: pattern:: Case ,
203+ source : gix_worktree:: fs:: cache:: state:: attributes:: Source ,
204+ attributes : crate :: permissions:: Attributes ,
205+ ) -> Result < gix_worktree:: fs:: cache:: state:: Attributes , config:: attribute_stack:: Error > {
206+ let configured_or_user_attributes = match self
207+ . trusted_file_path ( "core" , None , Core :: ATTRIBUTES_FILE . name )
208+ . transpose ( ) ?
209+ {
210+ Some ( attributes) => Some ( attributes) ,
211+ None => {
212+ if attributes. git {
213+ self . xdg_config_path ( "attributes" ) . ok ( ) . flatten ( ) . map ( Cow :: Owned )
214+ } else {
215+ None
216+ }
217+ }
218+ } ;
219+ let attribute_files = [ gix_attributes:: Source :: GitInstallation , gix_attributes:: Source :: System ]
220+ . into_iter ( )
221+ . filter ( |source| match source {
222+ Source :: GitInstallation => attributes. git_binary ,
223+ Source :: System => attributes. system ,
224+ Source :: Git | Source :: Local => unreachable ! ( "we don't offer turning this off right now" ) ,
225+ } )
226+ . filter_map ( |source| source. storage_location ( & mut Self :: make_source_env ( self . environment ) ) )
227+ . chain ( configured_or_user_attributes) ;
228+ let info_attributes_path = git_dir. join ( "info" ) . join ( "attributes" ) ;
229+ let mut buf = Vec :: new ( ) ;
230+ Ok ( gix_worktree:: fs:: cache:: state:: Attributes :: new (
231+ gix_attributes:: Search :: new_globals ( attribute_files, & mut buf) ?,
232+ Default :: default ( ) ,
233+ Some ( info_attributes_path) ,
234+ case,
235+ source,
236+ ) )
237+ }
238+
199239 pub ( crate ) fn xdg_config_path (
200240 & self ,
201241 resource_file_name : & str ,
202242 ) -> Result < Option < PathBuf > , gix_sec:: permission:: Error < PathBuf > > {
203243 std:: env:: var_os ( "XDG_CONFIG_HOME" )
204- . map ( |path| ( PathBuf :: from ( path) , & self . xdg_config_home_env ) )
244+ . map ( |path| ( PathBuf :: from ( path) , & self . environment . xdg_config_home ) )
205245 . or_else ( || {
206246 gix_path:: env:: home_dir ( ) . map ( |mut p| {
207247 (
208248 {
209249 p. push ( ".config" ) ;
210250 p
211251 } ,
212- & self . home_env ,
252+ & self . environment . home ,
213253 )
214254 } )
215255 } )
@@ -225,6 +265,6 @@ impl Cache {
225265 /// We never fail for here even if the permission is set to deny as we `gix-config` will fail later
226266 /// if it actually wants to use the home directory - we don't want to fail prematurely.
227267 pub ( crate ) fn home_dir ( & self ) -> Option < PathBuf > {
228- gix_path:: env:: home_dir ( ) . and_then ( |path| self . home_env . check_opt ( path) )
268+ gix_path:: env:: home_dir ( ) . and_then ( |path| self . environment . home . check_opt ( path) )
229269 }
230270}
0 commit comments