diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index 64a514500..fa4bef6aa 100644 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -2492,7 +2492,8 @@ object Defaults extends BuildCommon { import Parser.and val base = token(Space) ~> token(and(NotSpace, not("--", "Unexpected: ---")).examples(exs)) val recurse = base flatMap { ex => - val (matching, notMatching) = exs.partition(GlobFilter(ex).accept) + val expandedEx = IncrementalTest.expandGlob(ex) + val (matching, notMatching) = exs.partition(GlobFilter(expandedEx).accept) distinctParser(notMatching, raw) map { result => if (raw) ex +: result else matching.toSeq ++ result } diff --git a/main/src/main/scala/sbt/internal/IncrementalTest.scala b/main/src/main/scala/sbt/internal/IncrementalTest.scala index 1fa9cb486..f9947d83b 100644 --- a/main/src/main/scala/sbt/internal/IncrementalTest.scala +++ b/main/src/main/scala/sbt/internal/IncrementalTest.scala @@ -69,11 +69,14 @@ object IncrementalTest: Vector(Digest.sha256Hash(salt.getBytes("UTF-8"))) } + /** Expands `...` to `**` in glob patterns. */ + def expandGlob(pattern: String): String = pattern.replace("...", "**") + def selectedFilter(args: Seq[String]): Seq[String => Boolean] = def matches(nfs: Seq[NameFilter], s: String) = nfs.exists(_.accept(s)) val (excludeArgs, includeArgs) = args.partition(_.startsWith("-")) - val includeFilters = includeArgs.map(GlobFilter.apply) - val excludeFilters = excludeArgs.map(_.substring(1)).map(GlobFilter.apply) + val includeFilters = includeArgs.map(expandGlob).map(GlobFilter.apply) + val excludeFilters = excludeArgs.map(_.substring(1)).map(expandGlob).map(GlobFilter.apply) (includeFilters, excludeArgs) match case (Nil, Nil) => Seq(const(true)) case (Nil, _) => Seq((s: String) => !matches(excludeFilters, s)) diff --git a/main/src/test/scala/SelectedFilterTest.scala b/main/src/test/scala/SelectedFilterTest.scala index 6a08ce558..9f947eaa8 100644 --- a/main/src/test/scala/SelectedFilterTest.scala +++ b/main/src/test/scala/SelectedFilterTest.scala @@ -101,4 +101,32 @@ object DefaultsTest extends verify.BasicTestSuite { ) == expected ) } + + test("`expandGlob` should replace ... with **") { + assert(IncrementalTest.expandGlob("...Test") == "**Test") + assert(IncrementalTest.expandGlob("com...Test") == "com**Test") + assert(IncrementalTest.expandGlob("...") == "**") + assert(IncrementalTest.expandGlob("Test") == "Test") + assert(IncrementalTest.expandGlob("**Test") == "**Test") + } + + test("it should work with ... as a shorthand for **") { + val expected = Map("com.example.Test1" -> true, "com.example.Test2" -> true, "Foo" -> false) + val filter = List("...Test*") + assert( + expected.map(t => + (t._1, IncrementalTest.selectedFilter(filter).exists(fn => fn(t._1))) + ) == expected + ) + } + + test("it should work with ... in exclusion patterns") { + val expected = Map("com.example.Test1" -> true, "com.example.Foo" -> false) + val filter = List("...Test*", "-...Foo") + assert( + expected.map(t => + (t._1, IncrementalTest.selectedFilter(filter).exists(fn => fn(t._1))) + ) == expected + ) + } } diff --git a/sbt-app/src/sbt-test/tests/test-exclude/test b/sbt-app/src/sbt-test/tests/test-exclude/test index f34def638..287f85fdb 100644 --- a/sbt-app/src/sbt-test/tests/test-exclude/test +++ b/sbt-app/src/sbt-test/tests/test-exclude/test @@ -59,3 +59,19 @@ $ delete target/Test2.run > testOnly -T*1 -T*2 -$ exists target/Test1.run -$ exists target/Test2.run + + +# with ... as a shorthand for ** (issue #8576) +> testOnly ...Test1 +$ exists target/Test1.run +-$ exists target/Test2.run + +$ delete target/Test1.run + + +# with ... in exclusion pattern +> testOnly ...Test... -...Test2 +$ exists target/Test1.run +-$ exists target/Test2.run + +$ delete target/Test1.run