@@ -48,7 +48,7 @@ type Project struct {
4848}
4949
5050// ServiceNames return names for all services in this Compose config
51- func (p Project ) ServiceNames () []string {
51+ func (p * Project ) ServiceNames () []string {
5252 var names []string
5353 for _ , s := range p .Services {
5454 names = append (names , s .Name )
@@ -58,7 +58,7 @@ func (p Project) ServiceNames() []string {
5858}
5959
6060// VolumeNames return names for all volumes in this Compose config
61- func (p Project ) VolumeNames () []string {
61+ func (p * Project ) VolumeNames () []string {
6262 var names []string
6363 for k := range p .Volumes {
6464 names = append (names , k )
@@ -68,7 +68,7 @@ func (p Project) VolumeNames() []string {
6868}
6969
7070// NetworkNames return names for all volumes in this Compose config
71- func (p Project ) NetworkNames () []string {
71+ func (p * Project ) NetworkNames () []string {
7272 var names []string
7373 for k := range p .Networks {
7474 names = append (names , k )
@@ -78,7 +78,7 @@ func (p Project) NetworkNames() []string {
7878}
7979
8080// SecretNames return names for all secrets in this Compose config
81- func (p Project ) SecretNames () []string {
81+ func (p * Project ) SecretNames () []string {
8282 var names []string
8383 for k := range p .Secrets {
8484 names = append (names , k )
@@ -88,7 +88,7 @@ func (p Project) SecretNames() []string {
8888}
8989
9090// ConfigNames return names for all configs in this Compose config
91- func (p Project ) ConfigNames () []string {
91+ func (p * Project ) ConfigNames () []string {
9292 var names []string
9393 for k := range p .Configs {
9494 names = append (names , k )
@@ -98,7 +98,7 @@ func (p Project) ConfigNames() []string {
9898}
9999
100100// GetServices retrieve services by names, or return all services if no name specified
101- func (p Project ) GetServices (names ... string ) (Services , error ) {
101+ func (p * Project ) GetServices (names ... string ) (Services , error ) {
102102 if len (names ) == 0 {
103103 return p .Services , nil
104104 }
@@ -120,7 +120,7 @@ func (p Project) GetServices(names ...string) (Services, error) {
120120}
121121
122122// GetService retrieve a specific service by name
123- func (p Project ) GetService (name string ) (ServiceConfig , error ) {
123+ func (p * Project ) GetService (name string ) (ServiceConfig , error ) {
124124 services , err := p .GetServices (name )
125125 if err != nil {
126126 return ServiceConfig {}, err
@@ -131,7 +131,7 @@ func (p Project) GetService(name string) (ServiceConfig, error) {
131131 return services [0 ], nil
132132}
133133
134- func (p Project ) AllServices () Services {
134+ func (p * Project ) AllServices () Services {
135135 var all Services
136136 all = append (all , p .Services ... )
137137 all = append (all , p .DisabledServices ... )
@@ -140,12 +140,16 @@ func (p Project) AllServices() Services {
140140
141141type ServiceFunc func (service ServiceConfig ) error
142142
143- // WithServices run ServiceFunc on each service and dependencies in dependency order
144- func (p Project ) WithServices (names []string , fn ServiceFunc ) error {
145- return p .withServices (names , fn , map [string ]bool {})
143+ // WithServices run ServiceFunc on each service and dependencies according to DependencyPolicy
144+ func (p * Project ) WithServices (names []string , fn ServiceFunc , options ... DependencyOption ) error {
145+ if len (options ) == 0 {
146+ // backward compatibility
147+ options = []DependencyOption {IncludeDependencies }
148+ }
149+ return p .withServices (names , fn , map [string ]bool {}, options )
146150}
147151
148- func (p Project ) withServices (names []string , fn ServiceFunc , seen map [string ]bool ) error {
152+ func (p * Project ) withServices (names []string , fn ServiceFunc , seen map [string ]bool , options [] DependencyOption ) error {
149153 services , err := p .GetServices (names ... )
150154 if err != nil {
151155 return err
@@ -155,9 +159,21 @@ func (p Project) withServices(names []string, fn ServiceFunc, seen map[string]bo
155159 continue
156160 }
157161 seen [service .Name ] = true
158- dependencies := service .GetDependencies ()
162+ var dependencies []string
163+ for _ , policy := range options {
164+ switch policy {
165+ case IncludeDependents :
166+ dependencies = append (dependencies , p .GetDependentsForService (service )... )
167+ case IncludeDependencies :
168+ dependencies = append (dependencies , service .GetDependencies ()... )
169+ case IgnoreDependencies :
170+ // Noop
171+ default :
172+ return fmt .Errorf ("unsupported dependency policy %d" , policy )
173+ }
174+ }
159175 if len (dependencies ) > 0 {
160- err := p .withServices (dependencies , fn , seen )
176+ err := p .withServices (dependencies , fn , seen , options )
161177 if err != nil {
162178 return err
163179 }
@@ -169,6 +185,18 @@ func (p Project) withServices(names []string, fn ServiceFunc, seen map[string]bo
169185 return nil
170186}
171187
188+ func (p * Project ) GetDependentsForService (s ServiceConfig ) []string {
189+ var dependent []string
190+ for _ , service := range p .Services {
191+ for name := range service .DependsOn {
192+ if name == s .Name {
193+ dependent = append (dependent , service .Name )
194+ }
195+ }
196+ }
197+ return dependent
198+ }
199+
172200// RelativePath resolve a relative path based project's working directory
173201func (p * Project ) RelativePath (path string ) string {
174202 if path [0 ] == '~' {
@@ -292,8 +320,16 @@ func (p *Project) WithoutUnnecessaryResources() {
292320 p .Configs = configs
293321}
294322
295- // ForServices restrict the project model to a subset of services
296- func (p * Project ) ForServices (names []string ) error {
323+ type DependencyOption int
324+
325+ const (
326+ IncludeDependencies = iota
327+ IncludeDependents
328+ IgnoreDependencies
329+ )
330+
331+ // ForServices restrict the project model to selected services and dependencies
332+ func (p * Project ) ForServices (names []string , options ... DependencyOption ) error {
297333 if len (names ) == 0 {
298334 // All services
299335 return nil
@@ -303,7 +339,7 @@ func (p *Project) ForServices(names []string) error {
303339 err := p .WithServices (names , func (service ServiceConfig ) error {
304340 set [service .Name ] = struct {}{}
305341 return nil
306- })
342+ }, options ... )
307343 if err != nil {
308344 return err
309345 }
0 commit comments