Repository: compose-spec/compose-go
Pull request #203 (2021-11-15 22:21:39)

Bump godotenv
This bump fixes unquoted values on environment files.

Still depends on https://github.com/compose-spec/godotenv/pull/11 to be merged

ulyssessouza: As @ndeloof said, that's just to test. @mat007 The error was to click on "Request review"... I think my brain just went in autopilot mode and clicked. Sorry

Patch:
diff --git a/cli/options.go b/cli/options.go
index 85f9cd3..72f21d0 100644
--- a/cli/options.go
+++ b/cli/options.go
@@ -24,7 +24,6 @@ import (
 	"regexp"
 	"strings"
 
-	"github.com/compose-spec/compose-go/errdefs"
 	"github.com/compose-spec/compose-go/loader"
 	"github.com/compose-spec/compose-go/types"
 	"github.com/compose-spec/godotenv"
@@ -250,16 +249,6 @@ func WithInterpolation(interpolation bool) ProjectOptionsFn {
 	}
 }
 
-// WithNormalization set ProjectOptions to enable/skip normalization
-func WithNormalization(normalization bool) ProjectOptionsFn {
-	return func(o *ProjectOptions) error {
-		o.loadOptions = append(o.loadOptions, func(options *loader.Options) {
-			options.SkipNormalization = !normalization
-		})
-		return nil
-	}
-}
-
 // WithResolvedPaths set ProjectOptions to enable paths resolution
 func WithResolvedPaths(resolve bool) ProjectOptionsFn {
 	return func(o *ProjectOptions) error {
@@ -375,7 +364,7 @@ func getConfigPathsFromOptions(options *ProjectOptions) ([]string, error) {
 	if len(options.ConfigPaths) != 0 {
 		return absolutePaths(options.ConfigPaths)
 	}
-	return nil, errors.Wrap(errdefs.ErrNotFound, "no configuration file provided")
+	return nil, errors.New("no configuration file provided")
 }
 
 func findFiles(names []string, pwd string) []string {
diff --git a/go.mod b/go.mod
index 91bc13e..d120a1c 100644
--- a/go.mod
+++ b/go.mod
@@ -3,7 +3,7 @@ module github.com/compose-spec/compose-go
 go 1.16
 
 require (
-	github.com/compose-spec/godotenv v1.1.0
+	github.com/compose-spec/godotenv v1.1.1
 	github.com/distribution/distribution/v3 v3.0.0-20210316161203-a01c71e2477e
 	github.com/docker/go-connections v0.4.0
 	github.com/docker/go-units v0.4.0
diff --git a/go.sum b/go.sum
index 4b09240..72f83cc 100644
--- a/go.sum
+++ b/go.sum
@@ -14,8 +14,8 @@ github.com/bshuster-repo/logrus-logstash-hook v1.0.0/go.mod h1:zsTqEiSzDgAa/8GZR
 github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8=
 github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50=
 github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE=
-github.com/compose-spec/godotenv v1.1.0 h1:wzShe5P6L/Aw3wsV357eWlZdMcPaOe2V2+3+qGwMEL4=
-github.com/compose-spec/godotenv v1.1.0/go.mod h1:zF/3BOa18Z24tts5qnO/E9YURQanJTBUf7nlcCTNsyc=
+github.com/compose-spec/godotenv v1.1.1 h1:lp+WpAInnw06YN9sV/XLUOV/9z4C+6wjJdWlrdVac7o=
+github.com/compose-spec/godotenv v1.1.1/go.mod h1:zF/3BOa18Z24tts5qnO/E9YURQanJTBUf7nlcCTNsyc=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
diff --git a/loader/full-example.yml b/loader/full-example.yml
index 529d28b..9463445 100644
--- a/loader/full-example.yml
+++ b/loader/full-example.yml
@@ -268,7 +268,7 @@ services:
       - .:/code
       - ./static:/var/www/html
       # User-relative path
-      - ~/configs:/etc/configs:ro
+      - ~/configs:/etc/configs/:ro
       # Named volume
       - datavolume:/var/lib/mysql
       - type: bind
diff --git a/loader/merge.go b/loader/merge.go
index 40405e3..0c7a6dd 100644
--- a/loader/merge.go
+++ b/loader/merge.go
@@ -114,11 +114,6 @@ func _merge(baseService *types.ServiceConfig, overrideService *types.ServiceConf
 	if overrideService.Entrypoint != nil {
 		baseService.Entrypoint = overrideService.Entrypoint
 	}
-	if baseService.Environment != nil {
-		baseService.Environment.OverrideBy(overrideService.Environment)
-	} else {
-		baseService.Environment = overrideService.Environment
-	}
 	return baseService, nil
 }
 
diff --git a/loader/volume.go b/loader/volume.go
index 0162aee..173b76b 100644
--- a/loader/volume.go
+++ b/loader/volume.go
@@ -17,7 +17,6 @@
 package loader
 
 import (
-	"path"
 	"strings"
 	"unicode"
 	"unicode/utf8"
@@ -37,11 +36,11 @@ func ParseVolume(spec string) (types.ServiceVolumeConfig, error) {
 		return volume, errors.New("invalid empty volume spec")
 	case 1, 2:
 		volume.Target = spec
-		volume.Type = types.VolumeTypeVolume
+		volume.Type = string(types.VolumeTypeVolume)
 		return volume, nil
 	}
 
-	var buffer []rune
+	buffer := []rune{}
 	for _, char := range spec + string(endOfSpec) {
 		switch {
 		case isWindowsDrive(buffer, char):
@@ -51,13 +50,12 @@ func ParseVolume(spec string) (types.ServiceVolumeConfig, error) {
 				populateType(&volume)
 				return volume, errors.Wrapf(err, "invalid spec: %s", spec)
 			}
-			buffer = nil
+			buffer = []rune{}
 		default:
 			buffer = append(buffer, char)
 		}
 	}
 
-	volume.Target = path.Clean(volume.Target)
 	populateType(&volume)
 	return volume, nil
 }


Test patch:
diff --git a/loader/full-struct_test.go b/loader/full-struct_test.go
index 3ffcc76..a81e047 100644
--- a/loader/full-struct_test.go
+++ b/loader/full-struct_test.go
@@ -399,7 +399,7 @@ func services(workingDir, homeDir string) []types.ServiceConfig {
 				{Source: "/opt/data", Target: "/var/lib/mysql", Type: "bind", Bind: &types.ServiceVolumeBind{CreateHostPath: true}},
 				{Source: workingDir, Target: "/code", Type: "bind", Bind: &types.ServiceVolumeBind{CreateHostPath: true}},
 				{Source: filepath.Join(workingDir, "static"), Target: "/var/www/html", Type: "bind", Bind: &types.ServiceVolumeBind{CreateHostPath: true}},
-				{Source: filepath.Join(homeDir, "/configs"), Target: "/etc/configs", Type: "bind", ReadOnly: true, Bind: &types.ServiceVolumeBind{CreateHostPath: true}},
+				{Source: filepath.Join(homeDir, "/configs"), Target: "/etc/configs/", Type: "bind", ReadOnly: true, Bind: &types.ServiceVolumeBind{CreateHostPath: true}},
 				{Source: "datavolume", Target: "/var/lib/mysql", Type: "volume", Volume: &types.ServiceVolumeVolume{}},
 				{Source: filepath.Join(workingDir, "opt"), Target: "/opt", Consistency: "cached", Type: "bind"},
 				{Target: "/opt", Type: "tmpfs", Tmpfs: &types.ServiceVolumeTmpfs{
@@ -851,7 +851,7 @@ func fullExampleYAML(workingDir, homeDir string) string {
         create_host_path: true
     - type: bind
       source: %s
-      target: /etc/configs
+      target: /etc/configs/
       read_only: true
       bind:
         create_host_path: true
@@ -1481,7 +1481,7 @@ func fullExampleJSON(workingDir, homeDir string) string {
         {
           "type": "bind",
           "source": "%s",
-          "target": "/etc/configs",
+          "target": "/etc/configs/",
           "read_only": true,
           "bind": {
             "create_host_path": true
diff --git a/loader/merge_test.go b/loader/merge_test.go
index b96fd33..42f5f38 100644
--- a/loader/merge_test.go
+++ b/loader/merge_test.go
@@ -1224,37 +1224,3 @@ func TestMergeCommands(t *testing.T) {
 	assert.NilError(t, err)
 	assert.DeepEqual(t, merged.Services[0].Command, types.ShellCommand{"/bin/ash", "-c", "echo 'world'"})
 }
-
-func TestMergeEnvironments(t *testing.T) {
-	configDetails := types.ConfigDetails{
-		ConfigFiles: []types.ConfigFile{
-			{Filename: "base.yml", Config: map[string]interface{}{
-				"services": map[string]interface{}{
-					"foo": map[string]interface{}{
-						"image": "alpine",
-						"environment": map[string]interface{}{
-							"NAME":  "BASE",
-							"VALUE": "BASE",
-						},
-					},
-				},
-			}},
-			{Filename: "override.yml", Config: map[string]interface{}{
-				"services": map[string]interface{}{
-					"foo": map[string]interface{}{
-						"image": "alpine",
-						"environment": map[string]interface{}{
-							"NAME":  "DEV",
-							"VALUE": nil,
-						},
-					},
-				},
-			}},
-		},
-	}
-	merged, err := loadTestProject(configDetails)
-	assert.NilError(t, err)
-	env := merged.Services[0].Environment
-	assert.Assert(t, *env["NAME"] == "DEV")
-	assert.Assert(t, env["VALUE"] == nil)
-}
diff --git a/loader/volume_test.go b/loader/volume_test.go
index cad2bb0..ca41867 100644
--- a/loader/volume_test.go
+++ b/loader/volume_test.go
@@ -34,13 +34,6 @@ func TestParseVolumeAnonymousVolume(t *testing.T) {
 	}
 }
 
-func TestParseVolumeCleanTarget(t *testing.T) {
-	volume, err := ParseVolume("/path/")
-	expected := types.ServiceVolumeConfig{Type: "volume", Target: "/path", Volume: &types.ServiceVolumeVolume{}}
-	assert.NilError(t, err)
-	assert.Check(t, is.DeepEqual(expected, volume))
-}
-
 func TestParseVolumeAnonymousVolumeWindows(t *testing.T) {
 	for _, path := range []string{"C:\\path", "Z:\\path\\foo"} {
 		volume, err := ParseVolume(path)