From c606392fccb440af19a4e73e737839f55a70e4fd Mon Sep 17 00:00:00 2001 From: Joao Machado <13315199+machadoit@users.noreply.github.com> Date: Wed, 9 Jul 2025 16:11:21 +0200 Subject: [PATCH 1/8] feature: Respect the file information for languages from the API CF-1742 --- cmd/analyze.go | 15 ++++--- cmd/analyze_test.go | 21 ++++++++- codacy-client/client.go | 2 +- domain/language.go | 16 +++++-- tools/language_config.go | 96 +++++++++++++++++++++++++++++----------- 5 files changed, 113 insertions(+), 37 deletions(-) diff --git a/cmd/analyze.go b/cmd/analyze.go index dfc256a0..f6e76a36 100644 --- a/cmd/analyze.go +++ b/cmd/analyze.go @@ -41,6 +41,7 @@ type LanguagesConfig struct { Name string `yaml:"name" json:"name"` Languages []string `yaml:"languages" json:"languages"` Extensions []string `yaml:"extensions" json:"extensions"` + Files []string `yaml:"files" json:"files"` } `yaml:"tools" json:"tools"` } @@ -90,7 +91,7 @@ func GetFileExtension(filePath string) string { return strings.ToLower(filepath.Ext(filePath)) } -// IsToolSupportedForFile checks if a tool supports a given file based on its extension +// IsToolSupportedForFile checks if a tool supports a given file based on its extension or filename func IsToolSupportedForFile(toolName string, filePath string, langConfig *LanguagesConfig) bool { if langConfig == nil { // If no language config is available, assume all tools are supported @@ -98,10 +99,7 @@ func IsToolSupportedForFile(toolName string, filePath string, langConfig *Langua } fileExt := GetFileExtension(filePath) - if fileExt == "" { - // If file has no extension, assume tool is supported - return true - } + fileName := filepath.Base(filePath) for _, tool := range langConfig.Tools { if tool.Name == toolName { @@ -117,6 +115,13 @@ func IsToolSupportedForFile(toolName string, filePath string, langConfig *Langua } } + // Check if filename is supported by this tool (exact match) + for _, file := range tool.Files { + if strings.EqualFold(file, fileName) { + return true + } + } + // Extension not found in tool's supported extensions return false } diff --git a/cmd/analyze_test.go b/cmd/analyze_test.go index e8de72ed..75ab3020 100644 --- a/cmd/analyze_test.go +++ b/cmd/analyze_test.go @@ -62,21 +62,31 @@ func TestIsToolSupportedForFile(t *testing.T) { Name string `yaml:"name" json:"name"` Languages []string `yaml:"languages" json:"languages"` Extensions []string `yaml:"extensions" json:"extensions"` + Files []string `yaml:"files" json:"files"` }{ { Name: "pylint", Languages: []string{"Python"}, Extensions: []string{".py"}, + Files: []string{}, + }, + { + Name: "eslint", + Languages: []string{"JavaScript", "TypeScript"}, + Extensions: []string{}, + Files: []string{}, }, { Name: "cppcheck", Languages: []string{"C", "CPP"}, Extensions: []string{".c", ".cpp", ".h", ".hpp"}, + Files: []string{}, }, { Name: "trivy", Languages: []string{"Multiple"}, - Extensions: []string{}, + Extensions: []string{".yaml", ".yml"}, + Files: []string{"requirements.txt"}, }, }, } @@ -111,7 +121,7 @@ func TestIsToolSupportedForFile(t *testing.T) { }, { name: "Tool with no extensions specified", - toolName: "trivy", + toolName: "eslint", filePath: "any.file", config: langConfig, want: true, @@ -130,6 +140,13 @@ func TestIsToolSupportedForFile(t *testing.T) { config: nil, want: true, }, + { + name: "Trivy with requirements.txt", + toolName: "trivy", + filePath: "requirements.txt", + config: langConfig, + want: true, + }, } for _, tt := range tests { diff --git a/codacy-client/client.go b/codacy-client/client.go index 5f7c7b56..f2934994 100644 --- a/codacy-client/client.go +++ b/codacy-client/client.go @@ -253,7 +253,7 @@ func GetToolsVersions() ([]domain.Tool, error) { } // GetRepositoryLanguages fetches the languages for a repository -func GetRepositoryLanguages(initFlags domain.InitFlags) ([]domain.Language, error) { +func GetRepositoryLanguages(initFlags domain.InitFlags) ([]domain.RepositoryLanguage, error) { baseURL := fmt.Sprintf("%s/api/v3/organizations/%s/%s/repositories/%s/settings/languages", CodacyApiBase, initFlags.Provider, diff --git a/domain/language.go b/domain/language.go index 6f9da01a..ee2a559b 100644 --- a/domain/language.go +++ b/domain/language.go @@ -1,23 +1,32 @@ package domain -// Language represents a language in the Codacy API -type Language struct { +// RepositoryLanguage represents a language in the Codacy API +type RepositoryLanguage struct { Name string `json:"name"` CodacyDefaults []string `json:"codacyDefaults"` Extensions []string `json:"extensions"` + DefaultFiles []string `json:"defaultFiles"` Enabled bool `json:"enabled"` Detected bool `json:"detected"` } // LanguagesResponse represents the structure of the languages response type LanguagesResponse struct { - Languages []Language `json:"languages"` + Languages []RepositoryLanguage `json:"languages"` +} + +// Language represents a processed language with combined extensions and files +type Language struct { + Name string + Extensions []string + Files []string } // LanguageTool represents a language tool with its file extensions from the API type LanguageTool struct { Name string `json:"name"` FileExtensions []string `json:"fileExtensions"` + Files []string `json:"files"` } // LanguageToolsResponse represents the structure of the language tools API response @@ -30,6 +39,7 @@ type ToolLanguageInfo struct { Name string `yaml:"name"` Languages []string `yaml:"languages,flow"` Extensions []string `yaml:"extensions,flow"` + Files []string `yaml:"files,flow"` } // LanguagesConfig represents the structure of the languages configuration file diff --git a/tools/language_config.go b/tools/language_config.go index d1aa10ef..6be36520 100644 --- a/tools/language_config.go +++ b/tools/language_config.go @@ -44,6 +44,12 @@ func buildToolLanguageInfoFromAPI() (map[string]domain.ToolLanguageInfo, error) languageExtensionsMap[strings.ToLower(langTool.Name)] = langTool.FileExtensions } + // Create map of language name to files + languageFilesMap := make(map[string][]string) + for _, langTool := range languageTools { + languageFilesMap[strings.ToLower(langTool.Name)] = langTool.Files + } + // Build tool language configurations from API data result := make(map[string]domain.ToolLanguageInfo) supportedToolNames := make(map[string]bool) @@ -72,8 +78,10 @@ func buildToolLanguageInfoFromAPI() (map[string]domain.ToolLanguageInfo, error) Extensions: []string{}, } - // Build extensions from API language data + // Build extensions and files from API language data extensionsSet := make(map[string]struct{}) + filesSet := make(map[string]struct{}) + for _, apiLang := range tool.Languages { lowerLang := strings.ToLower(apiLang) if extensions, exists := languageExtensionsMap[lowerLang]; exists { @@ -81,13 +89,22 @@ func buildToolLanguageInfoFromAPI() (map[string]domain.ToolLanguageInfo, error) extensionsSet[ext] = struct{}{} } } + if files, exists := languageFilesMap[lowerLang]; exists { + for _, file := range files { + filesSet[file] = struct{}{} + } + } } - // Convert set to sorted slice + // Convert sets to sorted slices for ext := range extensionsSet { configTool.Extensions = append(configTool.Extensions, ext) } slices.Sort(configTool.Extensions) + for file := range filesSet { + configTool.Files = append(configTool.Files, file) + } + slices.Sort(configTool.Files) // Sort languages alphabetically slices.Sort(configTool.Languages) @@ -201,18 +218,6 @@ func CreateLanguagesConfigFile(apiTools []domain.Tool, toolsConfigDir string, to // buildRemoteModeLanguagesConfig builds the languages config for remote mode using repository languages as source of truth func buildRemoteModeLanguagesConfig(apiTools []domain.Tool, toolIDMap map[string]string, initFlags domain.InitFlags) ([]domain.ToolLanguageInfo, error) { - // Get language file extensions from API - languageTools, err := codacyclient.GetLanguageTools() - if err != nil { - return nil, fmt.Errorf("failed to get language tools from API: %w", err) - } - - // Create map of language name to file extensions - languageExtensionsMap := make(map[string][]string) - for _, langTool := range languageTools { - languageExtensionsMap[strings.ToLower(langTool.Name)] = langTool.FileExtensions - } - // Get repository languages - this is the single source of truth for remote mode repositoryLanguages, err := getRepositoryLanguages(initFlags) if err != nil { @@ -232,18 +237,36 @@ func buildRemoteModeLanguagesConfig(apiTools []domain.Tool, toolIDMap map[string Name: shortName, Languages: []string{}, Extensions: []string{}, + Files: []string{}, } // Use only languages that exist in the repository extensionsSet := make(map[string]struct{}) + filesSet := make(map[string]struct{}) for _, lang := range tool.Languages { lowerLang := strings.ToLower(lang) - if repoExts, exists := repositoryLanguages[lowerLang]; exists && len(repoExts) > 0 { - configTool.Languages = append(configTool.Languages, lang) - // Add repository-specific extensions - for _, ext := range repoExts { - extensionsSet[ext] = struct{}{} + if repoLang, exists := repositoryLanguages[lowerLang]; exists { + // Check if this language has either extensions or files + hasExtensions := len(repoLang.Extensions) > 0 + hasFiles := len(repoLang.Files) > 0 + + if hasExtensions || hasFiles { + configTool.Languages = append(configTool.Languages, lang) + + // Add repository-specific extensions if they exist + if hasExtensions { + for _, ext := range repoLang.Extensions { + extensionsSet[ext] = struct{}{} + } + } + + // Add repository-specific files if they exist + if hasFiles { + for _, file := range repoLang.Files { + filesSet[file] = struct{}{} + } + } } } } @@ -254,6 +277,12 @@ func buildRemoteModeLanguagesConfig(apiTools []domain.Tool, toolIDMap map[string } slices.Sort(configTool.Extensions) + // Convert files set to sorted slice + for file := range filesSet { + configTool.Files = append(configTool.Files, file) + } + slices.Sort(configTool.Files) + // Sort languages alphabetically slices.Sort(configTool.Languages) @@ -264,14 +293,14 @@ func buildRemoteModeLanguagesConfig(apiTools []domain.Tool, toolIDMap map[string return configTools, nil } -func getRepositoryLanguages(initFlags domain.InitFlags) (map[string][]string, error) { +func getRepositoryLanguages(initFlags domain.InitFlags) (map[string]domain.Language, error) { response, err := codacyclient.GetRepositoryLanguages(initFlags) if err != nil { return nil, fmt.Errorf("failed to get repository languages: %w", err) } - // Create map to store language name -> combined extensions - result := make(map[string][]string) + // Create map to store language name -> Language struct + result := make(map[string]domain.Language) // Filter and process languages for _, lang := range response { @@ -285,17 +314,32 @@ func getRepositoryLanguages(initFlags domain.InitFlags) (map[string][]string, er extensions[ext] = struct{}{} } - // Convert map to slice + // Combine and deduplicate files + files := make(map[string]struct{}) + for _, file := range lang.DefaultFiles { + files[file] = struct{}{} + } + + // Convert extension map to slice extSlice := make([]string, 0, len(extensions)) for ext := range extensions { extSlice = append(extSlice, ext) } - - // Sort extensions for consistent ordering in the config file slices.Sort(extSlice) + // Convert files map to slice + fileSlice := make([]string, 0, len(files)) + for file := range files { + fileSlice = append(fileSlice, file) + } + slices.Sort(fileSlice) + // Add to result map with lowercase key for case-insensitive matching - result[strings.ToLower(lang.Name)] = extSlice + result[strings.ToLower(lang.Name)] = domain.Language{ + Name: lang.Name, + Extensions: extSlice, + Files: fileSlice, + } } } From 6487f9612c57587c9c6a0b4eea1d5358ead0d15a Mon Sep 17 00:00:00 2001 From: Joao Machado <13315199+machadoit@users.noreply.github.com> Date: Wed, 9 Jul 2025 18:44:38 +0200 Subject: [PATCH 2/8] Add integration test for trivy a and pylint CF-1742 Trivy should check and report on requirements.txt (done) Pylint should ignore the requirements.txt (not done yet) When the CLI is fixed to generate the correct files for pylint (not having the requirements.txt file), the langauges-config.yaml should be regenerated in order to fix the test --- .../tools-configs/languages-config.yaml | 5 + .../test/src/.codacy/tools-configs/pylint.rc | 9 ++ .../tools/pylint/test/src/requirements.txt | 2 + plugins/tools/trivy/test/expected.sarif | 124 ++++++++++++++++-- plugins/tools/trivy/test/src/requirements.txt | 1 + 5 files changed, 133 insertions(+), 8 deletions(-) create mode 100644 plugins/tools/pylint/test/src/.codacy/tools-configs/languages-config.yaml create mode 100644 plugins/tools/pylint/test/src/.codacy/tools-configs/pylint.rc create mode 100644 plugins/tools/pylint/test/src/requirements.txt create mode 100644 plugins/tools/trivy/test/src/requirements.txt diff --git a/plugins/tools/pylint/test/src/.codacy/tools-configs/languages-config.yaml b/plugins/tools/pylint/test/src/.codacy/tools-configs/languages-config.yaml new file mode 100644 index 00000000..d3ea1908 --- /dev/null +++ b/plugins/tools/pylint/test/src/.codacy/tools-configs/languages-config.yaml @@ -0,0 +1,5 @@ +tools: + - name: pylint + languages: [Python] + extensions: [.py] + files: [Pipfile.lock, poetry.lock, requirements.txt, uv.lock] diff --git a/plugins/tools/pylint/test/src/.codacy/tools-configs/pylint.rc b/plugins/tools/pylint/test/src/.codacy/tools-configs/pylint.rc new file mode 100644 index 00000000..92f4aea4 --- /dev/null +++ b/plugins/tools/pylint/test/src/.codacy/tools-configs/pylint.rc @@ -0,0 +1,9 @@ +[MASTER] +ignore=CVS +persistent=yes +load-plugins= + +[MESSAGES CONTROL] +disable=all +enable=C0123,C0200,C0303,E0100,E0101,E0102,E0103,E0104,E0105,E0106,E0107,E0108,E0110,E0112,E0113,E0114,E0115,E0116,E0117,E0202,E0203,E0211,E0236,E0238,E0239,E0240,E0241,E0301,E0302,E0601,E0603,E0604,E0701,E0702,E0704,E0710,E0711,E0712,E1003,E1102,E1111,E1120,E1121,E1123,E1124,E1125,E1126,E1127,E1132,E1200,E1201,E1205,E1206,E1300,E1301,E1302,E1303,E1304,E1305,E1306,R0202,R0203,W0101,W0102,W0104,W0105,W0106,W0107,W0108,W0109,W0120,W0122,W0124,W0150,W0199,W0221,W0222,W0233,W0404,W0410,W0601,W0602,W0604,W0611,W0612,W0622,W0702,W0705,W0711,W1300,W1301,W1302,W1303,W1305,W1306,W1307 + diff --git a/plugins/tools/pylint/test/src/requirements.txt b/plugins/tools/pylint/test/src/requirements.txt new file mode 100644 index 00000000..fbde3519 --- /dev/null +++ b/plugins/tools/pylint/test/src/requirements.txt @@ -0,0 +1,2 @@ +# This file should be successfully ignored by Codacy CLI as pylint does not support it. +django==1.11.29 \ No newline at end of file diff --git a/plugins/tools/trivy/test/expected.sarif b/plugins/tools/trivy/test/expected.sarif index 9507b051..562e72b3 100644 --- a/plugins/tools/trivy/test/expected.sarif +++ b/plugins/tools/trivy/test/expected.sarif @@ -9,6 +9,33 @@ } }, "results": [ + { + "level": "note", + "locations": [ + { + "message": { + "text": "package-lock.json: brace-expansion@1.1.11" + }, + "physicalLocation": { + "artifactLocation": { + "uri": "package-lock.json", + "uriBaseId": "ROOTPATH" + }, + "region": { + "endColumn": 1, + "endLine": 357, + "startColumn": 1, + "startLine": 349 + } + } + } + ], + "message": { + "text": "Package: brace-expansion\nInstalled Version: 1.1.11\nVulnerability CVE-2025-5889\nSeverity: LOW\nFixed Version: 2.0.2, 1.1.12, 3.0.1, 4.0.1\nLink: [CVE-2025-5889](https://avd.aquasec.com/nvd/cve-2025-5889)" + }, + "ruleId": "CVE-2025-5889", + "ruleIndex": 0 + }, { "level": "error", "locations": [ @@ -37,31 +64,112 @@ "ruleIndex": 1 }, { - "level": "note", + "level": "error", "locations": [ { "message": { - "text": "package-lock.json: brace-expansion@1.1.11" + "text": "requirements.txt: django@1.11.29" }, "physicalLocation": { "artifactLocation": { - "uri": "package-lock.json", + "uri": "requirements.txt", "uriBaseId": "ROOTPATH" }, "region": { "endColumn": 1, - "endLine": 357, + "endLine": 1, "startColumn": 1, - "startLine": 349 + "startLine": 1 } } } ], "message": { - "text": "Package: brace-expansion\nInstalled Version: 1.1.11\nVulnerability CVE-2025-5889\nSeverity: LOW\nFixed Version: 2.0.2, 1.1.12, 3.0.1, 4.0.1\nLink: [CVE-2025-5889](https://avd.aquasec.com/nvd/cve-2025-5889)" + "text": "Package: django\nInstalled Version: 1.11.29\nVulnerability CVE-2022-36359\nSeverity: HIGH\nFixed Version: 3.2.15, 4.0.7\nLink: [CVE-2022-36359](https://avd.aquasec.com/nvd/cve-2022-36359)" }, - "ruleId": "CVE-2025-5889", - "ruleIndex": 0 + "ruleId": "CVE-2022-36359", + "ruleIndex": 2 + }, + { + "level": "warning", + "locations": [ + { + "message": { + "text": "requirements.txt: django@1.11.29" + }, + "physicalLocation": { + "artifactLocation": { + "uri": "requirements.txt", + "uriBaseId": "ROOTPATH" + }, + "region": { + "endColumn": 1, + "endLine": 1, + "startColumn": 1, + "startLine": 1 + } + } + } + ], + "message": { + "text": "Package: django\nInstalled Version: 1.11.29\nVulnerability CVE-2021-33203\nSeverity: MEDIUM\nFixed Version: 2.2.24, 3.1.12, 3.2.4\nLink: [CVE-2021-33203](https://avd.aquasec.com/nvd/cve-2021-33203)" + }, + "ruleId": "CVE-2021-33203", + "ruleIndex": 3 + }, + { + "level": "warning", + "locations": [ + { + "message": { + "text": "requirements.txt: django@1.11.29" + }, + "physicalLocation": { + "artifactLocation": { + "uri": "requirements.txt", + "uriBaseId": "ROOTPATH" + }, + "region": { + "endColumn": 1, + "endLine": 1, + "startColumn": 1, + "startLine": 1 + } + } + } + ], + "message": { + "text": "Package: django\nInstalled Version: 1.11.29\nVulnerability CVE-2024-45231\nSeverity: MEDIUM\nFixed Version: 5.1.1, 5.0.9, 4.2.16\nLink: [CVE-2024-45231](https://avd.aquasec.com/nvd/cve-2024-45231)" + }, + "ruleId": "CVE-2024-45231", + "ruleIndex": 4 + }, + { + "level": "warning", + "locations": [ + { + "message": { + "text": "requirements.txt: django@1.11.29" + }, + "physicalLocation": { + "artifactLocation": { + "uri": "requirements.txt", + "uriBaseId": "ROOTPATH" + }, + "region": { + "endColumn": 1, + "endLine": 1, + "startColumn": 1, + "startLine": 1 + } + } + } + ], + "message": { + "text": "Package: django\nInstalled Version: 1.11.29\nVulnerability CVE-2025-48432\nSeverity: MEDIUM\nFixed Version: 5.2.2, 5.1.10, 4.2.22\nLink: [CVE-2025-48432](https://avd.aquasec.com/nvd/cve-2025-48432)" + }, + "ruleId": "CVE-2025-48432", + "ruleIndex": 5 } ], "tool": { diff --git a/plugins/tools/trivy/test/src/requirements.txt b/plugins/tools/trivy/test/src/requirements.txt new file mode 100644 index 00000000..fd925c78 --- /dev/null +++ b/plugins/tools/trivy/test/src/requirements.txt @@ -0,0 +1 @@ +django==1.11.29 \ No newline at end of file From 3ff97a7d2db907f14640ab60077cc24a56bfe188 Mon Sep 17 00:00:00 2001 From: Joao Machado <13315199+machadoit@users.noreply.github.com> Date: Wed, 9 Jul 2025 19:21:58 +0200 Subject: [PATCH 3/8] feature: Only consider specific files for Trivy CF-1742 --- plugins/runtime-utils_test.go | 8 +-- plugins/tool-utils.go | 63 ++++++++++--------- plugins/tool-utils_test.go | 50 +++++++++++++++ .../tools-configs/languages-config.yaml | 2 +- plugins/tools/trivy/plugin.yaml | 1 + .../tools-configs/languages-config.yaml | 5 ++ .../test/src/.codacy/tools-configs/trivy.yaml | 10 +++ tools/language_config.go | 21 +++++-- 8 files changed, 120 insertions(+), 40 deletions(-) create mode 100644 plugins/tools/trivy/test/src/.codacy/tools-configs/languages-config.yaml create mode 100644 plugins/tools/trivy/test/src/.codacy/tools-configs/trivy.yaml diff --git a/plugins/runtime-utils_test.go b/plugins/runtime-utils_test.go index 73532bbd..34d6f0d5 100644 --- a/plugins/runtime-utils_test.go +++ b/plugins/runtime-utils_test.go @@ -69,21 +69,21 @@ func TestProcessRuntimes(t *testing.T) { // Assert the download URL is correctly formatted expectedDownloadURL := "https://nodejs.org/dist/v18.17.1/" + expectedFileName + "." + expectedExtension assert.Equal(t, expectedDownloadURL, nodeInfo.DownloadURL) - + // Assert binary paths are correctly set assert.NotNil(t, nodeInfo.Binaries) assert.Greater(t, len(nodeInfo.Binaries), 0) - + // Check if node and npm binaries are present nodeBinary := nodeInfo.InstallDir + "/bin/node" npmBinary := nodeInfo.InstallDir + "/bin/npm" - + // Add .exe extension for Windows if runtime.GOOS == "windows" { nodeBinary += ".exe" npmBinary += ".exe" } - + assert.Equal(t, nodeBinary, nodeInfo.Binaries["node"]) assert.Equal(t, npmBinary, nodeInfo.Binaries["npm"]) } diff --git a/plugins/tool-utils.go b/plugins/tool-utils.go index 580158c5..17530679 100644 --- a/plugins/tool-utils.go +++ b/plugins/tool-utils.go @@ -55,18 +55,19 @@ type RuntimeBinaries struct { // ToolPluginConfig holds the structure of the tool plugin.yaml file type ToolPluginConfig struct { - Name string `yaml:"name"` - Description string `yaml:"description"` - DefaultVersion string `yaml:"default_version"` - Runtime string `yaml:"runtime"` - RuntimeBinaries RuntimeBinaries `yaml:"runtime_binaries"` - Installation InstallationConfig `yaml:"installation"` - Download DownloadConfig `yaml:"download"` - Environment map[string]string `yaml:"environment"` - Binaries []ToolBinary `yaml:"binaries"` - Formatters []Formatter `yaml:"formatters"` - OutputOptions OutputOptions `yaml:"output_options"` - AnalysisOptions AnalysisOptions `yaml:"analysis_options"` + Name string `yaml:"name"` + Description string `yaml:"description"` + DefaultVersion string `yaml:"default_version"` + SupportsSpecificFiles bool `yaml:"support_specific_files"` + Runtime string `yaml:"runtime"` + RuntimeBinaries RuntimeBinaries `yaml:"runtime_binaries"` + Installation InstallationConfig `yaml:"installation"` + Download DownloadConfig `yaml:"download"` + Environment map[string]string `yaml:"environment"` + Binaries []ToolBinary `yaml:"binaries"` + Formatters []Formatter `yaml:"formatters"` + OutputOptions OutputOptions `yaml:"output_options"` + AnalysisOptions AnalysisOptions `yaml:"analysis_options"` } // ToolConfig represents configuration for a tool @@ -78,15 +79,16 @@ type ToolConfig struct { // ToolInfo contains all processed information about a tool type ToolInfo struct { - Name string - Version string - Runtime string - InstallDir string - Binaries map[string]string // Map of binary name to full path - Formatters map[string]string // Map of formatter name to flag - OutputFlag string - AutofixFlag string - DefaultPath string + Name string + Version string + Runtime string + InstallDir string + Binaries map[string]string // Map of binary name to full path + Formatters map[string]string // Map of formatter name to flag + OutputFlag string + AutofixFlag string + DefaultPath string + SupportsSpecificFiles bool // Whether tool supports specific file analysis // Runtime binaries PackageManager string ExecutionBinary string @@ -135,15 +137,16 @@ func ProcessTools(configs []ToolConfig, toolDir string, runtimes map[string]*Run } // Create ToolInfo with basic information info := &ToolInfo{ - Name: config.Name, - Version: config.Version, - Runtime: toolRuntime, - InstallDir: installDir, - Binaries: make(map[string]string), - Formatters: make(map[string]string), - OutputFlag: pluginConfig.OutputOptions.FileFlag, - AutofixFlag: pluginConfig.AnalysisOptions.AutofixFlag, - DefaultPath: pluginConfig.AnalysisOptions.DefaultPath, + Name: config.Name, + Version: config.Version, + Runtime: toolRuntime, + InstallDir: installDir, + Binaries: make(map[string]string), + Formatters: make(map[string]string), + OutputFlag: pluginConfig.OutputOptions.FileFlag, + AutofixFlag: pluginConfig.AnalysisOptions.AutofixFlag, + DefaultPath: pluginConfig.AnalysisOptions.DefaultPath, + SupportsSpecificFiles: pluginConfig.SupportsSpecificFiles, // Store runtime binary information PackageManager: pluginConfig.RuntimeBinaries.PackageManager, ExecutionBinary: pluginConfig.RuntimeBinaries.Execution, diff --git a/plugins/tool-utils_test.go b/plugins/tool-utils_test.go index f459c06f..ee18ac30 100644 --- a/plugins/tool-utils_test.go +++ b/plugins/tool-utils_test.go @@ -66,6 +66,9 @@ func TestProcessTools(t *testing.T) { // Assert installation command templates are correctly set assert.Equal(t, "install --prefix {{.InstallDir}} {{.PackageName}}@{{.Version}} @microsoft/eslint-formatter-sarif", eslintInfo.InstallCommand) assert.Equal(t, "config set registry {{.Registry}}", eslintInfo.RegistryCommand) + + // Assert that eslint does not support specific files (default false) + assert.False(t, eslintInfo.SupportsSpecificFiles, "eslint should not support specific files") } func TestProcessToolsWithDownload(t *testing.T) { @@ -120,6 +123,9 @@ func TestProcessToolsWithDownload(t *testing.T) { trivyBinary := filepath.Join(expectedInstallDir, "trivy") assert.Equal(t, trivyBinary, trivyInfo.Binaries["trivy"]) + // Assert that trivy supports specific files (from plugin.yaml) + assert.True(t, trivyInfo.SupportsSpecificFiles, "trivy should support specific files") + // Verify URL components assert.Contains(t, trivyInfo.DownloadURL, "aquasecurity/trivy/releases/download") assert.Contains(t, trivyInfo.DownloadURL, trivyInfo.Version) @@ -199,3 +205,47 @@ func TestGetSupportedTools(t *testing.T) { }) } } + +func TestGetToolConfig(t *testing.T) { + pluginManager := GetPluginManager() + + tests := []struct { + name string + toolName string + expectedSupportsSpecificFiles bool + expectedError bool + }{ + { + name: "trivy should support specific files", + toolName: "trivy", + expectedSupportsSpecificFiles: true, + expectedError: false, + }, + { + name: "eslint should not support specific files", + toolName: "eslint", + expectedSupportsSpecificFiles: false, + expectedError: false, + }, + { + name: "non-existent tool should return error", + toolName: "non-existent-tool", + expectedError: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + config, err := pluginManager.GetToolConfig(tt.toolName) + + if tt.expectedError { + assert.Error(t, err) + return + } + + assert.NoError(t, err) + assert.Equal(t, tt.expectedSupportsSpecificFiles, config.SupportsSpecificFiles, + "SupportsSpecificFiles should match expected value for %s", tt.toolName) + }) + } +} diff --git a/plugins/tools/pylint/test/src/.codacy/tools-configs/languages-config.yaml b/plugins/tools/pylint/test/src/.codacy/tools-configs/languages-config.yaml index d3ea1908..cb75085e 100644 --- a/plugins/tools/pylint/test/src/.codacy/tools-configs/languages-config.yaml +++ b/plugins/tools/pylint/test/src/.codacy/tools-configs/languages-config.yaml @@ -2,4 +2,4 @@ tools: - name: pylint languages: [Python] extensions: [.py] - files: [Pipfile.lock, poetry.lock, requirements.txt, uv.lock] + files: [] diff --git a/plugins/tools/trivy/plugin.yaml b/plugins/tools/trivy/plugin.yaml index c4a1c169..8def664c 100644 --- a/plugins/tools/trivy/plugin.yaml +++ b/plugins/tools/trivy/plugin.yaml @@ -1,6 +1,7 @@ name: trivy description: Trivy is a comprehensive security scanner for containers and other artifacts. default_version: 0.59.1 +support_specific_files: true download: url_template: "https://github.com/aquasecurity/trivy/releases/download/v{{.Version}}/trivy_{{.Version}}_{{.OS}}-{{.Arch}}.{{.Extension}}" file_name_template: "trivy_{{.Version}}_{{.OS}}_{{.Arch}}" diff --git a/plugins/tools/trivy/test/src/.codacy/tools-configs/languages-config.yaml b/plugins/tools/trivy/test/src/.codacy/tools-configs/languages-config.yaml new file mode 100644 index 00000000..648997a7 --- /dev/null +++ b/plugins/tools/trivy/test/src/.codacy/tools-configs/languages-config.yaml @@ -0,0 +1,5 @@ +tools: + - name: trivy + languages: [C, CPP, CSharp, Dart, Dockerfile, Elixir, Go, JSON, Java, Javascript, PHP, Python, Ruby, Rust, Scala, Swift, Terraform, TypeScript, XML, YAML] + extensions: [.c, .cc, .cpp, .cs, .cxx, .dart, .dockerfile, .ex, .exs, .gemspec, .go, .h, .hpp, .ino, .java, .jbuilder, .js, .jsm, .json, .jsx, .mjs, .opal, .php, .podspec, .pom, .py, .rake, .rb, .rlib, .rs, .scala, .swift, .tf, .ts, .tsx, .vue, .wsdl, .xml, .xsl, .yaml, .yml] + files: [.deps.json, Berksfile, Capfile, Cargo.lock, Cheffile, Directory.Packages.props, Dockerfile, Fastfile, Gemfile, Gemfile.lock, Guardfile, Package.resolved, Packages.props, Pipfile.lock, Podfile, Podfile.lock, Rakefile, Thorfile, Vagabondfile, Vagrantfile, build.sbt.lock, composer.lock, conan.lock, config.ru, go.mod, gradle.lockfile, mix.lock, package-lock.json, package.json, packages.config, packages.lock.json, pnpm-lock.yaml, poetry.lock, pom.xml, pubspec.lock, requirements.txt, uv.lock, yarn.lock] diff --git a/plugins/tools/trivy/test/src/.codacy/tools-configs/trivy.yaml b/plugins/tools/trivy/test/src/.codacy/tools-configs/trivy.yaml new file mode 100644 index 00000000..c785541c --- /dev/null +++ b/plugins/tools/trivy/test/src/.codacy/tools-configs/trivy.yaml @@ -0,0 +1,10 @@ +severity: + - LOW + - MEDIUM + - HIGH + - CRITICAL + +scan: + scanners: + - vuln + - secret diff --git a/tools/language_config.go b/tools/language_config.go index 6be36520..62bccf96 100644 --- a/tools/language_config.go +++ b/tools/language_config.go @@ -82,6 +82,10 @@ func buildToolLanguageInfoFromAPI() (map[string]domain.ToolLanguageInfo, error) extensionsSet := make(map[string]struct{}) filesSet := make(map[string]struct{}) + // Check if this tool supports specific files + toolInfo := config.Config.Tools()[toolName] + supportsSpecificFiles := toolInfo != nil && toolInfo.SupportsSpecificFiles + for _, apiLang := range tool.Languages { lowerLang := strings.ToLower(apiLang) if extensions, exists := languageExtensionsMap[lowerLang]; exists { @@ -89,9 +93,12 @@ func buildToolLanguageInfoFromAPI() (map[string]domain.ToolLanguageInfo, error) extensionsSet[ext] = struct{}{} } } - if files, exists := languageFilesMap[lowerLang]; exists { - for _, file := range files { - filesSet[file] = struct{}{} + // Only populate files if the tool supports specific files + if supportsSpecificFiles { + if files, exists := languageFilesMap[lowerLang]; exists { + for _, file := range files { + filesSet[file] = struct{}{} + } } } } @@ -244,12 +251,16 @@ func buildRemoteModeLanguagesConfig(apiTools []domain.Tool, toolIDMap map[string extensionsSet := make(map[string]struct{}) filesSet := make(map[string]struct{}) + // Check if this tool supports specific files + toolInfo := config.Config.Tools()[shortName] + supportsSpecificFiles := toolInfo != nil && toolInfo.SupportsSpecificFiles + for _, lang := range tool.Languages { lowerLang := strings.ToLower(lang) if repoLang, exists := repositoryLanguages[lowerLang]; exists { // Check if this language has either extensions or files hasExtensions := len(repoLang.Extensions) > 0 - hasFiles := len(repoLang.Files) > 0 + hasFiles := len(repoLang.Files) > 0 && supportsSpecificFiles if hasExtensions || hasFiles { configTool.Languages = append(configTool.Languages, lang) @@ -261,7 +272,7 @@ func buildRemoteModeLanguagesConfig(apiTools []domain.Tool, toolIDMap map[string } } - // Add repository-specific files if they exist + // Add repository-specific files if they exist (only if tool supports it) if hasFiles { for _, file := range repoLang.Files { filesSet[file] = struct{}{} From 735cc09c00e3ebc9e3efd7d2748087c885002957 Mon Sep 17 00:00:00 2001 From: Joao Machado <13315199+machadoit@users.noreply.github.com> Date: Wed, 9 Jul 2025 19:42:17 +0200 Subject: [PATCH 4/8] tests: Add the files array to the tests CF-1742 --- .../expected/tools-configs/languages-config.yaml | 8 ++++++++ .../expected/tools-configs/languages-config.yaml | 8 +++++++- .../expected/tools-configs/languages-config.yaml | 10 +++++++++- .../src/.codacy/tools-configs/languages-config.yaml | 1 - tools/language_config.go | 1 + 5 files changed, 25 insertions(+), 3 deletions(-) diff --git a/integration-tests/config-discover/expected/tools-configs/languages-config.yaml b/integration-tests/config-discover/expected/tools-configs/languages-config.yaml index 5d54c143..37fb52d7 100644 --- a/integration-tests/config-discover/expected/tools-configs/languages-config.yaml +++ b/integration-tests/config-discover/expected/tools-configs/languages-config.yaml @@ -2,24 +2,32 @@ tools: - name: dartanalyzer languages: [Dart] extensions: [.dart] + files: [] - name: eslint languages: [Javascript, TypeScript] extensions: [.js, .jsm, .jsx, .mjs, .ts, .tsx, .vue] + files: [] - name: lizard languages: [C, CPP, CSharp, Erlang, Fortran, Go, Java, Javascript, Kotlin, Lua, Objective C, PHP, Python, Ruby, Rust, Scala, Solidity, Swift, TypeScript] extensions: [.c, .cc, .cpp, .cs, .cxx, .gemspec, .go, .h, .hpp, .ino, .java, .jbuilder, .js, .jsm, .jsx, .kt, .kts, .m, .mjs, .opal, .php, .podspec, .py, .rake, .rb, .rlib, .rs, .scala, .swift, .ts, .tsx, .vue] + files: [] - name: pmd languages: [Apex, JSP, Java, Javascript, PLSQL, SQL, Velocity, VisualForce, XML] extensions: [.cls, .component, .fnc, .java, .js, .jsm, .jsp, .jsx, .mjs, .page, .pck, .pkb, .pkh, .pks, .plb, .pld, .plh, .pls, .pom, .prc, .sql, .tpb, .tps, .trg, .trigger, .tyb, .typ, .vm, .vue, .wsdl, .xml, .xsl] + files: [] - name: pylint languages: [Python] extensions: [.py] + files: [] - name: revive languages: [Go] extensions: [.go] + files: [] - name: semgrep languages: [Apex, C, CPP, CSharp, Dockerfile, Go, Java, Javascript, Kotlin, PHP, PLSQL, Python, Ruby, Rust, SQL, Scala, Shell, Swift, Terraform, TypeScript, YAML] extensions: [.bash, .c, .cc, .cls, .cpp, .cs, .cxx, .dockerfile, .fnc, .gemspec, .go, .h, .hpp, .ino, .java, .jbuilder, .js, .jsm, .jsx, .kt, .kts, .mjs, .opal, .pck, .php, .pkb, .pkh, .pks, .plb, .pld, .plh, .pls, .podspec, .prc, .py, .rake, .rb, .rlib, .rs, .scala, .sh, .sql, .swift, .tf, .tpb, .tps, .trg, .trigger, .ts, .tsx, .tyb, .typ, .vue, .yaml, .yml] + files: [] - name: trivy languages: [C, CPP, CSharp, Dart, Dockerfile, Elixir, Go, JSON, Java, Javascript, PHP, Python, Ruby, Rust, Scala, Swift, Terraform, TypeScript, XML, YAML] extensions: [.c, .cc, .cpp, .cs, .cxx, .dart, .dockerfile, .ex, .exs, .gemspec, .go, .h, .hpp, .ino, .java, .jbuilder, .js, .jsm, .json, .jsx, .mjs, .opal, .php, .podspec, .pom, .py, .rake, .rb, .rlib, .rs, .scala, .swift, .tf, .ts, .tsx, .vue, .wsdl, .xml, .xsl, .yaml, .yml] + files: [] diff --git a/integration-tests/init-with-token/expected/tools-configs/languages-config.yaml b/integration-tests/init-with-token/expected/tools-configs/languages-config.yaml index 8c8d5243..78b3f433 100644 --- a/integration-tests/init-with-token/expected/tools-configs/languages-config.yaml +++ b/integration-tests/init-with-token/expected/tools-configs/languages-config.yaml @@ -2,18 +2,24 @@ tools: - name: eslint languages: [Javascript] extensions: [.js, .jsm, .jsx, .mjs, .vue] + files: [] - name: lizard languages: [Java, Javascript, Python] extensions: [.java, .js, .jsm, .jsx, .mjs, .py, .vue] + files: [] - name: pmd languages: [Java, Javascript] extensions: [.java, .js, .jsm, .jsx, .mjs, .vue] + files: [] - name: pylint languages: [Python] extensions: [.py] + files: [] - name: semgrep languages: [Java, Javascript, Python] extensions: [.java, .js, .jsm, .jsx, .mjs, .py, .vue] + files: [] - name: trivy languages: [JSON, Java, Javascript, Python] - extensions: [.java, .js, .jsm, .json, .jsx, .mjs, .py, .vue] \ No newline at end of file + extensions: [.java, .js, .jsm, .json, .jsx, .mjs, .py, .vue] + files: [] \ No newline at end of file diff --git a/integration-tests/init-without-token/expected/tools-configs/languages-config.yaml b/integration-tests/init-without-token/expected/tools-configs/languages-config.yaml index 385510f8..244df542 100644 --- a/integration-tests/init-without-token/expected/tools-configs/languages-config.yaml +++ b/integration-tests/init-without-token/expected/tools-configs/languages-config.yaml @@ -2,24 +2,32 @@ tools: - name: dartanalyzer languages: [Dart] extensions: [.dart] + files: [] - name: eslint languages: [Javascript, TypeScript] extensions: [.js, .jsm, .jsx, .mjs, .ts, .tsx, .vue] + files: [] - name: lizard languages: [C, CPP, CSharp, Erlang, Fortran, Go, Java, Javascript, Kotlin, Lua, Objective C, PHP, Python, Ruby, Rust, Scala, Solidity, Swift, TypeScript] extensions: [.c, .cc, .cpp, .cs, .cxx, .gemspec, .go, .h, .hpp, .ino, .java, .jbuilder, .js, .jsm, .jsx, .kt, .kts, .m, .mjs, .opal, .php, .podspec, .py, .rake, .rb, .rlib, .rs, .scala, .swift, .ts, .tsx, .vue] + files: [] - name: pmd languages: [Apex, JSP, Java, Javascript, PLSQL, SQL, Velocity, VisualForce, XML] extensions: [.cls, .component, .fnc, .java, .js, .jsm, .jsp, .jsx, .mjs, .page, .pck, .pkb, .pkh, .pks, .plb, .pld, .plh, .pls, .pom, .prc, .sql, .tpb, .tps, .trg, .trigger, .tyb, .typ, .vm, .vue, .wsdl, .xml, .xsl] + files: [] - name: pylint languages: [Python] extensions: [.py] + files: [] - name: revive languages: [Go] extensions: [.go] + files: [] - name: semgrep languages: [Apex, C, CPP, CSharp, Dockerfile, Go, Java, Javascript, Kotlin, PHP, PLSQL, Python, Ruby, Rust, SQL, Scala, Shell, Swift, Terraform, TypeScript, YAML] extensions: [.bash, .c, .cc, .cls, .cpp, .cs, .cxx, .dockerfile, .fnc, .gemspec, .go, .h, .hpp, .ino, .java, .jbuilder, .js, .jsm, .jsx, .kt, .kts, .mjs, .opal, .pck, .php, .pkb, .pkh, .pks, .plb, .pld, .plh, .pls, .podspec, .prc, .py, .rake, .rb, .rlib, .rs, .scala, .sh, .sql, .swift, .tf, .tpb, .tps, .trg, .trigger, .ts, .tsx, .tyb, .typ, .vue, .yaml, .yml] + files: [] - name: trivy languages: [C, CPP, CSharp, Dart, Dockerfile, Elixir, Go, JSON, Java, Javascript, PHP, Python, Ruby, Rust, Scala, Swift, Terraform, TypeScript, XML, YAML] - extensions: [.c, .cc, .cpp, .cs, .cxx, .dart, .dockerfile, .ex, .exs, .gemspec, .go, .h, .hpp, .ino, .java, .jbuilder, .js, .jsm, .json, .jsx, .mjs, .opal, .php, .podspec, .pom, .py, .rake, .rb, .rlib, .rs, .scala, .swift, .tf, .ts, .tsx, .vue, .wsdl, .xml, .xsl, .yaml, .yml] \ No newline at end of file + extensions: [.c, .cc, .cpp, .cs, .cxx, .dart, .dockerfile, .ex, .exs, .gemspec, .go, .h, .hpp, .ino, .java, .jbuilder, .js, .jsm, .json, .jsx, .mjs, .opal, .php, .podspec, .pom, .py, .rake, .rb, .rlib, .rs, .scala, .swift, .tf, .ts, .tsx, .vue, .wsdl, .xml, .xsl, .yaml, .yml] + files: [] \ No newline at end of file diff --git a/plugins/tools/pylint/test/src/.codacy/tools-configs/languages-config.yaml b/plugins/tools/pylint/test/src/.codacy/tools-configs/languages-config.yaml index cb75085e..2a134aed 100644 --- a/plugins/tools/pylint/test/src/.codacy/tools-configs/languages-config.yaml +++ b/plugins/tools/pylint/test/src/.codacy/tools-configs/languages-config.yaml @@ -2,4 +2,3 @@ tools: - name: pylint languages: [Python] extensions: [.py] - files: [] diff --git a/tools/language_config.go b/tools/language_config.go index 62bccf96..69c65b48 100644 --- a/tools/language_config.go +++ b/tools/language_config.go @@ -76,6 +76,7 @@ func buildToolLanguageInfoFromAPI() (map[string]domain.ToolLanguageInfo, error) Name: toolName, Languages: tool.Languages, Extensions: []string{}, + Files: []string{}, } // Build extensions and files from API language data From 3aa49babf79825f511fd51fa3378c31c78075fa5 Mon Sep 17 00:00:00 2001 From: Joao Machado <13315199+machadoit@users.noreply.github.com> Date: Wed, 9 Jul 2025 19:50:39 +0200 Subject: [PATCH 5/8] tests: Add the expected files to the trivey expected yamls --- .../expected/tools-configs/languages-config.yaml | 2 +- .../expected/tools-configs/languages-config.yaml | 2 +- .../expected/tools-configs/languages-config.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/integration-tests/config-discover/expected/tools-configs/languages-config.yaml b/integration-tests/config-discover/expected/tools-configs/languages-config.yaml index 37fb52d7..6e686c11 100644 --- a/integration-tests/config-discover/expected/tools-configs/languages-config.yaml +++ b/integration-tests/config-discover/expected/tools-configs/languages-config.yaml @@ -30,4 +30,4 @@ tools: - name: trivy languages: [C, CPP, CSharp, Dart, Dockerfile, Elixir, Go, JSON, Java, Javascript, PHP, Python, Ruby, Rust, Scala, Swift, Terraform, TypeScript, XML, YAML] extensions: [.c, .cc, .cpp, .cs, .cxx, .dart, .dockerfile, .ex, .exs, .gemspec, .go, .h, .hpp, .ino, .java, .jbuilder, .js, .jsm, .json, .jsx, .mjs, .opal, .php, .podspec, .pom, .py, .rake, .rb, .rlib, .rs, .scala, .swift, .tf, .ts, .tsx, .vue, .wsdl, .xml, .xsl, .yaml, .yml] - files: [] + files: [.deps.json, Berksfile, Capfile, Cargo.lock, Cheffile, Directory.Packages.props, Dockerfile, Fastfile, Gemfile, Gemfile.lock, Guardfile, Package.resolved, Packages.props, Pipfile.lock, Podfile, Podfile.lock, Rakefile, Thorfile, Vagabondfile, Vagrantfile, build.sbt.lock, composer.lock, conan.lock, config.ru, go.mod, gradle.lockfile, mix.lock, package-lock.json, package.json, packages.config, packages.lock.json, pnpm-lock.yaml, poetry.lock, pom.xml, pubspec.lock, requirements.txt, uv.lock, yarn.lock] diff --git a/integration-tests/init-with-token/expected/tools-configs/languages-config.yaml b/integration-tests/init-with-token/expected/tools-configs/languages-config.yaml index 78b3f433..4c80d5f8 100644 --- a/integration-tests/init-with-token/expected/tools-configs/languages-config.yaml +++ b/integration-tests/init-with-token/expected/tools-configs/languages-config.yaml @@ -22,4 +22,4 @@ tools: - name: trivy languages: [JSON, Java, Javascript, Python] extensions: [.java, .js, .jsm, .json, .jsx, .mjs, .py, .vue] - files: [] \ No newline at end of file + files: [.deps.json, Berksfile, Capfile, Cargo.lock, Cheffile, Directory.Packages.props, Dockerfile, Fastfile, Gemfile, Gemfile.lock, Guardfile, Package.resolved, Packages.props, Pipfile.lock, Podfile, Podfile.lock, Rakefile, Thorfile, Vagabondfile, Vagrantfile, build.sbt.lock, composer.lock, conan.lock, config.ru, go.mod, gradle.lockfile, mix.lock, package-lock.json, package.json, packages.config, packages.lock.json, pnpm-lock.yaml, poetry.lock, pom.xml, pubspec.lock, requirements.txt, uv.lock, yarn.lock] \ No newline at end of file diff --git a/integration-tests/init-without-token/expected/tools-configs/languages-config.yaml b/integration-tests/init-without-token/expected/tools-configs/languages-config.yaml index 244df542..0998dce0 100644 --- a/integration-tests/init-without-token/expected/tools-configs/languages-config.yaml +++ b/integration-tests/init-without-token/expected/tools-configs/languages-config.yaml @@ -30,4 +30,4 @@ tools: - name: trivy languages: [C, CPP, CSharp, Dart, Dockerfile, Elixir, Go, JSON, Java, Javascript, PHP, Python, Ruby, Rust, Scala, Swift, Terraform, TypeScript, XML, YAML] extensions: [.c, .cc, .cpp, .cs, .cxx, .dart, .dockerfile, .ex, .exs, .gemspec, .go, .h, .hpp, .ino, .java, .jbuilder, .js, .jsm, .json, .jsx, .mjs, .opal, .php, .podspec, .pom, .py, .rake, .rb, .rlib, .rs, .scala, .swift, .tf, .ts, .tsx, .vue, .wsdl, .xml, .xsl, .yaml, .yml] - files: [] \ No newline at end of file + files: [.deps.json, Berksfile, Capfile, Cargo.lock, Cheffile, Directory.Packages.props, Dockerfile, Fastfile, Gemfile, Gemfile.lock, Guardfile, Package.resolved, Packages.props, Pipfile.lock, Podfile, Podfile.lock, Rakefile, Thorfile, Vagabondfile, Vagrantfile, build.sbt.lock, composer.lock, conan.lock, config.ru, go.mod, gradle.lockfile, mix.lock, package-lock.json, package.json, packages.config, packages.lock.json, pnpm-lock.yaml, poetry.lock, pom.xml, pubspec.lock, requirements.txt, uv.lock, yarn.lock] \ No newline at end of file From 59966086e2182bf2986e466bd3e95448e8931f43 Mon Sep 17 00:00:00 2001 From: Joao Machado <13315199+machadoit@users.noreply.github.com> Date: Thu, 10 Jul 2025 11:08:25 +0200 Subject: [PATCH 6/8] Revert "feature: Only consider specific files for Trivy CF-1742" This reverts commit 3ff97a7d2db907f14640ab60077cc24a56bfe188. This was not working properly due timings of configs --- plugins/runtime-utils_test.go | 8 +-- plugins/tool-utils.go | 63 +++++++++---------- plugins/tool-utils_test.go | 50 --------------- plugins/tools/trivy/plugin.yaml | 1 - .../tools-configs/languages-config.yaml | 5 -- .../test/src/.codacy/tools-configs/trivy.yaml | 10 --- tools/language_config.go | 21 ++----- 7 files changed, 39 insertions(+), 119 deletions(-) delete mode 100644 plugins/tools/trivy/test/src/.codacy/tools-configs/languages-config.yaml delete mode 100644 plugins/tools/trivy/test/src/.codacy/tools-configs/trivy.yaml diff --git a/plugins/runtime-utils_test.go b/plugins/runtime-utils_test.go index 34d6f0d5..73532bbd 100644 --- a/plugins/runtime-utils_test.go +++ b/plugins/runtime-utils_test.go @@ -69,21 +69,21 @@ func TestProcessRuntimes(t *testing.T) { // Assert the download URL is correctly formatted expectedDownloadURL := "https://nodejs.org/dist/v18.17.1/" + expectedFileName + "." + expectedExtension assert.Equal(t, expectedDownloadURL, nodeInfo.DownloadURL) - + // Assert binary paths are correctly set assert.NotNil(t, nodeInfo.Binaries) assert.Greater(t, len(nodeInfo.Binaries), 0) - + // Check if node and npm binaries are present nodeBinary := nodeInfo.InstallDir + "/bin/node" npmBinary := nodeInfo.InstallDir + "/bin/npm" - + // Add .exe extension for Windows if runtime.GOOS == "windows" { nodeBinary += ".exe" npmBinary += ".exe" } - + assert.Equal(t, nodeBinary, nodeInfo.Binaries["node"]) assert.Equal(t, npmBinary, nodeInfo.Binaries["npm"]) } diff --git a/plugins/tool-utils.go b/plugins/tool-utils.go index 17530679..580158c5 100644 --- a/plugins/tool-utils.go +++ b/plugins/tool-utils.go @@ -55,19 +55,18 @@ type RuntimeBinaries struct { // ToolPluginConfig holds the structure of the tool plugin.yaml file type ToolPluginConfig struct { - Name string `yaml:"name"` - Description string `yaml:"description"` - DefaultVersion string `yaml:"default_version"` - SupportsSpecificFiles bool `yaml:"support_specific_files"` - Runtime string `yaml:"runtime"` - RuntimeBinaries RuntimeBinaries `yaml:"runtime_binaries"` - Installation InstallationConfig `yaml:"installation"` - Download DownloadConfig `yaml:"download"` - Environment map[string]string `yaml:"environment"` - Binaries []ToolBinary `yaml:"binaries"` - Formatters []Formatter `yaml:"formatters"` - OutputOptions OutputOptions `yaml:"output_options"` - AnalysisOptions AnalysisOptions `yaml:"analysis_options"` + Name string `yaml:"name"` + Description string `yaml:"description"` + DefaultVersion string `yaml:"default_version"` + Runtime string `yaml:"runtime"` + RuntimeBinaries RuntimeBinaries `yaml:"runtime_binaries"` + Installation InstallationConfig `yaml:"installation"` + Download DownloadConfig `yaml:"download"` + Environment map[string]string `yaml:"environment"` + Binaries []ToolBinary `yaml:"binaries"` + Formatters []Formatter `yaml:"formatters"` + OutputOptions OutputOptions `yaml:"output_options"` + AnalysisOptions AnalysisOptions `yaml:"analysis_options"` } // ToolConfig represents configuration for a tool @@ -79,16 +78,15 @@ type ToolConfig struct { // ToolInfo contains all processed information about a tool type ToolInfo struct { - Name string - Version string - Runtime string - InstallDir string - Binaries map[string]string // Map of binary name to full path - Formatters map[string]string // Map of formatter name to flag - OutputFlag string - AutofixFlag string - DefaultPath string - SupportsSpecificFiles bool // Whether tool supports specific file analysis + Name string + Version string + Runtime string + InstallDir string + Binaries map[string]string // Map of binary name to full path + Formatters map[string]string // Map of formatter name to flag + OutputFlag string + AutofixFlag string + DefaultPath string // Runtime binaries PackageManager string ExecutionBinary string @@ -137,16 +135,15 @@ func ProcessTools(configs []ToolConfig, toolDir string, runtimes map[string]*Run } // Create ToolInfo with basic information info := &ToolInfo{ - Name: config.Name, - Version: config.Version, - Runtime: toolRuntime, - InstallDir: installDir, - Binaries: make(map[string]string), - Formatters: make(map[string]string), - OutputFlag: pluginConfig.OutputOptions.FileFlag, - AutofixFlag: pluginConfig.AnalysisOptions.AutofixFlag, - DefaultPath: pluginConfig.AnalysisOptions.DefaultPath, - SupportsSpecificFiles: pluginConfig.SupportsSpecificFiles, + Name: config.Name, + Version: config.Version, + Runtime: toolRuntime, + InstallDir: installDir, + Binaries: make(map[string]string), + Formatters: make(map[string]string), + OutputFlag: pluginConfig.OutputOptions.FileFlag, + AutofixFlag: pluginConfig.AnalysisOptions.AutofixFlag, + DefaultPath: pluginConfig.AnalysisOptions.DefaultPath, // Store runtime binary information PackageManager: pluginConfig.RuntimeBinaries.PackageManager, ExecutionBinary: pluginConfig.RuntimeBinaries.Execution, diff --git a/plugins/tool-utils_test.go b/plugins/tool-utils_test.go index ee18ac30..f459c06f 100644 --- a/plugins/tool-utils_test.go +++ b/plugins/tool-utils_test.go @@ -66,9 +66,6 @@ func TestProcessTools(t *testing.T) { // Assert installation command templates are correctly set assert.Equal(t, "install --prefix {{.InstallDir}} {{.PackageName}}@{{.Version}} @microsoft/eslint-formatter-sarif", eslintInfo.InstallCommand) assert.Equal(t, "config set registry {{.Registry}}", eslintInfo.RegistryCommand) - - // Assert that eslint does not support specific files (default false) - assert.False(t, eslintInfo.SupportsSpecificFiles, "eslint should not support specific files") } func TestProcessToolsWithDownload(t *testing.T) { @@ -123,9 +120,6 @@ func TestProcessToolsWithDownload(t *testing.T) { trivyBinary := filepath.Join(expectedInstallDir, "trivy") assert.Equal(t, trivyBinary, trivyInfo.Binaries["trivy"]) - // Assert that trivy supports specific files (from plugin.yaml) - assert.True(t, trivyInfo.SupportsSpecificFiles, "trivy should support specific files") - // Verify URL components assert.Contains(t, trivyInfo.DownloadURL, "aquasecurity/trivy/releases/download") assert.Contains(t, trivyInfo.DownloadURL, trivyInfo.Version) @@ -205,47 +199,3 @@ func TestGetSupportedTools(t *testing.T) { }) } } - -func TestGetToolConfig(t *testing.T) { - pluginManager := GetPluginManager() - - tests := []struct { - name string - toolName string - expectedSupportsSpecificFiles bool - expectedError bool - }{ - { - name: "trivy should support specific files", - toolName: "trivy", - expectedSupportsSpecificFiles: true, - expectedError: false, - }, - { - name: "eslint should not support specific files", - toolName: "eslint", - expectedSupportsSpecificFiles: false, - expectedError: false, - }, - { - name: "non-existent tool should return error", - toolName: "non-existent-tool", - expectedError: true, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - config, err := pluginManager.GetToolConfig(tt.toolName) - - if tt.expectedError { - assert.Error(t, err) - return - } - - assert.NoError(t, err) - assert.Equal(t, tt.expectedSupportsSpecificFiles, config.SupportsSpecificFiles, - "SupportsSpecificFiles should match expected value for %s", tt.toolName) - }) - } -} diff --git a/plugins/tools/trivy/plugin.yaml b/plugins/tools/trivy/plugin.yaml index 8def664c..c4a1c169 100644 --- a/plugins/tools/trivy/plugin.yaml +++ b/plugins/tools/trivy/plugin.yaml @@ -1,7 +1,6 @@ name: trivy description: Trivy is a comprehensive security scanner for containers and other artifacts. default_version: 0.59.1 -support_specific_files: true download: url_template: "https://github.com/aquasecurity/trivy/releases/download/v{{.Version}}/trivy_{{.Version}}_{{.OS}}-{{.Arch}}.{{.Extension}}" file_name_template: "trivy_{{.Version}}_{{.OS}}_{{.Arch}}" diff --git a/plugins/tools/trivy/test/src/.codacy/tools-configs/languages-config.yaml b/plugins/tools/trivy/test/src/.codacy/tools-configs/languages-config.yaml deleted file mode 100644 index 648997a7..00000000 --- a/plugins/tools/trivy/test/src/.codacy/tools-configs/languages-config.yaml +++ /dev/null @@ -1,5 +0,0 @@ -tools: - - name: trivy - languages: [C, CPP, CSharp, Dart, Dockerfile, Elixir, Go, JSON, Java, Javascript, PHP, Python, Ruby, Rust, Scala, Swift, Terraform, TypeScript, XML, YAML] - extensions: [.c, .cc, .cpp, .cs, .cxx, .dart, .dockerfile, .ex, .exs, .gemspec, .go, .h, .hpp, .ino, .java, .jbuilder, .js, .jsm, .json, .jsx, .mjs, .opal, .php, .podspec, .pom, .py, .rake, .rb, .rlib, .rs, .scala, .swift, .tf, .ts, .tsx, .vue, .wsdl, .xml, .xsl, .yaml, .yml] - files: [.deps.json, Berksfile, Capfile, Cargo.lock, Cheffile, Directory.Packages.props, Dockerfile, Fastfile, Gemfile, Gemfile.lock, Guardfile, Package.resolved, Packages.props, Pipfile.lock, Podfile, Podfile.lock, Rakefile, Thorfile, Vagabondfile, Vagrantfile, build.sbt.lock, composer.lock, conan.lock, config.ru, go.mod, gradle.lockfile, mix.lock, package-lock.json, package.json, packages.config, packages.lock.json, pnpm-lock.yaml, poetry.lock, pom.xml, pubspec.lock, requirements.txt, uv.lock, yarn.lock] diff --git a/plugins/tools/trivy/test/src/.codacy/tools-configs/trivy.yaml b/plugins/tools/trivy/test/src/.codacy/tools-configs/trivy.yaml deleted file mode 100644 index c785541c..00000000 --- a/plugins/tools/trivy/test/src/.codacy/tools-configs/trivy.yaml +++ /dev/null @@ -1,10 +0,0 @@ -severity: - - LOW - - MEDIUM - - HIGH - - CRITICAL - -scan: - scanners: - - vuln - - secret diff --git a/tools/language_config.go b/tools/language_config.go index 69c65b48..7404d0ec 100644 --- a/tools/language_config.go +++ b/tools/language_config.go @@ -83,10 +83,6 @@ func buildToolLanguageInfoFromAPI() (map[string]domain.ToolLanguageInfo, error) extensionsSet := make(map[string]struct{}) filesSet := make(map[string]struct{}) - // Check if this tool supports specific files - toolInfo := config.Config.Tools()[toolName] - supportsSpecificFiles := toolInfo != nil && toolInfo.SupportsSpecificFiles - for _, apiLang := range tool.Languages { lowerLang := strings.ToLower(apiLang) if extensions, exists := languageExtensionsMap[lowerLang]; exists { @@ -94,12 +90,9 @@ func buildToolLanguageInfoFromAPI() (map[string]domain.ToolLanguageInfo, error) extensionsSet[ext] = struct{}{} } } - // Only populate files if the tool supports specific files - if supportsSpecificFiles { - if files, exists := languageFilesMap[lowerLang]; exists { - for _, file := range files { - filesSet[file] = struct{}{} - } + if files, exists := languageFilesMap[lowerLang]; exists { + for _, file := range files { + filesSet[file] = struct{}{} } } } @@ -252,16 +245,12 @@ func buildRemoteModeLanguagesConfig(apiTools []domain.Tool, toolIDMap map[string extensionsSet := make(map[string]struct{}) filesSet := make(map[string]struct{}) - // Check if this tool supports specific files - toolInfo := config.Config.Tools()[shortName] - supportsSpecificFiles := toolInfo != nil && toolInfo.SupportsSpecificFiles - for _, lang := range tool.Languages { lowerLang := strings.ToLower(lang) if repoLang, exists := repositoryLanguages[lowerLang]; exists { // Check if this language has either extensions or files hasExtensions := len(repoLang.Extensions) > 0 - hasFiles := len(repoLang.Files) > 0 && supportsSpecificFiles + hasFiles := len(repoLang.Files) > 0 if hasExtensions || hasFiles { configTool.Languages = append(configTool.Languages, lang) @@ -273,7 +262,7 @@ func buildRemoteModeLanguagesConfig(apiTools []domain.Tool, toolIDMap map[string } } - // Add repository-specific files if they exist (only if tool supports it) + // Add repository-specific files if they exist if hasFiles { for _, file := range repoLang.Files { filesSet[file] = struct{}{} From c91d49bcb315af776b635109c7a410095c497030 Mon Sep 17 00:00:00 2001 From: Joao Machado <13315199+machadoit@users.noreply.github.com> Date: Thu, 10 Jul 2025 11:42:34 +0200 Subject: [PATCH 7/8] fix: Only consider LanguageFiles from the API for Trivy CF-1742 --- .../config-discover/expected/codacy.yaml | 2 +- .../tools-configs/languages-config.yaml | 2 +- .../.codacy/tools-configs/eslint.config.mjs | 67 +++++++++++++++++++ .../tools-configs/languages-config.yaml | 4 ++ .../tools-configs/languages-config.yaml | 1 + .../tools-configs/languages-config.yaml | 33 +++++++++ .../test/src/.codacy/tools-configs/trivy.yaml | 10 +++ tools/language_config.go | 19 ++++-- 8 files changed, 131 insertions(+), 7 deletions(-) create mode 100644 plugins/tools/eslint/test/src/.codacy/tools-configs/eslint.config.mjs create mode 100644 plugins/tools/eslint/test/src/.codacy/tools-configs/languages-config.yaml create mode 100644 plugins/tools/trivy/test/src/.codacy/tools-configs/languages-config.yaml create mode 100644 plugins/tools/trivy/test/src/.codacy/tools-configs/trivy.yaml diff --git a/integration-tests/config-discover/expected/codacy.yaml b/integration-tests/config-discover/expected/codacy.yaml index 2bc78526..558d375b 100644 --- a/integration-tests/config-discover/expected/codacy.yaml +++ b/integration-tests/config-discover/expected/codacy.yaml @@ -10,4 +10,4 @@ tools: - pmd@7.11.0 - pylint@3.3.6 - semgrep@1.78.0 - - trivy@0.59.1 \ No newline at end of file + - trivy@0.59.1 diff --git a/integration-tests/init-with-token/expected/tools-configs/languages-config.yaml b/integration-tests/init-with-token/expected/tools-configs/languages-config.yaml index 4c80d5f8..71f6d25f 100644 --- a/integration-tests/init-with-token/expected/tools-configs/languages-config.yaml +++ b/integration-tests/init-with-token/expected/tools-configs/languages-config.yaml @@ -22,4 +22,4 @@ tools: - name: trivy languages: [JSON, Java, Javascript, Python] extensions: [.java, .js, .jsm, .json, .jsx, .mjs, .py, .vue] - files: [.deps.json, Berksfile, Capfile, Cargo.lock, Cheffile, Directory.Packages.props, Dockerfile, Fastfile, Gemfile, Gemfile.lock, Guardfile, Package.resolved, Packages.props, Pipfile.lock, Podfile, Podfile.lock, Rakefile, Thorfile, Vagabondfile, Vagrantfile, build.sbt.lock, composer.lock, conan.lock, config.ru, go.mod, gradle.lockfile, mix.lock, package-lock.json, package.json, packages.config, packages.lock.json, pnpm-lock.yaml, poetry.lock, pom.xml, pubspec.lock, requirements.txt, uv.lock, yarn.lock] \ No newline at end of file + files: [Pipfile.lock, gradle.lockfile, package-lock.json, package.json, pnpm-lock.yaml, poetry.lock, pom.xml, requirements.txt, uv.lock, yarn.lock] diff --git a/plugins/tools/eslint/test/src/.codacy/tools-configs/eslint.config.mjs b/plugins/tools/eslint/test/src/.codacy/tools-configs/eslint.config.mjs new file mode 100644 index 00000000..92f3fc1b --- /dev/null +++ b/plugins/tools/eslint/test/src/.codacy/tools-configs/eslint.config.mjs @@ -0,0 +1,67 @@ +export default [ + { + rules: { + "constructor-super": ["error"], + "for-direction": ["error"], + "getter-return": ["error", {"allowImplicit": false}], + "no-async-promise-executor": ["error"], + "no-case-declarations": ["error"], + "no-class-assign": ["error"], + "no-compare-neg-zero": ["error"], + "no-cond-assign": ["error", "except-parens"], + "no-constant-condition": ["error", {"checkLoops": true}], + "no-const-assign": ["error"], + "no-control-regex": ["error"], + "no-debugger": ["error"], + "no-delete-var": ["error"], + "no-dupe-args": ["error"], + "no-dupe-class-members": ["error"], + "no-dupe-else-if": ["error"], + "no-dupe-keys": ["error"], + "no-duplicate-case": ["error"], + "no-empty": ["error", {"allowEmptyCatch": false}], + "no-empty-character-class": ["error"], + "no-empty-pattern": ["error", {"allowObjectPatternsAsParameters": false}], + "no-ex-assign": ["error"], + "no-extra-boolean-cast": ["error", {"enforceForLogicalOperands": false}], + "no-extra-semi": ["error"], + "no-fallthrough": ["error", {"allowEmptyCase": false}], + "no-func-assign": ["error"], + "no-global-assign": ["error"], + "no-import-assign": ["error"], + "no-inner-declarations": ["error", "functions"], + "no-invalid-regexp": ["error"], + "no-irregular-whitespace": ["error", {"skipComments": false, "skipJSXText": false, "skipRegExps": false, "skipStrings": true, "skipTemplates": false}], + "no-loss-of-precision": ["error"], + "no-misleading-character-class": ["error"], + "no-mixed-spaces-and-tabs": ["error"], + "no-new-symbol": ["error"], + "no-nonoctal-decimal-escape": ["error"], + "no-obj-calls": ["error"], + "no-octal": ["error"], + "no-prototype-builtins": ["error"], + "no-redeclare": ["error", {"builtinGlobals": true}], + "no-regex-spaces": ["error"], + "no-self-assign": ["error", {"props": true}], + "no-setter-return": ["error"], + "no-shadow-restricted-names": ["error"], + "no-sparse-arrays": ["error"], + "no-this-before-super": ["error"], + "no-undef": ["error", {"typeof": false}], + "no-unexpected-multiline": ["error"], + "no-unreachable": ["error"], + "no-unsafe-finally": ["error"], + "no-unsafe-negation": ["error", {"enforceForOrderingRelations": false}], + "no-unsafe-optional-chaining": ["error", {"disallowArithmeticOperators": false}], + "no-unused-labels": ["error"], + "no-unused-vars": ["error"], + "no-useless-backreference": ["error"], + "no-useless-catch": ["error"], + "no-useless-escape": ["error"], + "no-with": ["error"], + "require-yield": ["error"], + "use-isnan": ["error", {"enforceForIndexOf": false, "enforceForSwitchCase": true}], + "valid-typeof": ["error", {"requireStringLiterals": false}], + } + } +]; \ No newline at end of file diff --git a/plugins/tools/eslint/test/src/.codacy/tools-configs/languages-config.yaml b/plugins/tools/eslint/test/src/.codacy/tools-configs/languages-config.yaml new file mode 100644 index 00000000..0026c53f --- /dev/null +++ b/plugins/tools/eslint/test/src/.codacy/tools-configs/languages-config.yaml @@ -0,0 +1,4 @@ +tools: + - name: eslint + languages: [Javascript, TypeScript] + extensions: [.js, .jsm, .jsx, .mjs, .ts, .tsx, .vue] diff --git a/plugins/tools/pylint/test/src/.codacy/tools-configs/languages-config.yaml b/plugins/tools/pylint/test/src/.codacy/tools-configs/languages-config.yaml index 2a134aed..8b270b2d 100644 --- a/plugins/tools/pylint/test/src/.codacy/tools-configs/languages-config.yaml +++ b/plugins/tools/pylint/test/src/.codacy/tools-configs/languages-config.yaml @@ -2,3 +2,4 @@ tools: - name: pylint languages: [Python] extensions: [.py] + files: [] \ No newline at end of file diff --git a/plugins/tools/trivy/test/src/.codacy/tools-configs/languages-config.yaml b/plugins/tools/trivy/test/src/.codacy/tools-configs/languages-config.yaml new file mode 100644 index 00000000..6e686c11 --- /dev/null +++ b/plugins/tools/trivy/test/src/.codacy/tools-configs/languages-config.yaml @@ -0,0 +1,33 @@ +tools: + - name: dartanalyzer + languages: [Dart] + extensions: [.dart] + files: [] + - name: eslint + languages: [Javascript, TypeScript] + extensions: [.js, .jsm, .jsx, .mjs, .ts, .tsx, .vue] + files: [] + - name: lizard + languages: [C, CPP, CSharp, Erlang, Fortran, Go, Java, Javascript, Kotlin, Lua, Objective C, PHP, Python, Ruby, Rust, Scala, Solidity, Swift, TypeScript] + extensions: [.c, .cc, .cpp, .cs, .cxx, .gemspec, .go, .h, .hpp, .ino, .java, .jbuilder, .js, .jsm, .jsx, .kt, .kts, .m, .mjs, .opal, .php, .podspec, .py, .rake, .rb, .rlib, .rs, .scala, .swift, .ts, .tsx, .vue] + files: [] + - name: pmd + languages: [Apex, JSP, Java, Javascript, PLSQL, SQL, Velocity, VisualForce, XML] + extensions: [.cls, .component, .fnc, .java, .js, .jsm, .jsp, .jsx, .mjs, .page, .pck, .pkb, .pkh, .pks, .plb, .pld, .plh, .pls, .pom, .prc, .sql, .tpb, .tps, .trg, .trigger, .tyb, .typ, .vm, .vue, .wsdl, .xml, .xsl] + files: [] + - name: pylint + languages: [Python] + extensions: [.py] + files: [] + - name: revive + languages: [Go] + extensions: [.go] + files: [] + - name: semgrep + languages: [Apex, C, CPP, CSharp, Dockerfile, Go, Java, Javascript, Kotlin, PHP, PLSQL, Python, Ruby, Rust, SQL, Scala, Shell, Swift, Terraform, TypeScript, YAML] + extensions: [.bash, .c, .cc, .cls, .cpp, .cs, .cxx, .dockerfile, .fnc, .gemspec, .go, .h, .hpp, .ino, .java, .jbuilder, .js, .jsm, .jsx, .kt, .kts, .mjs, .opal, .pck, .php, .pkb, .pkh, .pks, .plb, .pld, .plh, .pls, .podspec, .prc, .py, .rake, .rb, .rlib, .rs, .scala, .sh, .sql, .swift, .tf, .tpb, .tps, .trg, .trigger, .ts, .tsx, .tyb, .typ, .vue, .yaml, .yml] + files: [] + - name: trivy + languages: [C, CPP, CSharp, Dart, Dockerfile, Elixir, Go, JSON, Java, Javascript, PHP, Python, Ruby, Rust, Scala, Swift, Terraform, TypeScript, XML, YAML] + extensions: [.c, .cc, .cpp, .cs, .cxx, .dart, .dockerfile, .ex, .exs, .gemspec, .go, .h, .hpp, .ino, .java, .jbuilder, .js, .jsm, .json, .jsx, .mjs, .opal, .php, .podspec, .pom, .py, .rake, .rb, .rlib, .rs, .scala, .swift, .tf, .ts, .tsx, .vue, .wsdl, .xml, .xsl, .yaml, .yml] + files: [.deps.json, Berksfile, Capfile, Cargo.lock, Cheffile, Directory.Packages.props, Dockerfile, Fastfile, Gemfile, Gemfile.lock, Guardfile, Package.resolved, Packages.props, Pipfile.lock, Podfile, Podfile.lock, Rakefile, Thorfile, Vagabondfile, Vagrantfile, build.sbt.lock, composer.lock, conan.lock, config.ru, go.mod, gradle.lockfile, mix.lock, package-lock.json, package.json, packages.config, packages.lock.json, pnpm-lock.yaml, poetry.lock, pom.xml, pubspec.lock, requirements.txt, uv.lock, yarn.lock] diff --git a/plugins/tools/trivy/test/src/.codacy/tools-configs/trivy.yaml b/plugins/tools/trivy/test/src/.codacy/tools-configs/trivy.yaml new file mode 100644 index 00000000..c785541c --- /dev/null +++ b/plugins/tools/trivy/test/src/.codacy/tools-configs/trivy.yaml @@ -0,0 +1,10 @@ +severity: + - LOW + - MEDIUM + - HIGH + - CRITICAL + +scan: + scanners: + - vuln + - secret diff --git a/tools/language_config.go b/tools/language_config.go index 7404d0ec..0afb7d9f 100644 --- a/tools/language_config.go +++ b/tools/language_config.go @@ -23,6 +23,12 @@ import ( // This file is responsible for building the languages-config.yaml file. // +// Tools that support specific files (hardcoded list) +// We want to move this to the API in the future +var supportSpecificFiles = map[string]bool{ + "trivy": true, +} + // buildToolLanguageInfoFromAPI builds tool language information from API data // This is the core shared logic used by both GetToolLanguageMappingFromAPI and buildToolLanguageConfigFromAPI func buildToolLanguageInfoFromAPI() (map[string]domain.ToolLanguageInfo, error) { @@ -90,9 +96,12 @@ func buildToolLanguageInfoFromAPI() (map[string]domain.ToolLanguageInfo, error) extensionsSet[ext] = struct{}{} } } - if files, exists := languageFilesMap[lowerLang]; exists { - for _, file := range files { - filesSet[file] = struct{}{} + // Only populate files if the tool supports specific files + if supportSpecificFiles[toolName] { + if files, exists := languageFilesMap[lowerLang]; exists { + for _, file := range files { + filesSet[file] = struct{}{} + } } } } @@ -262,8 +271,8 @@ func buildRemoteModeLanguagesConfig(apiTools []domain.Tool, toolIDMap map[string } } - // Add repository-specific files if they exist - if hasFiles { + // Add repository-specific files if they exist and tool supports specific files + if hasFiles && supportSpecificFiles[shortName] { for _, file := range repoLang.Files { filesSet[file] = struct{}{} } From 3aa5761c69273c71bcaead6cb3cca61e6ebe545e Mon Sep 17 00:00:00 2001 From: Joao Machado <13315199+machadoit@users.noreply.github.com> Date: Thu, 10 Jul 2025 12:04:34 +0200 Subject: [PATCH 8/8] Bring back code wrongly removed during the feature dev CF-1742 --- cmd/analyze.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cmd/analyze.go b/cmd/analyze.go index f6e76a36..d651a209 100644 --- a/cmd/analyze.go +++ b/cmd/analyze.go @@ -99,6 +99,12 @@ func IsToolSupportedForFile(toolName string, filePath string, langConfig *Langua } fileExt := GetFileExtension(filePath) + + if fileExt == "" { + // If file has no extension, assume tool is supported + return true + } + fileName := filepath.Base(filePath) for _, tool := range langConfig.Tools {