@@ -4,9 +4,10 @@ import (
44 "context"
55 "fmt"
66 "path/filepath"
7+ goruntime "runtime"
78 "time"
89
9- "github.com/devboxos/devboxos/shared/runtime"
10+ sharedRuntime "github.com/devboxos/devboxos/shared/runtime"
1011 "github.com/devboxos/devboxos/shared/secrets"
1112 "github.com/devboxos/devboxos/shared/types"
1213)
@@ -22,9 +23,9 @@ func NewLifecycle(resolver *secrets.Resolver) *Lifecycle {
2223}
2324
2425// StartService starts a single service using the given runtime.
25- func (l * Lifecycle ) StartService (ctx context.Context , rt runtime .Runtime , name string , svc types.Service , networkName string , projectPath string , statusChan chan <- string ) (string , error ) {
26+ func (l * Lifecycle ) StartService (ctx context.Context , rt sharedRuntime .Runtime , name string , svc types.Service , networkName string , projectPath string , statusChan chan <- string ) (string , error ) {
2627 // Build container config
27- cfg := runtime .ContainerConfig {
28+ cfg := sharedRuntime .ContainerConfig {
2829 Name : fmt .Sprintf ("devbox-%s" , name ),
2930 Image : svc .Image ,
3031 Command : parseCommand (svc .Command ),
@@ -108,7 +109,7 @@ func (l *Lifecycle) StartService(ctx context.Context, rt runtime.Runtime, name s
108109 contextDir = filepath .Join (projectPath , contextDir )
109110 }
110111
111- buildCfg := runtime .BuildConfig {
112+ buildCfg := sharedRuntime .BuildConfig {
112113 ContextDir : contextDir ,
113114 Dockerfile : svc .Build .Dockerfile ,
114115 BuildArgs : svc .Build .Args ,
@@ -120,8 +121,8 @@ func (l *Lifecycle) StartService(ctx context.Context, rt runtime.Runtime, name s
120121 return "" , fmt .Errorf ("build image for %s: %w" , name , err )
121122 }
122123 cfg .Image = builtImage
123- } else if svc .Image != "" {
124- // Pull image if no build config
124+ } else if svc .Image != "" && svc . Command == "" {
125+ // Pull image only for pure Docker services (image without command override)
125126 if err := rt .PullImage (ctx , svc .Image ); err != nil {
126127 return "" , fmt .Errorf ("pull image %s: %w" , svc .Image , err )
127128 }
@@ -150,20 +151,20 @@ func (l *Lifecycle) StartService(ctx context.Context, rt runtime.Runtime, name s
150151}
151152
152153// StopService stops a single service.
153- func (l * Lifecycle ) StopService (ctx context.Context , rt runtime .Runtime , containerID string , gracePeriod int ) error {
154+ func (l * Lifecycle ) StopService (ctx context.Context , rt sharedRuntime .Runtime , containerID string , gracePeriod int ) error {
154155 if err := rt .StopContainer (ctx , containerID , gracePeriod ); err != nil {
155156 return fmt .Errorf ("stop container %s: %w" , containerID , err )
156157 }
157158 return nil
158159}
159160
160161// RemoveService removes a service container.
161- func (l * Lifecycle ) RemoveService (ctx context.Context , rt runtime .Runtime , containerID string ) error {
162+ func (l * Lifecycle ) RemoveService (ctx context.Context , rt sharedRuntime .Runtime , containerID string ) error {
162163 return rt .RemoveContainer (ctx , containerID , true )
163164}
164165
165166// WaitForHealthy waits for a service to become healthy.
166- func (l * Lifecycle ) WaitForHealthy (ctx context.Context , rt runtime .Runtime , containerID string , svc types.Service ) error {
167+ func (l * Lifecycle ) WaitForHealthy (ctx context.Context , rt sharedRuntime .Runtime , containerID string , svc types.Service ) error {
167168 if svc .Healthcheck == nil {
168169 // No health check defined, assume healthy after brief delay
169170 time .Sleep (2 * time .Second )
@@ -217,6 +218,8 @@ func parseCommand(cmd string) []string {
217218 if cmd == "" {
218219 return nil
219220 }
220- // Simple split — a real implementation would handle quotes
221+ if goruntime .GOOS == "windows" {
222+ return []string {"cmd" , "/C" , cmd }
223+ }
221224 return []string {"sh" , "-c" , cmd }
222225}
0 commit comments