Skip to content

Commit 31f34ee

Browse files
authored
Merge pull request #94 from pressly/resolve_vars
Resolve ENV VARs locally
2 parents ef1e199 + 5efc19a commit 31f34ee

File tree

3 files changed

+63
-23
lines changed

3 files changed

+63
-23
lines changed

cmd/sup/main.go

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -246,9 +246,17 @@ func main() {
246246
network.Hosts = hosts
247247
}
248248

249-
// --env flag sets environment variables and overrides values defined in Supfile
250249
var vars sup.EnvList
251-
var supEnv string
250+
for _, val := range append(conf.Env, network.Env...) {
251+
vars.Set(val.Key, val.Value)
252+
}
253+
if err := vars.ResolveValues(); err != nil {
254+
fmt.Fprintln(os.Stderr, err)
255+
os.Exit(1)
256+
}
257+
258+
// Parse CLI --env flag env vars, define $SUP_ENV and override values defined in Supfile.
259+
var cliVars sup.EnvList
252260
for _, env := range envVars {
253261
if len(env) == 0 {
254262
continue
@@ -261,16 +269,16 @@ func main() {
261269
continue
262270
}
263271
vars.Set(env[:i], env[i+1:])
272+
cliVars.Set(env[:i], env[i+1:])
264273
}
265-
if len(vars) > 0 {
266-
network.Env = append(network.Env, vars...)
267274

268-
// Separate loop to omit duplicated keys.
269-
for _, v := range vars {
270-
supEnv += fmt.Sprintf(" -e %v=%q", v.Key, v.Value)
271-
}
272-
network.Env.Set("SUP_ENV", strings.TrimSpace(supEnv))
275+
// SUP_ENV is generated only from CLI env vars.
276+
// Separate loop to omit duplicates.
277+
supEnv := ""
278+
for _, v := range cliVars {
279+
supEnv += fmt.Sprintf(" -e %v=%q", v.Key, v.Value)
273280
}
281+
vars.Set("SUP_ENV", strings.TrimSpace(supEnv))
274282

275283
// Create new Stackup app.
276284
app, err := sup.New(conf)
@@ -282,7 +290,7 @@ func main() {
282290
app.Prefix(!disablePrefix)
283291

284292
// Run all the commands in the given network.
285-
err = app.Run(network, commands...)
293+
err = app.Run(network, vars, commands...)
286294
if err != nil {
287295
fmt.Fprintln(os.Stderr, err)
288296
os.Exit(1)

sup.go

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import (
1313
"golang.org/x/crypto/ssh"
1414
)
1515

16-
const VERSION = "0.4"
16+
const VERSION = "0.5"
1717

1818
type Stackup struct {
1919
conf *Supfile
@@ -30,17 +30,12 @@ func New(conf *Supfile) (*Stackup, error) {
3030
// Run runs set of commands on multiple hosts defined by network sequentially.
3131
// TODO: This megamoth method needs a big refactor and should be split
3232
// to multiple smaller methods.
33-
func (sup *Stackup) Run(network *Network, commands ...*Command) error {
33+
func (sup *Stackup) Run(network *Network, envVars EnvList, commands ...*Command) error {
3434
if len(commands) == 0 {
3535
return errors.New("no commands to be run")
3636
}
3737

38-
// Process all ENVs into a string of form
39-
// `export FOO="bar"; export BAR="baz";`.
40-
env := ``
41-
for _, v := range append(sup.conf.Env, network.Env...) {
42-
env += v.AsExport() + " "
43-
}
38+
env := envVars.AsExport()
4439

4540
// Create clients for every host (either SSH or Localhost).
4641
var bastion *SSHClient

supfile.go

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import (
99
"os/exec"
1010
"strings"
1111

12+
"github.com/pkg/errors"
13+
1214
"gopkg.in/yaml.v2"
1315
)
1416

@@ -70,7 +72,7 @@ func (e EnvVar) AsExport() string {
7072

7173
// EnvList is a list of environment variables that maps to a YAML map,
7274
// but maintains order, enabling late variables to reference early variables.
73-
type EnvList []EnvVar
75+
type EnvList []*EnvVar
7476

7577
func (e *EnvList) UnmarshalYAML(unmarshal func(interface{}) error) error {
7678
items := []yaml.MapItem{}
@@ -91,20 +93,55 @@ func (e *EnvList) UnmarshalYAML(unmarshal func(interface{}) error) error {
9193

9294
// Set key to be equal value in this list.
9395
func (e *EnvList) Set(key, value string) {
94-
9596
for i, v := range *e {
9697
if v.Key == key {
9798
(*e)[i].Value = value
9899
return
99100
}
100101
}
101102

102-
*e = append(*e, EnvVar{
103+
*e = append(*e, &EnvVar{
103104
Key: key,
104105
Value: value,
105106
})
106107
}
107108

109+
func (e *EnvList) ResolveValues() error {
110+
if len(*e) == 0 {
111+
return nil
112+
}
113+
114+
exports := ""
115+
for i, v := range *e {
116+
exports += v.AsExport()
117+
118+
cmd := exec.Command("bash", "-c", exports+"echo -n "+v.Value+";")
119+
cwd, err := os.Getwd()
120+
if err != nil {
121+
return err
122+
}
123+
cmd.Dir = cwd
124+
resolvedValue, err := cmd.Output()
125+
if err != nil {
126+
return errors.Wrapf(err, "resolving env var %v failed", v.Key)
127+
}
128+
129+
(*e)[i].Value = string(resolvedValue)
130+
}
131+
132+
return nil
133+
}
134+
135+
func (e *EnvList) AsExport() string {
136+
// Process all ENVs into a string of form
137+
// `export FOO="bar"; export BAR="baz";`.
138+
exports := ``
139+
for _, v := range *e {
140+
exports += v.AsExport() + " "
141+
}
142+
return exports
143+
}
144+
108145
type ErrMustUpdate struct {
109146
Msg string
110147
}
@@ -173,10 +210,10 @@ func NewSupfile(file string) (*Supfile, error) {
173210

174211
fallthrough
175212

176-
case "0.4":
213+
case "0.4", "0.5":
177214

178215
default:
179-
return nil, ErrMustUpdate{"unsupported version"}
216+
return nil, ErrMustUpdate{"unsupported version " + conf.Version}
180217
}
181218

182219
for i, network := range conf.Networks {

0 commit comments

Comments
 (0)