Browse code

Warn/deprecate continuing on empty lines in `Dockerfile`

This fix is related to 29005 and 24693. Currently in `Dockerfile`
empty lines will continue as long as there is line escape before.
This may cause some issues. The issue in 24693 is an example.
A non-empty line after an empty line might be considered to be a
separate instruction by many users. However, it is actually part
of the last instruction under the current `Dockerfile` parsing
rule.

This fix is an effort to reduce the confusion around the parsing
of `Dockerfile`. Even though this fix does not change the behavior
of the `Dockerfile` parsing, it tries to deprecate the empty line
continuation and present a warning for the user. In this case,
at least it prompt users to check for the Dockerfile and avoid
the confusion if possible.

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>

Yong Tang authored on 2016/12/06 11:55:07
Showing 1 changed files
... ...
@@ -243,6 +243,7 @@ type Result struct {
243 243
 	AST         *Node
244 244
 	EscapeToken rune
245 245
 	Platform    string
246
+	Warnings    []string
246 247
 }
247 248
 
248 249
 // Parse reads lines from a Reader, parses the lines into an AST and returns
... ...
@@ -252,6 +253,7 @@ func Parse(rwc io.Reader) (*Result, error) {
252 252
 	currentLine := 0
253 253
 	root := &Node{StartLine: -1}
254 254
 	scanner := bufio.NewScanner(rwc)
255
+	warnings := []string{}
255 256
 
256 257
 	var err error
257 258
 	for scanner.Scan() {
... ...
@@ -272,6 +274,7 @@ func Parse(rwc io.Reader) (*Result, error) {
272 272
 			continue
273 273
 		}
274 274
 
275
+		var hasEmptyContinuationLine bool
275 276
 		for !isEndOfLine && scanner.Scan() {
276 277
 			bytesRead, err := processLine(d, scanner.Bytes(), false)
277 278
 			if err != nil {
... ...
@@ -279,8 +282,8 @@ func Parse(rwc io.Reader) (*Result, error) {
279 279
 			}
280 280
 			currentLine++
281 281
 
282
-			// TODO: warn this is being deprecated/removed
283 282
 			if isEmptyContinuationLine(bytesRead) {
283
+				hasEmptyContinuationLine = true
284 284
 				continue
285 285
 			}
286 286
 
... ...
@@ -289,13 +292,27 @@ func Parse(rwc io.Reader) (*Result, error) {
289 289
 			line += continuationLine
290 290
 		}
291 291
 
292
+		if hasEmptyContinuationLine {
293
+			warning := "[WARNING]: Empty continuation line found in:\n    " + line
294
+			warnings = append(warnings, warning)
295
+		}
296
+
292 297
 		child, err := newNodeFromLine(line, d)
293 298
 		if err != nil {
294 299
 			return nil, err
295 300
 		}
296 301
 		root.AddChild(child, startLine, currentLine)
297 302
 	}
298
-	return &Result{AST: root, EscapeToken: d.escapeToken, Platform: d.platformToken}, nil
303
+
304
+	if len(warnings) > 0 {
305
+		warnings = append(warnings, "[WARNING]: Empty continuation lines will become errors in a future release.")
306
+	}
307
+	return &Result{
308
+		AST:         root,
309
+		Warnings:    warnings,
310
+		EscapeToken: d.escapeToken,
311
+		Platform: d.platformToken,
312
+	}, nil
299 313
 }
300 314
 
301 315
 func trimComments(src []byte) []byte {
... ...
@@ -326,6 +343,5 @@ func processLine(d *Directive, token []byte, stripLeftWhitespace bool) ([]byte,
326 326
 	if stripLeftWhitespace {
327 327
 		token = trimWhitespace(token)
328 328
 	}
329
-	err := d.possibleParserDirective(string(token))
330
-	return trimComments(token), err
329
+	return trimComments(token), d.possibleParserDirective(string(token))
331 330
 }