Skip to content
19 changes: 15 additions & 4 deletions cmd/devenv/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"os"
"path/filepath"
"strings"
"time"

"github.com/nauticalab/devenv-engine/internal/config"
Expand Down Expand Up @@ -309,11 +310,21 @@ func printConfigSummary(cfg *config.DevEnvConfig) {
fmt.Printf(" Git: %s <%s>\n", cfg.Git.Name, cfg.Git.Email)
}

if cfg.Resources.CPU != nil || cfg.Resources.Memory != "" {
cpuStr := formatCPU(cfg.Resources.CPU)
fmt.Printf(" Resources: CPU=%s, Memory=%s, GPU=%d\n",
cpuStr, cfg.Resources.Memory, cfg.Resources.GPU)
cpuStr := cfg.CPU() // e.g., "4000m" or "0"
memStr := cfg.Memory() // e.g., "16Gi" or ""

hasCPU := cpuStr != "0"
hasMem := memStr != ""

if hasCPU || hasMem {
var parts []string
if hasCPU {
parts = append(parts, fmt.Sprintf("CPU=%s", cpuStr))
}
if hasMem {
parts = append(parts, fmt.Sprintf("Memory=%s", memStr))
}
fmt.Printf(" Resources: %s\n", strings.Join(parts, ", "))
}

if len(cfg.Volumes) > 0 {
Expand Down
9 changes: 5 additions & 4 deletions internal/config/example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,13 @@ func ExampleLoadDeveloperConfig() {
sshKeys, err := cfg.GetSSHKeys()
if err != nil {
log.Fatal(err)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually log.Fatal logs the output to stderr and then call os.Exit(1) so return statement would be unreachable here.

return
}
fmt.Printf("SSH Keys: %d configured\n", len(sshKeys))

// Output:
// Developer: testuser
// CPU: 4
// CPU: 4000m
// Memory: 16Gi
// User ID: 2000
// SSH Keys: 1 configured
Expand All @@ -45,7 +46,7 @@ func ExampleDevEnvConfig_CPU() {
Name: "alice",
BaseConfig: config.BaseConfig{
Resources: config.ResourceConfig{
CPU: "8", // String value
CPU: 8, // String value
},
},
}
Expand All @@ -70,8 +71,8 @@ func ExampleDevEnvConfig_CPU() {
fmt.Printf("Default CPU: %s\n", cfg3.CPU())

// Output:
// String CPU: 8
// Integer CPU: 4
// String CPU: 8000m
// Integer CPU: 4000m
// Default CPU: 0
}

Expand Down
56 changes: 56 additions & 0 deletions internal/config/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"os"
"path/filepath"
"strings"

"gopkg.in/yaml.v3"
)
Expand Down Expand Up @@ -216,3 +217,58 @@ func mergeVolumes(global, user []VolumeMount) []VolumeMount {

return result
}

// normalizeSSHKeys converts the flexible SSH key field to a string slice
// Handles both single string and string array formats from YAML
func normalizeSSHKeys(sshKeyField any) ([]string, error) {
if sshKeyField == nil {
return []string{}, nil
}

switch keys := sshKeyField.(type) {
case string:
s := strings.TrimSpace(keys)
// Single SSH key
if s == "" {
return []string{}, fmt.Errorf("SSH key cannot be empty string")
}
return []string{s}, nil

case []string:
// Direct string slice
if len(keys) == 0 {
return nil, fmt.Errorf("SSH key array cannot be empty")
}
out := make([]string, len(keys))
for i, k := range keys {
s := strings.TrimSpace(k)
if s == "" {
return nil, fmt.Errorf("SSH key at index %d cannot be empty", i)
}
out[i] = s
}
return out, nil

case []any: // alias of []interface{}
if len(keys) == 0 {
return nil, fmt.Errorf("SSH key array cannot be empty")
}
out := make([]string, len(keys))
// Array of SSH keys (from YAML)
for i, e := range keys {
s, ok := e.(string)
if !ok {
return nil, fmt.Errorf("SSH key at index %d is not a string", i)
}
s = strings.TrimSpace(s)
if s == "" {
return nil, fmt.Errorf("SSH key at index %d cannot be empty", i)
}
out[i] = s
}
return out, nil

default:
return nil, fmt.Errorf("SSH key field must be string or array of strings, got %T", sshKeyField)
}
}
Loading