fe85fefcc5
Change-Id: Idfe81897dc701c24c0f81b0021cb1d640e8224ac
192 lines
5.3 KiB
Go
192 lines
5.3 KiB
Go
// Copyright (C) 2022 Storj Labs, Inc.
|
|
// See LICENSE for copying information.
|
|
|
|
//go:build ignore
|
|
// +build ignore
|
|
|
|
package main
|
|
|
|
import (
|
|
"context"
|
|
"flag"
|
|
"log"
|
|
"os"
|
|
"os/exec"
|
|
"os/signal"
|
|
"runtime"
|
|
"strings"
|
|
"syscall"
|
|
"time"
|
|
|
|
"storj.io/common/sync2"
|
|
)
|
|
|
|
func newCommand(ctx context.Context, directory string, name string, args ...string) *exec.Cmd {
|
|
cmd := exec.CommandContext(ctx, name, args...)
|
|
cmd.Dir = directory
|
|
|
|
return cmd
|
|
}
|
|
|
|
type Checks struct {
|
|
Modules bool
|
|
Copyright bool
|
|
Imports bool
|
|
PeerConstraints bool
|
|
AtomicAlign bool
|
|
Monkit bool
|
|
Errors bool
|
|
Static bool
|
|
Monitoring bool
|
|
WASMSize bool
|
|
Protolock bool
|
|
CheckDowngrades bool
|
|
GolangCI bool
|
|
}
|
|
|
|
func main() {
|
|
workDir, err := os.Getwd()
|
|
if err != nil {
|
|
log.Fatalln("error", err)
|
|
}
|
|
checks := Checks{}
|
|
|
|
parallel := flag.Int("parallel", runtime.NumCPU(), "specify the number of tasks to run concurrently")
|
|
race := flag.Bool("race", false, "pass race to appropriate linters")
|
|
flag.StringVar(&workDir, "work-dir", workDir, "specify the working directory")
|
|
|
|
flag.BoolVar(&checks.Modules, "modules", checks.Modules, "check module tidiness")
|
|
flag.BoolVar(&checks.Copyright, "copyright", checks.Copyright, "ensure copyright")
|
|
flag.BoolVar(&checks.Imports, "imports", checks.Imports, "check import usage")
|
|
flag.BoolVar(&checks.PeerConstraints, "peer-constraints", checks.PeerConstraints, "check peer constraints")
|
|
flag.BoolVar(&checks.AtomicAlign, "atomic-align", checks.AtomicAlign, "ensure atomic alignment")
|
|
flag.BoolVar(&checks.Monkit, "monkit", checks.Monkit, "check monkit usage")
|
|
flag.BoolVar(&checks.Errors, "errs", checks.Errors, "check error usage")
|
|
flag.BoolVar(&checks.Static, "staticcheck", checks.Static, "perform static analysis checks against the code base")
|
|
flag.BoolVar(&checks.Monitoring, "monitoring", checks.Monitoring, "check monitoring")
|
|
flag.BoolVar(&checks.WASMSize, "wasm-size", checks.WASMSize, "check the wasm file size for optimal performance")
|
|
flag.BoolVar(&checks.Protolock, "protolock", checks.Protolock, "check the status of the protolock file")
|
|
flag.BoolVar(&checks.CheckDowngrades, "check-downgrades", checks.CheckDowngrades, "run the check-downgrades tool")
|
|
flag.BoolVar(&checks.GolangCI, "golangci", checks.GolangCI, "run the golangci-lint tool")
|
|
|
|
flag.Parse()
|
|
|
|
target := []string{"./..."}
|
|
if args := flag.Args(); len(args) > 0 {
|
|
target = args
|
|
}
|
|
|
|
ctx, halt := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
|
|
defer halt()
|
|
|
|
limiter := sync2.NewLimiter(*parallel)
|
|
|
|
submit := func(cmd *exec.Cmd) bool {
|
|
prefix := "[" + cmd.Dir + " " + strings.Join(cmd.Args, " ") + "]"
|
|
|
|
return limiter.Go(ctx, func() {
|
|
start := time.Now()
|
|
|
|
log.Println(prefix, "running")
|
|
defer func() {
|
|
log.Println(prefix, "done", time.Since(start))
|
|
}()
|
|
|
|
out, _ := cmd.CombinedOutput()
|
|
exitCode := cmd.ProcessState.ExitCode()
|
|
if exitCode > 0 {
|
|
log.Fatalln(prefix, "error", string(out))
|
|
}
|
|
})
|
|
}
|
|
|
|
// separate commands into two tiers to handle commands that can not be run in parallel (like staticcheck and
|
|
// golangci-lint).
|
|
commands := [][]*exec.Cmd{
|
|
make([]*exec.Cmd, 0, 10),
|
|
make([]*exec.Cmd, 0, 1),
|
|
}
|
|
|
|
if checks.Modules {
|
|
commands[0] = append(commands[0], newCommand(ctx, workDir, "check-mod-tidy"))
|
|
}
|
|
|
|
if checks.Copyright {
|
|
commands[0] = append(commands[0], newCommand(ctx, workDir, "check-copyright"))
|
|
}
|
|
|
|
if checks.Imports {
|
|
args := make([]string, 0, 2)
|
|
if *race {
|
|
args = append(args, "-race")
|
|
}
|
|
|
|
args = append(args, target...)
|
|
commands[0] = append(commands[0], newCommand(ctx, workDir, "check-imports", args...))
|
|
}
|
|
|
|
if checks.PeerConstraints {
|
|
args := make([]string, 0, 1)
|
|
if *race {
|
|
args = append(args, "-race")
|
|
}
|
|
|
|
commands[0] = append(commands[0], newCommand(ctx, workDir, "check-peer-constraints", args...))
|
|
}
|
|
|
|
if checks.AtomicAlign {
|
|
commands[0] = append(commands[0], newCommand(ctx, workDir, "check-atomic-align", target...))
|
|
}
|
|
|
|
if checks.Monkit {
|
|
commands[0] = append(commands[0], newCommand(ctx, workDir, "check-monkit", target...))
|
|
}
|
|
|
|
if checks.Errors {
|
|
commands[0] = append(commands[0], newCommand(ctx, workDir, "check-errs", target...))
|
|
}
|
|
|
|
if checks.Static {
|
|
commands[0] = append(commands[0], newCommand(ctx, workDir, "staticcheck", target...))
|
|
}
|
|
|
|
if checks.Monitoring {
|
|
commands[0] = append(commands[0], newCommand(ctx, workDir, "make", "check-monitoring"))
|
|
}
|
|
|
|
if checks.WASMSize {
|
|
commands[0] = append(commands[0], newCommand(ctx, workDir, "make", "test-wasm-size"))
|
|
}
|
|
|
|
if checks.Protolock {
|
|
commands[0] = append(commands[0], newCommand(ctx, workDir, "protolock", "status"))
|
|
}
|
|
|
|
if checks.CheckDowngrades {
|
|
commands[0] = append(commands[0], newCommand(ctx, workDir, "check-downgrades", target...))
|
|
}
|
|
|
|
if checks.GolangCI {
|
|
args := append([]string{"--config", "/go/ci/.golangci.yml", "--skip-dirs", "(^|/)node_modules($|/)", "-j=2", "run"}, target...)
|
|
commands[1] = append(commands[1], newCommand(ctx, workDir, "golangci-lint", args...))
|
|
}
|
|
|
|
start := time.Now()
|
|
defer func() {
|
|
log.Println("total time", time.Since(start))
|
|
}()
|
|
|
|
for _, tier := range commands {
|
|
for _, cmd := range tier {
|
|
ok := submit(cmd)
|
|
if !ok {
|
|
log.Fatalln("error", "failed to submit task to queue")
|
|
}
|
|
}
|
|
|
|
limiter.Wait()
|
|
}
|
|
|
|
limiter.Wait()
|
|
}
|