@@ -14,6 +14,7 @@ import (
1414 "net/http"
1515 "os"
1616 "path/filepath"
17+ "strings"
1718 "time"
1819
1920 "github.com/spf13/cobra"
@@ -130,35 +131,83 @@ func createConfigurationFiles(tools []tools.Tool, cliLocalMode bool) error {
130131}
131132
132133func configFileTemplate (tools []tools.Tool ) string {
134+ // Maps to track which tools are enabled
135+ toolsMap := make (map [string ]bool )
136+ toolVersions := make (map [string ]string )
137+
138+ // Track needed runtimes
139+ needsNode := false
140+ needsPython := false
133141
134142 // Default versions
135- eslintVersion := "9.3.0"
136- trivyVersion := "0.59.1" // Latest stable version
137- pylintVersion := "3.3.6"
138- pmdVersion := "6.55.0"
143+ defaultVersions := map [string ]string {
144+ ESLint : "9.3.0" ,
145+ Trivy : "0.59.1" ,
146+ PyLint : "3.3.6" ,
147+ PMD : "6.55.0" ,
148+ }
139149
150+ // Build map of enabled tools with their versions
140151 for _ , tool := range tools {
141- switch tool .Uuid {
142- case ESLint :
143- eslintVersion = tool .Version
144- case Trivy :
145- trivyVersion = tool .Version
146- case PyLint :
147- pylintVersion = tool .Version
148- case PMD :
149- pmdVersion = tool .Version
152+ toolsMap [tool .Uuid ] = true
153+ if tool .Version != "" {
154+ toolVersions [tool .Uuid ] = tool .Version
155+ } else {
156+ toolVersions [tool .Uuid ] = defaultVersions [tool .Uuid ]
157+ }
158+
159+ // Check if tool needs a runtime
160+ if tool .Uuid == ESLint {
161+ needsNode = true
162+ } else if tool .Uuid == PyLint {
163+ needsPython = true
164+ }
165+ }
166+
167+ // Start building the YAML content
168+ var sb strings.Builder
169+ sb .WriteString ("runtimes:\n " )
170+
171+ // Only include runtimes needed by the enabled tools
172+ if len (tools ) > 0 {
173+ if needsNode {
174+ sb .
WriteString (
" - [email protected] \n " )
175+ }
176+ if needsPython {
177+ sb .
WriteString (
" - [email protected] \n " )
178+ }
179+ } else {
180+ // In local mode with no tools specified, include all runtimes
181+ sb .
WriteString (
" - [email protected] \n " )
182+ sb .
WriteString (
" - [email protected] \n " )
183+ }
184+
185+ sb .WriteString ("tools:\n " )
186+
187+ // If we have tools from the API (enabled tools), use only those
188+ if len (tools ) > 0 {
189+ // Add only the tools that are in the API response (enabled tools)
190+ uuidToName := map [string ]string {
191+ ESLint : "eslint" ,
192+ Trivy : "trivy" ,
193+ PyLint : "pylint" ,
194+ PMD : "pmd" ,
195+ }
196+
197+ for uuid , name := range uuidToName {
198+ if toolsMap [uuid ] {
199+ sb .WriteString (fmt .Sprintf (" - %s@%s\n " , name , toolVersions [uuid ]))
200+ }
150201 }
202+ } else {
203+ // If no tools were specified (local mode), include all defaults
204+ sb .WriteString (fmt .Sprintf (" - eslint@%s\n " , defaultVersions [ESLint ]))
205+ sb .WriteString (fmt .Sprintf (" - trivy@%s\n " , defaultVersions [Trivy ]))
206+ sb .WriteString (fmt .Sprintf (" - pylint@%s\n " , defaultVersions [PyLint ]))
207+ sb .WriteString (fmt .Sprintf (" - pmd@%s\n " , defaultVersions [PMD ]))
151208 }
152209
153- return fmt .Sprintf (`runtimes:
154- 155- 156- tools:
157- - eslint@%s
158- - trivy@%s
159- - pylint@%s
160- - pmd@%s
161- ` , eslintVersion , trivyVersion , pylintVersion , pmdVersion )
210+ return sb .String ()
162211}
163212
164213func cliConfigFileTemplate (cliLocalMode bool ) string {
@@ -183,6 +232,11 @@ func buildRepositoryConfigurationFiles(token string) error {
183232 return fmt .Errorf ("failed to create tools-configs directory: %w" , err )
184233 }
185234
235+ // Clear any previous configuration files
236+ if err := cleanConfigDirectory (toolsConfigDir ); err != nil {
237+ return fmt .Errorf ("failed to clean configuration directory: %w" , err )
238+ }
239+
186240 client := & http.Client {
187241 Timeout : 10 * time .Second ,
188242 }
@@ -192,12 +246,17 @@ func buildRepositoryConfigurationFiles(token string) error {
192246 return err
193247 }
194248
195- err = createConfigurationFiles (apiTools , true )
249+ // Filter out any tools that use configuration file
250+ configuredToolsWithUI := tools .FilterToolsByConfigUsage (apiTools )
251+
252+ // Create main config files with all enabled API tools
253+ err = createConfigurationFiles (apiTools , false )
196254 if err != nil {
197255 log .Fatal (err )
198256 }
199257
200- for _ , tool := range apiTools {
258+ // Only generate config files for tools not using their own config file
259+ for _ , tool := range configuredToolsWithUI {
201260 url := fmt .Sprintf ("%s/api/v3/analysis/organizations/%s/%s/repositories/%s/tools/%s/patterns?enabled=true" ,
202261 CodacyApiBase ,
203262 initFlags .provider ,
@@ -375,6 +434,33 @@ func createDefaultEslintConfigFile(toolsConfigDir string) error {
375434 return os .WriteFile (filepath .Join (toolsConfigDir , "eslint.config.mjs" ), []byte (content ), utils .DefaultFilePerms )
376435}
377436
437+ // cleanConfigDirectory removes all previous configuration files in the tools-configs directory
438+ func cleanConfigDirectory (toolsConfigDir string ) error {
439+ // Check if directory exists
440+ if _ , err := os .Stat (toolsConfigDir ); os .IsNotExist (err ) {
441+ return nil // Directory doesn't exist, nothing to clean
442+ }
443+
444+ // Read directory contents
445+ entries , err := os .ReadDir (toolsConfigDir )
446+ if err != nil {
447+ return fmt .Errorf ("failed to read config directory: %w" , err )
448+ }
449+
450+ // Remove all files
451+ for _ , entry := range entries {
452+ if ! entry .IsDir () { // Only remove files, not subdirectories
453+ filePath := filepath .Join (toolsConfigDir , entry .Name ())
454+ if err := os .Remove (filePath ); err != nil {
455+ return fmt .Errorf ("failed to remove file %s: %w" , filePath , err )
456+ }
457+ }
458+ }
459+
460+ fmt .Println ("Cleaned previous configuration files" )
461+ return nil
462+ }
463+
378464const (
379465 ESLint string = "f8b29663-2cb2-498d-b923-a10c6a8c05cd"
380466 Trivy string = "2fd7fbe0-33f9-4ab3-ab73-e9b62404e2cb"
0 commit comments