dockerfile: scope CopyIgnoredFile suppression to relevant negations - #7127
Open
fredrikblau wants to merge 1 commit into
Open
dockerfile: scope CopyIgnoredFile suppression to relevant negations#7127fredrikblau wants to merge 1 commit into
fredrikblau wants to merge 1 commit into
Conversation
The CopyIgnoredFile rule was skipped for the whole build as soon as the .dockerignore contained any negated pattern, because PatternMatcher's Exclusions() is a single global flag with no relation to the path being copied. A negation for an unrelated directory, or for a path that does not exist, silently disabled the rule for every COPY and ADD in the Dockerfile. The suppression exists because it is valid for a directory to be excluded and a file inside it to be negated, in which case copying the directory still copies content and the warning would be wrong. That case only arises when a negation re-includes a path at or below the copied path, so only check for such negations instead of any negation at all. MatchesOrParentMatches already resolves negations correctly for a given path in every other case. Patterns containing wildcards cannot be statically resolved, so they are treated as matching anything at or below the longest path prefix that precedes the first wildcard, keeping the suppression conservative. Signed-off-by: amirahrari <ahrariamir@proton.me>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #7125
CopyIgnoredFilestops firing for the entire build as soon as.dockerignorecontains any!line — including a negation for an unrelated directory, or one naming a path that does not exist.The cause is in
validateCopySourcePath:PatternMatcher.Exclusions()is a single global boolean — true when the pattern list contains a negation anywhere, with no relation to the path being copied. One!line therefore disables the rule for everyCOPYandADDin the Dockerfile. The failure mode is quiet in an unpleasant way: the documented way to silence a genuineCopyIgnoredFilewarning is to add a!line, and doing so switches the check off for everything after it whiledocker build --checkkeeps reporting no warnings.Keeping the original concern
The comment describes a real false positive and this change preserves it. With
suband!sub/keep.txt,COPY sub /dststill copiessub/keep.txt, so warning thatsubis excluded would be wrong — andMatchesOrParentMatches("sub")does return true.But that ambiguity only arises when a negation re-includes something at or below the path being copied. Everywhere else
MatchesOrParentMatchesalready resolves negations correctly: with that same.dockerignore,COPY sub/a.txtcorrectly reports excluded andCOPY sub/keep.txtcorrectly reports not excluded.So rather than the global flag, the source path is now compared against the individual negated patterns, and the check is skipped only when some negation could re-include a path at or below that source path. Patterns containing
*,?or[cannot be resolved statically, so they are treated as matching anything at or below the longest path prefix preceding the first wildcard, in both directions. That deliberately errs toward suppression — a noisy linter is worse than a quiet one..and/context roots keep their existing handling.Known imprecision
A wildcard negation whose literal prefix is empty (
!*.txt,!**/x) still suppresses the rule for all source paths, even though patternmatcher's*does not cross/and such a pattern can only re-include top-level entries. That is no worse than current behaviour and can be tightened separately if you'd like.Tests
TestValidateCopySourcePathis a table covering every row of the issue's reproduction — unrelated negation, negation for a nonexistent path, negation placed before the exclude, and a wildcard negation with a disjoint prefix — plus the cases that must stay silent:sub+!sub/keep.txtwithCOPY sub, nested and wildcard negations inside the copied directory, a wildcard negation that could reach into it (!*/keep.txt), parent-directory re-inclusion (**+!subwithCOPY sub/a.txt), and the three context-root cases.Reverting
validations.goalone fails 5 of these subtests and passes the rest; with the change all 19 pass.testCopyIgnoredFileNegationadds the same two groups to the lint integration suite against a real build context. I could not run the integration suite locally — it needs a buildkitd worker — so those are compile-checked only; the unit table above is what I actually ran.