Repository: compose-spec/compose-go
Pull request #271 (2022-06-02 14:44:48)

allow '.' (dot) in environment variable name
Fix https://github.com/docker/compose/issues/8862


Patch:
diff --git a/README.md b/README.md
index 97de5a5..e0ccbc8 100644
--- a/README.md
+++ b/README.md
@@ -9,4 +9,3 @@ Go reference library for parsing and loading Compose files as specified by the
 * [compose-ref](https://github.com/compose-spec/compose-ref)
 * [containerd/nerdctl](https://github.com/containerd/nerdctl)
 * [compose-cli](https://github.com/docker/compose-cli)
-* [tilt.dev](https://github.com/tilt-dev/tilt)
diff --git a/dotenv/parser.go b/dotenv/parser.go
index fab656b..4ca6bd0 100644
--- a/dotenv/parser.go
+++ b/dotenv/parser.go
@@ -105,9 +105,9 @@ loop:
 			offset = i + 1
 			inherited = char == '\n'
 			break loop
-		case '_':
+		case '_', '.':
 		default:
-			// variable name should match [A-Za-z0-9_]
+			// variable name should match [A-Za-z0-9_.]
 			if unicode.IsLetter(rchar) || unicode.IsNumber(rchar) {
 				continue
 			}
diff --git a/loader/example1.env b/loader/example1.env
index f19ec0d..61716e9 100644
--- a/loader/example1.env
+++ b/loader/example1.env
@@ -1,5 +1,7 @@
 # passed through
 FOO=foo_from_env_file
+ENV.WITH.DOT=ok
+ENV_WITH_UNDERSCORE=ok
 
 # overridden in example2.env
 BAR=bar_from_env_file


Test patch:
diff --git a/loader/full-struct_test.go b/loader/full-struct_test.go
index 9bdb637..28da93c 100644
--- a/loader/full-struct_test.go
+++ b/loader/full-struct_test.go
@@ -164,10 +164,12 @@ func services(workingDir, homeDir string) []types.ServiceConfig {
 			DomainName: "foo.com",
 			Entrypoint: []string{"/code/entrypoint.sh", "-p", "3000"},
 			Environment: map[string]*string{
-				"FOO": strPtr("foo_from_env_file"),
-				"BAR": strPtr("this is a secret"),
-				"BAZ": strPtr("baz_from_service_def"),
-				"QUX": strPtr("qux_from_environment"),
+				"FOO":                 strPtr("foo_from_env_file"),
+				"BAR":                 strPtr("this is a secret"),
+				"BAZ":                 strPtr("baz_from_service_def"),
+				"QUX":                 strPtr("qux_from_environment"),
+				"ENV.WITH.DOT":        strPtr("ok"),
+				"ENV_WITH_UNDERSCORE": strPtr("ok"),
 			},
 			EnvFile: []string{
 				"./example1.env",
@@ -691,6 +693,8 @@ services:
     environment:
       BAR: this is a secret
       BAZ: baz_from_service_def
+      ENV.WITH.DOT: ok
+      ENV_WITH_UNDERSCORE: ok
       FOO: foo_from_env_file
       QUX: qux_from_environment
     env_file:
@@ -1261,6 +1265,8 @@ func fullExampleJSON(workingDir, homeDir string) string {
       "environment": {
         "BAR": "this is a secret",
         "BAZ": "baz_from_service_def",
+        "ENV.WITH.DOT": "ok",
+        "ENV_WITH_UNDERSCORE": "ok",
         "FOO": "foo_from_env_file",
         "QUX": "qux_from_environment"
       },
diff --git a/loader/loader_test.go b/loader/loader_test.go
index 60569b2..ca64d98 100644
--- a/loader/loader_test.go
+++ b/loader/loader_test.go
@@ -766,10 +766,12 @@ func TestDiscardEnvFileOption(t *testing.T) {
      - example2.env
 `
 	expectedEnvironmentMap := types.MappingWithEquals{
-		"FOO": strPtr("foo_from_env_file"),
-		"BAZ": strPtr("baz_from_env_file"),
-		"BAR": strPtr("bar_from_env_file_2"), // Original value is overwritten by example2.env
-		"QUX": strPtr("quz_from_env_file_2"),
+		"FOO":                 strPtr("foo_from_env_file"),
+		"BAZ":                 strPtr("baz_from_env_file"),
+		"BAR":                 strPtr("bar_from_env_file_2"), // Original value is overwritten by example2.env
+		"QUX":                 strPtr("quz_from_env_file_2"),
+		"ENV.WITH.DOT":        strPtr("ok"),
+		"ENV_WITH_UNDERSCORE": strPtr("ok"),
 	}
 	configDetails := buildConfigDetails(dict, nil)