1+ using System . IO . Abstractions ;
2+ using GitVersion . Agents ;
3+ using GitVersion . Extensions ;
4+ using GitVersion . FileSystemGlobbing ;
5+ using GitVersion . Helpers ;
6+ using GitVersion . Logging ;
7+ using GitVersion . OutputVariables ;
8+ using Spectre . Console . Cli ;
9+
10+ namespace GitVersion ;
11+
12+ /// <summary>
13+ /// Interceptor to capture parsed arguments
14+ /// </summary>
15+ internal class ArgumentInterceptor : ICommandInterceptor
16+ {
17+ private readonly ParseResultStorage storage ;
18+ private readonly IEnvironment environment ;
19+ private readonly IFileSystem fileSystem ;
20+ private readonly ICurrentBuildAgent buildAgent ;
21+ private readonly IConsole console ;
22+ private readonly IGlobbingResolver globbingResolver ;
23+
24+ public ArgumentInterceptor ( ParseResultStorage storage , IEnvironment environment , IFileSystem fileSystem , ICurrentBuildAgent buildAgent , IConsole console , IGlobbingResolver globbingResolver )
25+ {
26+ this . storage = storage ;
27+ this . environment = environment ;
28+ this . fileSystem = fileSystem ;
29+ this . buildAgent = buildAgent ;
30+ this . console = console ;
31+ this . globbingResolver = globbingResolver ;
32+ }
33+
34+ public void Intercept ( CommandContext context , CommandSettings settings )
35+ {
36+ if ( settings is GitVersionSettings gitVersionSettings )
37+ {
38+ var arguments = ConvertToArguments ( gitVersionSettings ) ;
39+ AddAuthentication ( arguments ) ;
40+ ValidateAndProcessArguments ( arguments ) ;
41+ this . storage . SetResult ( arguments ) ;
42+ }
43+ }
44+
45+ private void AddAuthentication ( Arguments arguments )
46+ {
47+ var username = this . environment . GetEnvironmentVariable ( "GITVERSION_REMOTE_USERNAME" ) ;
48+ if ( ! username . IsNullOrWhiteSpace ( ) )
49+ {
50+ arguments . Authentication . Username = username ;
51+ }
52+
53+ var password = this . environment . GetEnvironmentVariable ( "GITVERSION_REMOTE_PASSWORD" ) ;
54+ if ( ! password . IsNullOrWhiteSpace ( ) )
55+ {
56+ arguments . Authentication . Password = password ;
57+ }
58+ }
59+
60+ private void ValidateAndProcessArguments ( Arguments arguments )
61+ {
62+ // Apply default output if none specified
63+ if ( arguments . Output . Count == 0 )
64+ {
65+ arguments . Output . Add ( OutputType . Json ) ;
66+ }
67+
68+ // Set default output file if file output is specified
69+ if ( arguments . Output . Contains ( OutputType . File ) && arguments . OutputFile == null )
70+ {
71+ arguments . OutputFile = "GitVersion.json" ;
72+ }
73+
74+ // Apply build agent settings
75+ arguments . NoFetch = arguments . NoFetch || this . buildAgent . PreventFetch ( ) ;
76+
77+ // Validate configuration file
78+ ValidateConfigurationFile ( arguments ) ;
79+
80+ // Process assembly info files
81+ if ( ! arguments . EnsureAssemblyInfo )
82+ {
83+ arguments . UpdateAssemblyInfoFileName = ResolveFiles ( arguments . TargetPath , arguments . UpdateAssemblyInfoFileName ) . ToHashSet ( ) ;
84+ }
85+ }
86+
87+ private void ValidateConfigurationFile ( Arguments arguments )
88+ {
89+ if ( arguments . ConfigurationFile . IsNullOrWhiteSpace ( ) ) return ;
90+
91+ if ( FileSystemHelper . Path . IsPathRooted ( arguments . ConfigurationFile ) )
92+ {
93+ if ( ! this . fileSystem . File . Exists ( arguments . ConfigurationFile ) )
94+ throw new WarningException ( $ "Could not find config file at '{ arguments . ConfigurationFile } '") ;
95+ arguments . ConfigurationFile = FileSystemHelper . Path . GetFullPath ( arguments . ConfigurationFile ) ;
96+ }
97+ else
98+ {
99+ var configFilePath = FileSystemHelper . Path . GetFullPath ( FileSystemHelper . Path . Combine ( arguments . TargetPath , arguments . ConfigurationFile ) ) ;
100+ if ( ! this . fileSystem . File . Exists ( configFilePath ) )
101+ throw new WarningException ( $ "Could not find config file at '{ configFilePath } '") ;
102+ arguments . ConfigurationFile = configFilePath ;
103+ }
104+ }
105+
106+ private IEnumerable < string > ResolveFiles ( string workingDirectory , ISet < string > ? assemblyInfoFiles )
107+ {
108+ if ( assemblyInfoFiles == null || assemblyInfoFiles . Count == 0 )
109+ {
110+ return [ ] ;
111+ }
112+
113+ var stringList = new List < string > ( ) ;
114+
115+ foreach ( var filePattern in assemblyInfoFiles )
116+ {
117+ if ( FileSystemHelper . Path . IsPathRooted ( filePattern ) )
118+ {
119+ stringList . Add ( filePattern ) ;
120+ }
121+ else
122+ {
123+ var searchRoot = FileSystemHelper . Path . GetFullPath ( workingDirectory ) ;
124+ var matchingFiles = this . globbingResolver . Resolve ( searchRoot , filePattern ) ;
125+ stringList . AddRange ( matchingFiles ) ;
126+ }
127+ }
128+
129+ return stringList ;
130+ }
131+
132+ private static Arguments ConvertToArguments ( GitVersionSettings settings )
133+ {
134+ var arguments = new Arguments ( ) ;
135+
136+ // Set target path - prioritize explicit targetpath option over positional argument
137+ arguments . TargetPath = settings . TargetPathOption ? . TrimEnd ( '/' , '\\ ' )
138+ ?? settings . TargetPath ? . TrimEnd ( '/' , '\\ ' )
139+ ?? SysEnv . CurrentDirectory ;
140+
141+ // Configuration options
142+ arguments . ConfigurationFile = settings . ConfigurationFile ;
143+ arguments . ShowConfiguration = settings . ShowConfiguration ;
144+
145+ // Handle override configuration
146+ if ( settings . OverrideConfiguration != null && settings . OverrideConfiguration . Any ( ) )
147+ {
148+ var parser = new OverrideConfigurationOptionParser ( ) ;
149+
150+ foreach ( var kvp in settings . OverrideConfiguration )
151+ {
152+ // Validate the key format - Spectre.Console.Cli should have already parsed key=value correctly
153+ // but we still need to validate against supported properties
154+ var keyValueOption = $ "{ kvp . Key } ={ kvp . Value } ";
155+
156+ var optionKey = kvp . Key . ToLowerInvariant ( ) ;
157+ if ( ! OverrideConfigurationOptionParser . SupportedProperties . Contains ( optionKey ) )
158+ {
159+ throw new WarningException ( $ "Could not parse --override-config option: { keyValueOption } . Unsupported 'key'.") ;
160+ }
161+
162+ parser . SetValue ( optionKey , kvp . Value ) ;
163+ }
164+
165+ arguments . OverrideConfiguration = parser . GetOverrideConfiguration ( ) ;
166+ }
167+ else
168+ {
169+ arguments . OverrideConfiguration = new Dictionary < object , object ? > ( ) ;
170+ }
171+
172+ // Output options
173+ if ( settings . Output != null && settings . Output . Any ( ) )
174+ {
175+ foreach ( var output in settings . Output )
176+ {
177+ if ( Enum . TryParse < OutputType > ( output , true , out var outputType ) )
178+ {
179+ arguments . Output . Add ( outputType ) ;
180+ }
181+ }
182+ }
183+
184+ arguments . OutputFile = settings . OutputFile ;
185+ arguments . Format = settings . Format ;
186+ arguments . ShowVariable = settings . ShowVariable ;
187+
188+ // Repository options
189+ arguments . TargetUrl = settings . Url ;
190+ arguments . TargetBranch = settings . Branch ;
191+ arguments . CommitId = settings . Commit ;
192+ arguments . ClonePath = settings . DynamicRepoLocation ;
193+
194+ // Authentication
195+ if ( ! string . IsNullOrWhiteSpace ( settings . Username ) )
196+ {
197+ arguments . Authentication . Username = settings . Username ;
198+ }
199+ if ( ! string . IsNullOrWhiteSpace ( settings . Password ) )
200+ {
201+ arguments . Authentication . Password = settings . Password ;
202+ }
203+
204+ // Behavioral flags
205+ arguments . NoFetch = settings . NoFetch ;
206+ arguments . NoCache = settings . NoCache ;
207+ arguments . NoNormalize = settings . NoNormalize ;
208+ arguments . AllowShallow = settings . AllowShallow ;
209+ arguments . Diag = settings . Diag ;
210+
211+ // Assembly info options
212+ arguments . UpdateAssemblyInfo = settings . UpdateAssemblyInfo ;
213+ arguments . EnsureAssemblyInfo = settings . EnsureAssemblyInfo ;
214+ arguments . UpdateProjectFiles = settings . UpdateProjectFiles ;
215+ arguments . UpdateWixVersionFile = settings . UpdateWixVersionFile ;
216+
217+ // Handle assembly info file names
218+ if ( settings . UpdateAssemblyInfoFileName != null && settings . UpdateAssemblyInfoFileName . Any ( ) )
219+ {
220+ arguments . UpdateAssemblyInfoFileName = settings . UpdateAssemblyInfoFileName . ToHashSet ( ) ;
221+ }
222+
223+ // Logging
224+ arguments . LogFilePath = settings . LogFilePath ;
225+ if ( Enum . TryParse < Verbosity > ( settings . Verbosity , true , out var verbosity ) )
226+ {
227+ arguments . Verbosity = verbosity ;
228+ }
229+
230+ return arguments ;
231+ }
232+ }
0 commit comments