55 "log"
66 "os"
77 "path/filepath"
8+ "strings"
89
910 "codacy/cli-v2/plugins"
1011 "codacy/cli-v2/utils"
@@ -68,6 +69,84 @@ func (c *ConfigType) Runtimes() map[string]*plugins.RuntimeInfo {
6869 return c .runtimes
6970}
7071
72+ // loadConfigOrInitializeEmpty reads the existing YAML config or returns an empty configuration if the file doesn't exist
73+ func (c * ConfigType ) loadConfigOrInitializeEmpty (codacyPath string ) (map [string ]interface {}, error ) {
74+ content , err := os .ReadFile (codacyPath )
75+ if err != nil && ! os .IsNotExist (err ) {
76+ return nil , fmt .Errorf ("error reading codacy.yaml: %w" , err )
77+ }
78+
79+ var config map [string ]interface {}
80+ if len (content ) > 0 {
81+ if err := yaml .Unmarshal (content , & config ); err != nil {
82+ return nil , fmt .Errorf ("error parsing codacy.yaml: %w" , err )
83+ }
84+ } else {
85+ config = make (map [string ]interface {})
86+ }
87+
88+ return config , nil
89+ }
90+
91+ // updateRuntimesList updates or adds a runtime entry in the runtimes list
92+ func updateRuntimesList (runtimes []interface {}, name , version string ) []interface {} {
93+ runtimeEntry := fmt .Sprintf ("%s@%s" , name , version )
94+
95+ // Check if runtime already exists and update it
96+ for i , r := range runtimes {
97+ if runtime , ok := r .(string ); ok {
98+ if strings .Split (runtime , "@" )[0 ] == name {
99+ runtimes [i ] = runtimeEntry
100+ return runtimes
101+ }
102+ }
103+ }
104+
105+ // Add new runtime if not found
106+ return append (runtimes , runtimeEntry )
107+ }
108+
109+ // writeConfig writes the config back to the YAML file
110+ func (c * ConfigType ) writeConfig (codacyPath string , config map [string ]interface {}) error {
111+ yamlData , err := yaml .Marshal (config )
112+ if err != nil {
113+ return fmt .Errorf ("error marshaling codacy.yaml: %w" , err )
114+ }
115+
116+ // Ensure directory exists
117+ if err := os .MkdirAll (filepath .Dir (codacyPath ), utils .DefaultDirPerms ); err != nil {
118+ return fmt .Errorf ("error creating .codacy directory: %w" , err )
119+ }
120+
121+ if err := os .WriteFile (codacyPath , yamlData , utils .DefaultFilePerms ); err != nil {
122+ return fmt .Errorf ("error writing codacy.yaml: %w" , err )
123+ }
124+
125+ return nil
126+ }
127+
128+ // addRuntimeToCodacyYaml adds or updates a runtime entry in codacy.yaml as a YAML list
129+ func (c * ConfigType ) addRuntimeToCodacyYaml (name string , version string ) error {
130+ codacyPath := filepath .Join (c .localCodacyDirectory , "codacy.yaml" )
131+
132+ config , err := c .loadConfigOrInitializeEmpty (codacyPath )
133+ if err != nil {
134+ return err
135+ }
136+
137+ // Get or create runtimes list
138+ runtimes , ok := config ["runtimes" ].([]interface {})
139+ if ! ok {
140+ runtimes = make ([]interface {}, 0 )
141+ }
142+
143+ // Update runtimes list
144+ runtimes = updateRuntimesList (runtimes , name , version )
145+ config ["runtimes" ] = runtimes
146+
147+ return c .writeConfig (codacyPath , config )
148+ }
149+
71150func (c * ConfigType ) AddRuntimes (configs []plugins.RuntimeConfig ) error {
72151 // Process the runtime configurations using the plugins.ProcessRuntimes function
73152 runtimeInfoMap , err := plugins .ProcessRuntimes (configs , c .runtimesDirectory )
@@ -78,6 +157,11 @@ func (c *ConfigType) AddRuntimes(configs []plugins.RuntimeConfig) error {
78157 // Store the runtime information in the config
79158 for name , info := range runtimeInfoMap {
80159 c .runtimes [name ] = info
160+
161+ // Update codacy.yaml with the new runtime
162+ if err := c .addRuntimeToCodacyYaml (name , info .Version ); err != nil {
163+ return fmt .Errorf ("failed to update codacy.yaml with runtime %s: %w" , name , err )
164+ }
81165 }
82166
83167 return nil
@@ -88,7 +172,58 @@ func (c *ConfigType) Tools() map[string]*plugins.ToolInfo {
88172}
89173
90174func (c * ConfigType ) AddTools (configs []plugins.ToolConfig ) error {
91- // Process the tool configurations using the plugins.ProcessTools function
175+ // Get the plugin manager to access tool configurations
176+ pluginManager := plugins .GetPluginManager ()
177+
178+ // Ensure all required runtimes are present before processing tools
179+ for _ , toolConfig := range configs {
180+ // Get the tool's plugin configuration to access runtime info
181+ pluginConfig , err := pluginManager .GetToolConfig (toolConfig .Name )
182+ if err != nil {
183+ return fmt .Errorf ("failed to get plugin config for tool %s: %w" , toolConfig .Name , err )
184+ }
185+
186+ if pluginConfig .Runtime != "" {
187+ // Special handling for dartanalyzer - check for existing dart or flutter runtimes
188+ if toolConfig .Name == "dartanalyzer" {
189+ // Check if either dart or flutter runtime is already available
190+ if runtimeInfo := c .runtimes ["flutter" ]; runtimeInfo != nil {
191+ // Flutter runtime exists, use it
192+ continue
193+ }
194+ if runtimeInfo := c .runtimes ["dart" ]; runtimeInfo != nil {
195+ // Dart runtime exists, use it
196+ continue
197+ }
198+ // Neither runtime exists, proceed with installing dart runtime
199+ pluginConfig .Runtime = "dart"
200+ }
201+
202+ runtimeInfo := c .runtimes [pluginConfig .Runtime ]
203+ if runtimeInfo == nil {
204+ // Get the default version for the runtime
205+ defaultVersions := plugins .GetRuntimeVersions ()
206+ version , ok := defaultVersions [pluginConfig .Runtime ]
207+ if ! ok {
208+ return fmt .Errorf ("no default version found for runtime %s" , pluginConfig .Runtime )
209+ }
210+
211+ // Add the runtime to the config
212+ fmt .Println ("Adding missing runtime to codacy.yaml" , pluginConfig .Runtime , version )
213+ if err := c .AddRuntimes ([]plugins.RuntimeConfig {{Name : pluginConfig .Runtime , Version : version }}); err != nil {
214+ return fmt .Errorf ("failed to add runtime %s: %w" , pluginConfig .Runtime , err )
215+ }
216+
217+ // Fetch the runtimeInfo again
218+ runtimeInfo = c .runtimes [pluginConfig .Runtime ]
219+ if runtimeInfo == nil {
220+ return fmt .Errorf ("runtime %s still missing after adding to config" , pluginConfig .Runtime )
221+ }
222+ }
223+ }
224+ }
225+
226+ // Now safe to process tools
92227 toolInfoMap , err := plugins .ProcessTools (configs , c .toolsDirectory , c .runtimes )
93228 if err != nil {
94229 return err
0 commit comments