diff --git a/docs/examples/skip.md b/docs/examples/skip.md index 402252dcc3..adeea9b9ab 100644 --- a/docs/examples/skip.md +++ b/docs/examples/skip.md @@ -5,7 +5,7 @@ Trivy traversals directories and looks for all lock files by default. If your image contains lock files which are not maintained by you, you can skip the file. ``` -$ trivy image --skip-files "/Gemfile.lock,/app/Pipfile.lock" quay.io/fluentd_elasticsearch/fluentd:v2.9.0 +$ trivy image --skip-files "/Gemfile.lock" --skip-files "/var/lib/gems/2.5.0/gems/http_parser.rb-0.6.0/Gemfile.lock" quay.io/fluentd_elasticsearch/fluentd:v2.9.0 ``` ## Skip Directories @@ -13,5 +13,5 @@ Trivy traversals directories and look for all lock files by default. If your image contains lock files which are not maintained by you, you can skip traversal in the specific directory. ``` -$ trivy image --skip-dirs "/usr/lib/ruby/gems,/etc" fluent/fluentd:edge +$ trivy image --skip-dirs /var/lib/gems/2.5.0/gems/fluent-plugin-detect-exceptions-0.0.13 --skip-dirs "/var/lib/gems/2.5.0/gems/http_parser.rb-0.6.0" quay.io/fluentd_elasticsearch/fluentd:v2.9.0 ``` diff --git a/integration/standalone_tar_test.go b/integration/standalone_tar_test.go index 3070560856..fd18fe4d40 100644 --- a/integration/standalone_tar_test.go +++ b/integration/standalone_tar_test.go @@ -413,10 +413,15 @@ func TestRun_WithTar(t *testing.T) { } if len(c.testArgs.SkipFiles) != 0 { - osArgs = append(osArgs, "--skip-files", strings.Join(c.testArgs.SkipFiles, ",")) + for _, skipFile := range c.testArgs.SkipFiles { + osArgs = append(osArgs, "--skip-files", skipFile) + } } + if len(c.testArgs.SkipDirs) != 0 { - osArgs = append(osArgs, "--skip-dirs", strings.Join(c.testArgs.SkipDirs, ",")) + for _, skipDir := range c.testArgs.SkipDirs { + osArgs = append(osArgs, "--skip-dirs", skipDir) + } } // Setup the output file diff --git a/pkg/commands/app.go b/pkg/commands/app.go index e6f316e0b6..976792c9e5 100644 --- a/pkg/commands/app.go +++ b/pkg/commands/app.go @@ -198,15 +198,15 @@ var ( EnvVars: []string{"TRIVY_LIST_ALL_PKGS"}, } - skipFiles = cli.StringFlag{ + skipFiles = cli.StringSliceFlag{ Name: "skip-files", - Usage: "specify the file path to skip traversal", + Usage: "specify the file paths to skip traversal", EnvVars: []string{"TRIVY_SKIP_FILES"}, } - skipDirectories = cli.StringFlag{ + skipDirs = cli.StringSliceFlag{ Name: "skip-dirs", - Usage: "specify the directory where the traversal is skipped", + Usage: "specify the directories where the traversal is skipped", EnvVars: []string{"TRIVY_SKIP_DIRS"}, } @@ -237,7 +237,7 @@ var ( &ignorePolicy, &listAllPackages, &skipFiles, - &skipDirectories, + &skipDirs, &cacheBackendFlag, } @@ -308,6 +308,10 @@ func setHidden(flags []cli.Flag, hidden bool) []cli.Flag { stringFlag := *pf stringFlag.Hidden = hidden f = &stringFlag + case *cli.StringSliceFlag: + stringSliceFlag := *pf + stringSliceFlag.Hidden = hidden + f = &stringSliceFlag case *cli.BoolFlag: boolFlag := *pf boolFlag.Hidden = hidden @@ -408,7 +412,7 @@ func NewFilesystemCommand() *cli.Command { &ignorePolicy, &listAllPackages, &skipFiles, - &skipDirectories, + &skipDirs, }, } } @@ -440,7 +444,7 @@ func NewRepositoryCommand() *cli.Command { &ignorePolicy, &listAllPackages, &skipFiles, - &skipDirectories, + &skipDirs, }, } } diff --git a/pkg/commands/artifact/run.go b/pkg/commands/artifact/run.go index fc3148818e..223ddba3d4 100644 --- a/pkg/commands/artifact/run.go +++ b/pkg/commands/artifact/run.go @@ -128,7 +128,7 @@ func scan(ctx context.Context, conf Config, initializeScanner InitializeScanner, ScanRemovedPackages: conf.ScanRemovedPkgs, // this is valid only for image subcommand ListAllPackages: conf.ListAllPkgs, SkipFiles: conf.SkipFiles, - SkipDirectories: conf.SkipDirectories, + SkipDirs: conf.SkipDirs, } log.Logger.Debugf("Vulnerability type: %s", scanOptions.VulnType) diff --git a/pkg/commands/config/artifact.go b/pkg/commands/config/artifact.go index 030933b0d0..5e1d25c9f2 100644 --- a/pkg/commands/config/artifact.go +++ b/pkg/commands/config/artifact.go @@ -2,7 +2,6 @@ package config import ( "os" - "strings" "time" "github.com/urfave/cli/v2" @@ -16,10 +15,8 @@ type ArtifactConfig struct { Timeout time.Duration ClearCache bool - skipDirectories string - SkipDirectories []string - skipFiles string - SkipFiles []string + SkipDirs []string + SkipFiles []string // this field is populated in Init() Target string @@ -28,11 +25,11 @@ type ArtifactConfig struct { // NewArtifactConfig is the factory method to return artifact config func NewArtifactConfig(c *cli.Context) ArtifactConfig { return ArtifactConfig{ - Input: c.String("input"), - Timeout: c.Duration("timeout"), - ClearCache: c.Bool("clear-cache"), - skipFiles: c.String("skip-files"), - skipDirectories: c.String("skip-dirs"), + Input: c.String("input"), + Timeout: c.Duration("timeout"), + ClearCache: c.Bool("clear-cache"), + SkipFiles: c.StringSlice("skip-files"), + SkipDirs: c.StringSlice("skip-dirs"), } } @@ -51,13 +48,5 @@ func (c *ArtifactConfig) Init(ctx *cli.Context, logger *zap.SugaredLogger) (err c.Target = ctx.Args().First() } - if c.skipDirectories != "" { - c.SkipDirectories = strings.Split(c.skipDirectories, ",") - } - - if c.skipFiles != "" { - c.SkipFiles = strings.Split(c.skipFiles, ",") - } - return nil } diff --git a/pkg/scanner/local/scan.go b/pkg/scanner/local/scan.go index df0b422375..b9726ff165 100644 --- a/pkg/scanner/local/scan.go +++ b/pkg/scanner/local/scan.go @@ -167,7 +167,7 @@ func (s Scanner) scanLibrary(apps []ftypes.Application, options types.ScanOption if len(app.Libraries) == 0 { continue } - if skipped(app.FilePath, options.SkipFiles, options.SkipDirectories) { + if skipped(app.FilePath, options.SkipFiles, options.SkipDirs) { continue } @@ -210,7 +210,7 @@ func (s Scanner) scanLibrary(apps []ftypes.Application, options types.ScanOption return results, nil } -func skipped(filePath string, skipFiles, skipDirectories []string) bool { +func skipped(filePath string, skipFiles, skipDirs []string) bool { for _, skipFile := range skipFiles { skipFile = strings.TrimLeft(filepath.Clean(skipFile), string(os.PathSeparator)) if filePath == skipFile { @@ -218,7 +218,7 @@ func skipped(filePath string, skipFiles, skipDirectories []string) bool { } } - for _, skipDir := range skipDirectories { + for _, skipDir := range skipDirs { skipDir = strings.TrimLeft(filepath.Clean(skipDir), string(os.PathSeparator)) rel, err := filepath.Rel(skipDir, filePath) if err != nil { diff --git a/pkg/scanner/local/scan_test.go b/pkg/scanner/local/scan_test.go index a87f03659f..a1a7e88e49 100644 --- a/pkg/scanner/local/scan_test.go +++ b/pkg/scanner/local/scan_test.go @@ -609,8 +609,8 @@ func TestScanner_Scan(t *testing.T) { target: "alpine:latest", layerIDs: []string{"sha256:5216338b40a7b96416b8b9858974bbe4acc3096ee60acbc4dfb1ee02aecceb10"}, options: types.ScanOptions{ - VulnType: []string{"library"}, - SkipDirectories: []string{"/usr/lib/ruby/gems"}, + VulnType: []string{"library"}, + SkipDirs: []string{"/usr/lib/ruby/gems"}, }, }, fixtures: []string{"testdata/fixtures/happy.yaml"}, @@ -829,9 +829,9 @@ func TestScanner_Scan(t *testing.T) { func Test_skipped(t *testing.T) { type args struct { - filePath string - skipFiles []string - skipDirectories []string + filePath string + skipFiles []string + skipDirs []string } tests := []struct { name string @@ -841,24 +841,24 @@ func Test_skipped(t *testing.T) { { name: "no skip directory", args: args{ - filePath: "app/Gemfile.lock", - skipDirectories: []string{}, + filePath: "app/Gemfile.lock", + skipDirs: []string{}, }, want: false, }, { name: "skip directory with the leading slash", args: args{ - filePath: "app/Gemfile.lock", - skipDirectories: []string{"/app"}, + filePath: "app/Gemfile.lock", + skipDirs: []string{"/app"}, }, want: true, }, { name: "skip directory without a slash", args: args{ - filePath: "usr/lib/ruby/gems/2.5.0/gems/http_parser.rb-0.6.0/Gemfile.lock", - skipDirectories: []string{"/usr/lib/ruby"}, + filePath: "usr/lib/ruby/gems/2.5.0/gems/http_parser.rb-0.6.0/Gemfile.lock", + skipDirs: []string{"/usr/lib/ruby"}, }, want: true, }, @@ -881,15 +881,15 @@ func Test_skipped(t *testing.T) { { name: "not skipped", args: args{ - filePath: "usr/lib/ruby/gems/2.5.0/gems/http_parser.rb-0.6.0/Gemfile.lock", - skipDirectories: []string{"lib/ruby"}, + filePath: "usr/lib/ruby/gems/2.5.0/gems/http_parser.rb-0.6.0/Gemfile.lock", + skipDirs: []string{"lib/ruby"}, }, want: false, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got := skipped(tt.args.filePath, tt.args.skipFiles, tt.args.skipDirectories) + got := skipped(tt.args.filePath, tt.args.skipFiles, tt.args.skipDirs) assert.Equal(t, tt.want, got) }) } diff --git a/pkg/types/scanoptions.go b/pkg/types/scanoptions.go index 7cfbcfb5da..f8d9a24f0b 100644 --- a/pkg/types/scanoptions.go +++ b/pkg/types/scanoptions.go @@ -6,5 +6,5 @@ type ScanOptions struct { ScanRemovedPackages bool ListAllPackages bool SkipFiles []string - SkipDirectories []string + SkipDirs []string }