Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1329)

Side by Side Diff: common/api/gitiles/gitiles.go

Issue 2977083002: Move gitiles module from milo to common/api. (Closed)
Patch Set: docnit Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The LUCI Authors. 1 // Copyright 2016 The LUCI Authors.
2 // 2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License. 4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at 5 // You may obtain a copy of the License at
6 // 6 //
7 // http://www.apache.org/licenses/LICENSE-2.0 7 // http://www.apache.org/licenses/LICENSE-2.0
8 // 8 //
9 // Unless required by applicable law or agreed to in writing, software 9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, 10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and 12 // See the License for the specific language governing permissions and
13 // limitations under the License. 13 // limitations under the License.
14 14
15 package gitiles 15 package gitiles
16 16
17 // TODO(tandrii): add tests.
18
17 import ( 19 import (
18 "encoding/json" 20 "encoding/json"
19 "fmt" 21 "fmt"
20 "net/http" 22 "net/http"
21 "net/url" 23 "net/url"
22 "strings" 24 "strings"
23 25
24 "github.com/luci/luci-go/milo/api/resp"
25 "github.com/luci/luci-go/server/auth" 26 "github.com/luci/luci-go/server/auth"
26 "golang.org/x/net/context" 27 "golang.org/x/net/context"
27 ) 28 )
28 29
29 // Repo defines a git repository. 30 // User is the author or the committer returned from gitiles.
30 type Repo struct {
31 » // Server is the full path to a git repository. Server must start with https://
32 » // and should not end with .git.
33 » Server string
34 » // Branch specifies a treeish of a git repository. This is generally a branch.
35 » Branch string
36 }
37
38 // User is the author or the committer returned from a gitiles log request.
39 type User struct { 31 type User struct {
40 Name string `json:"name"` 32 Name string `json:"name"`
41 Email string `json:"email"` 33 Email string `json:"email"`
42 Time string `json:"time"` 34 Time string `json:"time"`
43 } 35 }
44 36
45 // Log is the Log information of a commit returned from a gitiles log request. 37 // Commit is the information of a commit returned from gitiles.
46 type Log struct { 38 type Commit struct {
47 Commit string `json:"commit"` 39 Commit string `json:"commit"`
48 Tree string `json:"tree"` 40 Tree string `json:"tree"`
49 Parents []string `json:"parents"` 41 Parents []string `json:"parents"`
50 Author User `json:"author"` 42 Author User `json:"author"`
51 Committer User `json:"committer"` 43 Committer User `json:"committer"`
52 Message string `json:"message"` 44 Message string `json:"message"`
53 } 45 }
54 46
55 // Commit is the JSON response from querying gitiles for a log request. 47 // LogResponse is the JSON response from querying gitiles for a log request.
56 type Commit struct { 48 type LogResponse struct {
57 » Log []Log `json:"log"` 49 » Log []Commit `json:"log"`
58 » Next string `json:"next"` 50 » Next string `json:"next"`
59 } 51 }
60 52
61 // fixURL validates and normalizes a repoURL and treeish, and returns the 53 // fixURL validates and normalizes a repoURL and treeish, and returns the
62 // log JSON gitiles URL. 54 // log JSON gitiles URL.
63 func fixURL(repoURL, treeish string) (string, error) { 55 func fixURL(repoURL, treeish string) (string, error) {
64 u, err := url.Parse(repoURL) 56 u, err := url.Parse(repoURL)
65 if err != nil { 57 if err != nil {
66 return "", err 58 return "", err
67 } 59 }
68 if u.Scheme != "https" { 60 if u.Scheme != "https" {
69 return "", fmt.Errorf("%s should start with https://", repoURL) 61 return "", fmt.Errorf("%s should start with https://", repoURL)
70 } 62 }
71 if !strings.HasSuffix(u.Host, ".googlesource.com") { 63 if !strings.HasSuffix(u.Host, ".googlesource.com") {
72 return "", fmt.Errorf("Only .googlesource.com repos supported") 64 return "", fmt.Errorf("Only .googlesource.com repos supported")
73 } 65 }
74 // Use the authenticated URL 66 // Use the authenticated URL
75 u.Path = "a/" + u.Path 67 u.Path = "a/" + u.Path
76 URL := fmt.Sprintf("%s/+log/%s?format=JSON", u.String(), treeish) 68 URL := fmt.Sprintf("%s/+log/%s?format=JSON", u.String(), treeish)
77 return URL, nil 69 return URL, nil
78 } 70 }
79 71
80 // GetCommits returns a list of commits based on a repo and treeish (usually 72 // Log returns a list of commits based on a repo and treeish (usually
81 // a branch). This should be equivilent of a "git log <treeish>" call in 73 // a branch). This should be equivilent of a "git log <treeish>" call in
82 // that repository. 74 // that repository.
83 func GetCommits(c context.Context, repoURL, treeish string, limit int) ([]resp.C ommit, error) { 75 func Log(c context.Context, repoURL, treeish string, limit int) ([]Commit, error ) {
84 // TODO(hinoka): Respect the limit. 76 // TODO(hinoka): Respect the limit.
85 URL, err := fixURL(repoURL, treeish) 77 URL, err := fixURL(repoURL, treeish)
86 if err != nil { 78 if err != nil {
87 return nil, err 79 return nil, err
88 } 80 }
89 t, err := auth.GetRPCTransport(c, auth.NoAuth) 81 t, err := auth.GetRPCTransport(c, auth.NoAuth)
90 if err != nil { 82 if err != nil {
91 return nil, err 83 return nil, err
92 } 84 }
93 client := http.Client{Transport: t} 85 client := http.Client{Transport: t}
94 r, err := client.Get(URL) 86 r, err := client.Get(URL)
95 if err != nil { 87 if err != nil {
96 return nil, err 88 return nil, err
97 } 89 }
98 if r.StatusCode != 200 { 90 if r.StatusCode != 200 {
99 return nil, fmt.Errorf("Failed to fetch %s, status code %d", URL , r.StatusCode) 91 return nil, fmt.Errorf("Failed to fetch %s, status code %d", URL , r.StatusCode)
100 } 92 }
101 defer r.Body.Close() 93 defer r.Body.Close()
102 // Strip out the jsonp header, which is ")]}'" 94 // Strip out the jsonp header, which is ")]}'"
103 trash := make([]byte, 4) 95 trash := make([]byte, 4)
104 r.Body.Read(trash) // Read the jsonp header 96 r.Body.Read(trash) // Read the jsonp header
105 » commits := Commit{} 97 » commits := LogResponse{}
106 if err := json.NewDecoder(r.Body).Decode(&commits); err != nil { 98 if err := json.NewDecoder(r.Body).Decode(&commits); err != nil {
107 return nil, err 99 return nil, err
108 } 100 }
109 // TODO(hinoka): If there is a page and we have gotten less than the lim it, 101 // TODO(hinoka): If there is a page and we have gotten less than the lim it,
110 // keep making requests for the next page until we have enough commits. 102 // keep making requests for the next page until we have enough commits.
111 103 » return commits.Log, nil
112 » // Move things into our own datastructure.
113 » result := make([]resp.Commit, len(commits.Log))
114 » for i, log := range commits.Log {
115 » » result[i] = resp.Commit{
116 » » » AuthorName: log.Author.Name,
117 » » » AuthorEmail: log.Author.Email,
118 » » » Repo: repoURL,
119 » » » Revision: resp.NewLink(log.Commit, repoURL+"/+/"+log. Commit),
120 » » » Description: log.Message,
121 » » » Title: strings.SplitN(log.Message, "\n", 2)[0],
122 » » » // TODO(hinoka): Fill in the rest of resp.Commit and add those details
123 » » » // in the html.
124 » » }
125 » }
126 » return result, nil
127 } 104 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698