Skip to content

Commit 975d8f0

Browse files
authored
Merge pull request #6334 from jsternberg/disable-checks
dockerfile: add syntax to skip a check
2 parents eaf60c1 + a248d48 commit 975d8f0

File tree

9 files changed

+188
-33
lines changed

9 files changed

+188
-33
lines changed

frontend/dockerfile/dockerfile2llb/convert.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ func ListTargets(ctx context.Context, dt []byte) (*targets.List, error) {
177177
for i, s := range stages {
178178
t := targets.Target{
179179
Name: s.Name,
180-
Description: s.Comment,
180+
Description: s.DocComment,
181181
Default: i == len(stages)-1,
182182
Base: s.BaseName,
183183
Platform: s.Platform,
@@ -296,6 +296,8 @@ func toDispatchState(ctx context.Context, dt []byte, opt ConvertOpt) (*dispatchS
296296

297297
// set base state for every image
298298
for i, st := range stages {
299+
lint := lint.WithMergedConfigFromComments(st.Comments)
300+
299301
nameMatch, err := shlex.ProcessWordWithMatches(st.BaseName, globalArgs)
300302
argKeys := unusedFromArgsCheckKeys(globalArgs, outline.allArgs)
301303
reportUnusedFromArgs(argKeys, nameMatch.Unmatched, st.Location, lint)
@@ -914,6 +916,8 @@ func (e *envsFromState) Keys() []string {
914916
}
915917

916918
func dispatch(d *dispatchState, cmd command, opt dispatchOpt) error {
919+
opt.lint = opt.lint.WithMergedConfigFromComments(cmd.Comments())
920+
917921
d.cmdIsOnBuild = cmd.isOnBuild
918922
var err error
919923
// ARG command value could be ignored, so defer handling the expansion error

frontend/dockerfile/dockerfile2llb/outline.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ func (ds *dispatchState) args(visited map[string]struct{}) []outline.Arg {
7575
args = append(args, outline.Arg{
7676
Name: a.definition.Key,
7777
Value: a.value,
78-
Description: a.definition.Comment,
78+
Description: a.definition.DocComment,
7979
Location: toSourceLocation(a.location),
8080
})
8181
visited[k] = struct{}{}
@@ -153,7 +153,7 @@ func (ds *dispatchState) Outline(dt []byte) outline.Outline {
153153

154154
out := outline.Outline{
155155
Name: ds.stage.Name,
156-
Description: ds.stage.Comment,
156+
Description: ds.stage.DocComment,
157157
Sources: [][]byte{dt},
158158
Args: args,
159159
Secrets: secrets,

frontend/dockerfile/dockerfile_lint_test.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,14 @@ ENV apikey=bar sunflower=foo
242242
ENV git_key=
243243
ENV PUBLIC_KEY=
244244
ARG public_token
245+
# check=skip=SecretsUsedInArgOrEnv // allow secret in environment
246+
ENV password=bar
247+
# check=skip=SecretsUsedInArgOrEnv // allow secret in arg
248+
ARG password
249+
# check=skip=all // is local to only this instruction
250+
ENV alternate_password=bar
251+
# check=skip=all // is local to only this instruction
252+
ARG alternate_password
245253
`)
246254
checkLinterWarnings(t, sb, &lintTestParams{
247255
Dockerfile: dockerfile,
@@ -843,6 +851,27 @@ MAINTAINER [email protected]
843851
dockerfile = []byte(`
844852
FROM scratch
845853
LABEL org.opencontainers.image.authors="[email protected]"
854+
`)
855+
checkLinterWarnings(t, sb, &lintTestParams{Dockerfile: dockerfile})
856+
857+
dockerfile = []byte(`
858+
FROM scratch
859+
# check=skip=JSONArgsRecommended
860+
CMD mycommand
861+
`)
862+
checkLinterWarnings(t, sb, &lintTestParams{Dockerfile: dockerfile})
863+
864+
dockerfile = []byte(`
865+
FROM scratch
866+
# check=skip=JSONArgsRecommended
867+
ENTRYPOINT mycommand
868+
`)
869+
checkLinterWarnings(t, sb, &lintTestParams{Dockerfile: dockerfile})
870+
871+
dockerfile = []byte(`
872+
FROM scratch
873+
# check=skip=MaintainerDeprecated
874+
846875
`)
847876
checkLinterWarnings(t, sb, &lintTestParams{Dockerfile: dockerfile})
848877
}
@@ -1018,6 +1047,13 @@ WORKDIR /app
10181047
10191048
FROM a AS b
10201049
WORKDIR subdir/
1050+
`)
1051+
checkLinterWarnings(t, sb, &lintTestParams{Dockerfile: dockerfile})
1052+
1053+
dockerfile = []byte(`
1054+
FROM scratch
1055+
# check=skip=WorkdirRelativePath
1056+
WORKDIR app/
10211057
`)
10221058
checkLinterWarnings(t, sb, &lintTestParams{Dockerfile: dockerfile})
10231059
}
@@ -1252,6 +1288,15 @@ FROM a AS c
12521288
},
12531289
},
12541290
})
1291+
1292+
dockerfile = []byte(`
1293+
FROM scratch
1294+
# check=skip=LegacyKeyValueFormat
1295+
ENV testkey value
1296+
# check=skip=LegacyKeyValueFormat
1297+
LABEL key value
1298+
`)
1299+
checkLinterWarnings(t, sb, &lintTestParams{Dockerfile: dockerfile})
12551300
}
12561301

12571302
func testRedundantTargetPlatform(t *testing.T, sb integration.Sandbox) {
@@ -1288,6 +1333,12 @@ FROM --platform=${TARGETPLATFORM} scratch
12881333
},
12891334
},
12901335
})
1336+
1337+
dockerfile = []byte(`
1338+
# check=skip=RedundantTargetPlatform
1339+
FROM --platform=$TARGETPLATFORM scratch
1340+
`)
1341+
checkLinterWarnings(t, sb, &lintTestParams{Dockerfile: dockerfile})
12911342
}
12921343

12931344
func testInvalidDefaultArgInFrom(t *testing.T, sb integration.Sandbox) {

frontend/dockerfile/dockerfile_outline_test.go

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,11 @@ RUN true
5454
5555
FROM scratch AS third
5656
ARG ABC=a
57+
# check=skip=all
58+
ARG password
59+
# alternate_password will show up in the outline
60+
# check=skip=all
61+
ARG alternate_password
5762
5863
# target defines build target
5964
FROM third AS target
@@ -81,6 +86,11 @@ RUN exit 0
8186
8287
FROM nanoserver AS third
8388
ARG ABC=a
89+
# check=skip=all
90+
ARG password
91+
# alternate_password will show up in the outline
92+
# check=skip=all
93+
ARG alternate_password
8494
8595
# target defines build target
8696
FROM third AS target
@@ -125,7 +135,7 @@ FROM second
125135
require.Equal(t, 1, len(outline.Sources))
126136
require.Equal(t, dockerfile, outline.Sources[0])
127137

128-
require.Equal(t, 5, len(outline.Args))
138+
require.Equal(t, 7, len(outline.Args))
129139

130140
arg := outline.Args[0]
131141
require.Equal(t, "inherited", arg.Name)
@@ -155,6 +165,18 @@ FROM second
155165
require.Equal(t, "ABC", arg.Name)
156166
require.Equal(t, "a", arg.Value)
157167

168+
arg = outline.Args[5]
169+
require.Equal(t, "password", arg.Name)
170+
require.Equal(t, "", arg.Value)
171+
require.Equal(t, "", arg.Description)
172+
require.Equal(t, int32(22), arg.Location.Ranges[0].Start.Line)
173+
174+
arg = outline.Args[6]
175+
require.Equal(t, "alternate_password", arg.Name)
176+
require.Equal(t, "", arg.Value)
177+
require.Equal(t, "will show up in the outline", arg.Description)
178+
require.Equal(t, int32(25), arg.Location.Ranges[0].Start.Line)
179+
158180
called = true
159181
return nil, nil
160182
}

frontend/dockerfile/instructions/commands.go

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ func (kvp *KeyValuePair) String() string {
2424

2525
// KeyValuePairOptional is identical to KeyValuePair, but allows for optional values.
2626
type KeyValuePairOptional struct {
27-
Key string
28-
Value *string
29-
Comment string
27+
Key string
28+
Value *string
29+
DocComment string
3030
}
3131

3232
func (kvpo *KeyValuePairOptional) String() string {
@@ -49,6 +49,7 @@ func (kvpo *KeyValuePairOptional) ValueString() string {
4949
type Command interface {
5050
Name() string
5151
Location() []parser.Range
52+
Comments() []string
5253
}
5354

5455
// KeyValuePairs is a slice of KeyValuePair
@@ -59,6 +60,7 @@ type withNameAndCode struct {
5960
code string
6061
name string
6162
location []parser.Range
63+
comments []string
6264
}
6365

6466
func (c *withNameAndCode) String() string {
@@ -75,8 +77,17 @@ func (c *withNameAndCode) Location() []parser.Range {
7577
return c.location
7678
}
7779

80+
func (c *withNameAndCode) Comments() []string {
81+
return c.comments
82+
}
83+
7884
func newWithNameAndCode(req parseRequest) withNameAndCode {
79-
return withNameAndCode{code: strings.TrimSpace(req.original), name: req.command, location: req.location}
85+
return withNameAndCode{
86+
code: strings.TrimSpace(req.original),
87+
name: req.command,
88+
location: req.location,
89+
comments: req.comments,
90+
}
8091
}
8192

8293
// SingleWordExpander is a provider for variable expansion where a single word
@@ -511,10 +522,11 @@ type Stage struct {
511522
BaseName string // name of the base stage or source
512523
Platform string // platform of base source to use
513524

514-
Comment string // doc-comment directly above the stage
525+
DocComment string // doc-comment directly above the stage
515526

516527
SourceCode string // contents of the defining FROM command
517528
Location []parser.Range // location of the defining FROM command
529+
Comments []string
518530
}
519531

520532
// AddCommand appends a command to the stage.

frontend/dockerfile/instructions/parse.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ func ParseInstruction(node *parser.Node) (v any, err error) {
7070

7171
// ParseInstruction converts an AST to a typed instruction (either a command or a build stage beginning when encountering a `FROM` statement)
7272
func ParseInstructionWithLinter(node *parser.Node, lint *linter.Linter) (v any, err error) {
73+
lint = lint.WithMergedConfigFromComments(node.PrevComment)
74+
7375
defer func() {
7476
if err != nil {
7577
err = parser.WithLocation(err, node.Location())
@@ -410,7 +412,8 @@ func parseFrom(req parseRequest) (*Stage, error) {
410412
Commands: []Command{},
411413
Platform: flPlatform.Value,
412414
Location: req.location,
413-
Comment: getComment(req.comments, stageName),
415+
Comments: req.comments,
416+
DocComment: getDocComment(req.comments, stageName),
414417
}, nil
415418
}
416419

@@ -761,7 +764,7 @@ func parseArg(req parseRequest) (*ArgCommand, error) {
761764
} else {
762765
kvpo.Key = arg
763766
}
764-
kvpo.Comment = getComment(req.comments, kvpo.Key)
767+
kvpo.DocComment = getDocComment(req.comments, kvpo.Key)
765768
pairs[i] = kvpo
766769
}
767770

@@ -817,7 +820,7 @@ func errTooManyArguments(command string) error {
817820
return errors.Errorf("Bad input to %s, too many arguments", command)
818821
}
819822

820-
func getComment(comments []string, name string) string {
823+
func getDocComment(comments []string, name string) string {
821824
if name == "" {
822825
return ""
823826
}

frontend/dockerfile/instructions/parse_test.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -193,18 +193,18 @@ ARG bar baz=123
193193
stages, meta, err := Parse(ast.AST, nil)
194194
require.NoError(t, err)
195195

196-
require.Equal(t, "defines first stage", stages[0].Comment)
196+
require.Equal(t, "defines first stage", stages[0].DocComment)
197197
require.Equal(t, "foo", meta[0].Args[0].Key)
198-
require.Equal(t, "sets foo", meta[0].Args[0].Comment)
198+
require.Equal(t, "sets foo", meta[0].Args[0].DocComment)
199199

200200
st := stages[0]
201201

202202
require.Equal(t, "foo", st.Commands[0].(*ArgCommand).Args[0].Key)
203-
require.Equal(t, "", st.Commands[0].(*ArgCommand).Args[0].Comment)
203+
require.Equal(t, "", st.Commands[0].(*ArgCommand).Args[0].DocComment)
204204
require.Equal(t, "bar", st.Commands[1].(*ArgCommand).Args[0].Key)
205-
require.Equal(t, "defines bar", st.Commands[1].(*ArgCommand).Args[0].Comment)
205+
require.Equal(t, "defines bar", st.Commands[1].(*ArgCommand).Args[0].DocComment)
206206
require.Equal(t, "baz", st.Commands[1].(*ArgCommand).Args[1].Key)
207-
require.Equal(t, "is something else", st.Commands[1].(*ArgCommand).Args[1].Comment)
207+
require.Equal(t, "is something else", st.Commands[1].(*ArgCommand).Args[1].DocComment)
208208
}
209209

210210
func TestErrorCases(t *testing.T) {

0 commit comments

Comments
 (0)