| ... | ... |
@@ -104,7 +104,7 @@ func (i *mockImage) OperatingSystem() string {
|
| 104 | 104 |
|
| 105 | 105 |
func (i *mockImage) MarshalJSON() ([]byte, error) {
|
| 106 | 106 |
type rawImage mockImage |
| 107 |
- return json.Marshal(rawImage(*i)) |
|
| 107 |
+ return json.Marshal(rawImage(*i)) //nolint:staticcheck |
|
| 108 | 108 |
} |
| 109 | 109 |
|
| 110 | 110 |
type mockImageCache struct {
|
| ... | ... |
@@ -35,7 +35,7 @@ func (cli *Client) ContainerList(ctx context.Context, options types.ContainerLis |
| 35 | 35 |
} |
| 36 | 36 |
|
| 37 | 37 |
if options.Filters.Len() > 0 {
|
| 38 |
- //lint:ignore SA1019 for old code |
|
| 38 |
+ //nolint:staticcheck // ignore SA1019 for old code |
|
| 39 | 39 |
filterJSON, err := filters.ToParamWithVersion(cli.version, options.Filters) |
| 40 | 40 |
|
| 41 | 41 |
if err != nil {
|
| ... | ... |
@@ -90,7 +90,7 @@ func buildEventsQueryParams(cliVersion string, options types.EventsOptions) (url |
| 90 | 90 |
} |
| 91 | 91 |
|
| 92 | 92 |
if options.Filters.Len() > 0 {
|
| 93 |
- //lint:ignore SA1019 for old code |
|
| 93 |
+ //nolint:staticcheck // ignore SA1019 for old code |
|
| 94 | 94 |
filterJSON, err := filters.ToParamWithVersion(cliVersion, options.Filters) |
| 95 | 95 |
if err != nil {
|
| 96 | 96 |
return nil, err |
| ... | ... |
@@ -88,7 +88,7 @@ func (cli *Client) setupHijackConn(ctx context.Context, req *http.Request, proto |
| 88 | 88 |
// Server hijacks the connection, error 'connection closed' expected |
| 89 | 89 |
resp, err := clientconn.Do(req) |
| 90 | 90 |
|
| 91 |
- //lint:ignore SA1019 for connecting to old (pre go1.8) daemons |
|
| 91 |
+ //nolint:staticcheck // ignore SA1019 for connecting to old (pre go1.8) daemons |
|
| 92 | 92 |
if err != httputil.ErrPersistEOF {
|
| 93 | 93 |
if err != nil {
|
| 94 | 94 |
return nil, err |
| ... | ... |
@@ -24,7 +24,7 @@ func (cli *Client) ImageList(ctx context.Context, options types.ImageListOptions |
| 24 | 24 |
} |
| 25 | 25 |
} |
| 26 | 26 |
if optionFilters.Len() > 0 {
|
| 27 |
- //lint:ignore SA1019 for old code |
|
| 27 |
+ //nolint:staticcheck // ignore SA1019 for old code |
|
| 28 | 28 |
filterJSON, err := filters.ToParamWithVersion(cli.version, optionFilters) |
| 29 | 29 |
if err != nil {
|
| 30 | 30 |
return images, err |
| ... | ... |
@@ -13,7 +13,7 @@ import ( |
| 13 | 13 |
func (cli *Client) NetworkList(ctx context.Context, options types.NetworkListOptions) ([]types.NetworkResource, error) {
|
| 14 | 14 |
query := url.Values{}
|
| 15 | 15 |
if options.Filters.Len() > 0 {
|
| 16 |
- //lint:ignore SA1019 for old code |
|
| 16 |
+ //nolint:staticcheck // ignore SA1019 for old code |
|
| 17 | 17 |
filterJSON, err := filters.ToParamWithVersion(cli.version, options.Filters) |
| 18 | 18 |
if err != nil {
|
| 19 | 19 |
return nil, err |
| ... | ... |
@@ -15,7 +15,7 @@ func (cli *Client) PluginList(ctx context.Context, filter filters.Args) (types.P |
| 15 | 15 |
query := url.Values{}
|
| 16 | 16 |
|
| 17 | 17 |
if filter.Len() > 0 {
|
| 18 |
- //lint:ignore SA1019 for old code |
|
| 18 |
+ //nolint:staticcheck // ignore SA1019 for old code |
|
| 19 | 19 |
filterJSON, err := filters.ToParamWithVersion(cli.version, filter) |
| 20 | 20 |
if err != nil {
|
| 21 | 21 |
return plugins, err |
| ... | ... |
@@ -15,7 +15,7 @@ func (cli *Client) VolumeList(ctx context.Context, filter filters.Args) (volumet |
| 15 | 15 |
query := url.Values{}
|
| 16 | 16 |
|
| 17 | 17 |
if filter.Len() > 0 {
|
| 18 |
- //lint:ignore SA1019 for old code |
|
| 18 |
+ //nolint:staticcheck // ignore SA1019 for old code |
|
| 19 | 19 |
filterJSON, err := filters.ToParamWithVersion(cli.version, filter) |
| 20 | 20 |
if err != nil {
|
| 21 | 21 |
return volumes, err |
| ... | ... |
@@ -493,9 +493,7 @@ func findConfigurationConflicts(config map[string]interface{}, flags *pflag.Flag
|
| 493 | 493 |
if len(unknownKeys) > 0 {
|
| 494 | 494 |
unknownNamedConflicts := func(f *pflag.Flag) {
|
| 495 | 495 |
if namedOption, ok := f.Value.(opts.NamedOption); ok {
|
| 496 |
- if _, valid := unknownKeys[namedOption.Name()]; valid {
|
|
| 497 |
- delete(unknownKeys, namedOption.Name()) |
|
| 498 |
- } |
|
| 496 |
+ delete(unknownKeys, namedOption.Name()) |
|
| 499 | 497 |
} |
| 500 | 498 |
} |
| 501 | 499 |
flags.VisitAll(unknownNamedConflicts) |
| ... | ... |
@@ -784,9 +784,8 @@ func (daemon *Daemon) connectToNetwork(container *container.Container, idOrName |
| 784 | 784 |
EndpointSettings: endpointConfig, |
| 785 | 785 |
IPAMOperational: operIPAM, |
| 786 | 786 |
} |
| 787 |
- if _, ok := container.NetworkSettings.Networks[n.ID()]; ok {
|
|
| 788 |
- delete(container.NetworkSettings.Networks, n.ID()) |
|
| 789 |
- } |
|
| 787 |
+ |
|
| 788 |
+ delete(container.NetworkSettings.Networks, n.ID()) |
|
| 790 | 789 |
|
| 791 | 790 |
if err := daemon.updateEndpointNetworkSettings(container, n, ep); err != nil {
|
| 792 | 791 |
return err |
| ... | ... |
@@ -62,10 +62,9 @@ func Scan(text string) (*events.Message, error) {
|
| 62 | 62 |
attrs[kv[0]] = kv[1] |
| 63 | 63 |
} |
| 64 | 64 |
|
| 65 |
- tu := time.Unix(t, tn) |
|
| 66 | 65 |
return &events.Message{
|
| 67 | 66 |
Time: t, |
| 68 |
- TimeNano: tu.UnixNano(), |
|
| 67 |
+ TimeNano: time.Unix(t, tn).UnixNano(), |
|
| 69 | 68 |
Type: md["eventType"], |
| 70 | 69 |
Action: md["action"], |
| 71 | 70 |
Actor: events.Actor{
|
| ... | ... |
@@ -729,9 +729,9 @@ func BenchmarkConcurrentAccess(b *testing.B) {
|
| 729 | 729 |
|
| 730 | 730 |
numConcurrent := 256 |
| 731 | 731 |
// create a bunch of ids |
| 732 |
- var ids []string |
|
| 732 |
+ ids := make([]string, numConcurrent) |
|
| 733 | 733 |
for i := 0; i < numConcurrent; i++ {
|
| 734 |
- ids = append(ids, stringid.GenerateRandomID()) |
|
| 734 |
+ ids[i] = stringid.GenerateRandomID() |
|
| 735 | 735 |
} |
| 736 | 736 |
|
| 737 | 737 |
if err := d.Create(ids[0], "", nil); err != nil {
|
| ... | ... |
@@ -743,7 +743,7 @@ func BenchmarkConcurrentAccess(b *testing.B) {
|
| 743 | 743 |
} |
| 744 | 744 |
|
| 745 | 745 |
parent := ids[1] |
| 746 |
- ids = append(ids[2:]) |
|
| 746 |
+ ids = ids[2:] |
|
| 747 | 747 |
|
| 748 | 748 |
chErr := make(chan error, numConcurrent) |
| 749 | 749 |
var outerGroup sync.WaitGroup |
| ... | ... |
@@ -606,7 +606,7 @@ func (d *Driver) parseStorageOpt(storageOpt map[string]string, driver *Driver) e |
| 606 | 606 |
|
| 607 | 607 |
// Set btrfs storage size |
| 608 | 608 |
func (d *Driver) setStorageSize(dir string, driver *Driver) error {
|
| 609 |
- if driver.options.size <= 0 {
|
|
| 609 |
+ if driver.options.size == 0 {
|
|
| 610 | 610 |
return fmt.Errorf("btrfs: invalid storage size: %s", units.HumanSize(float64(driver.options.size)))
|
| 611 | 611 |
} |
| 612 | 612 |
if d.options.minSpace > 0 && driver.options.size < d.options.minSpace {
|
| ... | ... |
@@ -549,7 +549,7 @@ type mockBlobStoreWithCreate struct {
|
| 549 | 549 |
} |
| 550 | 550 |
|
| 551 | 551 |
func (blob *mockBlobStoreWithCreate) Create(ctx context.Context, options ...distribution.BlobCreateOption) (distribution.BlobWriter, error) {
|
| 552 |
- return nil, errcode.Errors(append([]error{errcode.ErrorCodeUnauthorized.WithMessage("unauthorized")}))
|
|
| 552 |
+ return nil, errcode.Errors([]error{errcode.ErrorCodeUnauthorized.WithMessage("unauthorized")})
|
|
| 553 | 553 |
} |
| 554 | 554 |
|
| 555 | 555 |
type mockRepoWithBlob struct {
|
| ... | ... |
@@ -1,11 +1,19 @@ |
| 1 | 1 |
#!/bin/sh |
| 2 | 2 |
|
| 3 |
-: "${GOLANGCI_LINT_COMMIT=v1.17.1}"
|
|
| 3 |
+: "${GOLANGCI_LINT_COMMIT=v1.20.0}"
|
|
| 4 | 4 |
|
| 5 | 5 |
install_golangci_lint() {
|
| 6 | 6 |
echo "Installing golangci-lint version ${GOLANGCI_LINT_COMMIT}"
|
| 7 | 7 |
go get -d github.com/golangci/golangci-lint/cmd/golangci-lint |
| 8 | 8 |
cd "$GOPATH/src/github.com/golangci/golangci-lint/" || exit 1 |
| 9 | 9 |
git checkout -q "${GOLANGCI_LINT_COMMIT}"
|
| 10 |
- go build -buildmode=pie -o "${PREFIX}/golangci-lint" "github.com/golangci/golangci-lint/cmd/golangci-lint"
|
|
| 10 |
+ |
|
| 11 |
+ version="$(git describe --tags)" |
|
| 12 |
+ commit="$(git rev-parse --short HEAD)" |
|
| 13 |
+ commitDate="$(git show -s --format=%cd)" |
|
| 14 |
+ |
|
| 15 |
+ go build \ |
|
| 16 |
+ -buildmode=pie \ |
|
| 17 |
+ -ldflags "-s -w -X \"main.version=${version}\" -X \"main.commit=${commit}\" -X \"main.date=${commitDate}\"" \
|
|
| 18 |
+ -o "${PREFIX}/golangci-lint" "github.com/golangci/golangci-lint/cmd/golangci-lint"
|
|
| 11 | 19 |
} |
| ... | ... |
@@ -6,7 +6,7 @@ SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
| 6 | 6 |
# CI platforms differ, so per-platform GOLANGCI_LINT_OPTS can be set |
| 7 | 7 |
# from a platform-specific Dockerfile, otherwise let's just set |
| 8 | 8 |
# (somewhat pessimistic) default of 10 minutes. |
| 9 |
-: ${GOLANGCI_LINT_OPTS=--deadline=20m}
|
|
| 9 |
+: "${GOLANGCI_LINT_OPTS=--timeout=10m}"
|
|
| 10 | 10 |
|
| 11 | 11 |
[ -n "${TESTDEBUG}" ] && set -x
|
| 12 | 12 |
|
| ... | ... |
@@ -18,9 +18,10 @@ elif ${PKG_CONFIG} 'libsystemd-journal' 2> /dev/null ; then
|
| 18 | 18 |
fi |
| 19 | 19 |
|
| 20 | 20 |
# TODO use --out-format=junit-xml and store artifacts |
| 21 |
-GOGC=20 golangci-lint run \ |
|
| 21 |
+# shellcheck disable=SC2086 |
|
| 22 |
+GOGC=75 golangci-lint run \ |
|
| 22 | 23 |
${GOLANGCI_LINT_OPTS} \
|
| 23 | 24 |
--print-resources-usage \ |
| 24 | 25 |
--build-tags="${DOCKER_BUILDTAGS}" \
|
| 25 | 26 |
--verbose \ |
| 26 |
- --config ${SCRIPTDIR}/golangci-lint.yml
|
|
| 27 |
+ --config "${SCRIPTDIR}/golangci-lint.yml"
|
| ... | ... |
@@ -1,7 +1,6 @@ |
| 1 | 1 |
linters: |
| 2 | 2 |
enable: |
| 3 | 3 |
- deadcode |
| 4 |
- - gofmt |
|
| 5 | 4 |
- goimports |
| 6 | 5 |
- golint |
| 7 | 6 |
- gosec |
| ... | ... |
@@ -9,7 +8,12 @@ linters: |
| 9 | 9 |
- govet |
| 10 | 10 |
- ineffassign |
| 11 | 11 |
- misspell |
| 12 |
+ - staticcheck |
|
| 13 |
+ - structcheck |
|
| 14 |
+ - typecheck |
|
| 12 | 15 |
- unconvert |
| 16 |
+ - unused |
|
| 17 |
+ - varcheck |
|
| 13 | 18 |
|
| 14 | 19 |
disable: |
| 15 | 20 |
- errcheck |
| ... | ... |
@@ -22,28 +26,52 @@ linters: |
| 22 | 22 |
- bundles |
| 23 | 23 |
- docs |
| 24 | 24 |
|
| 25 |
- skip-files: |
|
| 26 |
- - ".*\\.pb\\.go" |
|
| 27 |
- - "dockerversion/version_autogen.go" |
|
| 28 |
- - "api/types/container/container_.*" |
|
| 29 |
- - "api/types/volume/volume_.*" |
|
| 30 |
- |
|
| 31 | 25 |
linters-settings: |
| 32 | 26 |
govet: |
| 33 | 27 |
check-shadowing: false |
| 34 | 28 |
|
| 35 | 29 |
issues: |
| 30 |
+ # The default exclusion rules are a bit too permissive, so copying the relevant ones below |
|
| 31 |
+ exclude-use-default: false |
|
| 32 |
+ |
|
| 36 | 33 |
exclude-rules: |
| 34 |
+ # These are copied from the default exclude rules, except for "ineffective break statement" |
|
| 35 |
+ # and GoDoc checks. |
|
| 36 |
+ # https://github.com/golangci/golangci-lint/blob/0cc87df732aaf1d5ad9ce9ca538d38d916918b36/pkg/config/config.go#L36 |
|
| 37 |
+ - text: "Error return value of .((os\\.)?std(out|err)\\..*|.*Close|.*Flush|os\\.Remove(All)?|.*printf?|os\\.(Un)?Setenv). is not checked" |
|
| 38 |
+ linters: |
|
| 39 |
+ - errcheck |
|
| 40 |
+ - text: "func name will be used as test\\.Test.* by other packages, and that stutters; consider calling this" |
|
| 41 |
+ linters: |
|
| 42 |
+ - golint |
|
| 43 |
+ - text: "G103: Use of unsafe calls should be audited" |
|
| 44 |
+ linters: |
|
| 45 |
+ - gosec |
|
| 46 |
+ - text: "G104: Errors unhandled" |
|
| 47 |
+ linters: |
|
| 48 |
+ - gosec |
|
| 49 |
+ - text: "G204: Subprocess launch(ed with (variable|function call)|ing should be audited)" |
|
| 50 |
+ linters: |
|
| 51 |
+ - gosec |
|
| 52 |
+ - text: "(G301|G302): (Expect directory permissions to be 0750 or less|Expect file permissions to be 0600 or less)" |
|
| 53 |
+ linters: |
|
| 54 |
+ - gosec |
|
| 55 |
+ - text: "G304: Potential file inclusion via variable" |
|
| 56 |
+ linters: |
|
| 57 |
+ - gosec |
|
| 58 |
+ |
|
| 37 | 59 |
# Exclude some linters from running on tests files. |
| 38 | 60 |
- path: _test\.go |
| 39 | 61 |
linters: |
| 40 | 62 |
- errcheck |
| 41 | 63 |
- gosec |
| 42 | 64 |
|
| 43 |
- - text: "G201: SQL string formatting" |
|
| 65 |
+ # Suppress golint complaining about generated types in api/types/ |
|
| 66 |
+ - text: "type name will be used as (container|volume)\\.(Container|Volume).* by other packages, and that stutters; consider calling this" |
|
| 67 |
+ path: "api/types/(volume|container)/" |
|
| 44 | 68 |
linters: |
| 45 |
- - gosec |
|
| 46 |
- - text: "G202: SQL string concatenation" |
|
| 69 |
+ - golint |
|
| 70 |
+ - text: "(G201|G202): SQL string (formatting|concatenation)" |
|
| 47 | 71 |
linters: |
| 48 | 72 |
- gosec |
| 49 | 73 |
# FIXME temporarily suppress these. See #39928 |
| ... | ... |
@@ -51,11 +79,7 @@ issues: |
| 51 | 51 |
linters: |
| 52 | 52 |
- staticcheck |
| 53 | 53 |
# FIXME temporarily suppress these. See #39924 |
| 54 |
- - text: "SA1019: h.Xattrs is deprecated: Use PAXRecords instead" |
|
| 55 |
- linters: |
|
| 56 |
- - staticcheck |
|
| 57 |
- # FIXME temporarily suppress these. See #39924 |
|
| 58 |
- - text: "SA1019: hdr.Xattrs is deprecated: Use PAXRecords instead" |
|
| 54 |
+ - text: "SA1019: .*\\.Xattrs is deprecated: Use PAXRecords instead" |
|
| 59 | 55 |
linters: |
| 60 | 56 |
- staticcheck |
| 61 | 57 |
# FIXME temporarily suppress these. See #39926 |
| ... | ... |
@@ -66,3 +90,7 @@ issues: |
| 66 | 66 |
- text: "SA1019: httputil.ClientConn is deprecated" |
| 67 | 67 |
linters: |
| 68 | 68 |
- staticcheck |
| 69 |
+ # FIXME temporarily suppress these (related to the ones above) |
|
| 70 |
+ - text: "SA1019: httputil.ErrPersistEOF is deprecated" |
|
| 71 |
+ linters: |
|
| 72 |
+ - staticcheck |
| ... | ... |
@@ -139,13 +139,13 @@ type JSONMessage struct {
|
| 139 | 139 |
Stream string `json:"stream,omitempty"` |
| 140 | 140 |
Status string `json:"status,omitempty"` |
| 141 | 141 |
Progress *JSONProgress `json:"progressDetail,omitempty"` |
| 142 |
- ProgressMessage string `json:"progress,omitempty"` //deprecated |
|
| 142 |
+ ProgressMessage string `json:"progress,omitempty"` // deprecated |
|
| 143 | 143 |
ID string `json:"id,omitempty"` |
| 144 | 144 |
From string `json:"from,omitempty"` |
| 145 | 145 |
Time int64 `json:"time,omitempty"` |
| 146 | 146 |
TimeNano int64 `json:"timeNano,omitempty"` |
| 147 | 147 |
Error *JSONError `json:"errorDetail,omitempty"` |
| 148 |
- ErrorMessage string `json:"error,omitempty"` //deprecated |
|
| 148 |
+ ErrorMessage string `json:"error,omitempty"` // deprecated |
|
| 149 | 149 |
// Aux contains out-of-band data, such as digests for push signing and image id after building. |
| 150 | 150 |
Aux *json.RawMessage `json:"aux,omitempty"` |
| 151 | 151 |
} |
| ... | ... |
@@ -177,7 +177,7 @@ func (jm *JSONMessage) Display(out io.Writer, isTerminal bool) error {
|
| 177 | 177 |
if isTerminal && jm.Stream == "" && jm.Progress != nil {
|
| 178 | 178 |
clearLine(out) |
| 179 | 179 |
endl = "\r" |
| 180 |
- fmt.Fprintf(out, endl) |
|
| 180 |
+ fmt.Fprint(out, endl) |
|
| 181 | 181 |
} else if jm.Progress != nil && jm.Progress.String() != "" { //disable progressbar in non-terminal
|
| 182 | 182 |
return nil |
| 183 | 183 |
} |
| ... | ... |
@@ -194,7 +194,7 @@ func (jm *JSONMessage) Display(out io.Writer, isTerminal bool) error {
|
| 194 | 194 |
} |
| 195 | 195 |
if jm.Progress != nil && isTerminal {
|
| 196 | 196 |
fmt.Fprintf(out, "%s %s%s", jm.Status, jm.Progress.String(), endl) |
| 197 |
- } else if jm.ProgressMessage != "" { //deprecated
|
|
| 197 |
+ } else if jm.ProgressMessage != "" { // deprecated
|
|
| 198 | 198 |
fmt.Fprintf(out, "%s %s%s", jm.Status, jm.ProgressMessage, endl) |
| 199 | 199 |
} else if jm.Stream != "" {
|
| 200 | 200 |
fmt.Fprintf(out, "%s%s", jm.Stream, endl) |