Chromium Code Reviews| OLD | NEW |
|---|---|
| 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, |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 158 } | 158 } |
| 159 nextPath := subPath + "&s=" + resp.Next | 159 nextPath := subPath + "&s=" + resp.Next |
| 160 resp = &logResponse{} | 160 resp = &logResponse{} |
| 161 if err := c.get(ctx, repoURL, nextPath, resp); err != nil { | 161 if err := c.get(ctx, repoURL, nextPath, resp); err != nil { |
| 162 return nil, err | 162 return nil, err |
| 163 } | 163 } |
| 164 result = append(result, resp.Log...) | 164 result = append(result, resp.Log...) |
| 165 } | 165 } |
| 166 } | 166 } |
| 167 | 167 |
| 168 // Refs returns a map resolving each ref in a repo to git revision. | |
| 169 // | |
| 170 // refsPath limits whcih refs to resolve to only those matching {refsPath}/*. | |
|
Vadim Sh.
2017/07/20 21:09:09
which
tandrii(chromium)
2017/07/20 22:12:05
Done.
| |
| 171 // refsPath should start with "refs" and should not include glob '*'. | |
| 172 // Typically, "refs/heads" should be used. | |
| 173 // | |
| 174 // To fetch **all** refs in a repo, specify just "refs" but beware of two | |
| 175 // caveats: | |
| 176 // * refs returned include a ref for each patchset for each Gerrit change | |
| 177 // associated with the repo | |
| 178 // * returned map will contain special "HEAD" ref whose value in resulting map | |
| 179 // will be name of the actual ref to which "HEAD" points, which is typically | |
| 180 // "refs/heads/master". | |
| 181 // | |
| 182 // Thus, if you are looking for all tags and all branches of repo, it's | |
| 183 // recommended to issue two Refs calls limited to "refs/tags" and "refs/heads" | |
| 184 // instead of one call for "refs". | |
| 185 // | |
| 186 // Since Gerrit allows per-ref ACLs, it is possible that some refs matching | |
| 187 // refPrefix would not be present in results because current user isn't granted | |
| 188 // read permission on them. | |
| 189 func (c *Client) Refs(ctx context.Context, repoURL, refsPath string) (map[string ]string, error) { | |
| 190 repoURL, err := NormalizeRepoURL(repoURL) | |
| 191 if err != nil { | |
| 192 return nil, err | |
| 193 } | |
| 194 if !strings.HasPrefix(refsPath, "refs") { | |
|
Vadim Sh.
2017/07/20 21:09:09
refsPath != "refs" && !strings.HasPrefix(refsPath,
tandrii(chromium)
2017/07/20 22:12:05
Done.
| |
| 195 return nil, fmt.Errorf("refsPath must start with \"refs\": %q", refsPath) | |
| 196 } | |
| 197 refsPath = strings.TrimRight(refsPath, "/") | |
| 198 | |
| 199 subPath := fmt.Sprintf("+%s?format=json", url.PathEscape(refsPath)) | |
| 200 resp := refsResponse{} | |
| 201 if err := c.get(ctx, repoURL, subPath, &resp); err != nil { | |
| 202 return nil, err | |
| 203 } | |
| 204 r := make(map[string]string, len(resp)) | |
| 205 for ref, v := range resp { | |
| 206 switch { | |
| 207 case v.Value == "": | |
| 208 // Weird case of what looks like hash with a target in a t least Chromium | |
| 209 // repo. | |
| 210 continue | |
| 211 case ref == "HEAD": | |
| 212 r["HEAD"] = v.Target | |
| 213 case refsPath != "refs": | |
| 214 // Gitiles omits refsPath from each ref if refsPath != " refs". Undo this | |
| 215 // inconsistency. | |
| 216 r[refsPath+"/"+ref] = v.Value | |
| 217 default: | |
| 218 r[ref] = v.Value | |
| 219 } | |
| 220 } | |
| 221 return r, nil | |
| 222 } | |
| 223 | |
| 168 //////////////////////////////////////////////////////////////////////////////// | 224 //////////////////////////////////////////////////////////////////////////////// |
| 169 | 225 |
| 226 type refsResponseRefInfo struct { | |
| 227 Value string `json:"value"` | |
| 228 Target string `json:"target"` | |
| 229 } | |
| 230 | |
| 231 // refsResponse is the JSON response from querying gitiles for a Refs request. | |
| 232 type refsResponse map[string]refsResponseRefInfo | |
| 233 | |
| 170 // logResponse is the JSON response from querying gitiles for a log request. | 234 // logResponse is the JSON response from querying gitiles for a log request. |
| 171 type logResponse struct { | 235 type logResponse struct { |
| 172 Log []Commit `json:"log"` | 236 Log []Commit `json:"log"` |
| 173 Next string `json:"next"` | 237 Next string `json:"next"` |
| 174 } | 238 } |
| 175 | 239 |
| 176 func (c *Client) get(ctx context.Context, repoURL, subPath string, result interf ace{}) error { | 240 func (c *Client) get(ctx context.Context, repoURL, subPath string, result interf ace{}) error { |
| 177 URL := fmt.Sprintf("%s/%s", repoURL, subPath) | 241 URL := fmt.Sprintf("%s/%s", repoURL, subPath) |
| 178 if c.mockRepoURL != "" { | 242 if c.mockRepoURL != "" { |
| 179 URL = fmt.Sprintf("%s/%s", c.mockRepoURL, subPath) | 243 URL = fmt.Sprintf("%s/%s", c.mockRepoURL, subPath) |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 198 return errors.Annotate(err, "unexpected response from Gitiles"). Err() | 262 return errors.Annotate(err, "unexpected response from Gitiles"). Err() |
| 199 } | 263 } |
| 200 if cnt != 4 || ")]}'" != string(trash) { | 264 if cnt != 4 || ")]}'" != string(trash) { |
| 201 return errors.New("unexpected response from Gitiles") | 265 return errors.New("unexpected response from Gitiles") |
| 202 } | 266 } |
| 203 if err = json.NewDecoder(r.Body).Decode(result); err != nil { | 267 if err = json.NewDecoder(r.Body).Decode(result); err != nil { |
| 204 return errors.Annotate(err, "failed to decode Gitiles response i nto %T", result).Err() | 268 return errors.Annotate(err, "failed to decode Gitiles response i nto %T", result).Err() |
| 205 } | 269 } |
| 206 return nil | 270 return nil |
| 207 } | 271 } |
| OLD | NEW |