Skip to content

Commit e497f1b

Browse files
authored
Merge pull request #269 from compose-spec/public-dot-env
Make dotEnv resolution plublic
2 parents e80b082 + a741998 commit e497f1b

File tree

3 files changed

+59
-43
lines changed

3 files changed

+59
-43
lines changed

cli/options.go

Lines changed: 36 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ func WithDefaultConfigPath(o *ProjectOptions) error {
145145
// WithEnv defines a key=value set of variables used for compose file interpolation
146146
func WithEnv(env []string) ProjectOptionsFn {
147147
return func(o *ProjectOptions) error {
148-
for k, v := range getAsEqualsMap(env) {
148+
for k, v := range utils.GetAsEqualsMap(env) {
149149
o.Environment[k] = v
150150
}
151151
return nil
@@ -169,7 +169,7 @@ func WithLoadOptions(loadOptions ...func(*loader.Options)) ProjectOptionsFn {
169169

170170
// WithOsEnv imports environment variables from OS
171171
func WithOsEnv(o *ProjectOptions) error {
172-
for k, v := range getAsEqualsMap(os.Environ()) {
172+
for k, v := range utils.GetAsEqualsMap(os.Environ()) {
173173
if _, set := o.Environment[k]; set {
174174
continue
175175
}
@@ -188,62 +188,76 @@ func WithEnvFile(file string) ProjectOptionsFn {
188188

189189
// WithDotEnv imports environment variables from .env file
190190
func WithDotEnv(o *ProjectOptions) error {
191-
dotEnvFile := o.EnvFile
191+
wd, err := o.GetWorkingDir()
192+
if err != nil {
193+
return err
194+
}
195+
envMap, err := GetEnvFromFile(o.Environment, wd, o.EnvFile)
196+
if err != nil {
197+
return err
198+
}
199+
for k, v := range envMap {
200+
o.Environment[k] = v
201+
}
202+
return nil
203+
}
204+
205+
func GetEnvFromFile(currentEnv map[string]string, workingDir string, filename string) (map[string]string, error) {
206+
envMap := make(map[string]string)
207+
208+
dotEnvFile := filename
192209
if dotEnvFile == "" {
193-
wd, err := o.GetWorkingDir()
194-
if err != nil {
195-
return err
196-
}
197-
dotEnvFile = filepath.Join(wd, ".env")
210+
dotEnvFile = filepath.Join(workingDir, ".env")
198211
}
199212
abs, err := filepath.Abs(dotEnvFile)
200213
if err != nil {
201-
return err
214+
return envMap, err
202215
}
203216
dotEnvFile = abs
204217

205218
s, err := os.Stat(dotEnvFile)
206219
if os.IsNotExist(err) {
207-
if o.EnvFile != "" {
208-
return errors.Errorf("Couldn't find env file: %s", o.EnvFile)
220+
if filename != "" {
221+
return nil, errors.Errorf("Couldn't find env file: %s", filename)
209222
}
210-
return nil
223+
return envMap, nil
211224
}
212225
if err != nil {
213-
return err
226+
return envMap, err
214227
}
215228

216229
if s.IsDir() {
217-
if o.EnvFile == "" {
218-
return nil
230+
if filename == "" {
231+
return envMap, nil
219232
}
220-
return errors.Errorf("%s is a directory", dotEnvFile)
233+
return envMap, errors.Errorf("%s is a directory", dotEnvFile)
221234
}
222235

223236
file, err := os.Open(dotEnvFile)
224237
if err != nil {
225-
return err
238+
return envMap, err
226239
}
227240
defer file.Close()
228241

229242
env, err := dotenv.ParseWithLookup(file, func(k string) (string, bool) {
230-
v, ok := o.Environment[k]
243+
v, ok := currentEnv[k]
231244
if !ok {
232245

233246
return "", false
234247
}
235248
return v, true
236249
})
237250
if err != nil {
238-
return err
251+
return envMap, err
239252
}
240253
for k, v := range env {
241-
if _, set := o.Environment[k]; set {
254+
if _, set := currentEnv[k]; set {
242255
continue
243256
}
244-
o.Environment[k] = v
257+
envMap[k] = v
245258
}
246-
return nil
259+
260+
return envMap, nil
247261
}
248262

249263
// WithInterpolation set ProjectOptions to enable/skip interpolation
@@ -412,22 +426,3 @@ func absolutePaths(p []string) ([]string, error) {
412426
}
413427
return paths, nil
414428
}
415-
416-
// getAsEqualsMap split key=value formatted strings into a key : value map
417-
func getAsEqualsMap(em []string) map[string]string {
418-
m := make(map[string]string)
419-
for _, v := range em {
420-
kv := strings.SplitN(v, "=", 2)
421-
m[kv[0]] = kv[1]
422-
}
423-
return m
424-
}
425-
426-
// getAsEqualsMap format a key : value map into key=value strings
427-
func getAsStringList(em map[string]string) []string {
428-
m := make([]string, 0, len(em))
429-
for k, v := range em {
430-
m = append(m, fmt.Sprintf("%s=%s", k, v))
431-
}
432-
return m
433-
}

cli/options_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"testing"
2424

2525
"github.com/compose-spec/compose-go/consts"
26+
"github.com/compose-spec/compose-go/utils"
2627
"gotest.tools/v3/assert"
2728
)
2829

@@ -231,8 +232,8 @@ func TestProjectNameFromWorkingDir(t *testing.T) {
231232
func TestEnvMap(t *testing.T) {
232233
m := map[string]string{}
233234
m["foo"] = "bar"
234-
l := getAsStringList(m)
235+
l := utils.GetAsStringList(m)
235236
assert.Equal(t, l[0], "foo=bar")
236-
m = getAsEqualsMap(l)
237+
m = utils.GetAsEqualsMap(l)
237238
assert.Equal(t, m["foo"], "bar")
238239
}

utils/stringutils.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package utils
1818

1919
import (
20+
"fmt"
2021
"strconv"
2122
"strings"
2223
)
@@ -36,3 +37,22 @@ func StringToBool(s string) bool {
3637
b, _ := strconv.ParseBool(strings.ToLower(strings.TrimSpace(s)))
3738
return b
3839
}
40+
41+
// GetAsEqualsMap split key=value formatted strings into a key : value map
42+
func GetAsEqualsMap(em []string) map[string]string {
43+
m := make(map[string]string)
44+
for _, v := range em {
45+
kv := strings.SplitN(v, "=", 2)
46+
m[kv[0]] = kv[1]
47+
}
48+
return m
49+
}
50+
51+
// GetAsEqualsMap format a key : value map into key=value strings
52+
func GetAsStringList(em map[string]string) []string {
53+
m := make([]string, 0, len(em))
54+
for k, v := range em {
55+
m = append(m, fmt.Sprintf("%s=%s", k, v))
56+
}
57+
return m
58+
}

0 commit comments

Comments
 (0)