2020-10-09 17:47:59 +03:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"flag"
|
|
|
|
"fmt"
|
|
|
|
"net/http"
|
2020-10-13 19:29:29 +03:00
|
|
|
"os"
|
2020-10-09 18:26:43 +03:00
|
|
|
"sort"
|
2020-10-09 17:47:59 +03:00
|
|
|
"strings"
|
|
|
|
"sync"
|
|
|
|
|
|
|
|
"github.com/dlorenc/scorecard/checker"
|
|
|
|
"github.com/dlorenc/scorecard/checks"
|
|
|
|
"github.com/dlorenc/scorecard/roundtripper"
|
|
|
|
"github.com/google/go-github/v32/github"
|
2020-10-13 19:29:29 +03:00
|
|
|
"github.com/prometheus/common/log"
|
|
|
|
"go.uber.org/zap"
|
2020-10-09 17:47:59 +03:00
|
|
|
)
|
|
|
|
|
|
|
|
var repo = flag.String("repo", "", "url to the repo")
|
|
|
|
var checksToRun = flag.String("checks", "", "specific checks to run, instead of all")
|
2020-10-13 21:51:24 +03:00
|
|
|
var logLevel = zap.LevelFlag("verbosity", zap.InfoLevel, "override the default log level")
|
2020-10-09 17:47:59 +03:00
|
|
|
|
2020-10-09 18:26:43 +03:00
|
|
|
type result struct {
|
2020-10-13 18:35:55 +03:00
|
|
|
cr checker.CheckResult
|
2020-10-09 18:26:43 +03:00
|
|
|
name string
|
|
|
|
}
|
|
|
|
|
2020-10-16 17:54:29 +03:00
|
|
|
func stringInListOrEmpty(s string, list []string) bool {
|
|
|
|
if len(list) == 0 {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
for _, le := range list {
|
|
|
|
if le == s {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2020-10-18 03:08:53 +03:00
|
|
|
func displayResult(result bool) string {
|
|
|
|
if result {
|
|
|
|
return "pass"
|
|
|
|
} else {
|
|
|
|
return "fail"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-09 17:47:59 +03:00
|
|
|
func main() {
|
|
|
|
flag.Parse()
|
2020-10-13 21:51:24 +03:00
|
|
|
cfg := zap.NewProductionConfig()
|
|
|
|
cfg.Level.SetLevel(*logLevel)
|
|
|
|
logger, _ := cfg.Build()
|
2020-10-13 19:29:29 +03:00
|
|
|
defer logger.Sync() // flushes buffer, if any
|
|
|
|
sugar := logger.Sugar()
|
2020-10-09 17:47:59 +03:00
|
|
|
|
|
|
|
split := strings.SplitN(*repo, "/", 3)
|
2020-10-14 21:28:10 +03:00
|
|
|
if len(split) != 3 {
|
|
|
|
log.Fatalf("invalid repo flag: %s, pass the full repository URL", *repo)
|
|
|
|
}
|
2020-10-09 17:47:59 +03:00
|
|
|
host, owner, repo := split[0], split[1], split[2]
|
|
|
|
|
|
|
|
switch host {
|
|
|
|
case "github.com":
|
|
|
|
default:
|
|
|
|
log.Fatalf("unsupported host: %s", host)
|
|
|
|
}
|
|
|
|
|
|
|
|
ctx := context.Background()
|
|
|
|
|
2020-10-09 18:26:43 +03:00
|
|
|
// Use our custom roundtripper
|
2020-10-13 19:29:29 +03:00
|
|
|
rt := roundtripper.NewTransport(ctx, sugar)
|
2020-10-09 17:47:59 +03:00
|
|
|
|
|
|
|
client := &http.Client{
|
|
|
|
Transport: rt,
|
|
|
|
}
|
|
|
|
ghClient := github.NewClient(client)
|
|
|
|
|
2020-10-13 18:35:55 +03:00
|
|
|
c := checker.Checker{
|
2020-10-09 17:47:59 +03:00
|
|
|
Ctx: ctx,
|
|
|
|
Client: ghClient,
|
|
|
|
HttpClient: client,
|
|
|
|
Owner: owner,
|
|
|
|
Repo: repo,
|
|
|
|
}
|
|
|
|
|
2020-10-09 18:26:43 +03:00
|
|
|
resultsCh := make(chan result)
|
2020-10-09 17:47:59 +03:00
|
|
|
wg := sync.WaitGroup{}
|
2020-10-16 17:54:29 +03:00
|
|
|
checksToRunList := []string{}
|
|
|
|
if len(*checksToRun) > 0 {
|
|
|
|
checksToRunList = strings.Split(*checksToRun, ",")
|
|
|
|
}
|
2020-10-09 17:47:59 +03:00
|
|
|
for _, check := range checks.AllChecks {
|
|
|
|
check := check
|
2020-10-16 17:54:29 +03:00
|
|
|
if !stringInListOrEmpty(check.Name, checksToRunList) {
|
|
|
|
continue
|
|
|
|
}
|
2020-10-09 17:47:59 +03:00
|
|
|
wg.Add(1)
|
2020-10-13 19:29:29 +03:00
|
|
|
fmt.Fprintf(os.Stderr, "Starting [%s]\n", check.Name)
|
2020-10-09 17:47:59 +03:00
|
|
|
go func() {
|
|
|
|
defer wg.Done()
|
2020-10-13 18:35:55 +03:00
|
|
|
runner := checker.Runner{Checker: c}
|
|
|
|
r := runner.Run(check.Fn)
|
2020-10-09 18:26:43 +03:00
|
|
|
resultsCh <- result{
|
|
|
|
name: check.Name,
|
|
|
|
cr: r,
|
|
|
|
}
|
2020-10-09 17:47:59 +03:00
|
|
|
}()
|
|
|
|
}
|
2020-10-09 18:26:43 +03:00
|
|
|
go func() {
|
|
|
|
wg.Wait()
|
|
|
|
close(resultsCh)
|
|
|
|
}()
|
2020-10-09 17:47:59 +03:00
|
|
|
|
2020-10-09 18:26:43 +03:00
|
|
|
// Collect results
|
|
|
|
results := []result{}
|
|
|
|
for result := range resultsCh {
|
2020-10-13 19:29:29 +03:00
|
|
|
fmt.Fprintf(os.Stderr, "Finished [%s]\n", result.name)
|
2020-10-09 18:26:43 +03:00
|
|
|
results = append(results, result)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Sort them by name
|
|
|
|
sort.Slice(results, func(i, j int) bool {
|
|
|
|
return results[i].name < results[j].name
|
|
|
|
})
|
|
|
|
|
|
|
|
fmt.Println()
|
|
|
|
fmt.Println("RESULTS")
|
|
|
|
fmt.Println("-------")
|
|
|
|
for _, r := range results {
|
2020-10-18 03:08:53 +03:00
|
|
|
fmt.Println(r.name, displayResult(r.cr.Pass), r.cr.Confidence)
|
2020-10-09 18:26:43 +03:00
|
|
|
}
|
2020-10-09 17:47:59 +03:00
|
|
|
}
|