Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 10 additions & 5 deletions cmd/analyze.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"`
}

Expand Down Expand Up @@ -90,18 +91,15 @@ 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
return true
}

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 {
Expand All @@ -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
}
Expand Down
21 changes: 19 additions & 2 deletions cmd/analyze_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"},
},
},
}
Expand Down Expand Up @@ -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,
Expand All @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion codacy-client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
16 changes: 13 additions & 3 deletions domain/language.go
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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: [.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]
Original file line number Diff line number Diff line change
Expand Up @@ -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]
extensions: [.java, .js, .jsm, .json, .jsx, .mjs, .py, .vue]
files: [Pipfile.lock, gradle.lockfile, package-lock.json, package.json, pnpm-lock.yaml, poetry.lock, pom.xml, requirements.txt, uv.lock, yarn.lock]
Original file line number Diff line number Diff line change
Expand Up @@ -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]
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]
8 changes: 4 additions & 4 deletions plugins/runtime-utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"])
}
63 changes: 33 additions & 30 deletions plugins/tool-utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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,
Expand Down
Loading