[WIP] rb-gateway

Review Request #6825 — Created Jan. 23, 2015 and discarded

Information

Reviewers

This is the beginnings of the rb-gateway project. It is meant to extend existing ReviewBoard functionalities to provide better support for repositories.

Currently, this is a wireframe set up using Google Go (no additional frameworks).

Structure is as followed:
- repository.go : Base repository structure and interface
- git_repository.go : The Git implementation of repository.go
- web_service.go : Handles all web services and routing
- util.go : Handles configuration loading and repository lookup
- config.json : Sample configuration file using .json format
- main.go : main() lives here

Currently as a test, the web server runs on port 8888. A sample works as follows:
1. Specify repo_name = path in config.json (see file attachment)
2. After the server is started, go to ./localhost:8888?repo=repo_name&id=sha
3. A file should download, however my shell exec command isn't currently working in Go - need to fix.


 
package main
// Base Repository "class"
type RepositoryInfo struct {
    Name string
    Path string
}
type Repository interface {
    GetName() string
    GetPath() string
    GetFile(id string) []byte
    GetFileExists(id string) bool
}
package main
import (
    "io"
    "net/http"
)
const (
    REPO = "repo"       // repo where the file is located
    ID = "id"           // a sha in Git, nodeid in Mercurial, etc.
)
// Sends a response containing the file blob, if it exists
// Currently uses request params - to change to path params?
// i.e. /file/repo/id instead of
//      /file?repo=repo1&id=sha1sha
func GetFile(w http.ResponseWriter, r *http.Request) {
    repoName := r.URL.Query().Get(REPO)
    id := r.URL.Query().Get(ID)
    if len(repoName) != 0 && len(id) != 0 {
        //GetRepository(repoName).GetFile(id)
        repo := GetRepository(repoName)
        w.Header().Set("Content-Type", "application/octet-stream")
        w.Write(repo.GetFile(id))
    }
}
// Sends a true or false response depending on whether the file exists
// Currently uses request params - to change to path params?
// i.e. /file/repo/name/id instead of
//      /file?repo=repo1&id=sha1
func FileExists(w http.ResponseWriter, r *http.Request
package main
import (
    "encoding/json"
    "log"
    "io/ioutil"
)
var Repos []Repository
// Loads the configuration file. The configuration file is assumed to
// be a json file. Currently just loads all repositories with their
// corresponding file paths. It also reads in the SCM type, which
// I intend to identify through the program in the future without
// needing it to be specified in the config
func LoadConfig() {
    const CONF_PATH = "config.json"
    type JsonRepo struct {
        Name    string
        Path    string
        Scm     string
    }
    type Configuration struct {
        Repositories []JsonRepo
    }
    var conf Configuration
    content, err := ioutil.ReadFile(CONF_PATH)
    if err != nil {
        log.Fatal("ReadFile: ", err)
    }
    if json.Unmarshal(content, &conf) != nil {
        log.Fatal("Unmarshal: ", err)
    }
    for _, r := range conf.Repositories {
        switch r.Scm {
            // to implement more later.. for now it's just git
package main
import (
    "net/http"
    "log"
)
func main() {
    // this calls loadConfig in util.go.
    // I might put util.go in another package in the near future
    LoadConfig()
    // this calls service.go's route to handle the routing.
    Route()
    // Start the server on port 8888
    err := http.ListenAndServe(":8888", nil)
    if err != nil {
        log.Fatal("ListenAndServe: ", err)
    }
}
package main
import (
    "os/exec"
    "fmt"
)
type GitRepository struct {
    RepositoryInfo
}
func (repo *GitRepository) GetName() string {
    return repo.Name
}
func (repo *GitRepository) GetPath() string {
    return repo.Path
}
// GetFile implementation - returns the file bytes
// after executing cd /path/to/repo ; git show sha
// This cmd is returning an empty byte[] for me atm, need to investigate later
func (repo *GitRepository) GetFile(id string) []byte {
    out, _ := exec.Command("cd", repo.Path, ";", "git", "show", id).Output()
    fmt.Println(out)
    return out
}
// GetFileExists implementation - returns true if the file exists
// after executing cd /path/to/repo ; git show sha
func (repo *GitRepository) GetFileExists(id string) bool {
    cmd := exec.Command("cd", repo.Path, ";", "git", "show", id)
    return cmd.Run() == nil
}
{
    "repositories":[
        {"name":"testrepo", "path":"/home/j/src/git-sandbox", "scm":"git"}
    ]
}

Description From Last Updated

It might be worthwhile to just set the Dir directly and then run git, instead of cd'ing. cmd := exec.Command("git", …

TB tbelaire

Might want to return a 404 if it's not there.

TB tbelaire

You don't really wan't to be executing shell scripts ever, just in case something is misconfigured.

brenniebrennie
There are no open issues
TB
  1. 
      
  2. Same here, the status code is a nice and easy way to check if it exists. It's like an exit code on a command line tool compared to checking the stdout.

  3. Show all issues

    Might want to return a 404 if it's not there.

  4. 
      
TB
  1. 
      
  2. Git Repository (Revision 1)
    24
        out, _ := exec.Command("cd", repo.Path, ";", "git", "show", id).Output()
    Show all issues

    It might be worthwhile to just set the Dir directly and then run git, instead of cd'ing.

    cmd := exec.Command("git", "show", id)
    cmd.Dir := repo.Path
    out, _ := cmd.Output()
    
    1. Hmm it seems cmd.Dir might not be a valid property ("non-name cmd.Dir on left side of :=") but I'm going to drop this issue since I will be testing git2go for now.

  3. 
      
brennie
  1. 
      
  2. Git Repository (Revision 1)
    24
        out, _ := exec.Command("cd", repo.Path, ";", "git", "show", id).Output()
    Show all issues

    You don't really wan't to be executing shell scripts ever, just in case something is misconfigured.

    1. Barret, is there a library that you would recommend I use to communicate with the git repos in this case? I think you mentioned libgit2.

    2. git2go is a wrapper around libgit2 that is maintained by the people who write libgit2.

  3. 
      
JY
Review request changed
Status:
Discarded
Change Summary:

Opening a new review request that points at rb-gateway

Loading...