Skip to content
Merged
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
17 changes: 3 additions & 14 deletions cmd/analyze.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"codacy/cli-v2/cmd/cmdutils"
"codacy/cli-v2/cmd/configsetup"
"codacy/cli-v2/config"
"codacy/cli-v2/constants"
"codacy/cli-v2/domain"
"codacy/cli-v2/plugins"
"codacy/cli-v2/tools"
Expand Down Expand Up @@ -41,22 +42,10 @@ type LanguagesConfig struct {
} `yaml:"tools" json:"tools"`
}

// toolConfigFileName maps tool names to their configuration filenames
var toolConfigFileName = map[string]string{
"eslint": "eslint.config.mjs",
"trivy": "trivy.yaml",
"pmd": "ruleset.xml",
"pylint": "pylint.rc",
"dartanalyzer": "analysis_options.yaml",
"semgrep": "semgrep.yaml",
"revive": "revive.toml",
"lizard": "lizard.yaml",
}

// LoadLanguageConfig loads the language configuration from the file
func LoadLanguageConfig() (*LanguagesConfig, error) {
// First, try to load the YAML config
yamlPath := filepath.Join(config.Config.ToolsConfigDirectory(), "languages-config.yaml")
yamlPath := filepath.Join(config.Config.ToolsConfigDirectory(), constants.LanguagesConfigFileName)

// Check if the YAML file exists
if _, err := os.Stat(yamlPath); err == nil {
Expand Down Expand Up @@ -293,7 +282,7 @@ func validateToolName(toolName string) error {
}

func checkIfConfigExistsAndIsNeeded(toolName string, cliLocalMode bool) error {
configFileName := toolConfigFileName[toolName]
configFileName := constants.ToolConfigFileNames[toolName]
if configFileName == "" {
// Tool doesn't use config file
return nil
Expand Down
27 changes: 14 additions & 13 deletions cmd/analyze_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"testing"

"codacy/cli-v2/config"
"codacy/cli-v2/constants"
"codacy/cli-v2/domain"

"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -103,28 +104,28 @@ func TestCheckIfConfigExistsAndIsNeededBehavior(t *testing.T) {
// TestToolConfigFileNameMapCompleteness ensures all expected tools have config mappings
func TestToolConfigFileNameMapCompleteness(t *testing.T) {
expectedTools := map[string]string{
"eslint": "eslint.config.mjs",
"trivy": "trivy.yaml",
"pmd": "ruleset.xml",
"pylint": "pylint.rc",
"dartanalyzer": "analysis_options.yaml",
"semgrep": "semgrep.yaml",
"revive": "revive.toml",
"lizard": "lizard.yaml",
"eslint": constants.ESLintConfigFileName,
"trivy": constants.TrivyConfigFileName,
"pmd": constants.PMDConfigFileName,
"pylint": constants.PylintConfigFileName,
"dartanalyzer": constants.DartAnalyzerConfigFileName,
"semgrep": constants.SemgrepConfigFileName,
"revive": constants.ReviveConfigFileName,
"lizard": constants.LizardConfigFileName,
}

t.Run("all_expected_tools_present", func(t *testing.T) {
for toolName, expectedFileName := range expectedTools {
actualFileName, exists := toolConfigFileName[toolName]
assert.True(t, exists, "Tool %s should exist in toolConfigFileName map", toolName)
actualFileName, exists := constants.ToolConfigFileNames[toolName]
assert.True(t, exists, "Tool %s should exist in constants.ToolConfigFileNames map", toolName)
assert.Equal(t, expectedFileName, actualFileName, "Config filename for %s should match expected", toolName)
}
})

t.Run("no_unexpected_tools", func(t *testing.T) {
for toolName := range toolConfigFileName {
for toolName := range constants.ToolConfigFileNames {
_, expected := expectedTools[toolName]
assert.True(t, expected, "Unexpected tool %s found in toolConfigFileName map", toolName)
assert.True(t, expected, "Unexpected tool %s found in constants.ToolConfigFileNames map", toolName)
}
})

Expand All @@ -139,7 +140,7 @@ func TestToolConfigFileNameMapCompleteness(t *testing.T) {
".toml": true,
}

for toolName, fileName := range toolConfigFileName {
for toolName, fileName := range constants.ToolConfigFileNames {
ext := filepath.Ext(fileName)
assert.True(t, validExtensions[ext], "Tool %s has config file %s with unexpected extension %s", toolName, fileName, ext)
}
Expand Down
35 changes: 18 additions & 17 deletions cmd/analyze_test.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package cmd

import (
"codacy/cli-v2/plugins"
"codacy/cli-v2/config"
"codacy/cli-v2/constants"
"codacy/cli-v2/domain"
"os"
"path/filepath"
"testing"

"codacy/cli-v2/config"
"codacy/cli-v2/domain"
"codacy/cli-v2/plugins"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -342,13 +343,13 @@ func TestCheckIfConfigExistsAndIsNeeded(t *testing.T) {
config.Config = *config.NewConfigType(tmpDir, tmpDir, tmpDir)

// Create config file if needed - using the same path logic as the function under test
if tt.configFileExists && toolConfigFileName[tt.toolName] != "" {
if tt.configFileExists && constants.ToolConfigFileNames[tt.toolName] != "" {
// Use config.Config.ToolsConfigDirectory() to get the exact same path the function will use
toolsConfigDir := config.Config.ToolsConfigDirectory()
err := os.MkdirAll(toolsConfigDir, 0755)
require.NoError(t, err)

configPath := filepath.Join(toolsConfigDir, toolConfigFileName[tt.toolName])
configPath := filepath.Join(toolsConfigDir, constants.ToolConfigFileNames[tt.toolName])
err = os.WriteFile(configPath, []byte("test config"), 0644)
require.NoError(t, err)

Expand All @@ -366,9 +367,9 @@ func TestCheckIfConfigExistsAndIsNeeded(t *testing.T) {
err = checkIfConfigExistsAndIsNeeded(tt.toolName, tt.cliLocalMode)

// Clean up any files that might have been created by the function under test
if !tt.configFileExists && toolConfigFileName[tt.toolName] != "" {
if !tt.configFileExists && constants.ToolConfigFileNames[tt.toolName] != "" {
toolsConfigDir := config.Config.ToolsConfigDirectory()
configPath := filepath.Join(toolsConfigDir, toolConfigFileName[tt.toolName])
configPath := filepath.Join(toolsConfigDir, constants.ToolConfigFileNames[tt.toolName])
if _, statErr := os.Stat(configPath); statErr == nil {
os.Remove(configPath)
}
Expand All @@ -386,20 +387,20 @@ func TestCheckIfConfigExistsAndIsNeeded(t *testing.T) {

func TestToolConfigFileNameMap(t *testing.T) {
expectedTools := map[string]string{
"eslint": "eslint.config.mjs",
"trivy": "trivy.yaml",
"pmd": "ruleset.xml",
"pylint": "pylint.rc",
"dartanalyzer": "analysis_options.yaml",
"semgrep": "semgrep.yaml",
"revive": "revive.toml",
"lizard": "lizard.yaml",
"eslint": constants.ESLintConfigFileName,
"trivy": constants.TrivyConfigFileName,
"pmd": constants.PMDConfigFileName,
"pylint": constants.PylintConfigFileName,
"dartanalyzer": constants.DartAnalyzerConfigFileName,
"semgrep": constants.SemgrepConfigFileName,
"revive": constants.ReviveConfigFileName,
"lizard": constants.LizardConfigFileName,
}

for toolName, expectedFileName := range expectedTools {
t.Run(toolName, func(t *testing.T) {
actualFileName, exists := toolConfigFileName[toolName]
assert.True(t, exists, "Tool %s should exist in toolConfigFileName map", toolName)
actualFileName, exists := constants.ToolConfigFileNames[toolName]
assert.True(t, exists, "Tool %s should exist in constants.ToolConfigFileNames map", toolName)
assert.Equal(t, expectedFileName, actualFileName, "Config filename for %s should match expected", toolName)
})
}
Expand Down
43 changes: 17 additions & 26 deletions cmd/configsetup/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,6 @@ import (
"codacy/cli-v2/utils"
)

// Configuration file names - extracted as constants to avoid duplication
const (
LanguagesConfigFileName = "languages-config.yaml"
GitIgnoreFileName = ".gitignore"
PMDConfigFileName = "ruleset.xml"
PylintConfigFileName = "pylint.rc"
TrivyConfigFileName = "trivy.yaml"
DartAnalyzerConfigFileName = "analysis_options.yaml"
SemgrepConfigFileName = "semgrep.yaml"
)

// ToolConfigCreator defines the interface for tool configuration creators
type ToolConfigCreator interface {
CreateConfig(toolsConfigDir string, patterns []domain.PatternConfiguration) error
Expand Down Expand Up @@ -76,71 +65,73 @@ type trivyConfigCreator struct{}

func (t *trivyConfigCreator) CreateConfig(toolsConfigDir string, patterns []domain.PatternConfiguration) error {
configString := tools.CreateTrivyConfig(patterns)
err := writeConfigFile(filepath.Join(toolsConfigDir, TrivyConfigFileName), []byte(configString))
err := writeConfigFile(filepath.Join(toolsConfigDir, constants.TrivyConfigFileName), []byte(configString))
if err == nil {
fmt.Println("Trivy configuration created based on Codacy settings")
}
return err
}

func (t *trivyConfigCreator) GetConfigFileName() string { return TrivyConfigFileName }
func (t *trivyConfigCreator) GetConfigFileName() string { return constants.TrivyConfigFileName }
func (t *trivyConfigCreator) GetToolName() string { return "Trivy" }

// pmdConfigCreator implements ToolConfigCreator for PMD
type pmdConfigCreator struct{}

func (p *pmdConfigCreator) CreateConfig(toolsConfigDir string, patterns []domain.PatternConfiguration) error {
configString := tools.CreatePmd6Config(patterns)
return writeConfigFile(filepath.Join(toolsConfigDir, PMDConfigFileName), []byte(configString))
return writeConfigFile(filepath.Join(toolsConfigDir, constants.PMDConfigFileName), []byte(configString))
}

func (p *pmdConfigCreator) GetConfigFileName() string { return PMDConfigFileName }
func (p *pmdConfigCreator) GetConfigFileName() string { return constants.PMDConfigFileName }
func (p *pmdConfigCreator) GetToolName() string { return "PMD" }

// pmd7ConfigCreator implements ToolConfigCreator for PMD7
type pmd7ConfigCreator struct{}

func (p *pmd7ConfigCreator) CreateConfig(toolsConfigDir string, patterns []domain.PatternConfiguration) error {
configString := tools.CreatePmd7Config(patterns)
err := writeConfigFile(filepath.Join(toolsConfigDir, PMDConfigFileName), []byte(configString))
err := writeConfigFile(filepath.Join(toolsConfigDir, constants.PMDConfigFileName), []byte(configString))
if err == nil {
fmt.Println("PMD7 configuration created based on Codacy settings")
}
return err
}

func (p *pmd7ConfigCreator) GetConfigFileName() string { return PMDConfigFileName }
func (p *pmd7ConfigCreator) GetConfigFileName() string { return constants.PMDConfigFileName }
func (p *pmd7ConfigCreator) GetToolName() string { return "PMD7" }

// pylintConfigCreator implements ToolConfigCreator for Pylint
type pylintConfigCreator struct{}

func (p *pylintConfigCreator) CreateConfig(toolsConfigDir string, patterns []domain.PatternConfiguration) error {
configString := pylint.GeneratePylintRC(patterns)
err := writeConfigFile(filepath.Join(toolsConfigDir, PylintConfigFileName), []byte(configString))
err := writeConfigFile(filepath.Join(toolsConfigDir, constants.PylintConfigFileName), []byte(configString))
if err == nil {
fmt.Println("Pylint configuration created based on Codacy settings")
}
return err
}

func (p *pylintConfigCreator) GetConfigFileName() string { return PylintConfigFileName }
func (p *pylintConfigCreator) GetConfigFileName() string { return constants.PylintConfigFileName }
func (p *pylintConfigCreator) GetToolName() string { return "Pylint" }

// dartAnalyzerConfigCreator implements ToolConfigCreator for Dart Analyzer
type dartAnalyzerConfigCreator struct{}

func (d *dartAnalyzerConfigCreator) CreateConfig(toolsConfigDir string, patterns []domain.PatternConfiguration) error {
configString := tools.CreateDartAnalyzerConfig(patterns)
err := writeConfigFile(filepath.Join(toolsConfigDir, DartAnalyzerConfigFileName), []byte(configString))
err := writeConfigFile(filepath.Join(toolsConfigDir, constants.DartAnalyzerConfigFileName), []byte(configString))
if err == nil {
fmt.Println("Dart configuration created based on Codacy settings")
}
return err
}

func (d *dartAnalyzerConfigCreator) GetConfigFileName() string { return DartAnalyzerConfigFileName }
func (d *dartAnalyzerConfigCreator) GetToolName() string { return "Dart Analyzer" }
func (d *dartAnalyzerConfigCreator) GetConfigFileName() string {
return constants.DartAnalyzerConfigFileName
}
func (d *dartAnalyzerConfigCreator) GetToolName() string { return "Dart Analyzer" }

// semgrepConfigCreator implements ToolConfigCreator for Semgrep
type semgrepConfigCreator struct{}
Expand All @@ -150,14 +141,14 @@ func (s *semgrepConfigCreator) CreateConfig(toolsConfigDir string, patterns []do
if err != nil {
return fmt.Errorf("failed to create Semgrep config: %v", err)
}
err = writeConfigFile(filepath.Join(toolsConfigDir, SemgrepConfigFileName), configData)
err = writeConfigFile(filepath.Join(toolsConfigDir, constants.SemgrepConfigFileName), configData)
if err == nil {
fmt.Println("Semgrep configuration created based on Codacy settings")
}
return err
}

func (s *semgrepConfigCreator) GetConfigFileName() string { return SemgrepConfigFileName }
func (s *semgrepConfigCreator) GetConfigFileName() string { return constants.SemgrepConfigFileName }
func (s *semgrepConfigCreator) GetToolName() string { return "Semgrep" }

// lizardConfigCreator implements ToolConfigCreator for Lizard
Expand Down Expand Up @@ -220,11 +211,11 @@ func CreateLanguagesConfigFileLocal(toolsConfigDir string) error {
languages: [Multiple]
extensions: []`

return writeConfigFile(filepath.Join(toolsConfigDir, LanguagesConfigFileName), []byte(content))
return writeConfigFile(filepath.Join(toolsConfigDir, constants.LanguagesConfigFileName), []byte(content))
}

func CreateGitIgnoreFile() error {
gitIgnorePath := filepath.Join(config.Config.LocalCodacyDirectory(), GitIgnoreFileName)
gitIgnorePath := filepath.Join(config.Config.LocalCodacyDirectory(), constants.GitIgnoreFileName)
content := "# Codacy CLI\ntools-configs/\n.gitignore\ncli-config.yaml\nlogs/\n"
return writeConfigFile(gitIgnorePath, []byte(content))
}
Expand Down
30 changes: 30 additions & 0 deletions constants/tool_configs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package constants

Check notice on line 1 in constants/tool_configs.go

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

constants/tool_configs.go#L1

should have a package comment

// Tool configuration file names - shared constants to avoid duplication
const (
// Language and project configuration files
LanguagesConfigFileName = "languages-config.yaml"
GitIgnoreFileName = ".gitignore"

// Tool-specific configuration files
ESLintConfigFileName = "eslint.config.mjs"
TrivyConfigFileName = "trivy.yaml"
PMDConfigFileName = "ruleset.xml"
PylintConfigFileName = "pylint.rc"
DartAnalyzerConfigFileName = "analysis_options.yaml"
SemgrepConfigFileName = "semgrep.yaml"
ReviveConfigFileName = "revive.toml"
LizardConfigFileName = "lizard.yaml"
)

// ToolConfigFileNames maps tool names to their configuration filenames
var ToolConfigFileNames = map[string]string{
"eslint": ESLintConfigFileName,
"trivy": TrivyConfigFileName,
"pmd": PMDConfigFileName,
"pylint": PylintConfigFileName,
"dartanalyzer": DartAnalyzerConfigFileName,
"semgrep": SemgrepConfigFileName,
"revive": ReviveConfigFileName,
"lizard": LizardConfigFileName,
}