@@ -42,18 +42,18 @@ private record DocumentInfo(
4242 ImmutableArray < byte > Hash ,
4343 Guid HashAlgorithm ) ;
4444
45- private readonly IConsole _console ;
45+ private readonly ParseResult _parseResult ;
4646 private bool _errorReported ;
4747
48- public Program ( IConsole console )
48+ public Program ( ParseResult parseResult )
4949 {
50- _console = console ;
50+ _parseResult = parseResult ;
5151 }
5252
5353 public static async Task < int > Main ( string [ ] args )
5454 {
5555 var rootCommand = GetRootCommand ( ) ;
56- return await rootCommand . InvokeAsync ( args ) ;
56+ return await rootCommand . Parse ( args ) . InvokeAsync ( ) ;
5757 }
5858
5959 private static string GetSourceLinkVersion ( )
@@ -62,41 +62,77 @@ private static string GetSourceLinkVersion()
6262 return attribute . InformationalVersion . Split ( '+' ) . First ( ) ;
6363 }
6464
65- private static RootCommand GetRootCommand ( )
65+ private static CliRootCommand GetRootCommand ( )
6666 {
67- var authArg = new Option < string > ( new [ ] { "--auth" , "-a" } , "Authentication method" ) . FromAmong ( AuthenticationMethod . Basic ) ;
68- var userArg = new Option < string > ( new [ ] { "--user" , "-u" } , "Username to use to authenticate" ) { Arity = ArgumentArity . ExactlyOne } ;
69- var passwordArg = new Option < string > ( new [ ] { "--password" , "-p" } , "Password to use to authenticate" ) { Arity = ArgumentArity . ExactlyOne } ;
67+ var authArg = new CliOption < string > ( "--auth" , "-a" )
68+ {
69+ Description = "Authentication method"
70+ } ;
71+ authArg . AcceptOnlyFromAmong ( AuthenticationMethod . Basic ) ;
72+
73+ var userArg = new CliOption < string > ( "--user" , "-u" )
74+ {
75+ Description = "Username to use to authenticate" ,
76+ Arity = ArgumentArity . ExactlyOne
77+ } ;
78+
79+ var passwordArg = new CliOption < string > ( "--password" , "-p" )
80+ {
81+ Description = "Password to use to authenticate" ,
82+ Arity = ArgumentArity . ExactlyOne
83+ } ;
7084
71- var test = new Command ( "test" , "TODO ")
85+ var offlineArg = new CliOption < bool > ( "--offline ")
7286 {
73- new Argument < string > ( "path" , "Path to an assembly or .pdb" ) ,
87+ Description = "Offline mode - skip validation of sourcelink URL targets"
88+ } ;
89+
90+ var test = new CliCommand ( "test" , "TODO" )
91+ {
92+ new CliArgument < string > ( "path" )
93+ {
94+ Description = "Path to an assembly or .pdb"
95+ } ,
7496 authArg ,
75- new Option < Encoding > ( new [ ] { "--auth-encoding" , "-e" } , ( arg ) => Encoding . GetEncoding ( arg . Tokens . Single ( ) . Value ) , false , "Encoding to use for authentication value" ) ,
97+ new CliOption < Encoding > ( "--auth-encoding" , "-e" )
98+ {
99+ CustomParser = arg => Encoding . GetEncoding ( arg . Tokens . Single ( ) . Value ) ,
100+ Description = "Encoding to use for authentication value"
101+ } ,
76102 userArg ,
77103 passwordArg ,
104+ offlineArg ,
78105 } ;
79- test . Handler = CommandHandler . Create < string , string ? , Encoding ? , string ? , string ? , IConsole > ( TestAsync ) ;
106+ test . Action = CommandHandler . Create < string , string ? , Encoding ? , string ? , string ? , bool , ParseResult > ( TestAsync ) ;
80107
81- var printJson = new Command ( "print-json" , "Print Source Link JSON stored in the PDB" )
108+ var printJson = new CliCommand ( "print-json" , "Print Source Link JSON stored in the PDB" )
82109 {
83- new Argument < string > ( "path" , "Path to an assembly or .pdb" ) ,
110+ new CliArgument < string > ( "path" )
111+ {
112+ Description = "Path to an assembly or .pdb"
113+ }
84114 } ;
85- printJson . Handler = CommandHandler . Create < string , IConsole > ( PrintJsonAsync ) ;
115+ printJson . Action = CommandHandler . Create < string , ParseResult > ( PrintJsonAsync ) ;
86116
87- var printDocuments = new Command ( "print-documents" , "TODO" )
117+ var printDocuments = new CliCommand ( "print-documents" , "TODO" )
88118 {
89- new Argument < string > ( "path" , "Path to an assembly or .pdb" ) ,
119+ new CliArgument < string > ( "path" )
120+ {
121+ Description = "Path to an assembly or .pdb"
122+ }
90123 } ;
91- printDocuments . Handler = CommandHandler . Create < string , IConsole > ( PrintDocumentsAsync ) ;
124+ printDocuments . Action = CommandHandler . Create < string , ParseResult > ( PrintDocumentsAsync ) ;
92125
93- var printUrls = new Command ( "print-urls" , "TODO" )
126+ var printUrls = new CliCommand ( "print-urls" , "TODO" )
94127 {
95- new Argument < string > ( "path" , "Path to an assembly or .pdb" ) ,
128+ new CliArgument < string > ( "path" )
129+ {
130+ Description = "Path to an assembly or .pdb"
131+ }
96132 } ;
97- printUrls . Handler = CommandHandler . Create < string , IConsole > ( PrintUrlsAsync ) ;
133+ printUrls . Action = CommandHandler . Create < string , ParseResult > ( PrintUrlsAsync ) ;
98134
99- var root = new RootCommand ( )
135+ var root = new CliRootCommand ( )
100136 {
101137 test ,
102138 printJson ,
@@ -106,13 +142,13 @@ private static RootCommand GetRootCommand()
106142
107143 root . Description = "dotnet-sourcelink" ;
108144
109- root . AddValidator ( commandResult =>
145+ root . Validators . Add ( commandResult =>
110146 {
111- if ( commandResult . FindResultFor ( authArg ) != null )
147+ if ( commandResult . GetResult ( authArg ) != null )
112148 {
113- if ( commandResult . FindResultFor ( userArg ) == null || commandResult . FindResultFor ( passwordArg ) == null )
149+ if ( commandResult . GetResult ( userArg ) == null || commandResult . GetResult ( passwordArg ) == null )
114150 {
115- commandResult . ErrorMessage = "Specify --user and --password options" ;
151+ commandResult . AddError ( "Specify --user and --password options" ) ;
116152 }
117153 }
118154 } ) ;
@@ -122,15 +158,15 @@ private static RootCommand GetRootCommand()
122158
123159 private void ReportError ( string message )
124160 {
125- _console . Error . Write ( message ) ;
126- _console . Error . Write ( Environment . NewLine ) ;
161+ _parseResult . Configuration . Error . Write ( message ) ;
162+ _parseResult . Configuration . Error . Write ( Environment . NewLine ) ;
127163 _errorReported = true ;
128164 }
129165
130166 private void WriteOutputLine ( string message )
131167 {
132- _console . Out . Write ( message ) ;
133- _console . Out . Write ( Environment . NewLine ) ;
168+ _parseResult . Configuration . Output . Write ( message ) ;
169+ _parseResult . Configuration . Output . Write ( Environment . NewLine ) ;
134170 }
135171
136172 private static async Task < int > TestAsync (
@@ -139,7 +175,8 @@ private static async Task<int> TestAsync(
139175 Encoding ? authEncoding ,
140176 string ? user ,
141177 string ? password ,
142- IConsole console )
178+ bool offline ,
179+ ParseResult parseResult )
143180 {
144181 var authenticationHeader = ( authMethod != null ) ? GetAuthenticationHeader ( authMethod , authEncoding ?? Encoding . ASCII , user ! , password ! ) : null ;
145182
@@ -152,17 +189,17 @@ private static async Task<int> TestAsync(
152189
153190 try
154191 {
155- return await new Program ( console ) . TestAsync ( path , authenticationHeader , cancellationSource . Token ) . ConfigureAwait ( false ) ;
192+ return await new Program ( parseResult ) . TestAsync ( path , authenticationHeader , offline , cancellationSource . Token ) . ConfigureAwait ( false ) ;
156193 }
157194 catch ( OperationCanceledException )
158195 {
159- console . Error . Write ( "Operation canceled." ) ;
160- console . Error . Write ( Environment . NewLine ) ;
196+ parseResult . Configuration . Error . Write ( "Operation canceled." ) ;
197+ parseResult . Configuration . Error . Write ( Environment . NewLine ) ;
161198 return - 1 ;
162199 }
163200 }
164201
165- private async Task < int > TestAsync ( string path , AuthenticationHeaderValue ? authenticationHeader , CancellationToken cancellationToken )
202+ private async Task < int > TestAsync ( string path , AuthenticationHeaderValue ? authenticationHeader , bool offline , CancellationToken cancellationToken )
166203 {
167204 var documents = new List < DocumentInfo > ( ) ;
168205 ReadAndResolveDocuments ( path , documents ) ;
@@ -172,31 +209,34 @@ private async Task<int> TestAsync(string path, AuthenticationHeaderValue? authen
172209 return _errorReported ? 1 : 0 ;
173210 }
174211
175- var handler = new HttpClientHandler ( ) ;
176- if ( handler . SupportsAutomaticDecompression )
177- handler . AutomaticDecompression = DecompressionMethods . GZip | DecompressionMethods . Deflate ;
212+ if ( ! offline )
213+ {
214+ var handler = new HttpClientHandler ( ) ;
215+ if ( handler . SupportsAutomaticDecompression )
216+ handler . AutomaticDecompression = DecompressionMethods . GZip | DecompressionMethods . Deflate ;
178217
179- using var client = new HttpClient ( handler ) ;
180- client . DefaultRequestHeaders . UserAgent . Add ( s_sourceLinkProductHeaderValue ) ;
181- client . DefaultRequestHeaders . Authorization = authenticationHeader ;
218+ using var client = new HttpClient ( handler ) ;
219+ client . DefaultRequestHeaders . UserAgent . Add ( s_sourceLinkProductHeaderValue ) ;
220+ client . DefaultRequestHeaders . Authorization = authenticationHeader ;
182221
183- var outputLock = new object ( ) ;
222+ var outputLock = new object ( ) ;
184223
185- var errorReporter = new Action < string > ( message =>
186- {
187- lock ( outputLock )
224+ var errorReporter = new Action < string > ( message =>
188225 {
189- ReportError ( message ) ;
190- }
191- } ) ;
226+ lock ( outputLock )
227+ {
228+ ReportError ( message ) ;
229+ }
230+ } ) ;
192231
193- var tasks = documents . Where ( document => document . Uri != null ) . Select ( document => DownloadAndValidateDocumentAsync ( client , document , errorReporter , cancellationToken ) ) ;
194-
195- _ = await Task . WhenAll ( tasks ) . ConfigureAwait ( false ) ;
232+ var tasks = documents . Where ( document => document . Uri != null ) . Select ( document => DownloadAndValidateDocumentAsync ( client , document , errorReporter , cancellationToken ) ) ;
196233
197- if ( _errorReported )
198- {
199- return 1 ;
234+ _ = await Task . WhenAll ( tasks ) . ConfigureAwait ( false ) ;
235+
236+ if ( _errorReported )
237+ {
238+ return 1 ;
239+ }
200240 }
201241
202242 WriteOutputLine ( $ "File '{ path } ' validated.") ;
@@ -277,8 +317,8 @@ private static async Task<bool> DownloadAndValidateDocumentAsync(HttpClient clie
277317 }
278318 }
279319
280- private static Task < int > PrintJsonAsync ( string path , IConsole console )
281- => Task . FromResult ( new Program ( console ) . PrintJson ( path ) ) ;
320+ private static Task < int > PrintJsonAsync ( string path , ParseResult parseResult )
321+ => Task . FromResult ( new Program ( parseResult ) . PrintJson ( path ) ) ;
282322
283323 private int PrintJson ( string path )
284324 {
@@ -299,8 +339,8 @@ private int PrintJson(string path)
299339 return _errorReported ? 1 : 0 ;
300340 }
301341
302- private static Task < int > PrintDocumentsAsync ( string path , IConsole console )
303- => Task . FromResult ( new Program ( console ) . PrintDocuments ( path ) ) ;
342+ private static Task < int > PrintDocumentsAsync ( string path , ParseResult parseResult )
343+ => Task . FromResult ( new Program ( parseResult ) . PrintDocuments ( path ) ) ;
304344
305345 public static string ToHex ( byte [ ] bytes )
306346 => BitConverter . ToString ( bytes ) . Replace ( "-" , "" ) . ToLowerInvariant ( ) ;
@@ -324,8 +364,8 @@ private int PrintDocuments(string path)
324364 return _errorReported ? 1 : 0 ;
325365 }
326366
327- private static Task < int > PrintUrlsAsync ( string path , IConsole console )
328- => Task . FromResult ( new Program ( console ) . PrintUrls ( path ) ) ;
367+ private static Task < int > PrintUrlsAsync ( string path , ParseResult parseResult )
368+ => Task . FromResult ( new Program ( parseResult ) . PrintUrls ( path ) ) ;
329369
330370 private int PrintUrls ( string path )
331371 {
0 commit comments