Skip to content

Commit d285b84

Browse files
Define dockerfile instructions set centrally.
Signed-off-by: Ernst von Oelsen <[email protected]>
1 parent f1c52c0 commit d285b84

22 files changed

+275
-253
lines changed

pkg/docker/dockerfile/ast/line_parsers.go

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,10 @@ import (
1212
"encoding/json"
1313
"errors"
1414
"fmt"
15+
df "github.com/mintoolkit/mint/pkg/docker/dockerfile"
1516
"strings"
1617
"unicode"
1718
"unicode/utf8"
18-
19-
"github.com/mintoolkit/mint/pkg/docker/instruction"
2019
)
2120

2221
type NameValError struct {
@@ -76,8 +75,8 @@ func parseSubCommand(rest string, d *Directive) (*Node, map[string]bool, error)
7675
return &Node{Children: []*Node{child}}, nil, nil
7776
}
7877

79-
// helper to parse words (i.e space delimited or quoted strings) in a statement.
80-
// The quotes are preserved as part of this function and they are stripped later
78+
// helper to parse words (i.e. space delimited or quoted strings) in a statement.
79+
// The quotes are preserved as part of this function, and they are stripped later
8180
// as part of processWords().
8281
func parseWords(rest string, d *Directive) []string {
8382
const (
@@ -224,12 +223,12 @@ func appendKeyValueNode(node, rootNode, prevNode *Node) (*Node, *Node) {
224223
}
225224

226225
func parseEnv(rest string, d *Directive) (*Node, map[string]bool, error) {
227-
node, err := parseNameVal(rest, instruction.Env, d)
226+
node, err := parseNameVal(rest, df.InstTypeEnv, d)
228227
return node, nil, err
229228
}
230229

231230
func parseLabel(rest string, d *Directive) (*Node, map[string]bool, error) {
232-
node, err := parseNameVal(rest, instruction.Label, d)
231+
node, err := parseNameVal(rest, df.InstTypeLabel, d)
233232
return node, nil, err
234233
}
235234

pkg/docker/dockerfile/ast/parser.go

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@ import (
77
"bufio"
88
"bytes"
99
"fmt"
10+
df "github.com/mintoolkit/mint/pkg/docker/dockerfile"
1011
"io"
1112
"regexp"
1213
"strconv"
1314
"strings"
1415
"unicode"
1516

16-
"github.com/mintoolkit/mint/pkg/docker/instruction"
1717
"github.com/pkg/errors"
1818
)
1919

@@ -190,24 +190,24 @@ func init() {
190190
// functions. Errors are propagated up by Parse() and the resulting AST can
191191
// be incorporated directly into the existing AST as a next.
192192
dispatch = map[string]func(string, *Directive) (*Node, map[string]bool, error){
193-
instruction.Add: parseMaybeJSONToList,
194-
instruction.Arg: parseNameOrNameVal,
195-
instruction.Cmd: parseMaybeJSON,
196-
instruction.Copy: parseMaybeJSONToList,
197-
instruction.Entrypoint: parseMaybeJSON,
198-
instruction.Env: parseEnv,
199-
instruction.Expose: parseStringsWhitespaceDelimited,
200-
instruction.From: parseStringsWhitespaceDelimited,
201-
instruction.Healthcheck: parseHealthConfig,
202-
instruction.Label: parseLabel,
203-
instruction.Maintainer: parseString,
204-
instruction.Onbuild: parseSubCommand,
205-
instruction.Run: parseMaybeJSON,
206-
instruction.Shell: parseMaybeJSON,
207-
instruction.StopSignal: parseString,
208-
instruction.User: parseString,
209-
instruction.Volume: parseMaybeJSONToList,
210-
instruction.Workdir: parseString,
193+
df.InstTypeAdd: parseMaybeJSONToList,
194+
df.InstTypeArg: parseNameOrNameVal,
195+
df.InstTypeCmd: parseMaybeJSON,
196+
df.InstTypeCopy: parseMaybeJSONToList,
197+
df.InstTypeEntrypoint: parseMaybeJSON,
198+
df.InstTypeEnv: parseEnv,
199+
df.InstTypeExpose: parseStringsWhitespaceDelimited,
200+
df.InstTypeFrom: parseStringsWhitespaceDelimited,
201+
df.InstTypeHealthcheck: parseHealthConfig,
202+
df.InstTypeLabel: parseLabel,
203+
df.InstTypeMaintainer: parseString,
204+
df.InstTypeOnbuild: parseSubCommand,
205+
df.InstTypeRun: parseMaybeJSON,
206+
df.InstTypeShell: parseMaybeJSON,
207+
df.InstTypeStopSignal: parseString,
208+
df.InstTypeUser: parseString,
209+
df.InstTypeVolume: parseMaybeJSONToList,
210+
df.InstTypeWorkdir: parseString,
211211
}
212212
}
213213

pkg/docker/dockerfile/ast/split_command.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ func splitCommand(line string) (string, []string, string, error) {
1515

1616
// Make sure we get the same results irrespective of leading/trailing spaces
1717
cmdline := tokenWhitespace.Split(strings.TrimSpace(line), 2)
18-
cmd := strings.ToLower(cmdline[0])
18+
cmd := strings.ToUpper(cmdline[0])
1919

2020
if len(cmdline) == 2 {
2121
var err error

pkg/docker/dockerfile/dockerfile.go

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -15,37 +15,47 @@ import (
1515
v "github.com/mintoolkit/mint/pkg/version"
1616
)
1717

18-
// note: dup (todo: refactor)
1918
const (
19+
//FROM
20+
InstTypeFrom = "FROM"
2021
//MAINTAINER:
21-
instPrefixMaintainer = "MAINTAINER "
22+
InstTypeMaintainer = "MAINTAINER"
23+
InstPrefixMaintainer = "MAINTAINER "
2224
//ENTRYPOINT:
23-
instTypeEntrypoint = "ENTRYPOINT"
24-
instPrefixEntrypoint = "ENTRYPOINT "
25+
InstTypeEntrypoint = "ENTRYPOINT"
26+
InstPrefixEntrypoint = "ENTRYPOINT "
2527
//CMD:
26-
instTypeCmd = "CMD"
27-
instPrefixCmd = "CMD "
28+
InstTypeCmd = "CMD"
29+
InstPrefixCmd = "CMD "
2830
//USER:
29-
instTypeUser = "USER"
30-
instPrefixUser = "USER "
31+
InstTypeUser = "USER"
32+
InstPrefixUser = "USER "
3133
//EXPOSE:
32-
instTypeExpose = "EXPOSE"
33-
instPrefixExpose = "EXPOSE "
34+
InstTypeExpose = "EXPOSE"
35+
InstPrefixExpose = "EXPOSE "
3436
//WORKDIR:
35-
instTypeWorkdir = "WORKDIR"
36-
instPrefixWorkdir = "WORKDIR "
37+
InstTypeWorkdir = "WORKDIR"
38+
InstPrefixWorkdir = "WORKDIR "
3739
//HEALTHCHECK:
38-
instTypeHealthcheck = "HEALTHCHECK"
39-
instPrefixHealthcheck = "HEALTHCHECK "
40+
InstTypeHealthcheck = "HEALTHCHECK"
41+
InstPrefixHealthcheck = "HEALTHCHECK "
42+
InstPrefixBasicEncHealthcheck = "HEALTHCHECK --"
4043
//ONBUILD:
41-
instTypeOnbuild = "ONBUILD"
44+
InstTypeOnbuild = "ONBUILD"
4245
//RUN:
43-
instTypeRun = "RUN"
44-
instPrefixRun = "RUN "
46+
InstTypeRun = "RUN"
47+
InstPrefixRun = "RUN "
4548
//ADD:
46-
instTypeAdd = "ADD"
49+
InstTypeAdd = "ADD"
4750
//COPY:
48-
instTypeCopy = "COPY"
51+
InstTypeCopy = "COPY"
52+
53+
InstTypeVolume = "VOLUME"
54+
InstTypeEnv = "ENV"
55+
InstTypeLabel = "LABEL"
56+
InstTypeStopSignal = "STOPSIGNAL"
57+
InstTypeShell = "SHELL"
58+
InstTypeArg = "ARG" //shouldn't see it as a standalone instruction
4959
)
5060

5161
// GenerateFromInfo builds and saves a Dockerfile file object
@@ -115,20 +125,20 @@ func GenerateFromInfo(
115125
}
116126

117127
if workingDir != "" {
118-
dfData.WriteString(instPrefixWorkdir)
128+
dfData.WriteString(InstPrefixWorkdir)
119129
dfData.WriteString(workingDir)
120130
dfData.WriteByte('\n')
121131
}
122132

123133
if user != "" {
124-
dfData.WriteString(instPrefixUser)
134+
dfData.WriteString(InstPrefixUser)
125135
dfData.WriteString(user)
126136
dfData.WriteByte('\n')
127137
}
128138

129139
if len(exposedPorts) > 0 {
130140
for portInfo := range exposedPorts {
131-
dfData.WriteString(instPrefixExpose)
141+
dfData.WriteString(InstPrefixExpose)
132142
dfData.WriteString(string(portInfo))
133143
dfData.WriteByte('\n')
134144
}

pkg/docker/dockerfile/parser/parser.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package parser
33

44
import (
55
"errors"
6+
df "github.com/mintoolkit/mint/pkg/docker/dockerfile"
67
"os"
78
"path/filepath"
89
"strconv"
@@ -71,7 +72,7 @@ func FromFile(fpath string) (*spec.Dockerfile, error) {
7172
inst.Errors = append(inst.Errors, node.Errors...)
7273
}
7374

74-
if inst.Name == instruction.Onbuild &&
75+
if inst.Name == df.InstTypeOnbuild &&
7576
node.Next != nil &&
7677
len(node.Next.Children) > 0 {
7778
inst.IsOnBuild = true
@@ -89,7 +90,7 @@ func FromFile(fpath string) (*spec.Dockerfile, error) {
8990
inst.IsJSONForm = true
9091
}
9192

92-
if inst.Name == instruction.From {
93+
if inst.Name == df.InstTypeFrom {
9394
currentStage = spec.NewBuildStage()
9495
currentStage.FromInstruction = inst
9596
currentStage.Index = len(dockerfile.Stages)
@@ -219,9 +220,9 @@ func FromFile(fpath string) (*spec.Dockerfile, error) {
219220
inst.StageIndex = instStageIndex
220221
currentStage.AllInstructions = append(currentStage.AllInstructions, inst)
221222

222-
if inst.Name == instruction.Onbuild {
223+
if inst.Name == df.InstTypeOnbuild {
223224
currentStage.OnBuildInstructions = append(currentStage.OnBuildInstructions, inst)
224-
} else if inst.Name == instruction.Copy {
225+
} else if inst.Name == df.InstTypeCopy {
225226
for _, flag := range inst.Flags {
226227
if strings.HasPrefix(flag, "--from=") {
227228
fparts := strings.SplitN(flag, "=", 2)
@@ -252,7 +253,7 @@ func FromFile(fpath string) (*spec.Dockerfile, error) {
252253

253254
if inst.IsValid {
254255
switch inst.Name {
255-
case instruction.Arg:
256+
case df.InstTypeArg:
256257
for _, iarg := range inst.Args {
257258
if iarg == "" {
258259
continue
@@ -268,7 +269,7 @@ func FromFile(fpath string) (*spec.Dockerfile, error) {
268269
//only one ARG is supposed to be defined, but we'll use all
269270
//the 'ARG' value count lint check will detect the extra values
270271
//the k=v ARG values are also not parsed (unlike ENV k=v values)
271-
case instruction.Env:
272+
case df.InstTypeEnv:
272273
for i := 0; i < len(inst.Args) && (i+1) < len(inst.Args); i += 2 {
273274
if len(inst.Args[i]) == 0 {
274275
continue
@@ -280,7 +281,7 @@ func FromFile(fpath string) (*spec.Dockerfile, error) {
280281
}
281282
}
282283
} else {
283-
if inst.Name == instruction.Arg {
284+
if inst.Name == df.InstTypeArg {
284285
if inst.IsValid && len(inst.Args) > 0 {
285286
dockerfile.ArgInstructions = append(dockerfile.ArgInstructions, inst)
286287
parts := strings.Split(inst.Args[0], "=")
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package parser
2+
3+
import (
4+
"github.com/stretchr/testify/require"
5+
"os"
6+
"testing"
7+
)
8+
9+
func TestFromFile(t *testing.T) {
10+
tmpFile, err := os.CreateTemp(".", "Dockerfile")
11+
require.NoError(t, err)
12+
defer os.Remove(tmpFile.Name())
13+
14+
for _, s := range []string{"MAINTAINER", "Maintainer", "maintainer"} {
15+
tmpFile.WriteString(s + " [email protected]")
16+
Dockerfile, err := FromFile(tmpFile.Name())
17+
18+
require.NoError(t, err)
19+
require.Equal(t, Dockerfile.AllInstructions[0].Name, "MAINTAINER")
20+
for _, inst := range Dockerfile.AllInstructions {
21+
require.Equal(t, inst.IsValid, true)
22+
require.Equal(t, inst.Errors, []string(nil))
23+
}
24+
}
25+
}

0 commit comments

Comments
 (0)