@@ -4,14 +4,15 @@ import (
44	"encoding/json" 
55	"flag" 
66	"fmt" 
7+ 	"net/http" 
78	"net/url" 
89	"os" 
10+ 	"sort" 
911	"strings" 
1012	"sync" 
1113	"time" 
1214
1315	"github.com/efritz/pentimento" 
14- 	"github.com/mattn/go-isatty" 
1516	"github.com/pkg/browser" 
1617	"github.com/pkg/errors" 
1718	"github.com/sourcegraph/codeintelutils" 
@@ -52,6 +53,8 @@ Examples:
5253		maxPayloadSizeMb      * int 
5354		ignoreUploadFailures  * bool 
5455		uploadRoute           * string 
56+ 		rawVerbosity          * int 
57+ 		verbosity             lsifUploadVerbosity 
5558	}
5659
5760	flagSet  :=  flag .NewFlagSet ("upload" , flag .ExitOnError )
@@ -67,6 +70,7 @@ Examples:
6770	flags .maxPayloadSizeMb  =  flagSet .Int ("max-payload-size" , 100 , `The maximum upload size (in megabytes). Indexes exceeding this limit will be uploaded over multiple HTTP requests.` )
6871	flags .ignoreUploadFailures  =  flagSet .Bool ("ignore-upload-failure" , false , `Exit with status code zero on upload failure.` )
6972	flags .uploadRoute  =  flagSet .String ("upload-route" , "/.api/lsif/upload" , "The path of the upload route." )
73+ 	flags .rawVerbosity  =  flagSet .Int ("trace" , 0 , "-trace=0 shows no logs; -trace=1 shows requests and response metadata; -trace=2 shows headers, -trace=3 shows response body" )
7074
7175	parseAndValidateFlags  :=  func (args  []string ) error  {
7276		flagSet .Parse (args )
@@ -146,6 +150,12 @@ Examples:
146150			return  errors .New ("max-payload-size must be positive" )
147151		}
148152
153+ 		// Don't need to check upper bounds as we only compare verbosity ranges 
154+ 		// It's fine if someone supplies -trace=42, but it will just behave the 
155+ 		// same as if they supplied the highest verbosity level we define 
156+ 		// internally. 
157+ 		flags .verbosity  =  lsifUploadVerbosity (* flags .rawVerbosity )
158+ 
149159		if  ! * flags .json  {
150160			fmt .Println (argsString )
151161		}
@@ -173,6 +183,7 @@ Examples:
173183			MaxRetries :           10 ,
174184			RetryInterval :        time .Millisecond  *  250 ,
175185			UploadProgressEvents : make (chan  codeintelutils.UploadProgressEvent ),
186+ 			Logger :               & lsifUploadRequestLogger {verbosity : flags .verbosity },
176187		}
177188
178189		var  wg  sync.WaitGroup 
@@ -181,7 +192,7 @@ Examples:
181192		go  func () {
182193			defer  wg .Done ()
183194
184- 			if  * flags .json  ||  * flags .noProgress  {
195+ 			if  * flags .json  ||  * flags .noProgress  ||   flags . verbosity   >   0   {
185196				return 
186197			}
187198
@@ -202,19 +213,19 @@ Examples:
202213		wg .Wait ()                        // Wait for progress bar goroutine to clear screen 
203214		if  err  !=  nil  {
204215			if  err  ==  codeintelutils .ErrUnauthorized  {
205- 				if  * flags .gitHubToken  ==  ""  {
206- 					return  fmt .Errorf ("you must provide -github-token=TOKEN, where TOKEN is a GitHub personal access token with 'repo' or 'public_repo' scope" )
216+ 				err  =  errorWithHint {
217+ 					err : err , hint : strings .Join ([]string {
218+ 						"You may need to specify or update your GitHub access token to use this endpoint." ,
219+ 						"See https://docs.sourcegraph.com/cli/references/lsif/upload." ,
220+ 					}, "\n " ),
207221				}
208222
209- 				if  isatty .IsTerminal (os .Stdout .Fd ()) {
210- 					fmt .Println ("You may need to specify or update your GitHub access token to use this endpoint." )
211- 					fmt .Println ("See https://github.com/sourcegraph/src-cli#authentication." )
212- 				}
213223			}
214224
215225			if  * flags .ignoreUploadFailures  {
216- 				fmt .Printf ("error: %s\n " , err )
217- 				return  nil 
226+ 				// Report but don't return 
227+ 				fmt .Println (err .Error ())
228+ 				err  =  nil 
218229			}
219230
220231			return  err 
@@ -312,3 +323,76 @@ func digits(n int) int {
312323	}
313324	return  1 
314325}
326+ 
327+ type  errorWithHint  struct  {
328+ 	err   error 
329+ 	hint  string 
330+ }
331+ 
332+ func  (e  errorWithHint ) Error () string  {
333+ 	return  fmt .Sprintf ("error: %s\n \n %s\n " , e .err , e .hint )
334+ }
335+ 
336+ type  lsifUploadVerbosity  int 
337+ 
338+ const  (
339+ 	lsifUploadVerbosityNone                   lsifUploadVerbosity  =  iota  // -trace=0 (default) 
340+ 	lsifUploadVerbosityTrace                                             // -trace=1 
341+ 	lsifUploadVerbosityTraceShowHeaders                                  // -trace=2 
342+ 	lsifUploadVerbosityTraceShowResponseBody                             // -trace=3 
343+ )
344+ 
345+ type  lsifUploadRequestLogger  struct  {
346+ 	verbosity  lsifUploadVerbosity 
347+ }
348+ 
349+ func  (l  * lsifUploadRequestLogger ) LogRequest (req  * http.Request ) {
350+ 	if  l .verbosity  ==  lsifUploadVerbosityNone  {
351+ 		return 
352+ 	}
353+ 
354+ 	if  l .verbosity  >=  lsifUploadVerbosityTrace  {
355+ 		fmt .Printf ("> %s %s\n " , req .Method , req .URL )
356+ 	}
357+ 
358+ 	if  l .verbosity  >=  lsifUploadVerbosityTraceShowHeaders  {
359+ 		fmt .Printf ("> Request Headers:\n " )
360+ 		for  _ , k  :=  range  sortHeaders (req .Header ) {
361+ 			fmt .Printf (">     %s: %s\n " , k , req .Header [k ])
362+ 		}
363+ 	}
364+ 
365+ 	fmt .Printf ("\n " )
366+ }
367+ 
368+ func  (l  * lsifUploadRequestLogger ) LogResponse (req  * http.Request , resp  * http.Response , body  []byte , elapsed  time.Duration ) {
369+ 	if  l .verbosity  ==  lsifUploadVerbosityNone  {
370+ 		return 
371+ 	}
372+ 
373+ 	if  l .verbosity  >=  lsifUploadVerbosityTrace  {
374+ 		fmt .Printf ("< %s %s %s in %s\n " , req .Method , req .URL , resp .Status , elapsed )
375+ 	}
376+ 
377+ 	if  l .verbosity  >=  lsifUploadVerbosityTraceShowHeaders  {
378+ 		fmt .Printf ("< Response Headers:\n " )
379+ 		for  _ , k  :=  range  sortHeaders (resp .Header ) {
380+ 			fmt .Printf ("<     %s: %s\n " , k , resp .Header [k ])
381+ 		}
382+ 	}
383+ 
384+ 	if  l .verbosity  >=  lsifUploadVerbosityTraceShowResponseBody  {
385+ 		fmt .Printf ("< Response Body: %s\n " , body )
386+ 	}
387+ 
388+ 	fmt .Printf ("\n " )
389+ }
390+ 
391+ func  sortHeaders (header  http.Header ) []string  {
392+ 	var  keys  []string 
393+ 	for  k  :=  range  header  {
394+ 		keys  =  append (keys , k )
395+ 	}
396+ 	sort .Strings (keys )
397+ 	return  keys 
398+ }
0 commit comments