Skip to content

Commit 06bb49b

Browse files
authored
fix: fix Lizard analysis run and configuration creation CF-1999 (#178)
* fix: fix Lizard runner * fix: refactor setup and fix Lizard remote init * remove commented code * fix copilot comments * fix build errors * fix config creation when parameters are not set * fix Codacy issues * fix indentation
1 parent fd2d067 commit 06bb49b

File tree

8 files changed

+909
-818
lines changed

8 files changed

+909
-818
lines changed

cmd/configsetup/codacy_yaml.go

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
// Package configsetup provides helpers to create Codacy configuration
2+
// files (codacy.yaml and related tool/runtime sections).
3+
package configsetup
4+
5+
import (
6+
"fmt"
7+
"log"
8+
"sort"
9+
"strings"
10+
11+
"codacy/cli-v2/domain"
12+
"codacy/cli-v2/plugins"
13+
)
14+
15+
// RuntimePluginConfig holds the structure of the runtime plugin.yaml file
16+
type RuntimePluginConfig struct {
17+
Name string `yaml:"name"`
18+
Description string `yaml:"description"`
19+
DefaultVersion string `yaml:"default_version"`
20+
}
21+
22+
// ConfigFileTemplate returns the content of codacy.yaml given the enabled
23+
// tools. It lists required runtimes and tools with their versions.
24+
func ConfigFileTemplate(tools []domain.Tool) string {
25+
toolsMap := make(map[string]bool)
26+
toolVersions := make(map[string]string)
27+
neededRuntimes := make(map[string]bool)
28+
29+
toolsWithLatestVersion, _, _ := KeepToolsWithLatestVersion(tools)
30+
31+
// Get versions and runtime dependencies
32+
defaultVersions := plugins.GetToolVersions()
33+
runtimeVersions := plugins.GetRuntimeVersions()
34+
runtimeDependencies := plugins.GetToolRuntimeDependencies()
35+
36+
// Process enabled tools
37+
for _, tool := range toolsWithLatestVersion {
38+
toolsMap[tool.Uuid] = true
39+
toolVersions[tool.Uuid] = getToolVersion(tool, defaultVersions)
40+
addRequiredRuntime(tool.Uuid, neededRuntimes, runtimeDependencies)
41+
}
42+
43+
var sb strings.Builder
44+
45+
// Build runtimes section
46+
buildRuntimesSection(&sb, tools, neededRuntimes, runtimeVersions, runtimeDependencies)
47+
48+
// Build tools section
49+
buildToolsSection(&sb, tools, toolsMap, toolVersions, defaultVersions)
50+
51+
return sb.String()
52+
}
53+
54+
// getToolVersion returns the version for a tool, preferring tool.Version over default.
55+
func getToolVersion(tool domain.Tool, defaultVersions map[string]string) string {
56+
if tool.Version != "" {
57+
return tool.Version
58+
}
59+
if meta, ok := domain.SupportedToolsMetadata[tool.Uuid]; ok {
60+
if defaultVersion, ok := defaultVersions[meta.Name]; ok {
61+
return defaultVersion
62+
}
63+
}
64+
return ""
65+
}
66+
67+
// addRequiredRuntime adds the runtime requirement for a tool.
68+
func addRequiredRuntime(toolUUID string, neededRuntimes map[string]bool, runtimeDependencies map[string]string) {
69+
if meta, ok := domain.SupportedToolsMetadata[toolUUID]; ok {
70+
if runtime, ok := runtimeDependencies[meta.Name]; ok {
71+
if meta.Name == "dartanalyzer" {
72+
// For dartanalyzer, default to dart runtime
73+
neededRuntimes["dart"] = true
74+
} else {
75+
neededRuntimes[runtime] = true
76+
}
77+
}
78+
}
79+
}
80+
81+
// buildRuntimesSection builds the runtimes section of the configuration.
82+
func buildRuntimesSection(sb *strings.Builder, tools []domain.Tool, neededRuntimes map[string]bool, runtimeVersions map[string]string, runtimeDependencies map[string]string) {
83+
sb.WriteString("runtimes:\n")
84+
85+
if len(tools) == 0 {
86+
// In local mode with no tools specified, include all necessary runtimes
87+
addAllSupportedRuntimes(neededRuntimes, runtimeDependencies)
88+
}
89+
90+
writeRuntimesList(sb, neededRuntimes, runtimeVersions)
91+
}
92+
93+
// addAllSupportedRuntimes adds all runtimes needed by supported tools.
94+
func addAllSupportedRuntimes(neededRuntimes map[string]bool, runtimeDependencies map[string]string) {
95+
supportedTools, err := plugins.GetSupportedTools()
96+
if err != nil {
97+
log.Printf("Warning: failed to get supported tools: %v", err)
98+
return
99+
}
100+
101+
for toolName := range supportedTools {
102+
if runtime, ok := runtimeDependencies[toolName]; ok {
103+
if toolName == "dartanalyzer" {
104+
neededRuntimes["dart"] = true
105+
} else {
106+
neededRuntimes[runtime] = true
107+
}
108+
}
109+
}
110+
}
111+
112+
// writeRuntimesList writes the sorted runtimes list to the string builder.
113+
func writeRuntimesList(sb *strings.Builder, neededRuntimes map[string]bool, runtimeVersions map[string]string) {
114+
var sortedRuntimes []string
115+
for runtime := range neededRuntimes {
116+
sortedRuntimes = append(sortedRuntimes, runtime)
117+
}
118+
sort.Strings(sortedRuntimes)
119+
120+
for _, runtime := range sortedRuntimes {
121+
sb.WriteString(fmt.Sprintf(" - %s@%s\n", runtime, runtimeVersions[runtime]))
122+
}
123+
}
124+
125+
// buildToolsSection builds the tools section of the configuration.
126+
func buildToolsSection(sb *strings.Builder, tools []domain.Tool, toolsMap map[string]bool, toolVersions map[string]string, defaultVersions map[string]string) {
127+
sb.WriteString("tools:\n")
128+
129+
if len(tools) > 0 {
130+
writeEnabledTools(sb, toolsMap, toolVersions)
131+
} else {
132+
writeAllSupportedTools(sb, defaultVersions)
133+
}
134+
}
135+
136+
// writeEnabledTools writes the enabled tools to the string builder.
137+
func writeEnabledTools(sb *strings.Builder, toolsMap map[string]bool, toolVersions map[string]string) {
138+
var sortedTools []string
139+
for uuid, meta := range domain.SupportedToolsMetadata {
140+
if toolsMap[uuid] {
141+
sortedTools = append(sortedTools, meta.Name)
142+
}
143+
}
144+
sort.Strings(sortedTools)
145+
146+
for _, name := range sortedTools {
147+
for uuid, meta := range domain.SupportedToolsMetadata {
148+
if meta.Name == name && toolsMap[uuid] {
149+
version := toolVersions[uuid]
150+
sb.WriteString(fmt.Sprintf(" - %s@%s\n", name, version))
151+
break
152+
}
153+
}
154+
}
155+
}
156+
157+
// writeAllSupportedTools writes all supported tools to the string builder.
158+
func writeAllSupportedTools(sb *strings.Builder, defaultVersions map[string]string) {
159+
supportedTools, err := plugins.GetSupportedTools()
160+
if err != nil {
161+
log.Printf("Warning: failed to get supported tools: %v", err)
162+
return
163+
}
164+
165+
var sortedTools []string
166+
for toolName := range supportedTools {
167+
if version, ok := defaultVersions[toolName]; ok && version != "" {
168+
sortedTools = append(sortedTools, toolName)
169+
}
170+
}
171+
sort.Strings(sortedTools)
172+
173+
for _, toolName := range sortedTools {
174+
if version, ok := defaultVersions[toolName]; ok {
175+
sb.WriteString(fmt.Sprintf(" - %s@%s\n", toolName, version))
176+
}
177+
}
178+
}

cmd/configsetup/config_creators.go

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
// Package configsetup provides helpers to create Codacy configuration
2+
// and helper files locally.
3+
package configsetup
4+
5+
import (
6+
"fmt"
7+
"path/filepath"
8+
9+
"codacy/cli-v2/config"
10+
"codacy/cli-v2/constants"
11+
"codacy/cli-v2/domain"
12+
"codacy/cli-v2/tools"
13+
14+
"gopkg.in/yaml.v3"
15+
)
16+
17+
// CreateLanguagesConfigFileLocal writes the languages configuration file to
18+
// the provided directory using data from the Codacy API.
19+
func CreateLanguagesConfigFileLocal(toolsConfigDir string) error {
20+
// Build tool language configurations from API
21+
configTools, err := tools.BuildLanguagesConfigFromAPI()
22+
if err != nil {
23+
return fmt.Errorf("failed to build languages config from API: %w", err)
24+
}
25+
26+
// Create the config structure
27+
config := domain.LanguagesConfig{
28+
Tools: configTools,
29+
}
30+
31+
// Marshal to YAML
32+
data, err := yaml.Marshal(config)
33+
if err != nil {
34+
return fmt.Errorf("failed to marshal languages config to YAML: %w", err)
35+
}
36+
37+
return writeConfigFile(filepath.Join(toolsConfigDir, constants.LanguagesConfigFileName), data)
38+
}
39+
40+
// CreateGitIgnoreFile creates a default .gitignore in the local Codacy
41+
// directory to avoid committing generated files.
42+
func CreateGitIgnoreFile() error {
43+
gitIgnorePath := filepath.Join(config.Config.LocalCodacyDirectory(), constants.GitIgnoreFileName)
44+
content := "# Codacy CLI\ntools-configs/\n.gitignore\ncli-config.yaml\nlogs/\n"
45+
return writeConfigFile(gitIgnorePath, []byte(content))
46+
}
47+
48+
// CreateConfigurationFiles generates project configuration files
49+
// (codacy.yaml and cli-config.yaml).
50+
func CreateConfigurationFiles(tools []domain.Tool, cliLocalMode bool, flags domain.InitFlags) error {
51+
// Create project config file
52+
configContent := ConfigFileTemplate(tools)
53+
if err := writeConfigFile(config.Config.ProjectConfigFile(), []byte(configContent)); err != nil {
54+
return fmt.Errorf("failed to write project config file: %w", err)
55+
}
56+
57+
// Create CLI config file
58+
cliConfigContent := buildCliConfigContent(cliLocalMode, flags)
59+
if err := writeConfigFile(config.Config.CliConfigFile(), []byte(cliConfigContent)); err != nil {
60+
return fmt.Errorf("failed to write CLI config file: %w", err)
61+
}
62+
63+
return nil
64+
}
65+
66+
// buildCliConfigContent creates the CLI configuration content.
67+
func buildCliConfigContent(cliLocalMode bool, initFlags domain.InitFlags) string {
68+
if cliLocalMode {
69+
return fmt.Sprintf("mode: local")
70+
}
71+
return fmt.Sprintf("mode: remote\nprovider: %s\norganization: %s\nrepository: %s", initFlags.Provider, initFlags.Organization, initFlags.Repository)
72+
}

0 commit comments

Comments
 (0)