[config] config:export --merge, --prefix, & --suffix
This commit is contained in:
@@ -10,29 +10,8 @@ config_docker_args() {
|
||||
verify_app_name "$APP"
|
||||
|
||||
if ! is_image_herokuish_based "$IMAGE"; then
|
||||
shopt -s extglob
|
||||
local ENV_ARGS
|
||||
declare -A ENV_ARGS
|
||||
for key in $(config_keys global); do
|
||||
VAR="$(config_get --global "$key")"
|
||||
printf -vVAR '%q' "${VAR%%*( )}"
|
||||
ENV_ARGS[$key]="$VAR"
|
||||
done
|
||||
for key in $(config_keys app "$APP"); do
|
||||
VAR="$(config_get "$APP" "$key")"
|
||||
printf -vVAR '%q' "${VAR%%*( )}"
|
||||
ENV_ARGS[$key]="$VAR"
|
||||
done
|
||||
shopt -u extglob
|
||||
local ALL_ENV_ARGS
|
||||
declare -a ALL_ENV_ARGS
|
||||
for key in "${!ENV_ARGS[@]}"; do
|
||||
local ARG="$key=${ENV_ARGS[$key]}"
|
||||
ALL_ENV_ARGS+=("--env")
|
||||
ALL_ENV_ARGS+=("$ARG")
|
||||
done
|
||||
|
||||
echo -n "$STDIN ${ALL_ENV_ARGS[@]}"
|
||||
local ENV_ARGS="$(config_export app $APP --prefix="-e" --separator=" " --merged)"
|
||||
echo -n "$STDIN $ENV_ARGS"
|
||||
else
|
||||
echo -n "$STDIN"
|
||||
fi
|
||||
|
||||
@@ -24,22 +24,23 @@ func (e *Env) String() string {
|
||||
|
||||
//EnvfileString returns the contents of this Env in ENVFILE format
|
||||
func (e *Env) EnvfileString() string {
|
||||
return e.stringWithEntryPrefix("")
|
||||
return e.StringWithPrefixAndSeparator("", "\n")
|
||||
}
|
||||
|
||||
//ExportfileString returns the contents of this Env as bash exports
|
||||
func (e *Env) ExportfileString() string {
|
||||
return e.stringWithEntryPrefix("export ")
|
||||
return e.StringWithPrefixAndSeparator("export ", "\n")
|
||||
}
|
||||
|
||||
func (e *Env) stringWithEntryPrefix(prefix string) string {
|
||||
//StringWithPrefixAndSeparator makes a string of the environment
|
||||
// with the given prefix and separator for each entry
|
||||
func (e *Env) StringWithPrefixAndSeparator(prefix string, separator string) string {
|
||||
keys := e.Keys()
|
||||
sort.Strings(keys)
|
||||
entries := make([]string, len(keys))
|
||||
for i, k := range keys {
|
||||
entries[i] = fmt.Sprintf("%s%s='%s'", prefix, k, SingleQuoteEscape(e.env[k]))
|
||||
}
|
||||
return strings.Join(entries, "\n")
|
||||
return strings.Join(entries, separator)
|
||||
}
|
||||
|
||||
//SingleQuoteEscape escapes the value as if it were shell-quoted in single quotes
|
||||
@@ -50,13 +51,23 @@ func SingleQuoteEscape(value string) string { // so that 'esc'apped' -> 'esc'\''
|
||||
//NewFromTarget creates an env from the given target. Tareget is either "--global" or an app name
|
||||
func NewFromTarget(target string) (*Env, error) {
|
||||
if target == "--global" {
|
||||
return parseEnv("global", getGlobalFile())
|
||||
return LoadGlobal()
|
||||
}
|
||||
appfile, err := getAppFile(target)
|
||||
return LoadApp(target)
|
||||
}
|
||||
|
||||
//LoadApp loads an environment for the given app
|
||||
func LoadApp(appName string) (*Env, error) {
|
||||
appfile, err := getAppFile(appName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return parseEnv(target, appfile)
|
||||
return parseEnv(appName, appfile)
|
||||
}
|
||||
|
||||
//LoadGlobal loads the global environmen
|
||||
func LoadGlobal() (*Env, error) {
|
||||
return parseEnv("global", getGlobalFile())
|
||||
}
|
||||
|
||||
//NewFromString creates an env from the given ENVFILE contents representation
|
||||
@@ -64,6 +75,13 @@ func NewFromString(rep string) (*Env, error) {
|
||||
return parseEnvFromReader("<unknown>", "", strings.NewReader(rep))
|
||||
}
|
||||
|
||||
//Merge merges the given environment on top of the reciever
|
||||
func (e *Env) Merge(other *Env) {
|
||||
for _, k := range other.Keys() {
|
||||
e.Set(k, other.GetDefault(k, ""))
|
||||
}
|
||||
}
|
||||
|
||||
//Set an environment variable
|
||||
func (e *Env) Set(key string, value string) {
|
||||
e.env[key] = value
|
||||
@@ -80,6 +98,7 @@ func (e *Env) Keys() []string {
|
||||
for k := range e.env {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
return keys
|
||||
}
|
||||
|
||||
@@ -108,6 +127,11 @@ func (e *Env) GetBoolDefault(key string, defaultValue bool) bool {
|
||||
return v != "0"
|
||||
}
|
||||
|
||||
//Len return the number of items in this environment
|
||||
func (e *Env) Len() int {
|
||||
return len(e.env)
|
||||
}
|
||||
|
||||
//Map return the Env as a map
|
||||
func (e *Env) Map() map[string]string {
|
||||
return e.env
|
||||
|
||||
@@ -44,6 +44,21 @@ func TestExportfileErrors(t *testing.T) {
|
||||
Expect(err).To(HaveOccurred())
|
||||
}
|
||||
|
||||
func TestMerge(t *testing.T) {
|
||||
RegisterTestingT(t)
|
||||
e, _ := NewFromString("FOO='bar'")
|
||||
e2, _ := NewFromString("BAR='baz'")
|
||||
e.Merge(e2)
|
||||
Expect(e.Map()).To(Equal(pairs("BAR", "baz", "FOO", "bar")))
|
||||
}
|
||||
|
||||
func TestArrayExport(t *testing.T) {
|
||||
RegisterTestingT(t)
|
||||
e, _ := NewFromString("BAR='BAZ'\nFOO='b'\\''ar '")
|
||||
Expect(e.StringWithPrefixAndSeparator("", " ")).To(Equal("BAR='BAZ' FOO='b'\\''ar '"))
|
||||
Expect(e.StringWithPrefixAndSeparator("-e", " ")).To(Equal("-eBAR='BAZ' -eFOO='b'\\''ar '"))
|
||||
}
|
||||
|
||||
func pairs(vars ...string) map[string]string {
|
||||
res := map[string]string{}
|
||||
var i = 0
|
||||
|
||||
@@ -11,10 +11,14 @@ import (
|
||||
|
||||
// print the environment to stdout
|
||||
func main() {
|
||||
const defaultPrefix = "export "
|
||||
args := flag.NewFlagSet("config:export", flag.ExitOnError)
|
||||
global := args.Bool("global", false, "--global: use the global environment")
|
||||
merged := args.Bool("merged", false, "--merged: merge app environment and global environment")
|
||||
keys := args.Bool("keys", false, "--keys: export keys only")
|
||||
envfile := args.Bool("envfile", false, "--envfile: export as envfile rather than bash exports")
|
||||
envfile := args.Bool("envfile", false, "--envfile: export as envfile rather than bash exports (--prefix='')")
|
||||
prefix := args.String("prefix", "export ", "--prefix: prefix")
|
||||
separator := args.String("separator", "\n", "--separator: separator")
|
||||
args.Parse(os.Args[2:])
|
||||
|
||||
appName := args.Arg(0)
|
||||
@@ -26,6 +30,9 @@ func main() {
|
||||
if appName != "" {
|
||||
common.LogFail("Trailing argument: " + appName)
|
||||
}
|
||||
if *merged == true {
|
||||
common.LogFail("Only app environments can be merged")
|
||||
}
|
||||
appName = "--global"
|
||||
}
|
||||
|
||||
@@ -33,6 +40,16 @@ func main() {
|
||||
if err != nil {
|
||||
common.LogFail(err.Error())
|
||||
}
|
||||
|
||||
if *merged {
|
||||
global, err := configenv.LoadGlobal()
|
||||
if err != nil {
|
||||
common.LogFail(err.Error())
|
||||
}
|
||||
global.Merge(env)
|
||||
env = global
|
||||
}
|
||||
|
||||
if *keys {
|
||||
for _, k := range env.Keys() {
|
||||
fmt.Println(k)
|
||||
@@ -41,8 +58,11 @@ func main() {
|
||||
}
|
||||
|
||||
if *envfile {
|
||||
fmt.Println(env.EnvfileString())
|
||||
} else {
|
||||
fmt.Println(env.ExportfileString())
|
||||
if *prefix != defaultPrefix {
|
||||
common.LogFail("--prefix and --envfile cannot both be given")
|
||||
return
|
||||
}
|
||||
*prefix = ""
|
||||
}
|
||||
fmt.Println(env.StringWithPrefixAndSeparator(*prefix, *separator))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user