Skip to content

Commit 6c20891

Browse files
authored
Fixes for handling different runtime packages and formats (#29)
1 parent c7d66b7 commit 6c20891

File tree

21 files changed

+1350
-242
lines changed

21 files changed

+1350
-242
lines changed

cmd/add.go

Lines changed: 74 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -122,27 +122,9 @@ func (c *AddCmd) run(cmd *cobra.Command, args []string) error {
122122
return fmt.Errorf("⚠️ Failed to get package '%s@%s' from registry: %w", name, c.Version, err)
123123
}
124124

125-
requestedTools, err := filter.MatchRequestedSlice(c.Tools, pkg.Tools)
125+
entry, err := parseServerEntry(pkg, runtime.Runtime(c.Runtime), c.Tools, c.MCPDSupportedRuntimes())
126126
if err != nil {
127-
return fmt.Errorf("error matching requested tools: %w", err)
128-
}
129-
130-
selectedRuntime, runtimeErr := c.runtime(pkg)
131-
if runtimeErr != nil {
132-
return runtimeErr
133-
}
134-
135-
version := "latest"
136-
if pkg.Version != "" {
137-
version = pkg.Version
138-
}
139-
140-
runtimePackageVersion := fmt.Sprintf("%s::%s@%s", selectedRuntime, pkg.Name, version)
141-
142-
entry := config.ServerEntry{
143-
Name: pkg.ID,
144-
Package: runtimePackageVersion,
145-
Tools: requestedTools,
127+
return fmt.Errorf("error parsing server entry: %w", err)
146128
}
147129

148130
cfg, err := c.cfgLoader.Load(flags.ConfigFile)
@@ -160,41 +142,94 @@ func (c *AddCmd) run(cmd *cobra.Command, args []string) error {
160142
cmd.OutOrStdout(),
161143
"✓ Added server '%s' (version: %s), tools: %s\n",
162144
name,
163-
version,
164-
strings.Join(requestedTools, ", "),
145+
entry.PackageVersion(),
146+
strings.Join(entry.Tools, ", "),
165147
)
166148
if err != nil {
167149
return err
168150
}
169-
logger.Debug("Server added", "name", name, "version", version, "tools", requestedTools)
151+
logger.Debug("Server added", "name", name, "version", entry.PackageVersion(), "tools", entry.Tools)
170152

171153
// Print the package info.
172154
if err = c.packagePrinter.PrintPackage(pkg); err != nil {
173155
return err
174156
}
175157

158+
_, err = fmt.Fprintln(cmd.OutOrStdout())
159+
if err != nil {
160+
return err
161+
}
162+
176163
return nil
177164
}
178165

179-
func (c *AddCmd) runtime(pkg packages.Package) (runtime.Runtime, error) {
180-
// TODO: Sort out preference for runtimes
181-
var selectedRuntime runtime.Runtime
182-
supportedRuntimes := runtime.DefaultSupportedRuntimes()
183-
for k, v := range pkg.InstallationDetails {
184-
if _, ok := supportedRuntimes[k]; ok {
185-
// We'll always end up with a supported runtime,
186-
// and hopefully one of them is the recommended installation.
187-
selectedRuntime = k
188-
if v.Recommended {
189-
break
190-
}
166+
// selectRuntime returns the most appropriate runtime from a set of installations,
167+
// given a list of supported runtimes in priority order.
168+
//
169+
// It first searches for any supported runtime marked as `Recommended` and returns the first such match.
170+
// If none are recommended, it returns the first matched runtime from the `supported` list.
171+
//
172+
// Returns an error if no supported runtime is found.
173+
func selectRuntime(
174+
installations map[runtime.Runtime]packages.Installation,
175+
requestedRuntime runtime.Runtime,
176+
supported []runtime.Runtime,
177+
) (runtime.Runtime, error) {
178+
// Try to select the recommended runtime if present.
179+
for _, rt := range supported {
180+
if requestedRuntime != "" && rt != requestedRuntime {
181+
continue
182+
}
183+
if inst, ok := installations[rt]; ok && inst.Recommended {
184+
return rt, nil
191185
}
192186
}
193-
// We shouldn't end up in this situation, but just in case.
194-
if selectedRuntime == "" {
195-
return "", fmt.Errorf("no supported runtimes found for '%s'", pkg.Name)
187+
188+
// Fall back to the first supported runtime by priority.
189+
for _, rt := range supported {
190+
if requestedRuntime != "" && rt != requestedRuntime {
191+
continue
192+
}
193+
if _, ok := installations[rt]; ok {
194+
return rt, nil
195+
}
196+
}
197+
198+
return "", fmt.Errorf("no supported runtimes found")
199+
}
200+
201+
func parseServerEntry(
202+
pkg packages.Package,
203+
requestedRuntime runtime.Runtime,
204+
requestedTools []string,
205+
supportedRuntimes []runtime.Runtime,
206+
) (config.ServerEntry, error) {
207+
requestedTools, err := filter.MatchRequestedSlice(requestedTools, pkg.Tools)
208+
if err != nil {
209+
return config.ServerEntry{}, fmt.Errorf("error matching requested tools: %w", err)
210+
}
211+
212+
selectedRuntime, runtimeErr := selectRuntime(pkg.InstallationDetails, requestedRuntime, supportedRuntimes)
213+
if runtimeErr != nil {
214+
return config.ServerEntry{}, fmt.Errorf("error selecting runtime from available installations: %w", runtimeErr)
196215
}
197-
return selectedRuntime, nil
216+
217+
v := "latest"
218+
if pkg.Version != "" {
219+
v = pkg.Version
220+
}
221+
222+
runtimeSpecificName := pkg.InstallationDetails[selectedRuntime].Package
223+
if runtimeSpecificName == "" {
224+
return config.ServerEntry{}, fmt.Errorf("installation package name is missing for runtime '%s'", selectedRuntime)
225+
}
226+
runtimePackageVersion := fmt.Sprintf("%s::%s@%s", selectedRuntime, runtimeSpecificName, v)
227+
228+
return config.ServerEntry{
229+
Name: pkg.ID,
230+
Package: runtimePackageVersion,
231+
Tools: requestedTools,
232+
}, nil
198233
}
199234

200235
func (c *AddCmd) options() []regopts.ResolveOption {

0 commit comments

Comments
 (0)