Skip to content

Commit 1b80ceb

Browse files
authored
feature: Respect the file information for languages from the API CF-1742 (#164)
* feature: Respect the file information for languages from the API CF-1742 * Add integration test for trivy a and pylint CF-1742 * tests: Add the files array to the tests CF-1742 * tests: Add the expected files to the trivy expected yamls * fix: Only consider LanguageFiles from the API for Trivy CF-1742
1 parent d5b5ef2 commit 1b80ceb

File tree

18 files changed

+397
-44
lines changed

18 files changed

+397
-44
lines changed

cmd/analyze.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ type LanguagesConfig struct {
4141
Name string `yaml:"name" json:"name"`
4242
Languages []string `yaml:"languages" json:"languages"`
4343
Extensions []string `yaml:"extensions" json:"extensions"`
44+
Files []string `yaml:"files" json:"files"`
4445
} `yaml:"tools" json:"tools"`
4546
}
4647

@@ -90,19 +91,22 @@ func GetFileExtension(filePath string) string {
9091
return strings.ToLower(filepath.Ext(filePath))
9192
}
9293

93-
// IsToolSupportedForFile checks if a tool supports a given file based on its extension
94+
// IsToolSupportedForFile checks if a tool supports a given file based on its extension or filename
9495
func IsToolSupportedForFile(toolName string, filePath string, langConfig *LanguagesConfig) bool {
9596
if langConfig == nil {
9697
// If no language config is available, assume all tools are supported
9798
return true
9899
}
99100

100101
fileExt := GetFileExtension(filePath)
102+
101103
if fileExt == "" {
102104
// If file has no extension, assume tool is supported
103105
return true
104106
}
105107

108+
fileName := filepath.Base(filePath)
109+
106110
for _, tool := range langConfig.Tools {
107111
if tool.Name == toolName {
108112
// If tool has no extensions defined, assume it supports all files
@@ -117,6 +121,13 @@ func IsToolSupportedForFile(toolName string, filePath string, langConfig *Langua
117121
}
118122
}
119123

124+
// Check if filename is supported by this tool (exact match)
125+
for _, file := range tool.Files {
126+
if strings.EqualFold(file, fileName) {
127+
return true
128+
}
129+
}
130+
120131
// Extension not found in tool's supported extensions
121132
return false
122133
}

cmd/analyze_test.go

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,21 +62,31 @@ func TestIsToolSupportedForFile(t *testing.T) {
6262
Name string `yaml:"name" json:"name"`
6363
Languages []string `yaml:"languages" json:"languages"`
6464
Extensions []string `yaml:"extensions" json:"extensions"`
65+
Files []string `yaml:"files" json:"files"`
6566
}{
6667
{
6768
Name: "pylint",
6869
Languages: []string{"Python"},
6970
Extensions: []string{".py"},
71+
Files: []string{},
72+
},
73+
{
74+
Name: "eslint",
75+
Languages: []string{"JavaScript", "TypeScript"},
76+
Extensions: []string{},
77+
Files: []string{},
7078
},
7179
{
7280
Name: "cppcheck",
7381
Languages: []string{"C", "CPP"},
7482
Extensions: []string{".c", ".cpp", ".h", ".hpp"},
83+
Files: []string{},
7584
},
7685
{
7786
Name: "trivy",
7887
Languages: []string{"Multiple"},
79-
Extensions: []string{},
88+
Extensions: []string{".yaml", ".yml"},
89+
Files: []string{"requirements.txt"},
8090
},
8191
},
8292
}
@@ -111,7 +121,7 @@ func TestIsToolSupportedForFile(t *testing.T) {
111121
},
112122
{
113123
name: "Tool with no extensions specified",
114-
toolName: "trivy",
124+
toolName: "eslint",
115125
filePath: "any.file",
116126
config: langConfig,
117127
want: true,
@@ -130,6 +140,13 @@ func TestIsToolSupportedForFile(t *testing.T) {
130140
config: nil,
131141
want: true,
132142
},
143+
{
144+
name: "Trivy with requirements.txt",
145+
toolName: "trivy",
146+
filePath: "requirements.txt",
147+
config: langConfig,
148+
want: true,
149+
},
133150
}
134151

135152
for _, tt := range tests {

codacy-client/client.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ func GetToolsVersions() ([]domain.Tool, error) {
253253
}
254254

255255
// GetRepositoryLanguages fetches the languages for a repository
256-
func GetRepositoryLanguages(initFlags domain.InitFlags) ([]domain.Language, error) {
256+
func GetRepositoryLanguages(initFlags domain.InitFlags) ([]domain.RepositoryLanguage, error) {
257257
baseURL := fmt.Sprintf("%s/api/v3/organizations/%s/%s/repositories/%s/settings/languages",
258258
CodacyApiBase,
259259
initFlags.Provider,

domain/language.go

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,32 @@
11
package domain
22

3-
// Language represents a language in the Codacy API
4-
type Language struct {
3+
// RepositoryLanguage represents a language in the Codacy API
4+
type RepositoryLanguage struct {
55
Name string `json:"name"`
66
CodacyDefaults []string `json:"codacyDefaults"`
77
Extensions []string `json:"extensions"`
8+
DefaultFiles []string `json:"defaultFiles"`
89
Enabled bool `json:"enabled"`
910
Detected bool `json:"detected"`
1011
}
1112

1213
// LanguagesResponse represents the structure of the languages response
1314
type LanguagesResponse struct {
14-
Languages []Language `json:"languages"`
15+
Languages []RepositoryLanguage `json:"languages"`
16+
}
17+
18+
// Language represents a processed language with combined extensions and files
19+
type Language struct {
20+
Name string
21+
Extensions []string
22+
Files []string
1523
}
1624

1725
// LanguageTool represents a language tool with its file extensions from the API
1826
type LanguageTool struct {
1927
Name string `json:"name"`
2028
FileExtensions []string `json:"fileExtensions"`
29+
Files []string `json:"files"`
2130
}
2231

2332
// LanguageToolsResponse represents the structure of the language tools API response
@@ -30,6 +39,7 @@ type ToolLanguageInfo struct {
3039
Name string `yaml:"name"`
3140
Languages []string `yaml:"languages,flow"`
3241
Extensions []string `yaml:"extensions,flow"`
42+
Files []string `yaml:"files,flow"`
3343
}
3444

3545
// LanguagesConfig represents the structure of the languages configuration file

integration-tests/config-discover/expected/codacy.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,4 @@ tools:
1010
1111
1212
13-
13+

integration-tests/config-discover/expected/tools-configs/languages-config.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,32 @@ tools:
22
- name: dartanalyzer
33
languages: [Dart]
44
extensions: [.dart]
5+
files: []
56
- name: eslint
67
languages: [Javascript, TypeScript]
78
extensions: [.js, .jsm, .jsx, .mjs, .ts, .tsx, .vue]
9+
files: []
810
- name: lizard
911
languages: [C, CPP, CSharp, Erlang, Fortran, Go, Java, Javascript, Kotlin, Lua, Objective C, PHP, Python, Ruby, Rust, Scala, Solidity, Swift, TypeScript]
1012
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]
13+
files: []
1114
- name: pmd
1215
languages: [Apex, JSP, Java, Javascript, PLSQL, SQL, Velocity, VisualForce, XML]
1316
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]
17+
files: []
1418
- name: pylint
1519
languages: [Python]
1620
extensions: [.py]
21+
files: []
1722
- name: revive
1823
languages: [Go]
1924
extensions: [.go]
25+
files: []
2026
- name: semgrep
2127
languages: [Apex, C, CPP, CSharp, Dockerfile, Go, Java, Javascript, Kotlin, PHP, PLSQL, Python, Ruby, Rust, SQL, Scala, Shell, Swift, Terraform, TypeScript, YAML]
2228
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]
29+
files: []
2330
- name: trivy
2431
languages: [C, CPP, CSharp, Dart, Dockerfile, Elixir, Go, JSON, Java, Javascript, PHP, Python, Ruby, Rust, Scala, Swift, Terraform, TypeScript, XML, YAML]
2532
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]
33+
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]

integration-tests/init-with-token/expected/tools-configs/languages-config.yaml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,24 @@ tools:
22
- name: eslint
33
languages: [Javascript]
44
extensions: [.js, .jsm, .jsx, .mjs, .vue]
5+
files: []
56
- name: lizard
67
languages: [Java, Javascript, Python]
78
extensions: [.java, .js, .jsm, .jsx, .mjs, .py, .vue]
9+
files: []
810
- name: pmd
911
languages: [Java, Javascript]
1012
extensions: [.java, .js, .jsm, .jsx, .mjs, .vue]
13+
files: []
1114
- name: pylint
1215
languages: [Python]
1316
extensions: [.py]
17+
files: []
1418
- name: semgrep
1519
languages: [Java, Javascript, Python]
1620
extensions: [.java, .js, .jsm, .jsx, .mjs, .py, .vue]
21+
files: []
1722
- name: trivy
1823
languages: [JSON, Java, Javascript, Python]
19-
extensions: [.java, .js, .jsm, .json, .jsx, .mjs, .py, .vue]
24+
extensions: [.java, .js, .jsm, .json, .jsx, .mjs, .py, .vue]
25+
files: [Pipfile.lock, gradle.lockfile, package-lock.json, package.json, pnpm-lock.yaml, poetry.lock, pom.xml, requirements.txt, uv.lock, yarn.lock]

integration-tests/init-without-token/expected/tools-configs/languages-config.yaml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,32 @@ tools:
22
- name: dartanalyzer
33
languages: [Dart]
44
extensions: [.dart]
5+
files: []
56
- name: eslint
67
languages: [Javascript, TypeScript]
78
extensions: [.js, .jsm, .jsx, .mjs, .ts, .tsx, .vue]
9+
files: []
810
- name: lizard
911
languages: [C, CPP, CSharp, Erlang, Fortran, Go, Java, Javascript, Kotlin, Lua, Objective C, PHP, Python, Ruby, Rust, Scala, Solidity, Swift, TypeScript]
1012
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]
13+
files: []
1114
- name: pmd
1215
languages: [Apex, JSP, Java, Javascript, PLSQL, SQL, Velocity, VisualForce, XML]
1316
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]
17+
files: []
1418
- name: pylint
1519
languages: [Python]
1620
extensions: [.py]
21+
files: []
1722
- name: revive
1823
languages: [Go]
1924
extensions: [.go]
25+
files: []
2026
- name: semgrep
2127
languages: [Apex, C, CPP, CSharp, Dockerfile, Go, Java, Javascript, Kotlin, PHP, PLSQL, Python, Ruby, Rust, SQL, Scala, Shell, Swift, Terraform, TypeScript, YAML]
2228
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]
29+
files: []
2330
- name: trivy
2431
languages: [C, CPP, CSharp, Dart, Dockerfile, Elixir, Go, JSON, Java, Javascript, PHP, Python, Ruby, Rust, Scala, Swift, Terraform, TypeScript, XML, YAML]
25-
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]
32+
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]
33+
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]
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
export default [
2+
{
3+
rules: {
4+
"constructor-super": ["error"],
5+
"for-direction": ["error"],
6+
"getter-return": ["error", {"allowImplicit": false}],
7+
"no-async-promise-executor": ["error"],
8+
"no-case-declarations": ["error"],
9+
"no-class-assign": ["error"],
10+
"no-compare-neg-zero": ["error"],
11+
"no-cond-assign": ["error", "except-parens"],
12+
"no-constant-condition": ["error", {"checkLoops": true}],
13+
"no-const-assign": ["error"],
14+
"no-control-regex": ["error"],
15+
"no-debugger": ["error"],
16+
"no-delete-var": ["error"],
17+
"no-dupe-args": ["error"],
18+
"no-dupe-class-members": ["error"],
19+
"no-dupe-else-if": ["error"],
20+
"no-dupe-keys": ["error"],
21+
"no-duplicate-case": ["error"],
22+
"no-empty": ["error", {"allowEmptyCatch": false}],
23+
"no-empty-character-class": ["error"],
24+
"no-empty-pattern": ["error", {"allowObjectPatternsAsParameters": false}],
25+
"no-ex-assign": ["error"],
26+
"no-extra-boolean-cast": ["error", {"enforceForLogicalOperands": false}],
27+
"no-extra-semi": ["error"],
28+
"no-fallthrough": ["error", {"allowEmptyCase": false}],
29+
"no-func-assign": ["error"],
30+
"no-global-assign": ["error"],
31+
"no-import-assign": ["error"],
32+
"no-inner-declarations": ["error", "functions"],
33+
"no-invalid-regexp": ["error"],
34+
"no-irregular-whitespace": ["error", {"skipComments": false, "skipJSXText": false, "skipRegExps": false, "skipStrings": true, "skipTemplates": false}],
35+
"no-loss-of-precision": ["error"],
36+
"no-misleading-character-class": ["error"],
37+
"no-mixed-spaces-and-tabs": ["error"],
38+
"no-new-symbol": ["error"],
39+
"no-nonoctal-decimal-escape": ["error"],
40+
"no-obj-calls": ["error"],
41+
"no-octal": ["error"],
42+
"no-prototype-builtins": ["error"],
43+
"no-redeclare": ["error", {"builtinGlobals": true}],
44+
"no-regex-spaces": ["error"],
45+
"no-self-assign": ["error", {"props": true}],
46+
"no-setter-return": ["error"],
47+
"no-shadow-restricted-names": ["error"],
48+
"no-sparse-arrays": ["error"],
49+
"no-this-before-super": ["error"],
50+
"no-undef": ["error", {"typeof": false}],
51+
"no-unexpected-multiline": ["error"],
52+
"no-unreachable": ["error"],
53+
"no-unsafe-finally": ["error"],
54+
"no-unsafe-negation": ["error", {"enforceForOrderingRelations": false}],
55+
"no-unsafe-optional-chaining": ["error", {"disallowArithmeticOperators": false}],
56+
"no-unused-labels": ["error"],
57+
"no-unused-vars": ["error"],
58+
"no-useless-backreference": ["error"],
59+
"no-useless-catch": ["error"],
60+
"no-useless-escape": ["error"],
61+
"no-with": ["error"],
62+
"require-yield": ["error"],
63+
"use-isnan": ["error", {"enforceForIndexOf": false, "enforceForSwitchCase": true}],
64+
"valid-typeof": ["error", {"requireStringLiterals": false}],
65+
}
66+
}
67+
];
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
tools:
2+
- name: eslint
3+
languages: [Javascript, TypeScript]
4+
extensions: [.js, .jsm, .jsx, .mjs, .ts, .tsx, .vue]

0 commit comments

Comments
 (0)