From a000a2926ba9e5dd046b2b8b6889efec6f4945c7 Mon Sep 17 00:00:00 2001 From: Alex Goodman Date: Wed, 6 Oct 2021 09:46:55 -0400 Subject: [PATCH] update linter + fix whitespace (#536) Signed-off-by: Alex Goodman --- .golangci.yaml | 8 ++++--- Makefile | 2 +- cmd/packages.go | 8 +++---- cmd/report_writer.go | 6 +++++- .../packages/model/spdx22/creation_info.go | 2 +- .../presenter/packages/spdx_json_presenter.go | 4 ++-- internal/presenter/packages/text_presenter.go | 4 ++-- .../generate/generate_license_list.go | 17 +++++++++++---- schema/json/generate.go | 6 +----- syft/file/digest_cataloger.go | 2 +- syft/pkg/apk_metadata.go | 2 +- syft/pkg/cataloger/apkdb/cataloger.go | 2 +- .../common/cpe/candidate_by_package_type.go | 6 +++--- syft/pkg/cataloger/deb/cataloger.go | 21 +++++++------------ syft/pkg/cataloger/rpmdb/cataloger.go | 2 +- syft/pkg/cataloger/rpmdb/parse_rpmdb.go | 2 +- syft/pkg/dpkg_metadata.go | 2 +- syft/pkg/ownership_by_files_relationship.go | 6 +++--- syft/pkg/rpmdb_metadata.go | 2 +- syft/source/all_layers_resolver.go | 1 - ui/event_handlers.go | 4 ---- 21 files changed, 54 insertions(+), 55 deletions(-) diff --git a/.golangci.yaml b/.golangci.yaml index 4d468d8a8..536445ff8 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -15,6 +15,7 @@ linters: - dogsled - dupl - errcheck + - exportloopref - funlen - gocognit - goconst @@ -22,7 +23,6 @@ linters: - gocyclo - gofmt - goimports - - golint - goprintffuncname - gosec - gosimple @@ -31,8 +31,8 @@ linters: - misspell - nakedret - nolintlint + - revive - rowserrcheck - - scopelint - staticcheck - structcheck - stylecheck @@ -49,11 +49,13 @@ linters: # - godot # - godox # - goerr113 +# - golint # deprecated # - gomnd # this is too aggressive # - interfacer # this is a good idea, but is no longer supported and is prone to false positives # - lll # without a way to specify per-line exception cases, this is not usable # - maligned # this is an excellent linter, but tricky to optimize and we are not sensitive to memory layout optimizations # - nestif # - prealloc # following this rule isn't consistently a good idea, as it sometimes forces unnecessary allocations that result in less idiomatic code +# - scopelint # deprecated # - testpackage -# - wsl +# - wsl # this doens't have an auto-fixer yet and is pretty noisy (https://github.com/bombsimon/wsl/issues/90) diff --git a/Makefile b/Makefile index 0844007e2..74f9966fe 100644 --- a/Makefile +++ b/Makefile @@ -101,7 +101,7 @@ $(TEMPDIR): .PHONY: bootstrap-tools bootstrap-tools: $(TEMPDIR) GO111MODULE=off GOBIN=$(shell realpath $(TEMPDIR)) go get -u golang.org/x/perf/cmd/benchstat - curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(TEMPDIR)/ v1.26.0 + curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(TEMPDIR)/ v1.42.1 curl -sSfL https://raw.githubusercontent.com/wagoodman/go-bouncer/master/bouncer.sh | sh -s -- -b $(TEMPDIR)/ v0.2.0 curl -sfL https://install.goreleaser.com/github.com/goreleaser/goreleaser.sh | sh -s -- -b $(TEMPDIR)/ v0.177.0 diff --git a/cmd/packages.go b/cmd/packages.go index 4078b66c7..248f78f7b 100644 --- a/cmd/packages.go +++ b/cmd/packages.go @@ -102,7 +102,7 @@ func init() { } func setPackageFlags(flags *pflag.FlagSet) { - ///////// Formatting & Input options ////////////////////////////////////////////// + // Formatting & Input options ////////////////////////////////////////////// flags.StringP( "scope", "s", source.SquashedScope.String(), @@ -118,7 +118,7 @@ func setPackageFlags(flags *pflag.FlagSet) { "file to write the report output to (default is STDOUT)", ) - ///////// Upload options ////////////////////////////////////////////////////////// + // Upload options ////////////////////////////////////////////////////////// flags.StringP( "host", "H", "", "the hostname or URL of the Anchore Enterprise instance to upload to", @@ -151,7 +151,7 @@ func setPackageFlags(flags *pflag.FlagSet) { } func bindPackagesConfigOptions(flags *pflag.FlagSet) error { - ///////// Formatting & Input options ////////////////////////////////////////////// + // Formatting & Input options ////////////////////////////////////////////// if err := viper.BindPFlag("package.cataloger.scope", flags.Lookup("scope")); err != nil { return err @@ -165,7 +165,7 @@ func bindPackagesConfigOptions(flags *pflag.FlagSet) error { return err } - ///////// Upload options ////////////////////////////////////////////////////////// + // Upload options ////////////////////////////////////////////////////////// if err := viper.BindPFlag("anchore.host", flags.Lookup("host")); err != nil { return err diff --git a/cmd/report_writer.go b/cmd/report_writer.go index bed18fb4f..a6fb63bec 100644 --- a/cmd/report_writer.go +++ b/cmd/report_writer.go @@ -11,18 +11,22 @@ import ( func reportWriter() (io.Writer, func() error, error) { nop := func() error { return nil } - path := strings.TrimSpace(appConfig.File) + switch len(path) { case 0: return os.Stdout, nop, nil + default: reportFile, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644) + if err != nil { return nil, nop, fmt.Errorf("unable to create report file: %w", err) } + return reportFile, func() error { log.Infof("report written to file=%q", path) + return reportFile.Close() }, nil } diff --git a/internal/presenter/packages/model/spdx22/creation_info.go b/internal/presenter/packages/model/spdx22/creation_info.go index 9e1f51080..5ec0cb505 100644 --- a/internal/presenter/packages/model/spdx22/creation_info.go +++ b/internal/presenter/packages/model/spdx22/creation_info.go @@ -10,7 +10,7 @@ type CreationInfo struct { Created time.Time `json:"created"` // Identify who (or what, in the case of a tool) created the SPDX file. If the SPDX file was created by an // individual, indicate the person's name. If the SPDX file was created on behalf of a company or organization, - //indicate the entity name. If the SPDX file was created using a software tool, indicate the name and version + // indicate the entity name. If the SPDX file was created using a software tool, indicate the name and version // for that tool. If multiple participants or tools were involved, use multiple instances of this field. Person // name or organization name may be designated as “anonymous” if appropriate. Creators []string `json:"creators"` diff --git a/internal/presenter/packages/spdx_json_presenter.go b/internal/presenter/packages/spdx_json_presenter.go index ded9a4a65..a73c30809 100644 --- a/internal/presenter/packages/spdx_json_presenter.go +++ b/internal/presenter/packages/spdx_json_presenter.go @@ -132,10 +132,10 @@ func newSPDXJsonElements(catalog *pkg.Catalog) ([]spdx22.Package, []spdx22.File, func cleanSPDXName(name string) string { // remove # according to specification - name = strings.Replace(name, "#", "-", -1) + name = strings.ReplaceAll(name, "#", "-") // remove : for url construction - name = strings.Replace(name, ":", "-", -1) + name = strings.ReplaceAll(name, ":", "-") // clean relative pathing return path.Clean(name) diff --git a/internal/presenter/packages/text_presenter.go b/internal/presenter/packages/text_presenter.go index 44127da64..22ed80afa 100644 --- a/internal/presenter/packages/text_presenter.go +++ b/internal/presenter/packages/text_presenter.go @@ -32,7 +32,7 @@ func (pres *TextPresenter) Present(output io.Writer) error { switch pres.srcMetadata.Scheme { case source.DirectoryScheme: - fmt.Fprintln(w, fmt.Sprintf("[Path: %s]", pres.srcMetadata.Path)) + fmt.Fprintf(w, "[Path: %s]\n", pres.srcMetadata.Path) case source.ImageScheme: fmt.Fprintln(w, "[Image]") @@ -51,7 +51,7 @@ func (pres *TextPresenter) Present(output io.Writer) error { // populate artifacts... rows := 0 for _, p := range pres.catalog.Sorted() { - fmt.Fprintln(w, fmt.Sprintf("[%s]", p.Name)) + fmt.Fprintf(w, "[%s]\n", p.Name) fmt.Fprintln(w, " Version:\t", p.Version) fmt.Fprintln(w, " Type:\t", string(p.Type)) fmt.Fprintln(w, " Found by:\t", p.FoundBy) diff --git a/internal/spdxlicense/generate/generate_license_list.go b/internal/spdxlicense/generate/generate_license_list.go index 881ce8d41..c569a5fe8 100644 --- a/internal/spdxlicense/generate/generate_license_list.go +++ b/internal/spdxlicense/generate/generate_license_list.go @@ -2,6 +2,7 @@ package main import ( "encoding/json" + "fmt" "log" "net/http" "os" @@ -49,14 +50,21 @@ type LicenseList struct { } func main() { + if err := run(); err != nil { + fmt.Println(err.Error()) + os.Exit(1) + } +} + +func run() error { resp, err := http.Get(url) if err != nil { - log.Fatalf("unable to get licenses list: %+v", err) + return fmt.Errorf("unable to get licenses list: %+v", err) } var result LicenseList if err = json.NewDecoder(resp.Body).Decode(&result); err != nil { - log.Fatalf("unable to decode license list: %+v", err) + return fmt.Errorf("unable to decode license list: %+v", err) } defer func() { if err := resp.Body.Close(); err != nil { @@ -66,7 +74,7 @@ func main() { f, err := os.Create(source) if err != nil { - log.Fatalf("unable to create %q: %+v", source, err) + return fmt.Errorf("unable to create %q: %+v", source, err) } defer func() { if err := f.Close(); err != nil { @@ -89,8 +97,9 @@ func main() { }) if err != nil { - log.Fatalf("unable to generate template: %+v", err) + return fmt.Errorf("unable to generate template: %+v", err) } + return nil } // Parsing the provided SPDX license list necessitates a two pass approach. diff --git a/schema/json/generate.go b/schema/json/generate.go index fa2c45da1..830e668c9 100644 --- a/schema/json/generate.go +++ b/schema/json/generate.go @@ -45,11 +45,7 @@ func build() *jsonschema.Schema { reflector := &jsonschema.Reflector{ AllowAdditionalProperties: true, TypeNamer: func(r reflect.Type) string { - name := r.Name() - if strings.HasPrefix(name, "JSON") { - name = strings.TrimPrefix(name, "JSON") - } - return name + return strings.TrimPrefix(r.Name(), "JSON") }, } documentSchema := reflector.ReflectFromType(reflect.TypeOf(&poweruser.JSONDocument{})) diff --git a/syft/file/digest_cataloger.go b/syft/file/digest_cataloger.go index a4cc74138..88728078d 100644 --- a/syft/file/digest_cataloger.go +++ b/syft/file/digest_cataloger.go @@ -99,7 +99,7 @@ func DigestAlgorithmName(hash crypto.Hash) string { func CleanDigestAlgorithmName(name string) string { lower := strings.ToLower(name) - return strings.Replace(lower, "-", "", -1) + return strings.ReplaceAll(lower, "-", "") } func digestsCatalogingProgress(locations int64) (*progress.Stage, *progress.Manual) { diff --git a/syft/pkg/apk_metadata.go b/syft/pkg/apk_metadata.go index cd6b4cd7c..497202f5a 100644 --- a/syft/pkg/apk_metadata.go +++ b/syft/pkg/apk_metadata.go @@ -9,7 +9,7 @@ import ( "github.com/scylladb/go-set/strset" ) -const ApkDbGlob = "**/lib/apk/db/installed" +const ApkDBGlob = "**/lib/apk/db/installed" var _ FileOwner = (*ApkMetadata)(nil) diff --git a/syft/pkg/cataloger/apkdb/cataloger.go b/syft/pkg/cataloger/apkdb/cataloger.go index 6219eaaf7..f82aef798 100644 --- a/syft/pkg/cataloger/apkdb/cataloger.go +++ b/syft/pkg/cataloger/apkdb/cataloger.go @@ -11,7 +11,7 @@ import ( // NewApkdbCataloger returns a new Alpine DB cataloger object. func NewApkdbCataloger() *common.GenericCataloger { globParsers := map[string]common.ParserFn{ - pkg.ApkDbGlob: parseApkDB, + pkg.ApkDBGlob: parseApkDB, } return common.NewGenericCataloger(nil, globParsers, "apkdb-cataloger") diff --git a/syft/pkg/cataloger/common/cpe/candidate_by_package_type.go b/syft/pkg/cataloger/common/cpe/candidate_by_package_type.go index bb008cbc7..ae0f2cc26 100644 --- a/syft/pkg/cataloger/common/cpe/candidate_by_package_type.go +++ b/syft/pkg/cataloger/common/cpe/candidate_by_package_type.go @@ -29,20 +29,20 @@ var defaultCandidateAdditions = buildCandidateLookup( { // example image: docker.io/nuxeo:latest pkg.JavaPkg, - candidateKey{PkgName: "elasticsearch"}, //, Vendor: "elasticsearch"}, + candidateKey{PkgName: "elasticsearch"}, // , Vendor: "elasticsearch"}, candidateAddition{AdditionalVendors: []string{"elastic"}}, }, { // example image: docker.io/kaazing-gateway:latest pkg.JavaPkg, - candidateKey{PkgName: "log4j"}, //, Vendor: "apache-software-foundation"}, + candidateKey{PkgName: "log4j"}, // , Vendor: "apache-software-foundation"}, candidateAddition{AdditionalVendors: []string{"apache"}}, }, { // example image: cassandra:latest pkg.JavaPkg, - candidateKey{PkgName: "apache-cassandra"}, //, Vendor: "apache"}, + candidateKey{PkgName: "apache-cassandra"}, // , Vendor: "apache"}, candidateAddition{AdditionalProducts: []string{"cassandra"}}, }, diff --git a/syft/pkg/cataloger/deb/cataloger.go b/syft/pkg/cataloger/deb/cataloger.go index 1cd000707..20e510160 100644 --- a/syft/pkg/cataloger/deb/cataloger.go +++ b/syft/pkg/cataloger/deb/cataloger.go @@ -36,9 +36,8 @@ func (c *Cataloger) Name() string { } // Catalog is given an object to resolve file references and content, this function returns any discovered Packages after analyzing dpkg support files. -// nolint:funlen func (c *Cataloger) Catalog(resolver source.FileResolver) ([]pkg.Package, error) { - dbFileMatches, err := resolver.FilesByGlob(pkg.DpkgDbGlob) + dbFileMatches, err := resolver.FilesByGlob(pkg.DpkgDBGlob) if err != nil { return nil, fmt.Errorf("failed to find dpkg status files's by glob: %w", err) } @@ -80,15 +79,13 @@ func addLicenses(resolver source.FileResolver, dbLocation source.Location, p *pk // get license information from the copyright file copyrightReader, copyrightLocation := fetchCopyrightContents(resolver, dbLocation, p) - if copyrightReader != nil { + if copyrightReader != nil && copyrightLocation != nil { defer internal.CloseAndLogError(copyrightReader, copyrightLocation.VirtualPath) // attach the licenses p.Licenses = parseLicensesFromCopyright(copyrightReader) // keep a record of the file where this was discovered - if copyrightLocation != nil { - p.Locations = append(p.Locations, *copyrightLocation) - } + p.Locations = append(p.Locations, *copyrightLocation) } } @@ -127,28 +124,24 @@ func getAdditionalFileListing(resolver source.FileResolver, dbLocation source.Lo md5Reader, md5Location := fetchMd5Contents(resolver, dbLocation, p) - if md5Reader != nil { + if md5Reader != nil && md5Location != nil { defer internal.CloseAndLogError(md5Reader, md5Location.VirtualPath) // attach the file list files = append(files, parseDpkgMD5Info(md5Reader)...) // keep a record of the file where this was discovered - if md5Location != nil { - locations = append(locations, *md5Location) - } + locations = append(locations, *md5Location) } conffilesReader, conffilesLocation := fetchConffileContents(resolver, dbLocation, p) - if conffilesReader != nil { + if conffilesReader != nil && conffilesLocation != nil { defer internal.CloseAndLogError(conffilesReader, conffilesLocation.VirtualPath) // attach the file list files = append(files, parseDpkgConffileInfo(md5Reader)...) // keep a record of the file where this was discovered - if conffilesLocation != nil { - locations = append(locations, *conffilesLocation) - } + locations = append(locations, *conffilesLocation) } return files, locations diff --git a/syft/pkg/cataloger/rpmdb/cataloger.go b/syft/pkg/cataloger/rpmdb/cataloger.go index 50e3697a3..642c494e9 100644 --- a/syft/pkg/cataloger/rpmdb/cataloger.go +++ b/syft/pkg/cataloger/rpmdb/cataloger.go @@ -28,7 +28,7 @@ func (c *Cataloger) Name() string { // Catalog is given an object to resolve file references and content, this function returns any discovered Packages after analyzing rpm db installation. func (c *Cataloger) Catalog(resolver source.FileResolver) ([]pkg.Package, error) { - fileMatches, err := resolver.FilesByGlob(pkg.RpmDbGlob) + fileMatches, err := resolver.FilesByGlob(pkg.RpmDBGlob) if err != nil { return nil, fmt.Errorf("failed to find rpmdb's by glob: %w", err) } diff --git a/syft/pkg/cataloger/rpmdb/parse_rpmdb.go b/syft/pkg/cataloger/rpmdb/parse_rpmdb.go index 794201d90..93220994b 100644 --- a/syft/pkg/cataloger/rpmdb/parse_rpmdb.go +++ b/syft/pkg/cataloger/rpmdb/parse_rpmdb.go @@ -93,7 +93,7 @@ func extractRpmdbFileRecords(resolver source.FilePathResolver, entry *rpmdb.Pack var records = make([]pkg.RpmdbFileRecord, 0) for _, record := range entry.Files { - //only persist RPMDB file records which exist in the image/directory, otherwise ignore them + // only persist RPMDB file records which exist in the image/directory, otherwise ignore them if resolver.HasPath(record.Path) { records = append(records, pkg.RpmdbFileRecord{ Path: record.Path, diff --git a/syft/pkg/dpkg_metadata.go b/syft/pkg/dpkg_metadata.go index 95e1ad6b4..e6e4d1c47 100644 --- a/syft/pkg/dpkg_metadata.go +++ b/syft/pkg/dpkg_metadata.go @@ -10,7 +10,7 @@ import ( "github.com/scylladb/go-set/strset" ) -const DpkgDbGlob = "**/var/lib/dpkg/{status,status.d/**}" +const DpkgDBGlob = "**/var/lib/dpkg/{status,status.d/**}" var _ FileOwner = (*DpkgMetadata)(nil) diff --git a/syft/pkg/ownership_by_files_relationship.go b/syft/pkg/ownership_by_files_relationship.go index 4e2b4d314..3aa2f37b7 100644 --- a/syft/pkg/ownership_by_files_relationship.go +++ b/syft/pkg/ownership_by_files_relationship.go @@ -9,9 +9,9 @@ import ( var globsForbiddenFromBeingOwned = []string{ // any OS DBs should automatically be ignored to prevent cyclic issues (e.g. the "rpm" RPM owns the path to the // RPM DB, so if not ignored that package would own all other packages on the system). - ApkDbGlob, - DpkgDbGlob, - RpmDbGlob, + ApkDBGlob, + DpkgDBGlob, + RpmDBGlob, // DEB packages share common copyright info between, this does not mean that sharing these paths implies ownership. "/usr/share/doc/**/copyright", } diff --git a/syft/pkg/rpmdb_metadata.go b/syft/pkg/rpmdb_metadata.go index 91f874915..36d38cea0 100644 --- a/syft/pkg/rpmdb_metadata.go +++ b/syft/pkg/rpmdb_metadata.go @@ -13,7 +13,7 @@ import ( "github.com/anchore/syft/syft/distro" ) -const RpmDbGlob = "**/var/lib/rpm/Packages" +const RpmDBGlob = "**/var/lib/rpm/Packages" var _ FileOwner = (*RpmdbMetadata)(nil) diff --git a/syft/source/all_layers_resolver.go b/syft/source/all_layers_resolver.go index 084eca7c2..5e8c1463a 100644 --- a/syft/source/all_layers_resolver.go +++ b/syft/source/all_layers_resolver.go @@ -120,7 +120,6 @@ func (r *allLayersResolver) FilesByPath(paths ...string) ([]Location, error) { } // FilesByGlob returns all file.References that match the given path glob pattern from any layer in the image. -// nolint:gocognit func (r *allLayersResolver) FilesByGlob(patterns ...string) ([]Location, error) { uniqueFileIDs := file.NewFileReferenceSet() uniqueLocations := make([]Location, 0) diff --git a/ui/event_handlers.go b/ui/event_handlers.go index c37582bd6..ba543a366 100644 --- a/ui/event_handlers.go +++ b/ui/event_handlers.go @@ -184,7 +184,6 @@ func PullDockerImageHandler(ctx context.Context, fr *frame.Frame, event partybus } // FetchImageHandler periodically writes a the image save and write-to-disk process in the form of a progress bar. -// nolint:dupl func FetchImageHandler(ctx context.Context, fr *frame.Frame, event partybus.Event, wg *sync.WaitGroup) error { _, prog, err := stereoEventParsers.ParseFetchImage(event) if err != nil { @@ -313,7 +312,6 @@ func PackageCatalogerStartedHandler(ctx context.Context, fr *frame.Frame, event } // SecretsCatalogerStartedHandler shows the intermittent secrets searching progress. -// nolint:dupl func SecretsCatalogerStartedHandler(ctx context.Context, fr *frame.Frame, event partybus.Event, wg *sync.WaitGroup) error { prog, err := syftEventParsers.ParseSecretsCatalogingStarted(event) if err != nil { @@ -401,7 +399,6 @@ func FileMetadataCatalogerStartedHandler(ctx context.Context, fr *frame.Frame, e } // FileIndexingStartedHandler shows the intermittent indexing progress from a directory resolver. -// nolint:dupl func FileIndexingStartedHandler(ctx context.Context, fr *frame.Frame, event partybus.Event, wg *sync.WaitGroup) error { path, prog, err := syftEventParsers.ParseFileIndexingStarted(event) if err != nil { @@ -487,7 +484,6 @@ func FileDigestsCatalogerStartedHandler(ctx context.Context, fr *frame.Frame, ev } // ImportStartedHandler shows the intermittent upload progress to Anchore Enterprise. -// nolint:dupl func ImportStartedHandler(ctx context.Context, fr *frame.Frame, event partybus.Event, wg *sync.WaitGroup) error { host, prog, err := syftEventParsers.ParseImportStarted(event) if err != nil {