You've already forked dcmerge
							
							feat: support service.command
This patch extends dcmerge to support the command attribut of a defined service.
For example:
```yaml
services:
  busybox
    command: [ "/usr/bin/cp", "--recursive", "--force", "/tmp/bar.txt", "/tmp/foo.txt"]
    image: library/busybox:latest
```
The command attribute is interpreted as a whole. This means that individual
arguments are not merged as a comparison, as this would change the meaning of
the command attribute.
			
			
This commit is contained in:
		| @@ -531,6 +531,7 @@ func NewSecret() *Secret { | ||||
| } | ||||
|  | ||||
| type Service struct { | ||||
| 	Command            []string                   `json:"command,omitempty" yaml:"command,omitempty"` | ||||
| 	CapabilitiesAdd    []string                   `json:"cap_add,omitempty" yaml:"cap_add,omitempty"` | ||||
| 	CapabilitiesDrop   []string                   `json:"cap_drop,omitempty" yaml:"cap_drop,omitempty"` | ||||
| 	DependsOnContainer *DependsOnContainer        `json:"depends_on,omitempty" yaml:"depends_on,omitempty"` | ||||
| @@ -641,7 +642,8 @@ func (s *Service) Equal(equalable Equalable) bool { | ||||
| 	case s == nil && service != nil: | ||||
| 		return false | ||||
| 	default: | ||||
| 		return equalSlice(s.CapabilitiesAdd, service.CapabilitiesAdd) && | ||||
| 		return equalSlice(s.Command, service.Command) && | ||||
| 			equalSlice(s.CapabilitiesAdd, service.CapabilitiesAdd) && | ||||
| 			equalSlice(s.CapabilitiesDrop, service.CapabilitiesDrop) && | ||||
| 			s.DependsOnContainer.Equal(service.DependsOnContainer) && | ||||
| 			s.Deploy.Equal(service.Deploy) && | ||||
| @@ -673,6 +675,7 @@ func (s *Service) MergeExistingWin(service *Service) { | ||||
| 	// 	fallthrough | ||||
|  | ||||
| 	default: | ||||
| 		s.mergeExistingWinCommand(service.Command) | ||||
| 		s.mergeExistingWinCapabilitiesAdd(service.CapabilitiesAdd) | ||||
| 		s.mergeExistingWinCapabilitiesDrop(service.CapabilitiesDrop) | ||||
| 		s.mergeExistingWinDependsOnContainer(service.DependsOnContainer) | ||||
| @@ -707,6 +710,7 @@ func (s *Service) MergeLastWin(service *Service) { | ||||
| 	// 	fallthrough | ||||
|  | ||||
| 	default: | ||||
| 		s.mergeLastWinCommand(service.Command) | ||||
| 		s.mergeLastWinCapabilitiesAdd(service.CapabilitiesAdd) | ||||
| 		s.mergeLastWinCapabilitiesDrop(service.CapabilitiesDrop) | ||||
| 		s.mergeLastWinDependsOnContainer(service.DependsOnContainer) | ||||
| @@ -723,6 +727,13 @@ func (s *Service) MergeLastWin(service *Service) { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (s *Service) mergeExistingWinCommand(command []string) { | ||||
| 	if len(s.Command) > 0 { | ||||
| 		return | ||||
| 	} | ||||
| 	s.Command = command | ||||
| } | ||||
|  | ||||
| func (s *Service) mergeExistingWinCapabilitiesAdd(capabilitiesAdd []string) { | ||||
| 	for _, capabilityAdd := range capabilitiesAdd { | ||||
| 		if !existsInSlice(s.CapabilitiesAdd, capabilityAdd) && len(capabilityAdd) > 0 { | ||||
| @@ -935,6 +946,12 @@ func (s *Service) mergeExistingWinVolumes(volumes []string) { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (s *Service) mergeLastWinCommand(command []string) { | ||||
| 	if len(command) > 0 { | ||||
| 		s.Command = command | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (s *Service) mergeLastWinCapabilitiesAdd(capabilitiesAdd []string) { | ||||
| 	for _, capabilityAdd := range capabilitiesAdd { | ||||
| 		if len(capabilityAdd) <= 0 { | ||||
|   | ||||
| @@ -301,6 +301,7 @@ func TestService_Equal(t *testing.T) { | ||||
| 		}, | ||||
| 		{ | ||||
| 			equalableA: &dockerCompose.Service{ | ||||
| 				Command:            []string{}, | ||||
| 				CapabilitiesAdd:    []string{}, | ||||
| 				CapabilitiesDrop:   []string{}, | ||||
| 				DependsOnContainer: &dockerCompose.DependsOnContainer{}, | ||||
| @@ -316,6 +317,7 @@ func TestService_Equal(t *testing.T) { | ||||
| 				Volumes:            []string{}, | ||||
| 			}, | ||||
| 			equalableB: &dockerCompose.Service{ | ||||
| 				Command:            []string{}, | ||||
| 				CapabilitiesAdd:    []string{}, | ||||
| 				CapabilitiesDrop:   []string{}, | ||||
| 				DependsOnContainer: &dockerCompose.DependsOnContainer{}, | ||||
| @@ -332,6 +334,15 @@ func TestService_Equal(t *testing.T) { | ||||
| 			}, | ||||
| 			expectedResult: true, | ||||
| 		}, | ||||
| 		{ | ||||
| 			equalableA: &dockerCompose.Service{ | ||||
| 				Command: []string{"/usr/bin/cp", "--recursive", "/tmp/foo.txt", "/tmp/bar.txt"}, | ||||
| 			}, | ||||
| 			equalableB: &dockerCompose.Service{ | ||||
| 				Command: []string{"/usr/bin/cp", "--recursive", "/tmp/foo.txt", "/tmp/bar.txt"}, | ||||
| 			}, | ||||
| 			expectedResult: true, | ||||
| 		}, | ||||
| 		{ | ||||
| 			equalableA: &dockerCompose.Service{ | ||||
| 				CapabilitiesAdd: []string{"NET_ADMIN"}, | ||||
| @@ -636,6 +647,52 @@ func TestService_MergeExistingWin(t *testing.T) { | ||||
| 			expectedService:    &dockerCompose.Service{}, | ||||
| 		}, | ||||
|  | ||||
| 		// Command | ||||
| 		{ | ||||
| 			serviceDeploymentA: &dockerCompose.Service{ | ||||
| 				Command: []string{"/usr/bin/cp", "--recursive", "/tmp/foo.txt", "/tmp/bar.txt"}, | ||||
| 			}, | ||||
| 			serviceDeploymentB: &dockerCompose.Service{ | ||||
| 				Command: []string{}, | ||||
| 			}, | ||||
| 			expectedService: &dockerCompose.Service{ | ||||
| 				Command: []string{"/usr/bin/cp", "--recursive", "/tmp/foo.txt", "/tmp/bar.txt"}, | ||||
| 			}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			serviceDeploymentA: &dockerCompose.Service{ | ||||
| 				Command: []string{}, | ||||
| 			}, | ||||
| 			serviceDeploymentB: &dockerCompose.Service{ | ||||
| 				Command: []string{"/usr/bin/cp", "--recursive", "/tmp/foo.txt", "/tmp/bar.txt"}, | ||||
| 			}, | ||||
| 			expectedService: &dockerCompose.Service{ | ||||
| 				Command: []string{"/usr/bin/cp", "--recursive", "/tmp/foo.txt", "/tmp/bar.txt"}, | ||||
| 			}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			serviceDeploymentA: &dockerCompose.Service{ | ||||
| 				Command: []string{"/usr/bin/cp", "--recursive", "/tmp/foo.txt", "/tmp/bar.txt"}, | ||||
| 			}, | ||||
| 			serviceDeploymentB: &dockerCompose.Service{ | ||||
| 				Command: []string{"/usr/bin/cp", "--recursive", "/tmp/foo.txt", "/tmp/bar.txt"}, | ||||
| 			}, | ||||
| 			expectedService: &dockerCompose.Service{ | ||||
| 				Command: []string{"/usr/bin/cp", "--recursive", "/tmp/foo.txt", "/tmp/bar.txt"}, | ||||
| 			}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			serviceDeploymentA: &dockerCompose.Service{ | ||||
| 				Command: []string{"/usr/bin/cp", "--recursive", "/tmp/foo.txt", "/tmp/bar.txt"}, | ||||
| 			}, | ||||
| 			serviceDeploymentB: &dockerCompose.Service{ | ||||
| 				Command: []string{""}, | ||||
| 			}, | ||||
| 			expectedService: &dockerCompose.Service{ | ||||
| 				Command: []string{"/usr/bin/cp", "--recursive", "/tmp/foo.txt", "/tmp/bar.txt"}, | ||||
| 			}, | ||||
| 		}, | ||||
|  | ||||
| 		// CapabilitiesAdd | ||||
| 		{ | ||||
| 			serviceDeploymentA: &dockerCompose.Service{ | ||||
| @@ -1620,6 +1677,52 @@ func TestService_MergeLastWin(t *testing.T) { | ||||
| 			expectedService:    &dockerCompose.Service{}, | ||||
| 		}, | ||||
|  | ||||
| 		// Command | ||||
| 		{ | ||||
| 			serviceDeploymentA: &dockerCompose.Service{ | ||||
| 				Command: []string{"/usr/bin/cp", "--recursive", "/tmp/foo.txt", "/tmp/bar.txt"}, | ||||
| 			}, | ||||
| 			serviceDeploymentB: &dockerCompose.Service{ | ||||
| 				Command: []string{}, | ||||
| 			}, | ||||
| 			expectedService: &dockerCompose.Service{ | ||||
| 				Command: []string{"/usr/bin/cp", "--recursive", "/tmp/foo.txt", "/tmp/bar.txt"}, | ||||
| 			}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			serviceDeploymentA: &dockerCompose.Service{ | ||||
| 				Command: []string{}, | ||||
| 			}, | ||||
| 			serviceDeploymentB: &dockerCompose.Service{ | ||||
| 				Command: []string{"/usr/bin/cp", "--recursive", "/tmp/foo.txt", "/tmp/bar.txt"}, | ||||
| 			}, | ||||
| 			expectedService: &dockerCompose.Service{ | ||||
| 				Command: []string{"/usr/bin/cp", "--recursive", "/tmp/foo.txt", "/tmp/bar.txt"}, | ||||
| 			}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			serviceDeploymentA: &dockerCompose.Service{ | ||||
| 				Command: []string{"/usr/bin/cp", "--recursive", "/tmp/foo.txt", "/tmp/bar.txt"}, | ||||
| 			}, | ||||
| 			serviceDeploymentB: &dockerCompose.Service{ | ||||
| 				Command: []string{"/usr/bin/cp", "--recursive", "/tmp/foo.txt", "/tmp/bar.txt"}, | ||||
| 			}, | ||||
| 			expectedService: &dockerCompose.Service{ | ||||
| 				Command: []string{"/usr/bin/cp", "--recursive", "/tmp/foo.txt", "/tmp/bar.txt"}, | ||||
| 			}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			serviceDeploymentA: &dockerCompose.Service{ | ||||
| 				Command: []string{"/usr/bin/cp", "--recursive", "/tmp/foo.txt", "/tmp/bar.txt"}, | ||||
| 			}, | ||||
| 			serviceDeploymentB: &dockerCompose.Service{ | ||||
| 				Command: []string{""}, | ||||
| 			}, | ||||
| 			expectedService: &dockerCompose.Service{ | ||||
| 				Command: []string{""}, | ||||
| 			}, | ||||
| 		}, | ||||
|  | ||||
| 		// CapabilitiesAdd | ||||
| 		{ | ||||
| 			serviceDeploymentA: &dockerCompose.Service{ | ||||
|   | ||||
| @@ -0,0 +1,4 @@ | ||||
| services: | ||||
|   frontend: | ||||
|     command: [ "/usr/bin/cp", "--recursive", "--force", "/tmp/foo.txt", "/tmp/bar.txt" ] | ||||
|     image: library/frontend:latest | ||||
| @@ -0,0 +1,4 @@ | ||||
| services: | ||||
|   frontend: | ||||
|     command: [ "/usr/bin/cp", "--recursive", "--force", "/tmp/bar.txt", "/tmp/foo.txt"] | ||||
|     image: library/frontend:latest | ||||
| @@ -0,0 +1,8 @@ | ||||
| services: | ||||
|   backend: | ||||
|     image: library/backend:latest | ||||
|   frontend: | ||||
|     depends_on: | ||||
|       backend: | ||||
|         condition: service_completed_successfully | ||||
|     image: library/frontend:latest | ||||
		Reference in New Issue
	
	Block a user