From a015fac5061bf8ca498fdceceff7dd0ac8550976 Mon Sep 17 00:00:00 2001 From: DMarinhoCodacy Date: Fri, 18 Sep 2026 12:11:00 +0100 Subject: [PATCH 1/2] Handle symlinks from breaking the tool --- internal/tool/command.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/internal/tool/command.go b/internal/tool/command.go index cff0999..575f5c1 100644 --- a/internal/tool/command.go +++ b/internal/tool/command.go @@ -180,6 +180,11 @@ func getMessage(patternDescriptions *[]codacy.PatternDescription, id string, ext func appendErrorToResult(result []codacy.Result, semgrepOutput SemgrepOutput) []codacy.Result { for _, semgrepError := range semgrepOutput.Errors { + // Skip errors with empty paths (e.g., from symlinks that couldn't be analyzed) + if semgrepError.Location.Path == "" { + continue + } + // Determine the size of the error message we're logging sizeMessage := 250 From ee08cc1021d92b416a7a9c68b70a6af80ac4c378 Mon Sep 17 00:00:00 2001 From: DMarinhoCodacy Date: Tue, 29 Sep 2026 15:39:01 +0100 Subject: [PATCH 2/2] Improve Output parser --- internal/tool/command.go | 43 +++++++++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/internal/tool/command.go b/internal/tool/command.go index 575f5c1..ea7c0b7 100644 --- a/internal/tool/command.go +++ b/internal/tool/command.go @@ -51,15 +51,31 @@ func executeCommandForFiles(configurationFile *os.File, toolExecution codacy.Too semgrepCmd := createCommand(configurationFile, toolExecution.SourceDir, language, files) semgrepOutput, semgrepError, err := runCommand(semgrepCmd) - if err != nil { - return nil, errors.New("Error running semgrep: " + *semgrepError + "\n" + err.Error()) + + // Try to parse output if we have any + if semgrepOutput != nil && *semgrepOutput != "" { + output, parseErr := parseCommandOutput(patternDescriptions, *semgrepOutput) + if parseErr != nil { + // If parsing fails and we had a command error, report the command error + if err != nil { + return nil, errors.New("Error running Opengrep: " + *semgrepError + "\n" + err.Error()) + } + return nil, parseErr + } + // Parsing succeeded, return results even if command had a non-zero exit + if err != nil { + fmt.Printf("Warning: Opengrep exited with error (some files may not have been analyzed): %v\n", err) + } + return output, nil } - output, err := parseCommandOutput(patternDescriptions, *semgrepOutput) + // No output and command failed if err != nil { - return nil, err + return nil, errors.New("Error running Opengrep: " + *semgrepError + "\n" + err.Error()) } - return output, nil + + // No output but command succeeded - return empty results + return []codacy.Result{}, nil } func createCommand(configurationFile *os.File, sourceDir, language string, files []string) *exec.Cmd { @@ -105,15 +121,18 @@ func createCommandParameters(language string, configurationFile *os.File, filesT } func runCommand(cmd *exec.Cmd) (*string, *string, error) { + var stdout bytes.Buffer var stderr bytes.Buffer + cmd.Stdout = &stdout cmd.Stderr = &stderr - cmdOutput, err := cmd.Output() - if err != nil { - stderrString := stderr.String() - return nil, &stderrString, err - } - cmdOutputString := string(cmdOutput) - return &cmdOutputString, nil, nil + + err := cmd.Run() + + stdoutString := stdout.String() + stderrString := stderr.String() + + // Return output regardless of error - the caller can decide what to do + return &stdoutString, &stderrString, err } func parseCommandOutput(patternDescriptions *[]codacy.PatternDescription, commandOutput string) ([]codacy.Result, error) {