Skip to content

Commit ca4886f

Browse files
Make status-check flag nillable (#5712)
* Make status-check flag nillable * Address code review comments
1 parent 0e506fa commit ca4886f

File tree

7 files changed

+138
-7
lines changed

7 files changed

+138
-7
lines changed

cmd/skaffold/app/cmd/flags.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -277,9 +277,10 @@ var flagRegistry = []Flag{
277277
Usage: "Wait for deployed resources to stabilize",
278278
Value: &opts.StatusCheck,
279279
DefValue: true,
280-
FlagAddMethod: "BoolVar",
280+
FlagAddMethod: "Var",
281281
DefinedOn: []string{"dev", "debug", "deploy", "run", "apply"},
282282
IsEnum: true,
283+
NoOptDefVal: "true",
283284
},
284285
{
285286
Name: "render-only",

cmd/skaffold/app/cmd/init_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ func TestFlagsToConfigVersion(t *testing.T) {
157157

158158
// we ignore Skaffold options
159159
test.expectedConfig.Opts = capturedConfig.Opts
160-
t.CheckErrorAndDeepEqual(test.shouldErr, err, test.expectedConfig, capturedConfig, cmp.AllowUnexported(cfg.StringOrUndefined{}))
160+
t.CheckErrorAndDeepEqual(test.shouldErr, err, test.expectedConfig, capturedConfig, cmp.AllowUnexported(cfg.StringOrUndefined{}, cfg.BoolOrUndefined{}))
161161
})
162162
}
163163
}

pkg/skaffold/config/options.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ type SkaffoldOptions struct {
4949
Force bool
5050
NoPrune bool
5151
NoPruneChildren bool
52-
StatusCheck bool
5352
AutoBuild bool
5453
AutoSync bool
5554
AutoDeploy bool
@@ -68,6 +67,7 @@ type SkaffoldOptions struct {
6867
DetectMinikube bool
6968
// Experimental is the entrypoint to run skaffold v3 before it's fully implemented.
7069
Experimental bool
70+
StatusCheck BoolOrUndefined
7171

7272
PortForward PortForwardOptions
7373
CustomTag string

pkg/skaffold/config/types.go

+48
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,54 @@ func (s *StringOrUndefined) String() string {
5353
return *s.value
5454
}
5555

56+
// BoolOrUndefined holds the value of a flag of type `bool`,
57+
// that's by default `undefined`.
58+
// We use this instead of just `bool` to differentiate `undefined`
59+
// and `false` values.
60+
type BoolOrUndefined struct {
61+
value *bool
62+
}
63+
64+
func (s *BoolOrUndefined) Type() string {
65+
return "bool"
66+
}
67+
68+
func (s *BoolOrUndefined) Value() *bool {
69+
return s.value
70+
}
71+
72+
func (s *BoolOrUndefined) Set(v string) error {
73+
switch v {
74+
case "true":
75+
s.value = util.BoolPtr(true)
76+
case "false":
77+
s.value = util.BoolPtr(false)
78+
default:
79+
s.value = nil
80+
}
81+
return nil
82+
}
83+
84+
func (s *BoolOrUndefined) SetNil() error {
85+
s.value = nil
86+
return nil
87+
}
88+
89+
func (s *BoolOrUndefined) String() string {
90+
b := s.value
91+
if b == nil {
92+
return ""
93+
}
94+
if *b {
95+
return "true"
96+
}
97+
return "false"
98+
}
99+
100+
func NewBoolOrUndefined(v *bool) BoolOrUndefined {
101+
return BoolOrUndefined{value: v}
102+
}
103+
56104
// Muted lists phases for which logs are muted.
57105
type Muted struct {
58106
Phases []string

pkg/skaffold/config/types_test.go

+67
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,73 @@ func TestStringOrUndefined(t *testing.T) {
8484
}
8585
}
8686

87+
func TestBoolOrUndefinedUsage(t *testing.T) {
88+
var output bytes.Buffer
89+
90+
cmd := &cobra.Command{}
91+
cmd.Flags().Var(&BoolOrUndefined{}, "bool-flag", "use it like this")
92+
cmd.SetOut(&output)
93+
cmd.Usage()
94+
95+
testutil.CheckDeepEqual(t, "Usage:\n\nFlags:\n --bool-flag use it like this\n", output.String())
96+
}
97+
98+
func TestBoolOrUndefined_SetNil(t *testing.T) {
99+
var s BoolOrUndefined
100+
s.Set("false")
101+
testutil.CheckDeepEqual(t, "false", s.String())
102+
s.SetNil()
103+
testutil.CheckDeepEqual(t, "", s.String())
104+
testutil.CheckDeepEqual(t, (*bool)(nil), s.value)
105+
testutil.CheckDeepEqual(t, (*bool)(nil), s.Value())
106+
}
107+
108+
func TestBoolOrUndefined(t *testing.T) {
109+
tests := []struct {
110+
description string
111+
args []string
112+
expected *bool
113+
}{
114+
{
115+
description: "undefined",
116+
args: []string{},
117+
expected: nil,
118+
},
119+
{
120+
description: "empty",
121+
args: []string{"--bool-flag="},
122+
expected: nil,
123+
},
124+
{
125+
description: "invalid",
126+
args: []string{"--bool-flag=invalid"},
127+
expected: nil,
128+
},
129+
{
130+
description: "true",
131+
args: []string{"--bool-flag=true"},
132+
expected: util.BoolPtr(true),
133+
},
134+
{
135+
description: "false",
136+
args: []string{"--bool-flag=false"},
137+
expected: util.BoolPtr(false),
138+
},
139+
}
140+
for _, test := range tests {
141+
testutil.Run(t, test.description, func(t *testutil.T) {
142+
var flag BoolOrUndefined
143+
144+
cmd := &cobra.Command{}
145+
cmd.Flags().Var(&flag, "bool-flag", "")
146+
cmd.SetArgs(test.args)
147+
cmd.Execute()
148+
149+
t.CheckDeepEqual(test.expected, flag.value)
150+
})
151+
}
152+
}
153+
87154
func TestMuted(t *testing.T) {
88155
tests := []struct {
89156
phases []string

pkg/skaffold/runner/deploy_test.go

+11-3
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import (
3535
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/kubernetes/client"
3636
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/runner/runcontext"
3737
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/schema/latest"
38+
"github.com/GoogleContainerTools/skaffold/pkg/skaffold/util"
3839
"github.com/GoogleContainerTools/skaffold/testutil"
3940
)
4041

@@ -43,25 +44,32 @@ func TestDeploy(t *testing.T) {
4344
tests := []struct {
4445
description string
4546
testBench *TestBench
46-
statusCheck bool
47+
statusCheck config.BoolOrUndefined
4748
shouldErr bool
4849
shouldWait bool
4950
}{
5051
{
5152
description: "deploy shd perform status check",
5253
testBench: &TestBench{},
53-
statusCheck: true,
54+
statusCheck: config.NewBoolOrUndefined(nil),
55+
shouldWait: true,
56+
},
57+
{
58+
description: "deploy shd perform status check",
59+
testBench: &TestBench{},
60+
statusCheck: config.NewBoolOrUndefined(util.BoolPtr(true)),
5461
shouldWait: true,
5562
},
5663
{
5764
description: "deploy shd not perform status check",
5865
testBench: &TestBench{},
66+
statusCheck: config.NewBoolOrUndefined(util.BoolPtr(false)),
5967
},
6068
{
6169
description: "deploy shd not perform status check when deployer is in error",
6270
testBench: &TestBench{deployErrors: []error{errors.New("deploy error")}},
6371
shouldErr: true,
64-
statusCheck: true,
72+
statusCheck: config.NewBoolOrUndefined(util.BoolPtr(true)),
6573
},
6674
}
6775

pkg/skaffold/runner/runcontext/context.go

+8-1
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,14 @@ func (rc *RunContext) Deployers() []latest.DeployType { return rc.Pipelines.Depl
146146

147147
func (rc *RunContext) TestCases() []*latest.TestCase { return rc.Pipelines.TestCases() }
148148

149+
func (rc *RunContext) StatusCheck() bool {
150+
sc := rc.Opts.StatusCheck.Value()
151+
if sc == nil {
152+
return true
153+
}
154+
return *sc
155+
}
156+
149157
func (rc *RunContext) StatusCheckDeadlineSeconds() int {
150158
return rc.Pipelines.StatusCheckDeadlineSeconds()
151159
}
@@ -185,7 +193,6 @@ func (rc *RunContext) RenderOnly() bool { return rc.Opt
185193
func (rc *RunContext) RenderOutput() string { return rc.Opts.RenderOutput }
186194
func (rc *RunContext) SkipRender() bool { return rc.Opts.SkipRender }
187195
func (rc *RunContext) SkipTests() bool { return rc.Opts.SkipTests }
188-
func (rc *RunContext) StatusCheck() bool { return rc.Opts.StatusCheck }
189196
func (rc *RunContext) Tail() bool { return rc.Opts.Tail }
190197
func (rc *RunContext) Trigger() string { return rc.Opts.Trigger }
191198
func (rc *RunContext) WaitForDeletions() config.WaitForDeletions { return rc.Opts.WaitForDeletions }

0 commit comments

Comments
 (0)