1+ using  System ; 
2+ using  System . Collections . Generic ; 
3+ using  System . IO ; 
4+ using  System . Text ; 
5+ using  Avalonia . Markup . Xaml . MarkupExtensions ; 
6+ 
7+ namespace  GitCredentialManager . Interop . Linux ; 
8+ 
9+ public  class  LinuxSettings  :  Settings 
10+ { 
11+     private  readonly  ITrace  _trace ; 
12+     private  readonly  IFileSystem  _fs ; 
13+ 
14+     private  IDictionary < string ,  string >  _extConfigCache ; 
15+ 
16+     /// <summary> 
17+     /// Reads settings from Git configuration, environment variables, and defaults from the 
18+     /// /etc/git-credential-manager.d app configuration directory. 
19+     /// </summary> 
20+     public  LinuxSettings ( IEnvironment  environment ,  IGit  git ,  ITrace  trace ,  IFileSystem  fs ) 
21+         :  base ( environment ,  git ) 
22+     { 
23+         EnsureArgument . NotNull ( trace ,  nameof ( trace ) ) ; 
24+         EnsureArgument . NotNull ( fs ,  nameof ( fs ) ) ; 
25+ 
26+         _trace  =  trace ; 
27+         _fs  =  fs ; 
28+ 
29+         PlatformUtils . EnsureLinux ( ) ; 
30+     } 
31+ 
32+     protected  internal  override  bool  TryGetExternalDefault ( string  section ,  string  scope ,  string  property ,  out  string  value ) 
33+     { 
34+         value  =  null ; 
35+ 
36+         _extConfigCache  ??=  ReadExternalConfiguration ( ) ; 
37+ 
38+         string  name  =  string . IsNullOrWhiteSpace ( scope ) 
39+             ?  $ "{ section } .{ property } "
40+             :  $ "{ section } .{ scope } .{ property } "; 
41+ 
42+         // Check if the setting exists in the configuration 
43+         if  ( ! _extConfigCache ? . TryGetValue ( name ,  out  value )  ??  false ) 
44+         { 
45+             // No property exists (or failed to read config) 
46+             return  false ; 
47+         } 
48+ 
49+         _trace . WriteLine ( $ "Default setting found in app configuration directory: { name } ={ value } ") ; 
50+         return  true ; 
51+     } 
52+ 
53+     private  IDictionary < string ,  string >  ReadExternalConfiguration ( ) 
54+     { 
55+         try 
56+         { 
57+             // Check for system-wide config files in /etc/git-credential-manager/config.d and concatenate them together 
58+             // in alphabetical order to form a single configuration. 
59+             const  string  configDir  =  Constants . LinuxAppDefaultsDirectoryPath ; 
60+             if  ( ! _fs . DirectoryExists ( configDir ) ) 
61+             { 
62+                 // No configuration directory exists 
63+                 return  null ; 
64+             } 
65+ 
66+             // Get all the files in the configuration directory 
67+             IEnumerable < string >  files  =  _fs . EnumerateFiles ( configDir ,  "*" ) ; 
68+ 
69+             // Read the contents of each file and concatenate them together 
70+             var  combinedFile  =  new  StringBuilder ( ) ; 
71+             foreach  ( string  file  in  files ) 
72+             { 
73+                 using  Stream  stream  =  _fs . OpenFileStream ( file ,  FileMode . Open ,  FileAccess . Read ,  FileShare . Read ) ; 
74+                 using  var  reader  =  new  StreamReader ( stream ) ; 
75+                 string  contents  =  reader . ReadToEnd ( ) ; 
76+                 combinedFile . Append ( contents ) ; 
77+                 combinedFile . Append ( '\n ' ) ; 
78+             } 
79+ 
80+             var  parser  =  new  LinuxConfigParser ( _trace ) ; 
81+ 
82+             return  parser . Parse ( combinedFile . ToString ( ) ) ; 
83+         } 
84+         catch  ( Exception  ex ) 
85+         { 
86+             // Reading defaults is not critical to the operation of the application 
87+             // so we can ignore any errors and just log the failure. 
88+             _trace . WriteLine ( "Failed to read default setting from app configuration directory." ) ; 
89+             _trace . WriteException ( ex ) ; 
90+             return  null ; 
91+         } 
92+     } 
93+ } 
0 commit comments