Created
October 27, 2016 01:56
-
-
Save thinca/ee3707b01a1aee1403dd511ec69d9aba to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"net/http" | |
"os" | |
"runtime" | |
"strconv" | |
"strings" | |
"golang.org/x/oauth2" | |
"github.com/google/go-github/github" | |
"github.com/haya14busa/errorformat" | |
"github.com/haya14busa/reviewdog" | |
) | |
type githubPR struct { | |
owner string | |
repo string | |
pr int | |
sha string | |
} | |
const usageMessage = ` | |
run-your-lint | curl -X POST \ | |
-F "owner=vim-jp" \ | |
-F "repos=vital.vim" \ | |
-F "pr_number=1" \ | |
-F "sha=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \ | |
-F "result=@-" \ | |
-F "efm=%f:%l:%c:%m" \ | |
review.example.com | |
` | |
func main() { | |
http.HandleFunc("/", mainHandler) | |
bind := fmt.Sprintf("%s:%s", os.Getenv("OPENSHIFT_GO_IP"), os.Getenv("OPENSHIFT_GO_PORT")) | |
fmt.Printf("listening on %s...", bind) | |
err := http.ListenAndServe(bind, nil) | |
if err != nil { | |
panic(err) | |
} | |
} | |
func mainHandler(res http.ResponseWriter, req *http.Request) { | |
switch req.Method { | |
case "GET": | |
fmt.Fprintf(res, "hello, world from %s", runtime.Version()) | |
case "POST": | |
err := req.ParseMultipartForm(1024 * 1024) | |
if err != nil { | |
res.WriteHeader(http.StatusBadRequest) | |
fmt.Fprintf(res, "Invalid form value %v", err) | |
return | |
} | |
fmt.Println(res, "MultipartForm: %+v\n", req.MultipartForm) | |
value := req.MultipartForm.Value | |
efms, ok := value["efm"] | |
if !ok { | |
res.WriteHeader(http.StatusBadRequest) | |
fmt.Fprintf(res, "Requires efm parameter") | |
return | |
} | |
p, err := efmParser(efms) | |
if err != nil { | |
res.WriteHeader(http.StatusBadRequest) | |
fmt.Fprintf(res, "Invalid efm: %v", efms) | |
return | |
} | |
gparam, err := getParameters(value) | |
if err != nil { | |
res.WriteHeader(http.StatusBadRequest) | |
fmt.Fprintf(res, "Invalid parameter: %v", err) | |
return | |
} | |
ok = verifyParam(gparam) | |
if !ok { | |
res.WriteHeader(http.StatusBadRequest) | |
fmt.Fprintf(res, "Not allowed: %v", gparam) | |
return | |
} | |
gs, err := githubService(gparam) | |
if err != nil { | |
res.WriteHeader(http.StatusBadRequest) | |
fmt.Fprintf(res, "Invalid parameter: %v", gparam) | |
return | |
} | |
result, ok := req.MultipartForm.File["result"] | |
if !ok { | |
res.WriteHeader(http.StatusBadRequest) | |
fmt.Fprintf(res, "Requires result parameter") | |
return | |
} | |
file, err := result[0].Open() | |
if err != nil { | |
res.WriteHeader(http.StatusInternalServerError) | |
fmt.Fprintf(res, "Fails on open result: %v", err) | |
return | |
} | |
defer file.Close() | |
app := reviewdog.NewReviewdog("", p, gs, gs) | |
if err := app.Run(file); err != nil { | |
res.WriteHeader(http.StatusInternalServerError) | |
fmt.Fprintf(res, "Error with run: %v", err) | |
return | |
} | |
for _, c := range gs.ListPostComments() { | |
fmt.Fprintln(res, strings.Join(c.Lines, "\n")) | |
} | |
gs.Flash() | |
} | |
} | |
func efmParser(efms []string) (reviewdog.Parser, error) { | |
efm, err := errorformat.NewErrorformat(efms) | |
if err != nil { | |
return nil, err | |
} | |
return reviewdog.NewErrorformatParser(efm), nil | |
} | |
func getParameters(value map[string][]string) (*githubPR, error) { | |
prs, ok := value["pr_number"] | |
if !ok { | |
return nil, fmt.Errorf("Requires pr_number parameter") | |
} | |
pr, err := strconv.Atoi(prs[0]) | |
if err != nil { | |
return nil, fmt.Errorf("unexpected value (pr_number): %v", prs) | |
} | |
owner, ok := value["owner"] | |
if !ok { | |
return nil, fmt.Errorf("Requires pr_number parameter") | |
} | |
repo, ok := value["repos"] | |
if !ok { | |
return nil, fmt.Errorf("Requires repos parameter") | |
} | |
sha, ok := value["sha"] | |
if !ok { | |
return nil, fmt.Errorf("Requires sha parameter") | |
} | |
g := &githubPR{ | |
owner: owner[0], | |
repo: repo[0], | |
pr: pr, | |
sha: sha[0], | |
} | |
return g, nil | |
} | |
func verifyParam(g *githubPR) bool { | |
// return g.owner == "vim-jp" | |
return true | |
} | |
func githubService(g *githubPR) (githubservice *reviewdog.GitHubPullRequest, err error) { | |
token, err := nonEmptyEnv("REVIEWDOG_GITHUB_API_TOKEN") | |
if err != nil { | |
return nil, err | |
} | |
ts := oauth2.StaticTokenSource( | |
&oauth2.Token{AccessToken: token}, | |
) | |
tc := oauth2.NewClient(oauth2.NoContext, ts) | |
client := github.NewClient(tc) | |
githubservice = reviewdog.NewGitHubPullReqest(client, g.owner, g.repo, g.pr, g.sha) | |
return githubservice, nil | |
} | |
func nonEmptyEnv(env string) (string, error) { | |
v := os.Getenv(env) | |
if v == "" { | |
return "", fmt.Errorf("environment variable $%v is not set", env) | |
} | |
return v, nil | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment