@@ -26,16 +26,17 @@ type binary struct {
2626type pluginConfig struct {
2727 Name string `yaml:"name"`
2828 Description string `yaml:"description"`
29- Download downloadConfig `yaml:"download"`
29+ Downloads []downloadConfig `yaml:"downloads"`
30+ ArchMapping map [string ]string `yaml:"arch_mapping"`
3031 Binaries []binary `yaml:"binaries"`
3132}
3233
3334// downloadConfig holds the download configuration from the plugin.yaml
3435type downloadConfig struct {
35- URLTemplate string `yaml:"url_template "`
36- FileNameTemplate string `yaml:"file_name_template "`
37- Extension extensionConfig `yaml:"extension "`
38- ArchMapping map [ string ] string `yaml:"arch_mapping "`
36+ OS [] string `yaml:"os "`
37+ URLTemplate string `yaml:"url_template "`
38+ FileNameTemplate string `yaml:"file_name_template "`
39+ Extension extensionConfig `yaml:"extension "`
3940}
4041
4142// extensionConfig defines the file extension based on OS
@@ -79,74 +80,92 @@ type RuntimeInfo struct {
7980// ProcessRuntimes processes a list of runtime configurations and returns a map of runtime information
8081func ProcessRuntimes (configs []RuntimeConfig , runtimesDir string ) (map [string ]* RuntimeInfo , error ) {
8182 result := make (map [string ]* RuntimeInfo )
82-
83+
8384 for _ , config := range configs {
8485 runtimeInfo , err := processRuntime (config , runtimesDir )
8586 if err != nil {
8687 return nil , err
8788 }
88-
89+
8990 result [config .Name ] = runtimeInfo
9091 }
91-
92+
9293 return result , nil
9394}
9495
95-
9696// ProcessRuntime processes a single runtime configuration and returns detailed runtime info
9797func processRuntime (config RuntimeConfig , runtimesDir string ) (* RuntimeInfo , error ) {
9898 plugin , err := loadPlugin (config .Name )
9999 if err != nil {
100100 return nil , fmt .Errorf ("failed to load plugin for runtime %s: %w" , config .Name , err )
101101 }
102-
103- fileName := plugin .getFileName (config .Version )
104- extension := plugin .getExtension (runtime .GOOS )
102+
103+ // Find the appropriate OS-specific download configuration
104+ var download downloadConfig
105+ found := false
106+ for _ , d := range plugin .Config .Downloads {
107+ for _ , os := range d .OS {
108+ if os == runtime .GOOS {
109+ download = d
110+ found = true
111+ break
112+ }
113+ }
114+ if found {
115+ break
116+ }
117+ }
118+
119+ if ! found {
120+ return nil , fmt .Errorf ("no download configuration found for OS %s in runtime %s" , runtime .GOOS , config .Name )
121+ }
122+
123+ fileName := plugin .getFileName (download , config .Version )
124+ extension := plugin .getExtension (download , runtime .GOOS )
105125 installDir := plugin .getInstallationDirectoryPath (runtimesDir , config .Version )
106-
126+
107127 // Create RuntimeInfo with essential information
108128 info := & RuntimeInfo {
109129 Name : config .Name ,
110130 Version : config .Version ,
111131 InstallDir : installDir ,
112- DownloadURL : plugin .getDownloadURL (config .Version ),
132+ DownloadURL : plugin .getDownloadURL (download , config .Version ),
113133 FileName : fileName ,
114134 Extension : extension ,
115135 Binaries : make (map [string ]string ),
116136 }
117-
137+
118138 // Process binary paths
119139 for _ , binary := range plugin .Config .Binaries {
120140 binaryPath := path .Join (installDir , binary .Path )
121-
141+
122142 // Add file extension for Windows executables
123143 if runtime .GOOS == "windows" && ! strings .HasSuffix (binaryPath , ".exe" ) {
124144 binaryPath += ".exe"
125145 }
126-
146+
127147 info .Binaries [binary .Name ] = binaryPath
128148 }
129-
149+
130150 return info , nil
131151}
132152
133-
134153// LoadPlugin loads a plugin configuration from the specified plugin directory
135154func loadPlugin (runtimeName string ) (* runtimePlugin , error ) {
136155 pluginPath := filepath .Join ("runtimes" , runtimeName , "plugin.yaml" )
137-
156+
138157 // Read from embedded filesystem
139158 data , err := pluginsFS .ReadFile (pluginPath )
140159 if err != nil {
141160 return nil , fmt .Errorf ("error reading plugin.yaml: %w" , err )
142161 }
143-
162+
144163 var config pluginConfig
145164 err = yaml .Unmarshal (data , & config )
146165 if err != nil {
147166 return nil , fmt .Errorf ("error parsing plugin.yaml: %w" , err )
148167 }
149-
168+
150169 return & runtimePlugin {
151170 Config : config ,
152171 ConfigPath : pluginPath ,
@@ -156,65 +175,65 @@ func loadPlugin(runtimeName string) (*runtimePlugin, error) {
156175// GetMappedArch returns the architecture mapping for the current system
157176func (p * runtimePlugin ) getMappedArch (goarch string ) string {
158177 // Check if there's a mapping for this architecture
159- if mappedArch , ok := p .Config .Download . ArchMapping [goarch ]; ok {
178+ if mappedArch , ok := p .Config .ArchMapping [goarch ]; ok {
160179 return mappedArch
161180 }
162181 // Return the original architecture if no mapping exists
163182 return goarch
164183}
165184
166185// GetExtension returns the appropriate file extension based on the OS
167- func (p * runtimePlugin ) getExtension (goos string ) string {
186+ func (p * runtimePlugin ) getExtension (download downloadConfig , goos string ) string {
168187 if goos == "windows" {
169- return p . Config . Download .Extension .Windows
188+ return download .Extension .Windows
170189 }
171- return p . Config . Download .Extension .Default
190+ return download .Extension .Default
172191}
173192
174193// GetFileName generates the filename based on the template in plugin.yaml
175- func (p * runtimePlugin ) getFileName (version string ) string {
194+ func (p * runtimePlugin ) getFileName (download downloadConfig , version string ) string {
176195 goos := runtime .GOOS
177196 goarch := runtime .GOARCH
178-
197+
179198 // Map Go architecture to runtime-specific architecture
180199 mappedArch := p .getMappedArch (goarch )
181-
200+
182201 // Prepare template data
183202 data := templateData {
184203 Version : version ,
185204 OS : goos ,
186205 Arch : mappedArch ,
187206 }
188-
207+
189208 // Execute template substitution for filename
190- tmpl , err := template .New ("filename" ).Parse (p . Config . Download .FileNameTemplate )
209+ tmpl , err := template .New ("filename" ).Parse (download .FileNameTemplate )
191210 if err != nil {
192211 return ""
193212 }
194-
213+
195214 var buf bytes.Buffer
196215 err = tmpl .Execute (& buf , data )
197216 if err != nil {
198217 return ""
199218 }
200-
219+
201220 return buf .String ()
202221}
203222
204223// GetDownloadURL generates the download URL based on the template in plugin.yaml
205- func (p * runtimePlugin ) getDownloadURL (version string ) string {
224+ func (p * runtimePlugin ) getDownloadURL (download downloadConfig , version string ) string {
206225 goos := runtime .GOOS
207226 goarch := runtime .GOARCH
208-
227+
209228 // Map Go architecture to runtime-specific architecture
210229 mappedArch := p .getMappedArch (goarch )
211-
230+
212231 // Get the appropriate extension
213- extension := p .getExtension (goos )
214-
232+ extension := p .getExtension (download , goos )
233+
215234 // Get the filename
216- fileName := p .getFileName (version )
217-
235+ fileName := p .getFileName (download , version )
236+
218237 // Prepare template data
219238 data := templateData {
220239 Version : version ,
@@ -223,24 +242,24 @@ func (p *runtimePlugin) getDownloadURL(version string) string {
223242 Arch : mappedArch ,
224243 Extension : extension ,
225244 }
226-
245+
227246 // Execute template substitution for URL
228- tmpl , err := template .New ("url" ).Parse (p . Config . Download .URLTemplate )
247+ tmpl , err := template .New ("url" ).Parse (download .URLTemplate )
229248 if err != nil {
230249 return ""
231250 }
232-
251+
233252 var buf bytes.Buffer
234253 err = tmpl .Execute (& buf , data )
235254 if err != nil {
236255 return ""
237256 }
238-
257+
239258 return buf .String ()
240259}
241260
242261// GetInstallationDirectoryPath returns the installation directory path for the runtime
243262func (p * runtimePlugin ) getInstallationDirectoryPath (runtimesDir string , version string ) string {
244- fileName := p .getFileName (version )
263+ fileName := p .getFileName (p . Config . Downloads [ 0 ], version )
245264 return path .Join (runtimesDir , fileName )
246265}
0 commit comments