55 "log"
66 "os"
77 "path/filepath"
8- "slices"
98 "sort"
109 "strings"
1110
@@ -186,17 +185,17 @@ var configDiscoverCmd = &cobra.Command{
186185 }
187186 }
188187
189- detectedLanguages , err := config .DetectLanguages (discoverPath , defaultToolLangMap )
188+ detectedTools , err := config .DetectRelevantTools (discoverPath , defaultToolLangMap )
190189 if err != nil {
191- log .Fatalf ("Error detecting languages : %v" , err )
190+ log .Fatalf ("Error detecting relevant tools : %v" , err )
192191 }
193- if len (detectedLanguages ) == 0 {
194- fmt .Println ("No known languages detected in the provided path." )
192+ if len (detectedTools ) == 0 {
193+ fmt .Println ("No relevant tools found for the file extensions in the provided path." )
195194 return
196195 }
197196
198197 toolsConfigDir := config .Config .ToolsConfigsDirectory ()
199- if err := updateLanguagesConfig ( detectedLanguages , toolsConfigDir , defaultToolLangMap ); err != nil {
198+ if err := updateLanguagesConfigForTools ( detectedTools , toolsConfigDir , defaultToolLangMap ); err != nil {
200199 log .Fatalf ("Error updating .codacy/tools-configs/languages-config.yaml: %v" , err )
201200 }
202201 fmt .Println ("Updated .codacy/tools-configs/languages-config.yaml" )
@@ -209,7 +208,8 @@ var configDiscoverCmd = &cobra.Command{
209208 }
210209
211210 codacyYAMLPath := config .Config .ProjectConfigFile ()
212- if err := updateCodacyYAML (detectedLanguages , codacyYAMLPath , defaultToolLangMap , configResetInitFlags , currentCliMode ); err != nil {
211+
212+ if err := updateCodacyYAMLForTools (detectedTools , codacyYAMLPath , configResetInitFlags , currentCliMode ); err != nil {
213213 if strings .Contains (err .Error (), "❌ Fatal:" ) {
214214 fmt .Println (err )
215215 os .Exit (1 )
@@ -218,21 +218,10 @@ var configDiscoverCmd = &cobra.Command{
218218 }
219219 fmt .Printf ("Updated %s with relevant tools.\n " , filepath .Base (codacyYAMLPath ))
220220
221- // Determine which tools are relevant for discovered languages and create their configurations
222- discoveredToolNames := make (map [string ]struct {})
223- for toolName , toolInfo := range defaultToolLangMap {
224- for _ , toolLang := range toolInfo .Languages {
225- if _ , detected := detectedLanguages [toolLang ]; detected {
226- discoveredToolNames [toolName ] = struct {}{}
227- break
228- }
229- }
230- }
231-
232221 // Create tool configuration files for discovered tools
233- if len (discoveredToolNames ) > 0 {
222+ if len (detectedTools ) > 0 {
234223 fmt .Printf ("\n Creating tool configurations for discovered tools...\n " )
235- if err := configsetup .CreateConfigurationFilesForDiscoveredTools (discoveredToolNames , toolsConfigDir , configResetInitFlags ); err != nil {
224+ if err := configsetup .CreateConfigurationFilesForDiscoveredTools (detectedTools , toolsConfigDir , configResetInitFlags ); err != nil {
236225 log .Printf ("Warning: Failed to create some tool configurations: %v" , err )
237226 }
238227 }
@@ -242,83 +231,29 @@ var configDiscoverCmd = &cobra.Command{
242231 },
243232}
244233
245- // updateLanguagesConfig updates the .codacy/tools-configs/languages-config.yaml file.
246- func updateLanguagesConfig ( detectedLanguages map [string ]struct {}, toolsConfigDir string , defaultToolLangMap map [string ]domain.ToolLanguageInfo ) error {
234+ // updateLanguagesConfigForTools updates the .codacy/tools-configs/languages-config.yaml file based on detected tools .
235+ func updateLanguagesConfigForTools ( detectedTools map [string ]struct {}, toolsConfigDir string , defaultToolLangMap map [string ]domain.ToolLanguageInfo ) error {
247236 langConfigPath := filepath .Join (toolsConfigDir , "languages-config.yaml" )
248- var langConf domain.LanguagesConfig
249237
250- if _ , err := os .Stat (langConfigPath ); err == nil {
251- data , err := os .ReadFile (langConfigPath )
252- if err != nil {
253- return fmt .Errorf ("failed to read existing languages-config.yaml: %w" , err )
254- }
255- if err := yaml .Unmarshal (data , & langConf ); err != nil {
238+ // Read existing languages config if it exists
239+ var langConf domain.LanguagesConfig
240+ if content , err := os .ReadFile (langConfigPath ); err == nil {
241+ if err := yaml .Unmarshal (content , & langConf ); err != nil {
256242 return fmt .Errorf ("failed to parse existing languages-config.yaml: %w" , err )
257243 }
258- } else if ! os .IsNotExist (err ) {
259- return fmt .Errorf ("failed to stat languages-config.yaml: %w" , err )
260244 }
261245
262- // Create a map of existing tools for easier update
263- existingToolsMap := make (map [string ]* domain.ToolLanguageInfo )
264- for i := range langConf .Tools {
265- existingToolsMap [ langConf . Tools [ i ]. Name ] = & langConf . Tools [ i ]
246+ // Create a map of existing tools for quick lookup
247+ existingTools := make (map [string ]domain.ToolLanguageInfo )
248+ for _ , tool := range langConf .Tools {
249+ existingTools [ tool . Name ] = tool
266250 }
267251
268- for toolName , toolInfoFromDefaults := range defaultToolLangMap {
269- isRelevantTool := false
270- relevantLangsForThisTool := []string {}
271- relevantExtsForThisToolMap := make (map [string ]struct {})
272-
273- for _ , langDefault := range toolInfoFromDefaults .Languages {
274- if _ , isDetected := detectedLanguages [langDefault ]; isDetected {
275- isRelevantTool = true
276- if ! slices .Contains (relevantLangsForThisTool , langDefault ) {
277- relevantLangsForThisTool = append (relevantLangsForThisTool , langDefault )
278- }
279- // Add extensions associated with this detected language for this tool
280- for _ , defaultExt := range toolInfoFromDefaults .Extensions {
281- // A simple heuristic: if a tool supports a language, and that language is detected,
282- // all default extensions of that tool for that language group are considered relevant.
283- // This assumes toolInfoFromDefaults.Extensions are relevant for all toolInfoFromDefaults.Languages.
284- // A more precise mapping might be needed if a tool's extensions vary significantly per language it supports.
285- relevantExtsForThisToolMap [defaultExt ] = struct {}{}
286- }
287- }
288- }
289-
290- if isRelevantTool {
291- relevantExtsForThisTool := config .GetSortedKeys (relevantExtsForThisToolMap )
292- sort .Strings (relevantLangsForThisTool )
293-
294- if existingEntry , ok := existingToolsMap [toolName ]; ok {
295- // Merge languages and extensions, keeping them unique and sorted
296- existingLangsSet := make (map [string ]struct {})
297- for _ , lang := range existingEntry .Languages {
298- existingLangsSet [lang ] = struct {}{}
299- }
300- for _ , lang := range relevantLangsForThisTool {
301- existingLangsSet [lang ] = struct {}{}
302- }
303- existingEntry .Languages = config .GetSortedKeys (existingLangsSet )
304-
305- existingExtsSet := make (map [string ]struct {})
306- for _ , ext := range existingEntry .Extensions {
307- existingExtsSet [ext ] = struct {}{}
308- }
309- for _ , ext := range relevantExtsForThisTool {
310- existingExtsSet [ext ] = struct {}{}
311- }
312- existingEntry .Extensions = config .GetSortedKeys (existingExtsSet )
313-
314- } else {
315- newEntry := domain.ToolLanguageInfo {
316- Name : toolName ,
317- Languages : relevantLangsForThisTool ,
318- Extensions : relevantExtsForThisTool ,
319- }
320- langConf .Tools = append (langConf .Tools , newEntry )
321- existingToolsMap [toolName ] = & langConf .Tools [len (langConf .Tools )- 1 ] // update map with pointer to new entry
252+ // Add detected tools that are not already present
253+ for toolName := range detectedTools {
254+ if _ , alreadyExists := existingTools [toolName ]; ! alreadyExists {
255+ if toolInfo , exists := defaultToolLangMap [toolName ]; exists {
256+ langConf .Tools = append (langConf .Tools , toolInfo )
322257 }
323258 }
324259 }
@@ -338,8 +273,9 @@ func updateLanguagesConfig(detectedLanguages map[string]struct{}, toolsConfigDir
338273 return os .WriteFile (langConfigPath , data , utils .DefaultFilePerms )
339274}
340275
341- // updateCodacyYAML updates the codacy.yaml file with newly relevant tools.
342- func updateCodacyYAML (detectedLanguages map [string ]struct {}, codacyYAMLPath string , defaultToolLangMap map [string ]domain.ToolLanguageInfo , initFlags domain.InitFlags , cliMode string ) error {
276+ // updateCodacyYAMLForTools updates the codacy.yaml file with detected tools.
277+ func updateCodacyYAMLForTools (detectedTools map [string ]struct {}, codacyYAMLPath string , initFlags domain.InitFlags , cliMode string ) error {
278+
343279 var configData map [string ]interface {}
344280
345281 // Read and parse codacy.yaml (validation is done globally in PersistentPreRun)
@@ -368,15 +304,7 @@ func updateCodacyYAML(detectedLanguages map[string]struct{}, codacyYAMLPath stri
368304 }
369305 }
370306
371- candidateToolsToAdd := make (map [string ]struct {}) // tool names like "eslint"
372- for toolName , toolInfo := range defaultToolLangMap {
373- for _ , lang := range toolInfo .Languages {
374- if _ , detected := detectedLanguages [lang ]; detected {
375- candidateToolsToAdd [toolName ] = struct {}{}
376- break
377- }
378- }
379- }
307+ candidateToolsToAdd := detectedTools
380308
381309 if cliMode == "remote" && initFlags .ApiToken != "" {
382310 fmt .Println ("Cloud mode: Verifying tools against repository settings..." )
@@ -411,9 +339,12 @@ func updateCodacyYAML(detectedLanguages map[string]struct{}, codacyYAMLPath stri
411339 }
412340
413341 defaultToolVersions := plugins .GetToolVersions ()
414- finalToolsList := currentToolsList // Start with existing tools
415342
343+ // Discover mode: preserve existing tools and add only new discovered ones
344+ finalToolsList := currentToolsList // Start with existing tools
416345 addedNewTool := false
346+
347+ // Add only newly discovered tools that aren't already configured
417348 for toolNameToAdd := range candidateToolsToAdd {
418349 if _ , alreadyConfigured := currentToolSetByName [toolNameToAdd ]; ! alreadyConfigured {
419350 version , ok := defaultToolVersions [toolNameToAdd ]
@@ -502,6 +433,7 @@ func updateCodacyYAML(detectedLanguages map[string]struct{}, codacyYAMLPath stri
502433 if err := os .MkdirAll (filepath .Dir (codacyYAMLPath ), utils .DefaultDirPerms ); err != nil {
503434 return fmt .Errorf ("error creating .codacy directory: %w" , err )
504435 }
436+
505437 return os .WriteFile (codacyYAMLPath , yamlData , utils .DefaultFilePerms )
506438}
507439
0 commit comments