Skip to content

🏃Re-enabling the golangci-lint #523

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/main.workflow
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ action "verify-emoji" {
uses = "./hack/release"
secrets = ["GITHUB_TOKEN"]
}

32 changes: 32 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,37 @@
run:
deadline: 5m

linters-settings:
lll:
line-length: 170
dupl:
threshold: 400

issues:
# don't skip warning about doc comments
exclude-use-default: false

# restore some of the defaults
# (fill in the rest as needed)
exclude-rules:
- linters: [errcheck]
text: "Error return value of .((os\\.)?std(out|err)\\..*|.*Close|.*Flush|os\\.Remove(All)?|.*printf?|os\\.(Un)?Setenv). is not checked"
linters:
disable-all: true
enable:
- misspell
- structcheck
- golint
- deadcode
- errcheck
- varcheck
- goconst
- unparam
- ineffassign
- nakedret
- interfacer
- gocyclo
- lll
- dupl
- goimports
- golint
17 changes: 11 additions & 6 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,39 +4,44 @@ go 1.11

require (
cloud.google.com/go v0.26.0 // indirect
github.com/Masterminds/semver v1.4.2 // indirect
github.com/Masterminds/vcs v1.13.1 // indirect
github.com/armon/go-radix v1.0.0 // indirect
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 // indirect
github.com/boltdb/bolt v1.3.1 // indirect
github.com/evanphx/json-patch v4.5.0+incompatible
github.com/go-logr/logr v0.1.0
github.com/go-logr/zapr v0.1.0
github.com/gogo/protobuf v1.1.1 // indirect
github.com/golang/dep v0.5.4 // indirect
github.com/golang/groupcache v0.0.0-20180513044358-24b0969c4cb7 // indirect
github.com/golangci/golangci-lint v1.15.0 // indirect
github.com/google/go-github/v25 v25.1.3
github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf // indirect
github.com/googleapis/gnostic v0.2.0 // indirect
github.com/hashicorp/golang-lru v0.0.0-20180201235237-0fb14efe8c47 // indirect
github.com/imdario/mergo v0.3.6 // indirect
github.com/jmank88/nuts v0.3.0 // indirect
github.com/json-iterator/go v1.1.5 // indirect
github.com/kr/pretty v0.1.0 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 // indirect
github.com/nightlyone/lockfile v0.0.0-20180618180623-0ad87eef1443 // indirect
github.com/onsi/ginkgo v1.6.0
github.com/onsi/gomega v1.4.2
github.com/pborman/uuid v0.0.0-20170612153648-e790cca94e6c // indirect
github.com/pelletier/go-toml v1.4.0 // indirect
github.com/prometheus/client_golang v0.9.0
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910
github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e // indirect
github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273 // indirect
github.com/sdboyer/constext v0.0.0-20170321163424-836a14457353 // indirect
github.com/spf13/pflag v1.0.2 // indirect
go.uber.org/atomic v1.3.2 // indirect
go.uber.org/multierr v1.1.0 // indirect
go.uber.org/zap v1.9.1
golang.org/x/crypto v0.0.0-20180820150726-614d502a4dac // indirect
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be // indirect
golang.org/x/sync v0.0.0-20190423024810-112230192c58 // indirect
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2 // indirect
gomodules.xyz/jsonpatch/v2 v2.0.0
google.golang.org/appengine v1.1.0 // indirect
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
gopkg.in/fsnotify.v1 v1.4.7
gopkg.in/inf.v0 v0.9.1 // indirect
k8s.io/api v0.0.0-20190409021203-6e4e0e4f393b
Expand Down
148 changes: 148 additions & 0 deletions go.sum

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions hack/lint2check/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
FROM golang

COPY lint2check /usr/bin/lint2check
COPY golangci-lint /usr/bin/golangci-lint
# make sure lint2check can find golangci-lint
ENV GO111MODULE=on

ENTRYPOINT ["/usr/bin/lint2check"]
4 changes: 4 additions & 0 deletions hack/lint2check/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# lint2check

lint2check runs golangci-lint, converts the results to github check API
results, and submits them as a separate check run.
11 changes: 11 additions & 0 deletions hack/lint2check/cloudbuild.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
steps:
- name: "golang"
args: ["go", "build", "-o", "lint2check", "."]
env: ["GO111MODULE=on", "CGO_ENABLED=0"]
- name: "golang"
args: ["go", "get", "github.com/golangci/golangci-lint/cmd/[email protected]"]
env: ["GO111MODULE=on", "CGO_ENABLED=0", "GOBIN=/workspace"]
- name: "gcr.io/cloud-builders/docker"
args: ["build", "-t", "gcr.io/$PROJECT_ID/lint2check", "."]
images:
- "gcr.io/$PROJECT_ID/lint2check"
5 changes: 5 additions & 0 deletions hack/lint2check/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module sigs.k8s.io/controller-runtime/hack/lint2check

go 1.12

require github.com/google/go-github/v25 v25.1.1
258 changes: 258 additions & 0 deletions hack/lint2check/lint2check.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,258 @@
/*
Copyright 2019 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package main

import (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this file is all github actions related

"context"
"encoding/json"
"os/exec"
"os"
"log"
"go/token"
"net/http"
"strings"
"time"
"fmt"

"github.com/google/go-github/v25/github"
)

type lintResults struct {
Issues []issue
Report reportData
}

type issue struct {
FromLinter string
Text string
Pos token.Position

LineRange *lineRange
Replacement *replacement
}

type replacement struct {
NeedOnlyDelete bool
NewLines []string
}

type lineRange struct {
From, To int
}

type reportData struct {
Warnings []warning
Linters []linterData
Error string
}

type linterData struct {
Name string
Enabled bool
}

type warning struct {
Tag string
Text string
}

type bearerTransport struct {
token string
}

func (b *bearerTransport) RoundTrip(req *http.Request) (*http.Response, error) {
req.Header.Set("Authorization", "Bearer "+b.token)
req.Header.Set("Accept", "application/vnd.github.antiope-preview+json")

return http.DefaultTransport.RoundTrip(req)
}

func main() {
if !lintAndSubmit() {
os.Exit(1)
}
}

func lintAndSubmit() (succeeded bool) {
ctx := context.Background()
token := os.Getenv("GITHUB_TOKEN")
if token == "" {
log.Print("must specify a GitHub token in $GITHUB_TOKEN")
return false
}
client := github.NewClient(&http.Client{Transport: &bearerTransport{
token: token,
}})

headSha := os.Getenv("GITHUB_SHA")
if headSha == "" {
log.Print("must specify a SHA to register the check against in $GITHUB_SHA")
return false
}

repoRaw := os.Getenv("GITHUB_REPOSITORY")
if repoRaw == "" || !strings.Contains(repoRaw, "/") {
log.Print("must specify a repository in $GITHUB_REPOSITORY as owner/repo")
return false
}
repoParts := strings.SplitN(repoRaw, "/", 2)
repoOwner := repoParts[0]
repoName := repoParts[1]

defInProgress := "in_progress"
checkRun, _, err := client.Checks.CreateCheckRun(ctx, repoOwner, repoName, github.CreateCheckRunOptions{
Name: "Linters",
HeadSHA: headSha,
Status: &defInProgress,
StartedAt: &github.Timestamp{Time: time.Now()},
})
if err != nil {
log.Print(err)
return false
}

succeeded = true

if err := runLints(checkRun); err != nil {
// don't return immediately -- submit things first
log.Print(err)
succeeded = false
}

defUnknownErr := "**unknown error while linting**"
if checkRun.Output.Title == nil || checkRun.Output.Summary == nil {
checkRun.Output.Title = &defUnknownErr
checkRun.Output.Summary = &defUnknownErr
}

log.Printf("Sending check run results %+v", checkRun)
_, _, err = client.Checks.UpdateCheckRun(ctx, repoOwner, repoName, *checkRun.ID, github.UpdateCheckRunOptions{
Name: *checkRun.Name,
Status: checkRun.Status,
Conclusion: checkRun.Conclusion,
CompletedAt: checkRun.CompletedAt,
Output: checkRun.Output,
})
if err != nil {
log.Print(err)
return false
}

log.Print("done")
return succeeded
}

func runLints(checkRun *github.CheckRun) error {
// TODO(directxman12); there's probably a way to run this directly,
// but this is easiest for now
args := append([]string{"run", "--out-format", "json"}, os.Args[1:]...)
lintOutRaw, checkErrRaw := exec.Command("golangci-lint", args...).Output()
// don't return early, since we might get results
if checkErrRaw != nil {
log.Print(checkErrRaw)
if exitErr, isExitErr := checkErrRaw.(*exec.ExitError); isExitErr {
log.Print(string(exitErr.Stderr))
}
}

// set the completed time so we have a timestamp in case of error return
checkRun.CompletedAt = &github.Timestamp{Time: time.Now()}

var lintRes lintResults
if err := json.Unmarshal(lintOutRaw, &lintRes); err != nil {
defFailure := "failure"
checkRun.Conclusion = &defFailure
return err
}

conclusion := "success"
summary := fmt.Sprintf("%v problems\n\n%v warnings", len(lintRes.Issues), len(lintRes.Report.Warnings))
switch {
case len(lintRes.Issues) > 0 || checkErrRaw != nil || lintRes.Report.Error != "":
conclusion = "failure"
case len(lintRes.Report.Warnings) > 0:
conclusion = "neutral"
}
checkRun.Conclusion = &conclusion

if lintRes.Report.Error != "" {
summary += fmt.Sprintf("\n\nError running linters: %s", lintRes.Report.Error)
}
defTitle := "Linter Runs"
checkRun.Output.Title = &defTitle
checkRun.Output.Summary = &summary

var linterLines []string
for _, linter := range lintRes.Report.Linters {
if !linter.Enabled {
continue
}
linterLines = append(linterLines, "- "+linter.Name)
}
details := fmt.Sprintf("## Enabled Linters\n\n%s\n", strings.Join(linterLines, "\n"))

if len(lintRes.Report.Warnings) > 0 {
var warningLines []string
for _, warning := range lintRes.Report.Warnings {
warningLines = append(warningLines, fmt.Sprintf("- *%s*: %s", warning.Tag, warning.Text))
}
details += fmt.Sprintf("## Warnings\n\n%s\n", strings.Join(warningLines, "\n"))
}

checkRun.Output.Text = &details

var annotations []*github.CheckRunAnnotation
for i := range lintRes.Issues {
// don't take references to the iteration variable
issue := lintRes.Issues[i]
defFailure := "failure"
issueDetails := ""

if issue.Replacement != nil {
if issue.Replacement.NeedOnlyDelete {
issueDetails = "\n\n*delete these lines*"
} else {
issueDetails = fmt.Sprintf("\n\n*replace these lines with*:\n\n```go\n%s\n```", strings.Join(issue.Replacement.NewLines, "\n"))
}
}

msg := issue.Text
msg += issueDetails

annot := &github.CheckRunAnnotation{
Path: &issue.Pos.Filename,
AnnotationLevel: &defFailure,
Message: &msg,
Title: &issue.FromLinter,
RawDetails: nil,
}

if issue.LineRange != nil {
annot.StartLine = &issue.LineRange.From
annot.EndLine = &issue.LineRange.To
} else {
annot.StartLine = &issue.Pos.Line
annot.EndLine = &issue.Pos.Line
// TODO(directxman12): go-github doesn't support columns yet,
// re-add this when they do
// annot.StartColumn = &issue.Pos.Column
// annot.EndColumn = &issue.Pos.Column
}

annotations = append(annotations, annot)
}

checkRun.Output.Annotations = annotations
return checkErrRaw
}
Loading