123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 |
- // Copyright (C) 2017 The Syncthing Authors.
- //
- // This Source Code Form is subject to the terms of the Mozilla Public
- // License, v. 2.0. If a copy of the MPL was not distributed with this file,
- // You can obtain one at https://mozilla.org/MPL/2.0/.
- package meta
- import (
- "bytes"
- "log"
- "os/exec"
- "strings"
- "testing"
- )
- var (
- // fast linters complete in a fraction of a second and might as well be
- // run always as part of the build
- fastLinters = []string{
- "deadcode",
- "golint",
- "ineffassign",
- "vet",
- }
- // slow linters take several seconds and are run only as part of the
- // "metalint" command.
- slowLinters = []string{
- "gosimple",
- "staticcheck",
- "structcheck",
- "unused",
- "varcheck",
- }
- // Which parts of the tree to lint
- lintDirs = []string{
- ".",
- "../cmd/...",
- "../lib/...",
- "../script/...",
- }
- // Messages to ignore
- lintExcludes = []string{
- ".pb.go",
- "should have comment",
- "protocol.Vector composite literal uses unkeyed fields",
- "cli.Requires composite literal uses unkeyed fields",
- "Use DialContext instead", // Go 1.7
- "os.SEEK_SET is deprecated", // Go 1.7
- "SA4017", // staticcheck "is a pure function but its return value is ignored"
- }
- )
- func TestCheckMetalint(t *testing.T) {
- if !isGometalinterInstalled() {
- return
- }
- gometalinter(t, lintDirs, lintExcludes...)
- }
- func isGometalinterInstalled() bool {
- if _, err := runError("gometalinter", "--disable-all"); err != nil {
- log.Println("gometalinter is not installed")
- return false
- }
- return true
- }
- func gometalinter(t *testing.T, dirs []string, excludes ...string) bool {
- params := []string{"--disable-all", "--concurrency=2", "--deadline=300s"}
- for _, linter := range fastLinters {
- params = append(params, "--enable="+linter)
- }
- if !testing.Short() {
- for _, linter := range slowLinters {
- params = append(params, "--enable="+linter)
- }
- }
- for _, exclude := range excludes {
- params = append(params, "--exclude="+exclude)
- }
- params = append(params, dirs...)
- bs, _ := runError("gometalinter", params...)
- nerr := 0
- lines := make(map[string]struct{})
- for _, line := range strings.Split(string(bs), "\n") {
- if line == "" {
- continue
- }
- if _, ok := lines[line]; ok {
- continue
- }
- log.Println(line)
- if strings.Contains(line, "executable file not found") {
- log.Println(` - Try "go run build.go setup" to install missing tools`)
- }
- lines[line] = struct{}{}
- nerr++
- }
- return nerr == 0
- }
- func runError(cmd string, args ...string) ([]byte, error) {
- ecmd := exec.Command(cmd, args...)
- bs, err := ecmd.CombinedOutput()
- return bytes.TrimSpace(bs), err
- }
|