Fix and comprehensively test glob ordering #267
Merged
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.
The Ordering[Matcher] implementation violated the general ordering
contract. sbt/sbt#4970 was still present
with sbt 1.3.0-RC5. This commit fixes the contract of Ordering[Matcher]
so that it should be sound for all Matcher instances.
Using jacoco, I was able to identify which branches of
the matchers were not being hit. After this change, all of the branches
were hit. While I'm not sure what was specifically causing the issue in
sbt/4970, I suspect that somewhere was an AndFilter, OrFilter or
NotFilter. The conversion in Globs from AndFilter, NotFilter and OrFilter to
Matcher created AndMatcher, NotMatcher and OrMatcher. The contract
between these matchers was not sound in the Ordering[Matcher]
implementation. Instead of trying to sort these, I just throw up my
hands and say that they are uncomparable.
After this change, I have 100% coverage of all of the branches in the
ordering implementations. Note that the ordering is unspecified between
AndMatcher, NotMatcher and OrMatcher. This means that, for example,
{ **/!foo, **/(foo && bar) } and { **/(foo && bar), **/!foo }
are both possible orderings depending on the initial ordering of these
two globs. However,
{ **/bar/!foo, **/foo/!bar }
is the only possible ordering for those two globs. In other words,
ordering is preserved up until two components differ only by an
(And|Not|Or)Matcher.
Here are screenshots showing that all of the branches are covered in jacoco:
By comparison, here was the previous jacoco coverage:
(whoops)