@@ -251,8 +251,6 @@ func toDispatchState(ctx context.Context, dt []byte, opt ConvertOpt) (*dispatchS
251
251
}
252
252
}
253
253
254
- validateCommandCasing (dockerfile , lint )
255
-
256
254
proxyEnv := proxyEnvFromBuildArgs (opt .BuildArgs )
257
255
258
256
stages , metaArgs , err := instructions .Parse (dockerfile .AST , lint )
@@ -263,6 +261,7 @@ func toDispatchState(ctx context.Context, dt []byte, opt ConvertOpt) (*dispatchS
263
261
return nil , errors .New ("dockerfile contains no stages to build" )
264
262
}
265
263
validateStageNames (stages , lint )
264
+ validateCommandCasing (stages , lint )
266
265
267
266
shlex := shell .NewLex (dockerfile .EscapeToken )
268
267
outline := newOutlineCapture ()
@@ -2199,32 +2198,49 @@ func isSelfConsistentCasing(s string) bool {
2199
2198
return s == strings .ToLower (s ) || s == strings .ToUpper (s )
2200
2199
}
2201
2200
2202
- func validateCommandCasing (dockerfile * parser.Result , lint * linter.Linter ) {
2201
+ func validateCaseMatch (name string , isMajorityLower bool , location []parser.Range , lint * linter.Linter ) {
2202
+ var correctCasing string
2203
+ if isMajorityLower && strings .ToLower (name ) != name {
2204
+ correctCasing = "lowercase"
2205
+ } else if ! isMajorityLower && strings .ToUpper (name ) != name {
2206
+ correctCasing = "uppercase"
2207
+ }
2208
+ if correctCasing != "" {
2209
+ msg := linter .RuleConsistentInstructionCasing .Format (name , correctCasing )
2210
+ lint .Run (& linter .RuleConsistentInstructionCasing , location , msg )
2211
+ }
2212
+ }
2213
+
2214
+ func validateCommandCasing (stages []instructions.Stage , lint * linter.Linter ) {
2203
2215
var lowerCount , upperCount int
2204
- for _ , node := range dockerfile . AST . Children {
2205
- if isSelfConsistentCasing (node . Value ) {
2206
- if strings .ToLower (node . Value ) == node . Value {
2216
+ for _ , stage := range stages {
2217
+ if isSelfConsistentCasing (stage . OrigCmd ) {
2218
+ if strings .ToLower (stage . OrigCmd ) == stage . OrigCmd {
2207
2219
lowerCount ++
2208
2220
} else {
2209
2221
upperCount ++
2210
2222
}
2211
2223
}
2224
+ for _ , cmd := range stage .Commands {
2225
+ cmdName := cmd .Name ()
2226
+ if isSelfConsistentCasing (cmdName ) {
2227
+ if strings .ToLower (cmdName ) == cmdName {
2228
+ lowerCount ++
2229
+ } else {
2230
+ upperCount ++
2231
+ }
2232
+ }
2233
+ }
2212
2234
}
2213
2235
2214
2236
isMajorityLower := lowerCount > upperCount
2215
- for _ , node := range dockerfile . AST . Children {
2237
+ for _ , stage := range stages {
2216
2238
// Here, we check both if the command is consistent per command (ie, "CMD" or "cmd", not "Cmd")
2217
2239
// as well as ensuring that the casing is consistent throughout the dockerfile by comparing the
2218
2240
// command to the casing of the majority of commands.
2219
- var correctCasing string
2220
- if isMajorityLower && strings .ToLower (node .Value ) != node .Value {
2221
- correctCasing = "lowercase"
2222
- } else if ! isMajorityLower && strings .ToUpper (node .Value ) != node .Value {
2223
- correctCasing = "uppercase"
2224
- }
2225
- if correctCasing != "" {
2226
- msg := linter .RuleConsistentInstructionCasing .Format (node .Value , correctCasing )
2227
- lint .Run (& linter .RuleConsistentInstructionCasing , node .Location (), msg )
2241
+ validateCaseMatch (stage .OrigCmd , isMajorityLower , stage .Location , lint )
2242
+ for _ , cmd := range stage .Commands {
2243
+ validateCaseMatch (cmd .Name (), isMajorityLower , cmd .Location (), lint )
2228
2244
}
2229
2245
}
2230
2246
}
0 commit comments