From adb421a40bca5eecb54ecfd178170689934bb275 Mon Sep 17 00:00:00 2001 From: filip Date: Thu, 7 Nov 2024 15:15:45 +0100 Subject: [PATCH] Add debug flag and logging to scan --- internal/cmd/scan/scan.go | 6 ++++++ internal/debug/debug.go | 16 ++++++++++++++++ internal/debug/debug_test.go | 23 +++++++++++++++++++++++ internal/scan/scanner.go | 11 +++++++++++ 4 files changed, 56 insertions(+) create mode 100644 internal/debug/debug.go create mode 100644 internal/debug/debug_test.go diff --git a/internal/cmd/scan/scan.go b/internal/cmd/scan/scan.go index c1f64dfd..ed5777c5 100644 --- a/internal/cmd/scan/scan.go +++ b/internal/cmd/scan/scan.go @@ -21,6 +21,7 @@ var callgraphGenerateTimeout int var callgraphUploadTimeout int var commitAuthor string var commitName string +var debug bool var exclusions = file.Exclusions() var inclusions = file.Exclusions() var integrationName string @@ -46,6 +47,7 @@ const ( CallGraphUploadTimeoutFlag = "callgraph-upload-timeout" CommitFlag = "commit" CommitAuthorFlag = "author" + DebugFlag = "debug" ExclusionFlag = "exclusion" IntegrationFlag = "integration" InclusionFlag = "inclusion" @@ -145,6 +147,7 @@ $ debricked scan . --include '**/node_modules/**'`) "\nExample:\n$ debricked resolve --verbose=false", }, "\n") cmd.Flags().BoolVar(&verbose, VerboseFlag, true, verboseDoc) + cmd.Flags().BoolVar(&debug, DebugFlag, false, "write all debug output to stderr") cmd.Flags().BoolVarP(&passOnDowntime, PassOnTimeOut, "p", false, "pass scan if there is a service access timeout") cmd.Flags().BoolVar(&noResolve, NoResolveFlag, false, `disables resolution of manifest files that lack lock files. Resolving manifest files enables more accurate dependency scanning since the whole dependency tree will be analysed. For example, if there is a "go.mod" in the target path, its dependencies are going to get resolved onto a lock file, and latter scanned.`) @@ -188,6 +191,8 @@ Leaving the field empty results in no SBOM generation.`, func RunE(s *scan.IScanner) func(_ *cobra.Command, args []string) error { return func(cmd *cobra.Command, args []string) error { + fmt.Println("Scanner started...") + path := "" if len(args) > 0 { path = args[0] @@ -214,6 +219,7 @@ func RunE(s *scan.IScanner) func(_ *cobra.Command, args []string) error { SBOMOutput: viper.GetString(SBOMOutputFlag), Exclusions: viper.GetStringSlice(ExclusionFlag), Verbose: viper.GetBool(VerboseFlag), + Debug: viper.GetBool(DebugFlag), Regenerate: viper.GetInt(RegenerateFlag), VersionHint: viper.GetBool(VersionHintFlag), RepositoryName: viper.GetString(RepositoryFlag), diff --git a/internal/debug/debug.go b/internal/debug/debug.go new file mode 100644 index 00000000..a33bd232 --- /dev/null +++ b/internal/debug/debug.go @@ -0,0 +1,16 @@ +package debug + +import ( + "fmt" + "os" + "strings" + + "github.com/fatih/color" +) + +func Print(message string, debug bool) { + if debug { + debugMessage := strings.Join([]string{"DEBUG: ", message, "\n"}, "") + fmt.Fprint(os.Stderr, color.BlueString(debugMessage)) + } +} diff --git a/internal/debug/debug_test.go b/internal/debug/debug_test.go new file mode 100644 index 00000000..de3fb480 --- /dev/null +++ b/internal/debug/debug_test.go @@ -0,0 +1,23 @@ +package debug + +import ( + "io" + "os" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestPrint(t *testing.T) { + rescueStderr := os.Stderr + r, w, _ := os.Pipe() + os.Stderr = w + + Print("hello", true) + + _ = w.Close() + output, _ := io.ReadAll(r) + os.Stderr = rescueStderr + + assert.Equal(t, "DEBUG: hello\n", string(output)) +} diff --git a/internal/scan/scanner.go b/internal/scan/scanner.go index 933ddf79..3d038b33 100644 --- a/internal/scan/scanner.go +++ b/internal/scan/scanner.go @@ -12,6 +12,7 @@ import ( "github.com/debricked/cli/internal/ci" "github.com/debricked/cli/internal/ci/env" "github.com/debricked/cli/internal/client" + "github.com/debricked/cli/internal/debug" "github.com/debricked/cli/internal/file" "github.com/debricked/cli/internal/fingerprint" "github.com/debricked/cli/internal/git" @@ -54,6 +55,7 @@ type DebrickedOptions struct { Exclusions []string Inclusions []string Verbose bool + Debug bool Regenerate int VersionHint bool RepositoryName string @@ -96,15 +98,18 @@ func (dScanner *DebrickedScanner) Scan(o IOptions) error { if !ok { return BadOptsErr } + debug.Print("Options initialized, finding CI service...", dOptions.Debug) e, _ := dScanner.ciService.Find() + debug.Print("Mapping environment variables...", dOptions.Debug) MapEnvToOptions(&dOptions, e) if err := SetWorkingDirectory(&dOptions); err != nil { return err } + debug.Print("Setting up git objects...", dOptions.Debug) gitMetaObject, err := git.NewMetaObject( dOptions.Path, dOptions.RepositoryName, @@ -117,6 +122,7 @@ func (dScanner *DebrickedScanner) Scan(o IOptions) error { return err } + debug.Print("Running scan with initialized scanner...", dOptions.Debug) result, err := dScanner.scan(dOptions, *gitMetaObject) if err != nil { return dScanner.handleScanError(err, dOptions.PassOnTimeOut) @@ -216,17 +222,20 @@ func (dScanner *DebrickedScanner) scanFingerprint(options DebrickedOptions) erro func (dScanner *DebrickedScanner) scan(options DebrickedOptions, gitMetaObject git.MetaObject) (*upload.UploadResult, error) { + debug.Print("Running scanResolve...", options.Debug) err := dScanner.scanResolve(options) if err != nil { return nil, err } + debug.Print("Running scanFingerprint...", options.Debug) err = dScanner.scanFingerprint(options) if err != nil { return nil, err } if options.CallGraph { + debug.Print("Running scanFingerprint...", options.Debug) configs := []config.IConfig{ config.NewConfig("java", []string{}, map[string]string{"pm": "maven"}, true, "maven"), config.NewConfig("golang", []string{}, map[string]string{"pm": "go"}, true, "go"), @@ -250,6 +259,7 @@ func (dScanner *DebrickedScanner) scan(options DebrickedOptions, gitMetaObject g } } + debug.Print("Matching groups...", options.Debug) fileGroups, err := dScanner.finder.GetGroups( file.DebrickedOptions{ RootPath: options.Path, @@ -263,6 +273,7 @@ func (dScanner *DebrickedScanner) scan(options DebrickedOptions, gitMetaObject g return nil, err } + debug.Print("Starting upload...", options.Debug) uploaderOptions := upload.DebrickedOptions{ FileGroups: fileGroups, GitMetaObject: gitMetaObject,