Skip to content

Commit f961a76

Browse files
fix issue with analysis using tool configuration file (#179)
* When the repository is using the tool configuration file instead of UI patterns, the tool will analyse with that file (only for ESLint for now) * We're now comparing the name of the tool instead of the shortName when running the analysis. This was needed because the call to the repository tools is returning the tool name rather than the shortName. The logic is the same. * When we call the method to run the tools, if the user is not using a tool configuration file (so it's relying on the local tool configuration on tools-configs), we still check if there's a config file as before.
1 parent 06bb49b commit f961a76

File tree

7 files changed

+82
-58
lines changed

7 files changed

+82
-58
lines changed

.gitignore

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,9 @@ go.work.sum
2727
# Codacy CLI
2828
cli-v2
2929
codacy-cli
30-
**/.codacy/logs/
31-
.codacy/
30+
.codacy/*
31+
!.codacy/codacy.yaml
32+
.github/instructions/
3233

3334

3435
#Ignore cursor AI rules

cmd/analyze.go

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ func loadsToolAndPatterns(toolName string, onlyEnabledPatterns bool) (domain.Too
245245
}
246246
var tool domain.Tool
247247
for _, t := range toolsResponse {
248-
if t.ShortName == toolName {
248+
if t.Name == toolName {
249249
tool = t
250250
break
251251
}
@@ -264,19 +264,19 @@ func getToolName(toolName string, version string) string {
264264
if toolName == "eslint" {
265265
switch majorVersion {
266266
case 7:
267-
return "eslint"
267+
return "ESLint (deprecated)"
268268
case 8:
269-
return "eslint-8"
269+
return "ESLint"
270270
case 9:
271-
return "eslint-9"
271+
return "ESLint9"
272272
}
273273
} else {
274274
if toolName == "pmd" {
275275
switch majorVersion {
276276
case 6:
277-
return "pmd"
277+
return "PMD"
278278
case 7:
279-
return "pmd-7"
279+
return "PMD7"
280280
}
281281
}
282282
}
@@ -347,14 +347,40 @@ func checkIfConfigExistsAndIsNeeded(toolName string, cliLocalMode bool) error {
347347
}
348348

349349
func runToolByName(toolName string, workDirectory string, pathsToCheck []string, autoFix bool, outputFile string, outputFormat string, tool *plugins.ToolInfo, runtime *plugins.RuntimeInfo, cliLocalMode bool) error {
350-
err := checkIfConfigExistsAndIsNeeded(toolName, cliLocalMode)
351-
if err != nil {
352-
return err
350+
var t *domain.Tool
351+
var usesConfigurationFile = false
352+
353+
//Check if the user is using the repository configuration file
354+
// If the user doesn't provide init flags, we skip fetching repository tools
355+
if initFlags != (domain.InitFlags{}) {
356+
// Get the tool name with the right version e.g. ESLint9, PMD7, etc.
357+
toolRightVersion := getToolName(toolName, tool.Version)
358+
359+
// Get the repository tools to access tool settings
360+
repositoryTools, _ := codacyclient.GetRepositoryTools(initFlags)
361+
362+
// Find the matching tool in repositoryTools
363+
for i, tool := range repositoryTools {
364+
if tool.Name == toolRightVersion {
365+
t = &repositoryTools[i]
366+
usesConfigurationFile = t.Settings.UsesConfigurationFile
367+
break
368+
}
369+
}
353370
}
371+
372+
// If the user is not using configuration file from repository, we check if there's a local one
373+
if !usesConfigurationFile {
374+
err := checkIfConfigExistsAndIsNeeded(toolName, cliLocalMode)
375+
if err != nil {
376+
return err
377+
}
378+
}
379+
354380
switch toolName {
355381
case "eslint":
356382
binaryPath := runtime.Binaries[tool.Runtime]
357-
return tools.RunEslint(workDirectory, tool.InstallDir, binaryPath, pathsToCheck, autoFix, outputFile, outputFormat)
383+
return tools.RunEslint(workDirectory, tool.InstallDir, binaryPath, pathsToCheck, autoFix, outputFile, outputFormat, usesConfigurationFile)
358384
case "trivy":
359385
binaryPath := tool.Binaries[toolName]
360386
return tools.RunTrivy(workDirectory, binaryPath, pathsToCheck, outputFile, outputFormat)

cmd/analyze_test.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,14 +64,14 @@ func TestGetToolName(t *testing.T) {
6464
expected string
6565
}{
6666
// ESLint cases
67-
{"eslint v7", "eslint", "7.32.0", "eslint"},
68-
{"eslint v8", "eslint", "8.15.0", "eslint-8"},
69-
{"eslint v9", "eslint", "9.1.0", "eslint-9"},
67+
{"eslint v7", "eslint", "7.32.0", "ESLint (deprecated)"},
68+
{"eslint v8", "eslint", "8.15.0", "ESLint"},
69+
{"eslint v9", "eslint", "9.1.0", "ESLint9"},
7070
{"eslint unknown version", "eslint", "10.0.0", "eslint"},
7171

7272
// PMD cases
73-
{"pmd v6", "pmd", "6.55.0", "pmd"},
74-
{"pmd v7", "pmd", "7.0.0", "pmd-7"},
73+
{"pmd v6", "pmd", "6.55.0", "PMD"},
74+
{"pmd v7", "pmd", "7.0.0", "PMD7"},
7575
{"pmd unknown version", "pmd", "8.0.0", "pmd"},
7676

7777
// Other tools should remain unchanged

cmd/configsetup/repository_config.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,6 @@ func createToolConfigurationFiles(tools []domain.Tool, flags domain.InitFlags) e
9191
}
9292

9393
// CreateToolConfigurationFile creates a configuration file for a single tool
94-
// CreateToolConfigurationFile generates a configuration file for a single tool.
9594
func CreateToolConfigurationFile(toolName string, flags domain.InitFlags) error {
9695
// Find the tool UUID by tool name
9796
toolUUID := getToolUUIDByName(toolName)

tools/eslintRunner.go

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,21 @@ import (
1111
// * Run from the root of the repo we want to analyse
1212
// * NODE_PATH="<the installed eslint path>/node_modules"
1313
// * The local installed ESLint should have the @microsoft/eslint-formatter-sarif installed
14-
func RunEslint(repositoryToAnalyseDirectory string, eslintInstallationDirectory string, nodeBinary string, pathsToCheck []string, autoFix bool, outputFile string, outputFormat string) error {
14+
func RunEslint(repositoryToAnalyseDirectory string, eslintInstallationDirectory string, nodeBinary string, pathsToCheck []string, autoFix bool, outputFile string, outputFormat string, usesConfigurationFile bool) error {
1515
eslintInstallationNodeModules := filepath.Join(eslintInstallationDirectory, "node_modules")
1616
eslintJsPath := filepath.Join(eslintInstallationNodeModules, ".bin", "eslint")
1717

1818
cmd := exec.Command(nodeBinary, eslintJsPath)
1919

2020
// Add config file from tools-configs directory if it exists
21-
if configFile, exists := ConfigFileExists(config.Config, "eslint.config.mjs"); exists {
22-
// For Eslint compatibility with version 8.
23-
// https://eslint.org/docs/v8.x/use/configure/configuration-files-new
24-
cmd.Env = append(cmd.Env, "ESLINT_USE_FLAT_CONFIG=true")
21+
if !usesConfigurationFile {
22+
if configFile, exists := ConfigFileExists(config.Config, "eslint.config.mjs"); exists {
23+
// For Eslint compatibility with version 8.
24+
// https://eslint.org/docs/v8.x/use/configure/configuration-files-new
25+
cmd.Env = append(cmd.Env, "ESLINT_USE_FLAT_CONFIG=true")
2526

26-
cmd.Args = append(cmd.Args, "-c", configFile)
27+
cmd.Args = append(cmd.Args, "-c", configFile)
28+
}
2729
}
2830

2931
if autoFix {

tools/lizard/lizardRunner.go

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,12 @@ import (
77
"codacy/cli-v2/domain"
88
"codacy/cli-v2/tools"
99
"codacy/cli-v2/utils/logger"
10-
"github.com/sirupsen/logrus"
1110
"encoding/json"
1211
"fmt"
1312
"os"
1413
"os/exec"
14+
15+
"github.com/sirupsen/logrus"
1516
)
1617

1718
// RunLizard runs the Lizard tool and returns any issues found
@@ -21,7 +22,6 @@ func RunLizard(workDirectory string, binary string, files []string, outputFile s
2122
var patterns []domain.PatternDefinition
2223
var errConfigs error
2324

24-
2525
if exists {
2626
// Configuration exists, read from file
2727
patterns, errConfigs = ReadConfig(configFile)
@@ -35,11 +35,10 @@ func RunLizard(workDirectory string, binary string, files []string, outputFile s
3535
return fmt.Errorf("failed to fetch default patterns: %v", errConfigs)
3636
}
3737
}
38+
3839
if len(patterns) == 0 {
3940
return fmt.Errorf("no valid patterns found in configuration")
4041
}
41-
42-
4342
// Construct base command with lizard module
4443
args := []string{"-m", "lizard", "-V"}
4544

@@ -50,23 +49,20 @@ func RunLizard(workDirectory string, binary string, files []string, outputFile s
5049
args = append(args, ".")
5150
}
5251

53-
5452
// For non-SARIF output, let Lizard handle file output directly
5553
if outputFormat != "sarif" && outputFile != "" {
5654
args = append(args, "-o", outputFile)
5755
}
5856

59-
6057
// Run the command
6158
cmd := exec.Command(binary, args...)
6259
cmd.Dir = workDirectory
6360

64-
6561
var err error
6662
var stderr bytes.Buffer
67-
63+
6864
cmd.Stderr = &stderr
69-
65+
7066
// For SARIF output, we need to capture and parse the output
7167
if outputFormat == "sarif" {
7268
var stdout bytes.Buffer

tools/runnerUtils_test.go

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ func TestConfigFileExistsInToolsConfigDirectory(t *testing.T) {
3535
"Config path should be correctly formed relative path")
3636
}
3737

38-
func TestConfigFileExistsInRepositoryDirectory(t *testing.T) {
38+
func TestConfigFilePrefersToolsConfigDirectory(t *testing.T) {
3939
// Create a test directory structure
4040
tempDir := t.TempDir()
4141
repoDir := filepath.Join(tempDir, "src")
@@ -49,19 +49,24 @@ func TestConfigFileExistsInRepositoryDirectory(t *testing.T) {
4949
err := os.MkdirAll(configDir, 0755)
5050
assert.NoError(t, err, "Failed to create test directory structure")
5151

52-
// Create a test config file on the repository directory
53-
existingConfigFile := filepath.Join(repoDir, "existing-config.yaml")
54-
err = os.WriteFile(existingConfigFile, []byte("test content"), 0644)
55-
assert.NoError(t, err, "Failed to create test config file")
52+
// Create a test config file in both locations
53+
generatedConfigFile := filepath.Join(configDir, "some-config.yaml")
54+
existingConfigFile := filepath.Join(repoDir, "some-config.yaml")
5655

57-
// Test case: The existing config file gets picked up
58-
configPath, exists := ConfigFileExists(config, "existing-config.yaml")
59-
assert.True(t, exists, "Config file should exist in tools config directory")
60-
assert.Equal(t, filepath.Join(config.RepositoryDirectory(), "existing-config.yaml"), configPath,
61-
"Config path should be correctly formed relative path")
56+
err = os.WriteFile(generatedConfigFile, []byte("tools config content"), 0644)
57+
assert.NoError(t, err, "Failed to create test config file in tools config directory")
58+
59+
err = os.WriteFile(existingConfigFile, []byte("repository config content"), 0644)
60+
assert.NoError(t, err, "Failed to create test config file in repository directory")
61+
62+
// Test case: Config file in tools config directory is preferred
63+
configPath, exists := ConfigFileExists(config, "some-config.yaml")
64+
assert.True(t, exists, "Config file should exist")
65+
assert.Equal(t, filepath.Join(config.ToolsConfigDirectory(), "some-config.yaml"), configPath,
66+
"Config path should prefer tools config directory")
6267
}
6368

64-
func TestConfigFilePrefersToolsConfigDirectory(t *testing.T) {
69+
func TestConfigFileExistsInRepositoryDirectory(t *testing.T) {
6570
// Create a test directory structure
6671
tempDir := t.TempDir()
6772
repoDir := filepath.Join(tempDir, "src")
@@ -75,21 +80,16 @@ func TestConfigFilePrefersToolsConfigDirectory(t *testing.T) {
7580
err := os.MkdirAll(configDir, 0755)
7681
assert.NoError(t, err, "Failed to create test directory structure")
7782

78-
// Create a test config file in both locations
79-
generatedConfigFile := filepath.Join(configDir, "some-config.yaml")
80-
existingConfigFile := filepath.Join(repoDir, "some-config.yaml")
81-
82-
err = os.WriteFile(generatedConfigFile, []byte("tools config content"), 0644)
83-
assert.NoError(t, err, "Failed to create test config file in tools config directory")
84-
85-
err = os.WriteFile(existingConfigFile, []byte("repository config content"), 0644)
86-
assert.NoError(t, err, "Failed to create test config file in repository directory")
83+
// Create a test config file on the repository directory
84+
existingConfigFile := filepath.Join(repoDir, "existing-config.yaml")
85+
err = os.WriteFile(existingConfigFile, []byte("test content"), 0644)
86+
assert.NoError(t, err, "Failed to create test config file")
8787

88-
// Test case: Config file in tools config directory is preferred
89-
configPath, exists := ConfigFileExists(config, "some-config.yaml")
90-
assert.True(t, exists, "Config file should exist")
91-
assert.Equal(t, filepath.Join(config.ToolsConfigDirectory(), "some-config.yaml"), configPath,
92-
"Config path should prefer tools config directory")
88+
// Test case: The existing config file gets picked up
89+
configPath, exists := ConfigFileExists(config, "existing-config.yaml")
90+
assert.True(t, exists, "Config file should exist in tools config directory")
91+
assert.Equal(t, filepath.Join(config.RepositoryDirectory(), "existing-config.yaml"), configPath,
92+
"Config path should be correctly formed relative path")
9393
}
9494

9595
func TestConfigFileDoesNotExist(t *testing.T) {

0 commit comments

Comments
 (0)