Browse Source

volume ls command can run without a project

Signed-off-by: Nicolas De Loof <[email protected]>
Nicolas De Loof 2 months ago
parent
commit
a473341058

+ 8 - 11
cmd/compose/volumes.go

@@ -55,24 +55,21 @@ func volumesCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Servic
 }
 
 func runVol(ctx context.Context, dockerCli command.Cli, backend api.Service, services []string, options volumesOptions) error {
-	project, _, err := options.projectOrName(ctx, dockerCli, services...)
+	project, name, err := options.projectOrName(ctx, dockerCli, services...)
 	if err != nil {
 		return err
 	}
 
-	names := project.ServiceNames()
-
-	if len(services) == 0 {
-		services = names
-	}
-
-	for _, service := range services {
-		if !slices.Contains(names, service) {
-			return fmt.Errorf("no such service: %s", service)
+	if project != nil {
+		names := project.ServiceNames()
+		for _, service := range services {
+			if !slices.Contains(names, service) {
+				return fmt.Errorf("no such service: %s", service)
+			}
 		}
 	}
 
-	volumes, err := backend.Volumes(ctx, project, api.VolumesOptions{
+	volumes, err := backend.Volumes(ctx, name, api.VolumesOptions{
 		Services: services,
 	})
 	if err != nil {

+ 1 - 1
pkg/api/api.go

@@ -101,7 +101,7 @@ type Service interface {
 	// Generate generates a Compose Project from existing containers
 	Generate(ctx context.Context, options GenerateOptions) (*types.Project, error)
 	// Volumes executes the equivalent to a `docker volume ls`
-	Volumes(ctx context.Context, project *types.Project, options VolumesOptions) ([]VolumesSummary, error)
+	Volumes(ctx context.Context, project string, options VolumesOptions) ([]VolumesSummary, error)
 }
 
 type VolumesOptions struct {

+ 3 - 6
pkg/compose/volumes.go

@@ -20,18 +20,15 @@ import (
 	"context"
 	"slices"
 
-	"github.com/compose-spec/compose-go/v2/types"
 	"github.com/docker/compose/v2/pkg/api"
 	"github.com/docker/docker/api/types/container"
 	"github.com/docker/docker/api/types/filters"
 	"github.com/docker/docker/api/types/volume"
 )
 
-func (s *composeService) Volumes(ctx context.Context, project *types.Project, options api.VolumesOptions) ([]api.VolumesSummary, error) {
-	projectName := project.Name
-
+func (s *composeService) Volumes(ctx context.Context, project string, options api.VolumesOptions) ([]api.VolumesSummary, error) {
 	allContainers, err := s.apiClient().ContainerList(ctx, container.ListOptions{
-		Filters: filters.NewArgs(projectFilter(projectName)),
+		Filters: filters.NewArgs(projectFilter(project)),
 	})
 	if err != nil {
 		return nil, err
@@ -51,7 +48,7 @@ func (s *composeService) Volumes(ctx context.Context, project *types.Project, op
 	}
 
 	volumesResponse, err := s.apiClient().VolumeList(ctx, volume.ListOptions{
-		Filters: filters.NewArgs(projectFilter(projectName)),
+		Filters: filters.NewArgs(projectFilter(project)),
 	})
 	if err != nil {
 		return nil, err

+ 2 - 4
pkg/compose/volumes_test.go

@@ -20,7 +20,6 @@ import (
 	"context"
 	"testing"
 
-	"github.com/compose-spec/compose-go/v2/types"
 	"github.com/docker/compose/v2/pkg/api"
 	"github.com/docker/docker/api/types/container"
 	"github.com/docker/docker/api/types/filters"
@@ -59,7 +58,6 @@ func TestVolumes(t *testing.T) {
 	}
 
 	ctx := context.Background()
-	project := &types.Project{Name: testProject}
 	args := filters.NewArgs(projectFilter(testProject))
 	listOpts := container.ListOptions{Filters: args}
 	volumeListArgs := filters.NewArgs(projectFilter(testProject))
@@ -75,14 +73,14 @@ func TestVolumes(t *testing.T) {
 
 	// Test without service filter - should return all project volumes
 	volumeOptions := api.VolumesOptions{}
-	volumes, err := tested.Volumes(ctx, project, volumeOptions)
+	volumes, err := tested.Volumes(ctx, testProject, volumeOptions)
 	expected := []api.VolumesSummary{vol1, vol2, vol3}
 	assert.NilError(t, err)
 	assert.DeepEqual(t, volumes, expected)
 
 	// Test with service filter - should only return volumes used by service1
 	volumeOptions = api.VolumesOptions{Services: []string{"service1"}}
-	volumes, err = tested.Volumes(ctx, project, volumeOptions)
+	volumes, err = tested.Volumes(ctx, testProject, volumeOptions)
 	expected = []api.VolumesSummary{vol1, vol2}
 	assert.NilError(t, err)
 	assert.DeepEqual(t, volumes, expected)

+ 1 - 13
pkg/mocks/mock_docker_compose_api.go

@@ -499,7 +499,7 @@ func (mr *MockServiceMockRecorder) Viz(ctx, project, options any) *gomock.Call {
 }
 
 // Volumes mocks base method.
-func (m *MockService) Volumes(ctx context.Context, project *types.Project, options api.VolumesOptions) ([]api.VolumesSummary, error) {
+func (m *MockService) Volumes(ctx context.Context, project string, options api.VolumesOptions) ([]api.VolumesSummary, error) {
 	m.ctrl.T.Helper()
 	ret := m.ctrl.Call(m, "Volumes", ctx, project, options)
 	ret0, _ := ret[0].([]api.VolumesSummary)
@@ -589,18 +589,6 @@ func (mr *MockLogConsumerMockRecorder) Log(containerName, message any) *gomock.C
 	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Log", reflect.TypeOf((*MockLogConsumer)(nil).Log), containerName, message)
 }
 
-// Register mocks base method.
-func (m *MockLogConsumer) Register(container string) {
-	m.ctrl.T.Helper()
-	m.ctrl.Call(m, "Register", container)
-}
-
-// Register indicates an expected call of Register.
-func (mr *MockLogConsumerMockRecorder) Register(container any) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Register", reflect.TypeOf((*MockLogConsumer)(nil).Register), container)
-}
-
 // Status mocks base method.
 func (m *MockLogConsumer) Status(container, msg string) {
 	m.ctrl.T.Helper()