Skip to content

Commit 2f87a11

Browse files
authored
Merge pull request docker#6202 from Mewsen/issue/6188
refactor(cli/compose/loader): extract ParseVolume() to its own package
2 parents 3046019 + ef7fd8b commit 2f87a11

File tree

6 files changed

+100
-72
lines changed

6 files changed

+100
-72
lines changed

cli/command/container/opts.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ import (
1212
"strings"
1313
"time"
1414

15-
"github.com/docker/cli/cli/compose/loader"
1615
"github.com/docker/cli/internal/lazyregexp"
16+
"github.com/docker/cli/internal/volumespec"
1717
"github.com/docker/cli/opts"
1818
"github.com/docker/go-connections/nat"
1919
"github.com/moby/moby/api/types/container"
@@ -364,7 +364,7 @@ func parse(flags *pflag.FlagSet, copts *containerOptions, serverOS string) (*con
364364
volumes := copts.volumes.GetMap()
365365
// add any bind targets to the list of container volumes
366366
for bind := range copts.volumes.GetMap() {
367-
parsed, err := loader.ParseVolume(bind)
367+
parsed, err := volumespec.Parse(bind)
368368
if err != nil {
369369
return nil, err
370370
}

cli/compose/loader/loader.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import (
1717
"github.com/docker/cli/cli/compose/schema"
1818
"github.com/docker/cli/cli/compose/template"
1919
"github.com/docker/cli/cli/compose/types"
20+
"github.com/docker/cli/internal/volumespec"
2021
"github.com/docker/cli/opts"
2122
"github.com/docker/cli/opts/swarmopts"
2223
"github.com/docker/go-connections/nat"
@@ -41,6 +42,13 @@ type Options struct {
4142
discardEnvFiles bool
4243
}
4344

45+
// ParseVolume parses a volume spec without any knowledge of the target platform.
46+
//
47+
// This function is unused, but kept for backward-compatibility for external users.
48+
func ParseVolume(spec string) (types.ServiceVolumeConfig, error) {
49+
return volumespec.Parse(spec)
50+
}
51+
4452
// WithDiscardEnvFiles sets the Options to discard the `env_file` section after resolving to
4553
// the `environment` section
4654
func WithDiscardEnvFiles(options *Options) {
@@ -756,7 +764,7 @@ var transformBuildConfig TransformerFunc = func(data any) (any, error) {
756764
var transformServiceVolumeConfig TransformerFunc = func(data any) (any, error) {
757765
switch value := data.(type) {
758766
case string:
759-
return ParseVolume(value)
767+
return volumespec.Parse(value)
760768
case map[string]any:
761769
return data, nil
762770
default:

cli/compose/types/types.go

Lines changed: 8 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import (
88
"fmt"
99
"strconv"
1010
"time"
11+
12+
"github.com/docker/cli/internal/volumespec"
1113
)
1214

1315
// UnsupportedProperties not yet supported by this implementation of the compose file
@@ -390,43 +392,23 @@ type ServicePortConfig struct {
390392
}
391393

392394
// ServiceVolumeConfig are references to a volume used by a service
393-
type ServiceVolumeConfig struct {
394-
Type string `yaml:",omitempty" json:"type,omitempty"`
395-
Source string `yaml:",omitempty" json:"source,omitempty"`
396-
Target string `yaml:",omitempty" json:"target,omitempty"`
397-
ReadOnly bool `mapstructure:"read_only" yaml:"read_only,omitempty" json:"read_only,omitempty"`
398-
Consistency string `yaml:",omitempty" json:"consistency,omitempty"`
399-
Bind *ServiceVolumeBind `yaml:",omitempty" json:"bind,omitempty"`
400-
Volume *ServiceVolumeVolume `yaml:",omitempty" json:"volume,omitempty"`
401-
Image *ServiceVolumeImage `yaml:",omitempty" json:"image,omitempty"`
402-
Tmpfs *ServiceVolumeTmpfs `yaml:",omitempty" json:"tmpfs,omitempty"`
403-
Cluster *ServiceVolumeCluster `yaml:",omitempty" json:"cluster,omitempty"`
404-
}
395+
type ServiceVolumeConfig = volumespec.VolumeConfig
405396

406397
// ServiceVolumeBind are options for a service volume of type bind
407-
type ServiceVolumeBind struct {
408-
Propagation string `yaml:",omitempty" json:"propagation,omitempty"`
409-
}
398+
type ServiceVolumeBind = volumespec.BindOpts
410399

411400
// ServiceVolumeVolume are options for a service volume of type volume
412-
type ServiceVolumeVolume struct {
413-
NoCopy bool `mapstructure:"nocopy" yaml:"nocopy,omitempty" json:"nocopy,omitempty"`
414-
Subpath string `mapstructure:"subpath" yaml:"subpath,omitempty" json:"subpath,omitempty"`
415-
}
401+
type ServiceVolumeVolume = volumespec.VolumeOpts
416402

417403
// ServiceVolumeImage are options for a service volume of type image
418-
type ServiceVolumeImage struct {
419-
Subpath string `mapstructure:"subpath" yaml:"subpath,omitempty" json:"subpath,omitempty"`
420-
}
404+
type ServiceVolumeImage = volumespec.ImageOpts
421405

422406
// ServiceVolumeTmpfs are options for a service volume of type tmpfs
423-
type ServiceVolumeTmpfs struct {
424-
Size int64 `yaml:",omitempty" json:"size,omitempty"`
425-
}
407+
type ServiceVolumeTmpfs = volumespec.TmpFsOpts
426408

427409
// ServiceVolumeCluster are options for a service volume of type cluster.
428410
// Deliberately left blank for future options, but unused now.
429-
type ServiceVolumeCluster struct{}
411+
type ServiceVolumeCluster = volumespec.ClusterOpts
430412

431413
// FileReferenceConfig for a reference to a swarm file object
432414
type FileReferenceConfig struct {

internal/volumespec/types.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package volumespec
2+
3+
// VolumeConfig are references to a volume used by a service
4+
type VolumeConfig struct {
5+
Type string `yaml:",omitempty" json:"type,omitempty"`
6+
Source string `yaml:",omitempty" json:"source,omitempty"`
7+
Target string `yaml:",omitempty" json:"target,omitempty"`
8+
ReadOnly bool `mapstructure:"read_only" yaml:"read_only,omitempty" json:"read_only,omitempty"`
9+
Consistency string `yaml:",omitempty" json:"consistency,omitempty"`
10+
Bind *BindOpts `yaml:",omitempty" json:"bind,omitempty"`
11+
Volume *VolumeOpts `yaml:",omitempty" json:"volume,omitempty"`
12+
Image *ImageOpts `yaml:",omitempty" json:"image,omitempty"`
13+
Tmpfs *TmpFsOpts `yaml:",omitempty" json:"tmpfs,omitempty"`
14+
Cluster *ClusterOpts `yaml:",omitempty" json:"cluster,omitempty"`
15+
}
16+
17+
// BindOpts are options for a service volume of type bind
18+
type BindOpts struct {
19+
Propagation string `yaml:",omitempty" json:"propagation,omitempty"`
20+
}
21+
22+
// VolumeOpts are options for a service volume of type volume
23+
type VolumeOpts struct {
24+
NoCopy bool `mapstructure:"nocopy" yaml:"nocopy,omitempty" json:"nocopy,omitempty"`
25+
Subpath string `mapstructure:"subpath" yaml:"subpath,omitempty" json:"subpath,omitempty"`
26+
}
27+
28+
// ImageOpts are options for a service volume of type image
29+
type ImageOpts struct {
30+
Subpath string `mapstructure:"subpath" yaml:"subpath,omitempty" json:"subpath,omitempty"`
31+
}
32+
33+
// TmpFsOpts are options for a service volume of type tmpfs
34+
type TmpFsOpts struct {
35+
Size int64 `yaml:",omitempty" json:"size,omitempty"`
36+
}
37+
38+
// ClusterOpts are options for a service volume of type cluster.
39+
// Deliberately left blank for future options, but unused now.
40+
type ClusterOpts struct{}

cli/compose/loader/volume.go renamed to internal/volumespec/volumespec.go

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,19 @@
1-
package loader
1+
package volumespec
22

33
import (
44
"strings"
55
"unicode"
66
"unicode/utf8"
77

8-
"github.com/docker/cli/cli/compose/types"
98
"github.com/moby/moby/api/types/mount"
109
"github.com/pkg/errors"
1110
)
1211

1312
const endOfSpec = rune(0)
1413

15-
// ParseVolume parses a volume spec without any knowledge of the target platform
16-
func ParseVolume(spec string) (types.ServiceVolumeConfig, error) {
17-
volume := types.ServiceVolumeConfig{}
14+
// Parse parses a volume spec without any knowledge of the target platform
15+
func Parse(spec string) (VolumeConfig, error) {
16+
volume := VolumeConfig{}
1817

1918
switch len(spec) {
2019
case 0:
@@ -49,7 +48,7 @@ func isWindowsDrive(buffer []rune, char rune) bool {
4948
return char == ':' && len(buffer) == 1 && unicode.IsLetter(buffer[0])
5049
}
5150

52-
func populateFieldFromBuffer(char rune, buffer []rune, volume *types.ServiceVolumeConfig) error {
51+
func populateFieldFromBuffer(char rune, buffer []rune, volume *VolumeConfig) error {
5352
strBuffer := string(buffer)
5453
switch {
5554
case len(buffer) == 0:
@@ -74,10 +73,10 @@ func populateFieldFromBuffer(char rune, buffer []rune, volume *types.ServiceVolu
7473
case "rw":
7574
volume.ReadOnly = false
7675
case "nocopy":
77-
volume.Volume = &types.ServiceVolumeVolume{NoCopy: true}
76+
volume.Volume = &VolumeOpts{NoCopy: true}
7877
default:
7978
if isBindOption(option) {
80-
volume.Bind = &types.ServiceVolumeBind{Propagation: option}
79+
volume.Bind = &BindOpts{Propagation: option}
8180
}
8281
// ignore unknown options
8382
}
@@ -94,7 +93,7 @@ func isBindOption(option string) bool {
9493
return false
9594
}
9695

97-
func populateType(volume *types.ServiceVolumeConfig) {
96+
func populateType(volume *VolumeConfig) {
9897
switch {
9998
// Anonymous volume
10099
case volume.Source == "":

0 commit comments

Comments
 (0)