You've already forked docker-volume-backup
mirror of
https://github.com/offen/docker-volume-backup.git
synced 2025-11-23 21:44:40 +02:00
Use proper path expansion
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@@ -11,6 +12,7 @@ import (
|
||||
"github.com/joho/godotenv"
|
||||
"github.com/offen/docker-volume-backup/internal/errwrap"
|
||||
"github.com/offen/envconfig"
|
||||
shell "mvdan.cc/sh/v3/shell"
|
||||
)
|
||||
|
||||
type configStrategy string
|
||||
@@ -99,11 +101,7 @@ func loadConfigsFromEnvFiles(directory string) ([]*Config, error) {
|
||||
continue
|
||||
}
|
||||
p := filepath.Join(directory, item.Name())
|
||||
f, err := os.ReadFile(p)
|
||||
if err != nil {
|
||||
return nil, errwrap.Wrap(err, fmt.Sprintf("error reading %s", item.Name()))
|
||||
}
|
||||
envFile, err := godotenv.Unmarshal(os.ExpandEnv(string(f)))
|
||||
envFile, err := source(p)
|
||||
if err != nil {
|
||||
return nil, errwrap.Wrap(err, fmt.Sprintf("error reading config file %s", p))
|
||||
}
|
||||
@@ -125,3 +123,39 @@ func loadConfigsFromEnvFiles(directory string) ([]*Config, error) {
|
||||
|
||||
return configs, nil
|
||||
}
|
||||
|
||||
// source tries to mimic the pre v2.37.0 behavior of calling
|
||||
// `set +a; source $path; set -a` and returns the env vars as a map
|
||||
func source(path string) (map[string]string, error) {
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
return nil, errwrap.Wrap(err, fmt.Sprintf("error opening %s", path))
|
||||
}
|
||||
|
||||
result := map[string]string{}
|
||||
scanner := bufio.NewScanner(f)
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
withExpansion, err := shell.Expand(line, nil)
|
||||
if err != nil {
|
||||
return nil, errwrap.Wrap(err, "error expanding env")
|
||||
}
|
||||
m, err := godotenv.Unmarshal(withExpansion)
|
||||
if err != nil {
|
||||
return nil, errwrap.Wrap(err, fmt.Sprintf("error sourcing %s", path))
|
||||
}
|
||||
for key, value := range m {
|
||||
currentValue, currentOk := os.LookupEnv(key)
|
||||
defer func() {
|
||||
if currentOk {
|
||||
os.Setenv(key, currentValue)
|
||||
return
|
||||
}
|
||||
os.Unsetenv(key)
|
||||
}()
|
||||
result[key] = value
|
||||
os.Setenv(key, value)
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
68
cmd/backup/config_provider_test.go
Normal file
68
cmd/backup/config_provider_test.go
Normal file
@@ -0,0 +1,68 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSource(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
input string
|
||||
expectError bool
|
||||
expectedOutput map[string]string
|
||||
}{
|
||||
{
|
||||
"default",
|
||||
"testdata/default.env",
|
||||
false,
|
||||
map[string]string{
|
||||
"FOO": "bar",
|
||||
"BAZ": "qux",
|
||||
},
|
||||
},
|
||||
{
|
||||
"not found",
|
||||
"testdata/nope.env",
|
||||
true,
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"braces",
|
||||
"testdata/braces.env",
|
||||
false,
|
||||
map[string]string{
|
||||
"FOO": "qux",
|
||||
"BAR": "xxx",
|
||||
"BAZ": "",
|
||||
},
|
||||
},
|
||||
{
|
||||
"expansion",
|
||||
"testdata/expansion.env",
|
||||
false,
|
||||
map[string]string{
|
||||
"BAR": "xxx",
|
||||
"FOO": "xxx",
|
||||
"BAZ": "xxx",
|
||||
"QUX": "yyy",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
os.Setenv("QUX", "yyy")
|
||||
defer os.Unsetenv("QUX")
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
result, err := source(test.input)
|
||||
if (err != nil) != test.expectError {
|
||||
t.Errorf("Unexpected error value %v", err)
|
||||
}
|
||||
if !reflect.DeepEqual(test.expectedOutput, result) {
|
||||
t.Errorf("Expected %v, got %v", test.expectedOutput, result)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
3
cmd/backup/testdata/braces.env
vendored
Normal file
3
cmd/backup/testdata/braces.env
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
FOO=${bar:-qux}
|
||||
BAR=xxx
|
||||
BAZ=$NOPE
|
||||
2
cmd/backup/testdata/default.env
vendored
Normal file
2
cmd/backup/testdata/default.env
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
FOO=bar
|
||||
BAZ=qux
|
||||
4
cmd/backup/testdata/expansion.env
vendored
Normal file
4
cmd/backup/testdata/expansion.env
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
BAR=xxx
|
||||
FOO=${BAR}
|
||||
BAZ=$BAR
|
||||
QUX=${QUX}
|
||||
Reference in New Issue
Block a user