Browse code

Add a test for warning on empty continuation lines.

Signed-off-by: Daniel Nephin <dnephin@docker.com>

Daniel Nephin authored on 2017/06/17 07:05:30
Showing 4 changed files
... ...
@@ -255,6 +255,7 @@ func (b *Builder) build(source builder.Source, dockerfile *parser.Result) (*buil
255 255
 		return nil, errors.Errorf("failed to reach build target %s in Dockerfile", b.options.Target)
256 256
 	}
257 257
 
258
+	dockerfile.PrintWarnings(b.Stderr)
258 259
 	b.buildArgs.WarnOnUnusedBuildArgs(b.Stderr)
259 260
 
260 261
 	if dispatchState.imageID == "" {
... ...
@@ -246,6 +246,14 @@ type Result struct {
246 246
 	Warnings    []string
247 247
 }
248 248
 
249
+// PrintWarnings to the writer
250
+func (r *Result) PrintWarnings(out io.Writer) {
251
+	if len(r.Warnings) == 0 {
252
+		return
253
+	}
254
+	fmt.Fprintf(out, strings.Join(r.Warnings, "\n")+"\n")
255
+}
256
+
249 257
 // Parse reads lines from a Reader, parses the lines into an AST and returns
250 258
 // the AST and escape token
251 259
 func Parse(rwc io.Reader) (*Result, error) {
... ...
@@ -311,7 +319,7 @@ func Parse(rwc io.Reader) (*Result, error) {
311 311
 		AST:         root,
312 312
 		Warnings:    warnings,
313 313
 		EscapeToken: d.escapeToken,
314
-		Platform: d.platformToken,
314
+		Platform:    d.platformToken,
315 315
 	}, nil
316 316
 }
317 317
 
... ...
@@ -27,40 +27,39 @@ func getDirs(t *testing.T, dir string) []string {
27 27
 	return dirs
28 28
 }
29 29
 
30
-func TestTestNegative(t *testing.T) {
30
+func TestParseErrorCases(t *testing.T) {
31 31
 	for _, dir := range getDirs(t, negativeTestDir) {
32 32
 		dockerfile := filepath.Join(negativeTestDir, dir, "Dockerfile")
33 33
 
34 34
 		df, err := os.Open(dockerfile)
35
-		require.NoError(t, err)
35
+		require.NoError(t, err, dockerfile)
36 36
 		defer df.Close()
37 37
 
38 38
 		_, err = Parse(df)
39
-		assert.Error(t, err)
39
+		assert.Error(t, err, dockerfile)
40 40
 	}
41 41
 }
42 42
 
43
-func TestTestData(t *testing.T) {
43
+func TestParseCases(t *testing.T) {
44 44
 	for _, dir := range getDirs(t, testDir) {
45 45
 		dockerfile := filepath.Join(testDir, dir, "Dockerfile")
46 46
 		resultfile := filepath.Join(testDir, dir, "result")
47 47
 
48 48
 		df, err := os.Open(dockerfile)
49
-		require.NoError(t, err)
49
+		require.NoError(t, err, dockerfile)
50 50
 		defer df.Close()
51 51
 
52 52
 		result, err := Parse(df)
53
-		require.NoError(t, err)
53
+		require.NoError(t, err, dockerfile)
54 54
 
55 55
 		content, err := ioutil.ReadFile(resultfile)
56
-		require.NoError(t, err)
56
+		require.NoError(t, err, resultfile)
57 57
 
58 58
 		if runtime.GOOS == "windows" {
59 59
 			// CRLF --> CR to match Unix behavior
60 60
 			content = bytes.Replace(content, []byte{'\x0d', '\x0a'}, []byte{'\x0a'}, -1)
61 61
 		}
62
-
63
-		assert.Contains(t, result.AST.Dump()+"\n", string(content), "In "+dockerfile)
62
+		assert.Equal(t, result.AST.Dump()+"\n", string(content), "In "+dockerfile)
64 63
 	}
65 64
 }
66 65
 
... ...
@@ -106,7 +105,7 @@ func TestParseWords(t *testing.T) {
106 106
 	}
107 107
 }
108 108
 
109
-func TestLineInformation(t *testing.T) {
109
+func TestParseIncludesLineNumbers(t *testing.T) {
110 110
 	df, err := os.Open(testFileLineInfo)
111 111
 	require.NoError(t, err)
112 112
 	defer df.Close()
... ...
@@ -115,10 +114,8 @@ func TestLineInformation(t *testing.T) {
115 115
 	require.NoError(t, err)
116 116
 
117 117
 	ast := result.AST
118
-	if ast.StartLine != 5 || ast.endLine != 31 {
119
-		fmt.Fprintf(os.Stderr, "Wrong root line information: expected(%d-%d), actual(%d-%d)\n", 5, 31, ast.StartLine, ast.endLine)
120
-		t.Fatal("Root line information doesn't match result.")
121
-	}
118
+	assert.Equal(t, 5, ast.StartLine)
119
+	assert.Equal(t, 31, ast.endLine)
122 120
 	assert.Len(t, ast.Children, 3)
123 121
 	expected := [][]int{
124 122
 		{5, 5},
... ...
@@ -126,10 +123,32 @@ func TestLineInformation(t *testing.T) {
126 126
 		{17, 31},
127 127
 	}
128 128
 	for i, child := range ast.Children {
129
-		if child.StartLine != expected[i][0] || child.endLine != expected[i][1] {
130
-			t.Logf("Wrong line information for child %d: expected(%d-%d), actual(%d-%d)\n",
131
-				i, expected[i][0], expected[i][1], child.StartLine, child.endLine)
132
-			t.Fatal("Root line information doesn't match result.")
133
-		}
129
+		msg := fmt.Sprintf("Child %d", i)
130
+		assert.Equal(t, expected[i], []int{child.StartLine, child.endLine}, msg)
134 131
 	}
135 132
 }
133
+
134
+func TestParseWarnsOnEmptyContinutationLine(t *testing.T) {
135
+	dockerfile := bytes.NewBufferString(`
136
+FROM alpine:3.6
137
+
138
+RUN something \
139
+
140
+    following \
141
+
142
+    more
143
+
144
+RUN another \
145
+
146
+    thing
147
+	`)
148
+
149
+	result, err := Parse(dockerfile)
150
+	require.NoError(t, err)
151
+	warnings := result.Warnings
152
+	assert.Len(t, warnings, 3)
153
+	assert.Contains(t, warnings[0], "Empty continuation line found in")
154
+	assert.Contains(t, warnings[0], "RUN something     following     more")
155
+	assert.Contains(t, warnings[1], "RUN another     thing")
156
+	assert.Contains(t, warnings[2], "will become errors in a future release")
157
+}
... ...
@@ -110,17 +110,13 @@ func newURLRemote(url string, dockerfilePath string, progressReader func(in io.R
110 110
 			return progressReader(rc), nil
111 111
 		},
112 112
 	})
113
-	if err != nil {
114
-		if err == dockerfileFoundErr {
115
-			res, err := parser.Parse(dockerfile)
116
-			if err != nil {
117
-				return nil, nil, err
118
-			}
119
-			return nil, res, nil
120
-		}
113
+	switch {
114
+	case err == dockerfileFoundErr:
115
+		res, err := parser.Parse(dockerfile)
116
+		return nil, res, err
117
+	case err != nil:
121 118
 		return nil, nil, err
122 119
 	}
123
-
124 120
 	return withDockerfileFromContext(c.(modifiableContext), dockerfilePath)
125 121
 }
126 122