-
Notifications
You must be signed in to change notification settings - Fork 0
/
cli.go
137 lines (117 loc) · 3.6 KB
/
cli.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
package src
import (
"log"
"net/http"
"net/url"
"os"
"strconv"
"github.com/gregjones/httpcache"
"github.com/gregjones/httpcache/diskcache"
"sourcegraph.com/sourcegraph/go-flags"
"sourcegraph.com/sourcegraph/go-sourcegraph/auth"
"sourcegraph.com/sourcegraph/go-sourcegraph/sourcegraph"
)
var CLI = flags.NewNamedParser("src", flags.Default)
// GlobalOpt contains global options.
var GlobalOpt struct {
Verbose bool `short:"v" description:"show verbose output"`
}
func init() {
CLI.LongDescription = "src builds projects, analyzes source code, and queries Sourcegraph."
CLI.AddGroup("Global options", "", &GlobalOpt)
}
func getEndpointURL() *url.URL {
if urlStr := os.Getenv("SRC_ENDPOINT"); urlStr != "" {
u, err := url.Parse(urlStr)
if err != nil {
log.Fatal("Parsing SRC_ENDPOINT URL string:", err)
}
return u
}
return &url.URL{Scheme: "https", Host: "sourcegraph.com", Path: "/api/"}
}
// getPermGrantTickets gets signed perm grant ticket strings from the
// SRCLIB_TICKET env var. Currently only 1 ticket can be provided. The
// signed ticket string should not contain the "Sourcegraph-Ticket "
// prefix.
func getPermGrantTickets() []string {
tkstr := os.Getenv("SRCLIB_TICKET")
if tkstr == "" {
return nil
}
return []string{tkstr}
}
// newAPIClient creates a new Sourcegraph API client for the endpoint
// given by endpointURL (a global) and that is authenticated using the
// credentials in ua (if non-nil) and perm grant ticket (if one is
// provided in SRCLIB_TICKET).
func newAPIClient(ua *userEndpointAuth, cache bool) *sourcegraph.Client {
endpointURL := getEndpointURL()
var transport http.RoundTripper
if cache {
transport = http.RoundTripper(httpcache.NewTransport(diskcache.New("/tmp/srclib-cache")))
} else {
transport = http.DefaultTransport
}
if tickets := getPermGrantTickets(); len(tickets) > 0 {
log.Println("# Using perm grant ticket from SRCLIB_TICKET.")
transport = &auth.TicketAuthedTransport{SignedTicketStrings: tickets, Transport: transport}
}
if ua == nil {
// Unauthenticated API client.
if GlobalOpt.Verbose {
log.Printf("# Using unauthenticated API client for endpoint %s.", endpointURL)
}
} else {
// Authenticated API client.
if GlobalOpt.Verbose {
log.Printf("# Using authenticated API client for endpoint %s (UID %d).", endpointURL, ua.UID)
}
transport = &auth.BasicAuthTransport{Username: strconv.Itoa(ua.UID), Password: ua.Key, Transport: transport}
}
if v, _ := strconv.ParseBool(os.Getenv("SRC_TRACE")); v {
transport = &tracingTransport{Writer: os.Stderr, Transport: transport}
}
c := sourcegraph.NewClient(&http.Client{Transport: transport})
c.BaseURL = endpointURL
return c
}
// NewAPIClientWithAuthIfPresent calls newAPIClient with the user auth
// credentials from the userAuthFile (if present), and otherwise
// creates an unauthed API client.
func NewAPIClientWithAuthIfPresent() *sourcegraph.Client {
return newAPIClientWithAuth(true)
}
func newAPIClientWithAuth(cache bool) *sourcegraph.Client {
var ua *userEndpointAuth
if uidStr, key := os.Getenv("SRC_UID"), os.Getenv("SRC_KEY"); uidStr != "" && key != "" {
uid, err := strconv.Atoi(uidStr)
if err != nil {
log.Fatal("Parsing SRC_UID:", err)
}
ua = &userEndpointAuth{UID: uid, Key: key}
} else {
a, err := readUserAuth()
if err != nil {
log.Fatal("Reading user auth:", err)
}
ua = a[getEndpointURL().String()]
}
return newAPIClient(ua, cache)
}
var (
absDir string
)
func init() {
var err error
absDir, err = os.Getwd()
if err != nil {
log.Fatal(err)
}
}
func Main() error {
log.SetFlags(0)
log.SetPrefix("")
_, err := CLI.Parse()
return err
}