-
Notifications
You must be signed in to change notification settings - Fork 18.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Warn/deprecate continuing on empty lines in Dockerfile
#29161
Conversation
ef2aa7f
to
c24fc80
Compare
How does this affect the |
/cc @thaJeztah @duglin |
@jhowardmsft this is only for blank lines inside a |
SGTM I can't seem to find the spot where we agreed on the plan... what was the decision for comments in continuation lines? Deprecate those too or just leave them? |
I'm not sure the current implementation is correct. Should have a look if we can do it otherwise, but just printing a list of "Skipping empty line ...." before the docker build may not provide enough information to the user to resolve the issue. Haven't had time to look into it further, but thought to just leave a comment for now 😊 |
I think one issue is that, currently the output of build always shows the instruction in one line (after processing). For example,
In the above example, we only see:
which might be confusing initially. I think for the generated warning, it might make sense to output the instruction in the original format, e.g.,
|
c24fc80
to
684c150
Compare
The PR has been updated and the warning message has been updated. Below is the new output to give user a better idea of which instruction (multiple lines) could be ambiguous:
|
073ec20
to
7433634
Compare
Ain't it enough for those corner cases to escape it like |
@yajo The issue is fairly complicated. One issue is that, under current behavior, a combination of escape with comment will result in the continuation beyond the last comment. Below is the example:
The above Dockerfile resulting in:
See issue #24693 for reference. |
Yeah, but that's what I'd expect given that Dockerfile. I mean that you should fix it like this:
... isn't it? |
for _, line := range strings.Split(scannedLine, "\n") { | ||
fmt.Fprintf(stderr, "[WARNING]: %s\n", line) | ||
} | ||
fmt.Fprintf(stderr, "[WARNING]: Empty lines inside a RUN instruction is deprecated, and will be removed in Docker 1.16.\n") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fwiw, this now mismatches with the version listed in deprecated.md
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@yongtang per the discussion, perhaps we should remove this line (or at least remove the "version"). We discussed this in the maintainers meeting, and we may have to accept that this behaviour is "bad" (hence the warnings to motivate people to change it), but that removing would be too much of a backward breaking change, that we'd likely never be able to actually remove it.
@duglin @thaJeztah did we decide on design here? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Design makes sense to me but I wonder if we are going to really remove this anytime soon (I mean, it's gonna break a lot of Dockerfile
if they don't update).
/ping @tiborvass @vieux and @tonistiigi for inputs 👼
We discussed this in the maintainers meeting and think the warning is a great thing to have, but we're still a bit worried about actually deprecating it. We should, but not sure how long to take before removing it. Adding a version to the dockerfile format would help 😇 #4907 |
We also should have some tests for these 😄 |
Would be great to see a unit test for either scenario - a test with a Dockerfile that should and shouldn't error. |
Would love to see tests for both scenarios as well. They would be of great help to those of us writing Dockerfile editors and/or linters. |
ping @yongtang 👼 |
Design LGTM |
@yongtang needs a rebase 👼 |
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>
7433634
to
5106e0a
Compare
Rebased to fix merge conflict. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wish we had a better way to pass in stderr
, it doesn't really feel appropriate as an argument to Parser right now, but I'm not seeing an easy way.
ParserOptions{}
might be good if we start adding more arguments.
@@ -171,11 +171,20 @@ func Parse(rwc io.Reader, d *Directive) (*Node, error) { | |||
} | |||
startLine := currentLine | |||
|
|||
warning := false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
warning
is a bit ambiguous, in this context it could mean many things.
How about blankLineWithinInstruction
?
if line != "" && child == nil { | ||
for scanner.Scan() { | ||
newline := scanner.Text() | ||
// Keep the original content of the current instruction | ||
scannedLine += "\n" + newline |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of re-using this variable that was intended to be just an intermediary in a calculation , which also requires both string concatenation and splitting later on, how about storing the lines in a slice and avoiding the concat+split?
for _, line := range strings.Split(scannedLine, "\n") { | ||
fmt.Fprintf(stderr, "[WARNING]: %s\n", line) | ||
} | ||
fmt.Fprintf(stderr, "[WARNING]: Empty lines inside a RUN instruction is deprecated, and will be removed in Docker 1.16.\n") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would probably be better off in a new function, it's not directly related to parsing.
if blankLineWithinInstruction {
warnOnBlankLinWithinInstruction(stderr, scannedLines)
}
I think we're going to be changing the result value of I'll ping you when that PR opens |
I see #32580 was opened |
This requires a pretty major rebase. |
@yongtang let me close this for now, but let me know if you want to work on this again |
I'll look at carrying this in a new PR. |
Opened #33719 to carry |
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 currentDockerfile
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 theDockerfile
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.Here are some of the examples:
Signed-off-by: Yong Tang yong.tang.github@outlook.com