Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ All notable changes to `src-cli` are documented in this file.

### Added

- Add verbosity flag to `lsif upload` action. Supply `-trace=1`, `-trace=2`, or `-trace=3` to the action to specify verbosity.

### Changed

### Fixed
Expand Down
104 changes: 94 additions & 10 deletions cmd/src/lsif_upload.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@ import (
"encoding/json"
"flag"
"fmt"
"net/http"
"net/url"
"os"
"sort"
"strings"
"sync"
"time"

"github.com/efritz/pentimento"
"github.com/mattn/go-isatty"
"github.com/pkg/browser"
"github.com/pkg/errors"
"github.com/sourcegraph/codeintelutils"
Expand Down Expand Up @@ -52,6 +53,8 @@ Examples:
maxPayloadSizeMb *int
ignoreUploadFailures *bool
uploadRoute *string
rawVerbosity *int
verbosity lsifUploadVerbosity
}

flagSet := flag.NewFlagSet("upload", flag.ExitOnError)
Expand All @@ -67,6 +70,7 @@ Examples:
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.`)
flags.ignoreUploadFailures = flagSet.Bool("ignore-upload-failure", false, `Exit with status code zero on upload failure.`)
flags.uploadRoute = flagSet.String("upload-route", "/.api/lsif/upload", "The path of the upload route.")
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")

parseAndValidateFlags := func(args []string) error {
flagSet.Parse(args)
Expand Down Expand Up @@ -146,6 +150,12 @@ Examples:
return errors.New("max-payload-size must be positive")
}

// Don't need to check upper bounds as we only compare verbosity ranges
// It's fine if someone supplies -trace=42, but it will just behave the
// same as if they supplied the highest verbosity level we define
// internally.
flags.verbosity = lsifUploadVerbosity(*flags.rawVerbosity)

if !*flags.json {
fmt.Println(argsString)
}
Expand Down Expand Up @@ -173,6 +183,7 @@ Examples:
MaxRetries: 10,
RetryInterval: time.Millisecond * 250,
UploadProgressEvents: make(chan codeintelutils.UploadProgressEvent),
Logger: &lsifUploadRequestLogger{verbosity: flags.verbosity},
}

var wg sync.WaitGroup
Expand All @@ -181,7 +192,7 @@ Examples:
go func() {
defer wg.Done()

if *flags.json || *flags.noProgress {
if *flags.json || *flags.noProgress || flags.verbosity > 0 {
return
}

Expand All @@ -202,19 +213,19 @@ Examples:
wg.Wait() // Wait for progress bar goroutine to clear screen
if err != nil {
if err == codeintelutils.ErrUnauthorized {
if *flags.gitHubToken == "" {
return fmt.Errorf("you must provide -github-token=TOKEN, where TOKEN is a GitHub personal access token with 'repo' or 'public_repo' scope")
err = errorWithHint{
err: err, hint: strings.Join([]string{
"You may need to specify or update your GitHub access token to use this endpoint.",
"See https://docs.sourcegraph.com/cli/references/lsif/upload.",
}, "\n"),
}

if isatty.IsTerminal(os.Stdout.Fd()) {
fmt.Println("You may need to specify or update your GitHub access token to use this endpoint.")
fmt.Println("See https://github.com/sourcegraph/src-cli#authentication.")
}
}

if *flags.ignoreUploadFailures {
fmt.Printf("error: %s\n", err)
return nil
// Report but don't return
fmt.Println(err.Error())
err = nil
}

return err
Expand Down Expand Up @@ -312,3 +323,76 @@ func digits(n int) int {
}
return 1
}

type errorWithHint struct {
err error
hint string
}

func (e errorWithHint) Error() string {
return fmt.Sprintf("error: %s\n\n%s\n", e.err, e.hint)
}

type lsifUploadVerbosity int

const (
lsifUploadVerbosityNone lsifUploadVerbosity = iota // -trace=0 (default)
lsifUploadVerbosityTrace // -trace=1
lsifUploadVerbosityTraceShowHeaders // -trace=2
lsifUploadVerbosityTraceShowResponseBody // -trace=3
)

type lsifUploadRequestLogger struct {
verbosity lsifUploadVerbosity
}

func (l *lsifUploadRequestLogger) LogRequest(req *http.Request) {
if l.verbosity == lsifUploadVerbosityNone {
return
}

if l.verbosity >= lsifUploadVerbosityTrace {
fmt.Printf("> %s %s\n", req.Method, req.URL)
}

if l.verbosity >= lsifUploadVerbosityTraceShowHeaders {
fmt.Printf("> Request Headers:\n")
for _, k := range sortHeaders(req.Header) {
fmt.Printf("> %s: %s\n", k, req.Header[k])
}
}

fmt.Printf("\n")
}

func (l *lsifUploadRequestLogger) LogResponse(req *http.Request, resp *http.Response, body []byte, elapsed time.Duration) {
if l.verbosity == lsifUploadVerbosityNone {
return
}

if l.verbosity >= lsifUploadVerbosityTrace {
fmt.Printf("< %s %s %s in %s\n", req.Method, req.URL, resp.Status, elapsed)
}

if l.verbosity >= lsifUploadVerbosityTraceShowHeaders {
fmt.Printf("< Response Headers:\n")
for _, k := range sortHeaders(resp.Header) {
fmt.Printf("< %s: %s\n", k, resp.Header[k])
}
}

if l.verbosity >= lsifUploadVerbosityTraceShowResponseBody {
fmt.Printf("< Response Body: %s\n", body)
}

fmt.Printf("\n")
}

func sortHeaders(header http.Header) []string {
var keys []string
for k := range header {
keys = append(keys, k)
}
sort.Strings(keys)
return keys
}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ require (
github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4
github.com/pkg/errors v0.9.1
github.com/sourcegraph/campaignutils v0.0.0-20201124055807-2f9cfa9317e2
github.com/sourcegraph/codeintelutils v0.0.0-20201118031531-b82ba3167b30
github.com/sourcegraph/codeintelutils v0.0.0-20210113171425-9ec641b48a8e
github.com/sourcegraph/go-diff v0.6.1
github.com/sourcegraph/jsonx v0.0.0-20200629203448-1a936bd500cf
github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf // indirect
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxr
github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ=
github.com/sourcegraph/campaignutils v0.0.0-20201124055807-2f9cfa9317e2 h1:MJu/6WzWdPegzYnZLb04IS0u4VyUpPIAHQyWT5i2vR8=
github.com/sourcegraph/campaignutils v0.0.0-20201124055807-2f9cfa9317e2/go.mod h1:xm6i78Mk2t4DBLQDqEFc/3x6IPf7yYZCgbNaTQGhJHA=
github.com/sourcegraph/codeintelutils v0.0.0-20201118031531-b82ba3167b30 h1:HrRrPyskdkHc6MqQS3ehH+DSraFnOhtvBWQ6AzEJC1o=
github.com/sourcegraph/codeintelutils v0.0.0-20201118031531-b82ba3167b30/go.mod h1:HplI8gRslTrTUUsSYwu28hSOderix7m5dHNca7xBzeo=
github.com/sourcegraph/codeintelutils v0.0.0-20210113171425-9ec641b48a8e h1:PdNc6fH0HHQ5xbnCwPkHuFdVCofQilFm9gG40fEQKms=
github.com/sourcegraph/codeintelutils v0.0.0-20210113171425-9ec641b48a8e/go.mod h1:HplI8gRslTrTUUsSYwu28hSOderix7m5dHNca7xBzeo=
github.com/sourcegraph/go-diff v0.6.1 h1:hmA1LzxW0n1c3Q4YbrFgg4P99GSnebYa3x8gr0HZqLQ=
github.com/sourcegraph/go-diff v0.6.1/go.mod h1:iBszgVvyxdc8SFZ7gm69go2KDdt3ag071iBaWPF6cjs=
github.com/sourcegraph/jsonx v0.0.0-20200629203448-1a936bd500cf h1:oAdWFqhStsWiiMP/vkkHiMXqFXzl1XfUNOdxKJbd6bI=
Expand Down