Skip to content

Commit 84ad644

Browse files
committed
alpha: initial critical support, build vars
1 parent 9ec8504 commit 84ad644

File tree

23 files changed

+222
-111
lines changed

23 files changed

+222
-111
lines changed

cmd/apps.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ func (e *Executor) newAppsCmd() *cobra.Command {
3636
return config.ErrProjectConfigNotFound
3737
}
3838

39+
// TODO: list apps from state as well
3940
return actions.NewAppList(e.Log(), e.cfg, listOpts).Run(cmd.Context())
4041
},
4142
}

cmd/deploy.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ func (e *Executor) newDeployCmd() *cobra.Command {
7070
f.BoolVar(&opts.Lock, "lock", true, "lock statefile during deploy")
7171
f.DurationVar(&opts.LockWait, "lock-wait", 0, "wait for lock if it is already acquired")
7272
f.BoolVar(&opts.AutoApprove, "yes", false, "auto approve changes")
73+
f.BoolVar(&opts.ForceApprove, "force", false, "force approve even critical changes")
7374
f.StringSliceVarP(&targetApps, "target-apps", "t", nil, "target only specified apps, can specify multiple or separate values with comma in a form of <app type>.<name>, e.g.: static.website,service.api")
7475
f.StringSliceVarP(&skipApps, "skip-apps", "s", nil, "skip specified apps (if they exist), can specify multiple or separate values with comma in a form of <app type>.<name>, e.g.: static.website,service.api")
7576
f.BoolVar(&opts.SkipAllApps, "skip-all-apps", false, "skip all apps (if they exist)")

cmd/executor.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,6 @@ func (e *Executor) commandPreRun(ctx context.Context) error {
7979
if cmd != nil {
8080
skipLoadConfig = cmd.Annotations[cmdSkipLoadConfigAnnotation] == "1"
8181
skipLoadApps = cmd.Annotations[cmdSkipLoadAppsAnnotation] == "1"
82-
skipLoadPlugins = cmd.Annotations[cmdSkipLoadPluginsAnnotation] == "1"
8382
skipCheckConfig = cmd.Annotations[cmdSkipCheckConfigAnnotation] == "1"
8483

8584
if skipLoadConfig {
@@ -121,7 +120,13 @@ func (e *Executor) commandPreRun(ctx context.Context) error {
121120
}
122121

123122
// Augment/load new commands.
124-
if skipLoadPlugins {
123+
return e.addPluginsCommands(cmd)
124+
}
125+
126+
func (e *Executor) addPluginsCommands(cmd *cobra.Command) error {
127+
skipLoadPlugins := cmd.Annotations[cmdSkipLoadPluginsAnnotation] == "1"
128+
129+
if skipLoadPlugins || e.cfg == nil {
125130
return nil
126131
}
127132

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ require (
1616
github.com/mholt/archiver/v3 v3.5.1
1717
github.com/mitchellh/go-homedir v1.1.0
1818
github.com/otiai10/copy v1.6.0
19-
github.com/outblocks/outblocks-plugin-go v0.0.0-20211112163452-b28f04e185aa
19+
github.com/outblocks/outblocks-plugin-go v0.0.0-20211115132657-c42fed05643f
2020
github.com/pterm/pterm v0.12.33
2121
github.com/spf13/cobra v1.2.1
2222
github.com/spf13/pflag v1.0.5

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -681,8 +681,8 @@ github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6
681681
github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo=
682682
github.com/otiai10/mint v1.3.2 h1:VYWnrP5fXmz1MXvjuUvcBrXSjGE6xjON+axB/UrpO3E=
683683
github.com/otiai10/mint v1.3.2/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc=
684-
github.com/outblocks/outblocks-plugin-go v0.0.0-20211112163452-b28f04e185aa h1:Dqz3zbQTe4euERE1ufU9WQSswrKxrNxNhoOLL8nK6NI=
685-
github.com/outblocks/outblocks-plugin-go v0.0.0-20211112163452-b28f04e185aa/go.mod h1:xosanOIc+3GlRA9b90/xRoYWzRgdhbew9T7+yTeI/TQ=
684+
github.com/outblocks/outblocks-plugin-go v0.0.0-20211115132657-c42fed05643f h1:Z6bxU4JvJSYM5piFCRWB0VMWjcDIXTWWAUNcTyHSfsY=
685+
github.com/outblocks/outblocks-plugin-go v0.0.0-20211115132657-c42fed05643f/go.mod h1:xosanOIc+3GlRA9b90/xRoYWzRgdhbew9T7+yTeI/TQ=
686686
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
687687
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
688688
github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=

internal/util/util.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,5 +87,5 @@ func IsTermDumb() bool {
8787
return true
8888
}
8989

90-
return true
90+
return false
9191
}

internal/util/vars.go

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package util
2+
3+
import (
4+
"fmt"
5+
"regexp"
6+
"strings"
7+
8+
"github.com/outblocks/outblocks-plugin-go/util"
9+
)
10+
11+
var escapePercent = regexp.MustCompile(`%([^{]|$)`)
12+
13+
type VarEvaluator struct {
14+
*util.BaseVarEvaluator
15+
}
16+
17+
func NewVarEvaluator(vars map[string]interface{}) *VarEvaluator {
18+
return &VarEvaluator{
19+
BaseVarEvaluator: util.NewBaseVarEvaluator(vars).
20+
WithEncoder(varEncoder).
21+
WithVarChar('%').
22+
WithIgnoreInvalid(true),
23+
}
24+
}
25+
26+
func varEncoder(input interface{}) ([]byte, error) {
27+
switch input.(type) {
28+
case string:
29+
return []byte("%s"), nil
30+
case int:
31+
return []byte("%d"), nil
32+
}
33+
34+
return nil, fmt.Errorf("unknown input type")
35+
}
36+
37+
func (e *VarEvaluator) Expand(input string) (string, error) {
38+
input = escapePercent.ReplaceAllString(input, "%$0")
39+
40+
format, params, err := e.ExpandRaw([]byte(input))
41+
if err != nil {
42+
return "", err
43+
}
44+
45+
return fmt.Sprintf(strings.ReplaceAll(string(format), "%{", "%%{"), params...), nil
46+
}
47+
48+
func (e *VarEvaluator) ExpandStringMap(input map[string]string) (map[string]string, error) {
49+
out := make(map[string]string, len(input))
50+
51+
var err error
52+
53+
for k, v := range input {
54+
out[k], err = e.Expand(v)
55+
if err != nil {
56+
return nil, err
57+
}
58+
}
59+
60+
return out, nil
61+
}

pkg/actions/app_add.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,7 @@ func (d *AppAdd) prompt() (interface{}, error) {
394394
return d.promptStatic()
395395
case config.AppTypeService:
396396
return d.promptService()
397-
// TODO: add adding app function
397+
// TODO: add adding function app
398398
default:
399399
return nil, fmt.Errorf("unsupported app type (WIP)")
400400
}
@@ -518,10 +518,10 @@ func (d *AppAdd) promptStatic() (*staticAppInfo, error) {
518518
AppType: config.AppTypeStatic,
519519
AppURL: d.opts.URL,
520520
AppDir: d.opts.Dir,
521-
AppDeploy: &config.AppDeploy{
521+
AppDeploy: &types.AppDeployInfo{
522522
Plugin: d.opts.DeployPlugin,
523523
},
524-
AppRun: &config.AppRun{
524+
AppRun: &types.AppRunInfo{
525525
Plugin: d.opts.RunPlugin,
526526
Command: d.opts.RunCommand,
527527
},
@@ -545,7 +545,7 @@ func (d *AppAdd) promptService() (*serviceAppInfo, error) { // nolint: unparam
545545
AppType: config.AppTypeService,
546546
AppURL: d.opts.URL,
547547
AppDir: d.opts.Dir,
548-
AppRun: &config.AppRun{
548+
AppRun: &types.AppRunInfo{
549549
Command: d.opts.RunCommand,
550550
},
551551
},

pkg/actions/deploy.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ type DeployOptions struct {
4949
Lock bool
5050
LockWait time.Duration
5151
AutoApprove bool
52+
ForceApprove bool
5253
TargetApps, SkipApps []string
5354
SkipAllApps bool
5455
}
@@ -144,7 +145,7 @@ func (d *Deploy) planAndApply(ctx context.Context, verify bool, state *types.Sta
144145

145146
spinner.Stop()
146147

147-
empty, canceled := planPrompt(d.log, deployChanges, dnsChanges, d.opts.AutoApprove)
148+
empty, canceled := planPrompt(d.log, deployChanges, dnsChanges, d.opts.AutoApprove, d.opts.ForceApprove)
148149

149150
shouldApply := !canceled && !empty
150151

pkg/actions/deploy_build.go

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
dockerclient "github.com/docker/docker/client"
1414
"github.com/outblocks/outblocks-cli/internal/util"
1515
"github.com/outblocks/outblocks-cli/pkg/config"
16+
"github.com/outblocks/outblocks-plugin-go/types"
1617
plugin_util "github.com/outblocks/outblocks-plugin-go/util"
1718
"github.com/outblocks/outblocks-plugin-go/util/errgroup"
1819
"github.com/pterm/pterm"
@@ -112,9 +113,16 @@ func (d *Deploy) runAppBuildCommand(ctx context.Context, cmd *util.CmdInfo, app
112113
return nil
113114
}
114115

115-
func (d *Deploy) buildStaticApp(ctx context.Context, app *config.StaticApp) error {
116+
func (d *Deploy) buildStaticApp(ctx context.Context, app *config.StaticApp, eval *util.VarEvaluator) error {
117+
var err error
118+
116119
env := plugin_util.MergeStringMaps(app.Env(), app.Build.Env)
117120

121+
env, err = eval.ExpandStringMap(env)
122+
if err != nil {
123+
return err
124+
}
125+
118126
cmd, err := util.NewCmdInfo(app.Build.Command, app.Dir(), util.FlattenEnvMap(env))
119127
if err != nil {
120128
return fmt.Errorf("error preparing build command for %s app: %s: %w", app.Type(), app.Name(), err)
@@ -123,7 +131,7 @@ func (d *Deploy) buildStaticApp(ctx context.Context, app *config.StaticApp) erro
123131
return d.runAppBuildCommand(ctx, cmd, &app.BasicApp)
124132
}
125133

126-
func (d *Deploy) buildServiceApp(ctx context.Context, app *config.ServiceApp) error {
134+
func (d *Deploy) buildServiceApp(ctx context.Context, app *config.ServiceApp, eval *util.VarEvaluator) error {
127135
dockercontext := filepath.Join(app.Dir(), app.Build.DockerContext)
128136
dockercontext, ok := plugin_util.CheckDir(dockercontext)
129137

@@ -142,7 +150,12 @@ func (d *Deploy) buildServiceApp(ctx context.Context, app *config.ServiceApp) er
142150
return err
143151
}
144152

145-
buildArgs := util.FlattenEnvMap(app.Build.DockerBuildArgs)
153+
buildArgsMap, err := eval.ExpandStringMap(app.Build.DockerBuildArgs)
154+
if err != nil {
155+
return err
156+
}
157+
158+
buildArgs := util.FlattenEnvMap(buildArgsMap)
146159
for i, arg := range buildArgs {
147160
buildArgs[i] = strings.ReplaceAll(arg, "\"", "\\\"")
148161
}
@@ -183,6 +196,20 @@ type appBuilder struct {
183196
}
184197

185198
func (d *Deploy) buildApps(ctx context.Context) error {
199+
appTypeMap := make(map[string]*types.App)
200+
201+
if len(d.opts.TargetApps) != 0 || len(d.opts.SkipApps) != 0 {
202+
// Get state apps as well.
203+
state, _, err := getState(ctx, d.cfg, false, 0)
204+
if err != nil {
205+
return err
206+
}
207+
208+
for _, app := range state.Apps {
209+
appTypeMap[app.ID] = &app.App
210+
}
211+
}
212+
186213
var builders []*appBuilder
187214

188215
g, _ := errgroup.WithConcurrency(ctx, defaultConcurrency)
@@ -194,6 +221,8 @@ func (d *Deploy) buildApps(ctx context.Context) error {
194221
var appsTemp []config.App
195222

196223
for _, app := range apps {
224+
appTypeMap[app.ID()] = app.PluginType()
225+
197226
if len(targetAppIDsMap) > 0 && !targetAppIDsMap[app.ID()] {
198227
continue
199228
}
@@ -207,7 +236,17 @@ func (d *Deploy) buildApps(ctx context.Context) error {
207236

208237
apps = appsTemp
209238

239+
// Flatten appTypeMap.
240+
appTypes := make([]*types.App, 0, len(appTypeMap))
241+
for _, app := range appTypeMap {
242+
appTypes = append(appTypes, app)
243+
}
244+
245+
appVars := types.AppVarsFromApps(appTypes)
246+
210247
for _, app := range apps {
248+
eval := util.NewVarEvaluator(types.VarsForApp(appVars, app.PluginType(), nil))
249+
211250
// TODO: add build app function
212251
switch app.Type() {
213252
case config.AppTypeStatic:
@@ -219,15 +258,15 @@ func (d *Deploy) buildApps(ctx context.Context) error {
219258

220259
builders = append(builders, &appBuilder{
221260
app: a,
222-
build: func() error { return d.buildStaticApp(ctx, a) },
261+
build: func() error { return d.buildStaticApp(ctx, a, eval) },
223262
})
224263

225264
case config.AppTypeService:
226265
a := app.(*config.ServiceApp)
227266

228267
builders = append(builders, &appBuilder{
229268
app: a,
230-
build: func() error { return d.buildServiceApp(ctx, a) },
269+
build: func() error { return d.buildServiceApp(ctx, a, eval) },
231270
})
232271
}
233272
}

0 commit comments

Comments
 (0)