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

Unified Diff: go/src/infra/libs/gitiles/gitiles.go

Issue 662113003: Drover's back, baby! (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git/+/master
Patch Set: more tests and refactors Created 6 years, 2 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « go/src/infra/libs/git/user_test.go ('k') | go/src/infra/libs/gitiles/priv_jsonCommitDiff.go » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: go/src/infra/libs/gitiles/gitiles.go
diff --git a/go/src/infra/libs/gitiles/gitiles.go b/go/src/infra/libs/gitiles/gitiles.go
new file mode 100644
index 0000000000000000000000000000000000000000..ea7045ac0dc13452be305fb94ac81032c7f39190
--- /dev/null
+++ b/go/src/infra/libs/gitiles/gitiles.go
@@ -0,0 +1,155 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package gitiles
+
+import (
+ "io"
+ "net/http"
+ "reflect"
+ "strings"
+
+ "infra/libs/git"
+)
+
+// Types ///////////////////////////////////////////////////////////////////////
+
+// Gitiles wraps one Gitiles server. Use NewGitiles to create one.
+type Gitiles struct {
+ url string
+ requests chan<- request
+}
+
+// Constructors ///////////////////////////////////////////////////////////////
+
+// NewGitiles creates a new Gitiles instance for the given |url|, and a maximum
+// number of concurrent requests.
+func NewGitiles(url string, maxConnections int) *Gitiles {
+ // TODO(iannucci): make a separate http.Client?
+ // TODO(iannucci): have a way to destroy the Gitiles instance?
+ requestChan := make(chan request, maxConnections)
+ ret := &Gitiles{
+ url: strings.TrimRight(url, "/"),
+ requests: requestChan,
+ }
+ for i := 0; i < maxConnections; i++ {
+ go ret.requestProcessor(requestChan)
+ }
+ return ret
+}
+
+// Member functions ////////////////////////////////////////////////////////////
+
+// URL returns the base url for this Gitiles service wrapper
+func (g *Gitiles) URL() string { return g.url }
+
+// JSON Returns an instance of target or an error.
+//
+// Example:
+// data := map[string]int{}
+// result, err := g.JSON(data, "some", "url", "pieces")
+// if err != nil { panic(err) }
+// data = *result.(*map[string]int)
+func (g *Gitiles) JSON(target interface{}, pieces ...string) (interface{}, error) {
+ reply := make(chan jsonResult, 1)
+ g.requests <- jsonRequest{
+ strings.Join(pieces, "/"),
+ reflect.TypeOf(target),
+ reply,
+ }
+ rslt := <-reply
+ return rslt.dataPtr, rslt.err
+}
+
+// Text returns the decoded text data or an error. It will load the given path
+// with format=TEXT and apply the base64 decoding.
+func (g *Gitiles) Text(pieces ...string) ([]byte, error) {
+ reply := make(chan textResult, 1)
+ g.requests <- textRequest{
+ strings.Join(pieces, "/"),
+ reply,
+ }
+ rslt := <-reply
+ return rslt.data, rslt.err
+}
+
+// GetObjectFromPath returns the git Object at the given commit:path, or an error.
+// This will hit the url:
+// {g.url}/+/{committish}/path/pieces...?format=TEXT
+// Passing NO pieces will return a git.Commit
+// Passing A blank piece (e.g. empty string) will return a git.Tree for the root
+// tree.
+// Passing non-blank pieces will return a git.Tree or git.Blob depending on
+// the path.
+func (g *Gitiles) GetObjectFromPath(committish string, pathPieces ...string) (git.InternableObject, error) {
+ ret := make(chan objectResult, 1)
+ g.requests <- objRequest{
+ textRequest{
+ strings.Join(append([]string{"+", committish}, pathPieces...), "/"),
+ nil,
+ },
+ ret,
+ }
+ rslt := <-ret
+ return rslt.object, rslt.err
+}
+
+// GetCommitDiff returns the git.TreeDiff from the given committish.
+func (g *Gitiles) GetCommitDiff(committish string) (git.TreeDiff, error) {
+ rslt, err := g.JSON(jsonCommitDiff{}, "+", committish)
+ if err != nil {
+ return nil, err
+ }
+ diff := *rslt.(*jsonCommitDiff)
+ return diff.ToResult()
+}
+
+func (g *Gitiles) GetTextCommitDiff(id *git.ObjectID) (string, error) {
+ rslt, err := g.Text("+", id.String()+"^!")
+ if err != nil {
+ return "", err
+ }
+ return string(rslt), nil
+}
+
+// Private /////////////////////////////////////////////////////////////////////
+
+type request interface {
+ Process(rsp *http.Response, err error)
+ Method() string
+ URLPath() string
+ Body() io.Reader
+}
+
+func (g *Gitiles) requestProcessor(queue <-chan request) {
+ // Launched as a goroutine to avoid blocking the request processor.
+ for r := range queue {
+ r := r
+ if r == nil {
+ continue
+ }
+
+ var req *http.Request
+ req, err := http.NewRequest(r.Method(), g.url+"/"+r.URLPath(), r.Body())
+ if err != nil {
+ r.Process(nil, err)
+ continue
+ }
+
+ rsp, err := http.DefaultClient.Do(req)
+ if err != nil {
+ r.Process(nil, err)
+ continue
+ }
+
+ e := StatusError(rsp.StatusCode)
+ if e.Bad() {
+ err = e
+ }
+ func() {
+ defer rsp.Body.Close()
+ r.Process(rsp, err)
+ }()
+ }
+}
« no previous file with comments | « go/src/infra/libs/git/user_test.go ('k') | go/src/infra/libs/gitiles/priv_jsonCommitDiff.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698