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>
| ... | ... |
@@ -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 |
} |