@@ -186,21 +186,15 @@ func (p *Project) AllServices() Services {
186186 return all
187187}
188188
189- type ServiceFunc func (name string , service ServiceConfig ) error
189+ type ServiceFunc func (name string , service * ServiceConfig ) error
190190
191- // WithServices runs ServiceFunc on each service and dependencies according to DependencyPolicy
192- // It returns a new Project instance with the changes and keep the original Project unchanged
193- func (p * Project ) WithServices (names []string , fn ServiceFunc , options ... DependencyOption ) (* Project , error ) {
194- newProject , err := p .deepCopy ()
195- if err != nil {
196- return nil , err
197- }
191+ // ForEachService runs ServiceFunc on each service and dependencies according to DependencyPolicy
192+ func (p * Project ) ForEachService (names []string , fn ServiceFunc , options ... DependencyOption ) error {
198193 if len (options ) == 0 {
199194 // backward compatibility
200195 options = []DependencyOption {IncludeDependencies }
201196 }
202- err = newProject .withServices (names , fn , map [string ]bool {}, options , map [string ]ServiceDependency {})
203- return newProject , err
197+ return p .withServices (names , fn , map [string ]bool {}, options , map [string ]ServiceDependency {})
204198}
205199
206200type withServicesOptions struct {
@@ -249,7 +243,7 @@ func (p *Project) withServices(names []string, fn ServiceFunc, seen map[string]b
249243 return err
250244 }
251245 }
252- if err := fn (name , service ); err != nil {
246+ if err := fn (name , service . deepCopy () ); err != nil {
253247 return err
254248 }
255249 }
@@ -299,13 +293,10 @@ func (s ServiceConfig) HasProfile(profiles []string) bool {
299293 return false
300294}
301295
302- // ApplyProfiles disables service which don't match selected profiles
296+ // WithProfiles disables services which don't match selected profiles
303297// It returns a new Project instance with the changes and keep the original Project unchanged
304- func (p * Project ) ApplyProfiles (profiles []string ) (* Project , error ) {
305- newProject , err := p .deepCopy ()
306- if err != nil {
307- return nil , err
308- }
298+ func (p * Project ) WithProfiles (profiles []string ) (* Project , error ) {
299+ newProject := p .deepCopy ()
309300 for _ , p := range profiles {
310301 if p == "*" {
311302 return newProject , nil
@@ -326,13 +317,10 @@ func (p *Project) ApplyProfiles(profiles []string) (*Project, error) {
326317 return newProject , nil
327318}
328319
329- // EnableServices ensures services are enabled and activate profiles accordingly
320+ // WithServicesEnabled ensures services are enabled and activate profiles accordingly
330321// It returns a new Project instance with the changes and keep the original Project unchanged
331- func (p * Project ) EnableServices (names ... string ) (* Project , error ) {
332- newProject , err := p .deepCopy ()
333- if err != nil {
334- return nil , err
335- }
322+ func (p * Project ) WithServicesEnabled (names ... string ) (* Project , error ) {
323+ newProject := p .deepCopy ()
336324 if len (names ) == 0 {
337325 return newProject , nil
338326 }
@@ -346,18 +334,18 @@ func (p *Project) EnableServices(names ...string) (*Project, error) {
346334 service := p .DisabledServices [name ]
347335 profiles = append (profiles , service .Profiles ... )
348336 }
349- newProject , err = newProject .ApplyProfiles (profiles )
337+ newProject , err : = newProject .WithProfiles (profiles )
350338 if err != nil {
351339 return newProject , err
352340 }
353341
354- return newProject .ResolveServicesEnvironment (true )
342+ return newProject .WithServicesEnvironmentResolved (true )
355343}
356344
357345// WithoutUnnecessaryResources drops networks/volumes/secrets/configs that are not referenced by active services
358346// It returns a new Project instance with the changes and keep the original Project unchanged
359- func (p * Project ) WithoutUnnecessaryResources () ( * Project , error ) {
360- newProject , err := p .deepCopy ()
347+ func (p * Project ) WithoutUnnecessaryResources () * Project {
348+ newProject := p .deepCopy ()
361349 requiredNetworks := map [string ]struct {}{}
362350 requiredVolumes := map [string ]struct {}{}
363351 requiredSecrets := map [string ]struct {}{}
@@ -416,7 +404,7 @@ func (p *Project) WithoutUnnecessaryResources() (*Project, error) {
416404 }
417405 }
418406 newProject .Configs = configs
419- return newProject , err
407+ return newProject
420408}
421409
422410type DependencyOption func (options * withServicesOptions )
@@ -433,16 +421,17 @@ func IgnoreDependencies(options *withServicesOptions) {
433421 options .dependencyPolicy = ignoreDependencies
434422}
435423
436- // ForServices restricts the project model to selected services and dependencies
424+ // WithSelectedServices restricts the project model to selected services and dependencies
437425// It returns a new Project instance with the changes and keep the original Project unchanged
438- func (p * Project ) ForServices (names []string , options ... DependencyOption ) (* Project , error ) {
426+ func (p * Project ) WithSelectedServices (names []string , options ... DependencyOption ) (* Project , error ) {
427+ newProject := p .deepCopy ()
439428 if len (names ) == 0 {
440429 // All services
441- return p . deepCopy ()
430+ return newProject , nil
442431 }
443432
444433 set := utils .NewSet [string ]()
445- newProject , err := p .WithServices (names , func (name string , service ServiceConfig ) error {
434+ err := p .ForEachService (names , func (name string , service * ServiceConfig ) error {
446435 set .Add (name )
447436 return nil
448437 }, options ... )
@@ -464,44 +453,43 @@ func (p *Project) ForServices(names []string, options ...DependencyOption) (*Pro
464453 s .DependsOn = dependencies
465454 enabled [name ] = s
466455 } else {
467- if newProject , err = newProject .DisableService (s ); err != nil {
468- return nil , err
469- }
456+ newProject = newProject .WithServicesDisabled (name )
470457 }
471458 }
472459 newProject .Services = enabled
473460 return newProject , nil
474461}
475462
476- // DisableService removes from the project model the given service and its references in all dependencies
463+ // WithServicesDisabled removes from the project model the given services and their references in all dependencies
477464// It returns a new Project instance with the changes and keep the original Project unchanged
478- func (p * Project ) DisableService (service ServiceConfig ) (* Project , error ) {
479- newProject , err := p .deepCopy ()
480- if err != nil {
481- return nil , err
482- }
483- // We should remove all dependencies which reference the disabled service
484- for i , s := range newProject .Services {
485- if _ , ok := s .DependsOn [service .Name ]; ok {
486- delete (s .DependsOn , service .Name )
487- newProject .Services [i ] = s
488- }
465+ func (p * Project ) WithServicesDisabled (names ... string ) * Project {
466+ newProject := p .deepCopy ()
467+ if len (names ) == 0 {
468+ return newProject
489469 }
490- delete (p .Services , service .Name )
491470 if newProject .DisabledServices == nil {
492471 newProject .DisabledServices = Services {}
493472 }
494- newProject .DisabledServices [service .Name ] = service
495- return newProject , err
473+ for _ , name := range names {
474+ // We should remove all dependencies which reference the disabled service
475+ for i , s := range newProject .Services {
476+ if _ , ok := s .DependsOn [name ]; ok {
477+ delete (s .DependsOn , name )
478+ newProject .Services [i ] = s
479+ }
480+ }
481+ if service , ok := newProject .Services [name ]; ok {
482+ newProject .DisabledServices [name ] = service
483+ delete (newProject .Services , name )
484+ }
485+ }
486+ return newProject
496487}
497488
498- // ResolveImages updates services images to include digest computed by a resolver function
489+ // WithImagesResolved updates services images to include digest computed by a resolver function
499490// It returns a new Project instance with the changes and keep the original Project unchanged
500- func (p * Project ) ResolveImages (resolver func (named reference.Named ) (godigest.Digest , error )) (* Project , error ) {
501- newProject , err := p .deepCopy ()
502- if err != nil {
503- return nil , err
504- }
491+ func (p * Project ) WithImagesResolved (resolver func (named reference.Named ) (godigest.Digest , error )) (* Project , error ) {
492+ newProject := p .deepCopy ()
505493 eg := errgroup.Group {}
506494 for i , s := range newProject .Services {
507495 idx := i
@@ -574,13 +562,10 @@ func (p *Project) MarshalJSON() ([]byte, error) {
574562 return json .Marshal (m )
575563}
576564
577- // ResolveServicesEnvironment parses env_files set for services to resolve the actual environment map for services
565+ // WithServicesEnvironmentResolved parses env_files set for services to resolve the actual environment map for services
578566// It returns a new Project instance with the changes and keep the original Project unchanged
579- func (p Project ) ResolveServicesEnvironment (discardEnvFiles bool ) (* Project , error ) {
580- newProject , err := p .deepCopy ()
581- if err != nil {
582- return nil , err
583- }
567+ func (p Project ) WithServicesEnvironmentResolved (discardEnvFiles bool ) (* Project , error ) {
568+ newProject := p .deepCopy ()
584569 for i , service := range newProject .Services {
585570 service .Environment = service .Environment .Resolve (newProject .Environment .Resolve )
586571
@@ -623,10 +608,10 @@ func (p Project) ResolveServicesEnvironment(discardEnvFiles bool) (*Project, err
623608 return newProject , nil
624609}
625610
626- func (p * Project ) deepCopy () ( * Project , error ) {
611+ func (p * Project ) deepCopy () * Project {
627612 instance , err := copystructure .Copy (p )
628613 if err != nil {
629- return nil , err
614+ panic ( err )
630615 }
631- return instance .(* Project ), nil
616+ return instance .(* Project )
632617}
0 commit comments