Skip to content

Commit 1e3264d

Browse files
Atryclaude
andcommitted
Reuse the extractor library via a private Compat.Extractor
Make `.extract` opt-in and keep it out of `com.thoughtworks`: - `Compat` is now `private[sbtApiMappings]` and exposes a nested `Extractor` member, imported with `import Compat.Extractor._`. This avoids leaking the `.extract` implicit onto every function via `import Compat._`. - On Scala 2.12, `Compat.Extractor` is `val Extractor = com.thoughtworks.Extractor`, i.e. a re-export of the `com.thoughtworks.extractor` library (added back as a Scala-2.12-only dependency). The library is reused as-is; its `sealed` `private[thoughtworks]` traits cannot be wrapped, but a plain `val` alias re-exports the object so its implicits come in through `import Compat.Extractor._`. - On Scala 3 `Compat.Extractor` is an `object` whose `extension` turns a function/partial function into a `PartialFunction` (already a valid pattern on Scala 3). No `com.thoughtworks.Extractor` shim, so the package is not polluted. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent a29bae7 commit 1e3264d

10 files changed

Lines changed: 34 additions & 35 deletions

File tree

build.sbt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,16 @@ pluginCrossBuild / sbtVersion := {
3434
// so most of the plugin sources can be shared across both sbt versions.
3535
addSbtPlugin("com.github.sbt" % "sbt2-compat" % "0.1.0")
3636

37+
// `.extract` pattern support, reused via `Compat.Extractor`. Only published for
38+
// Scala 2.12; on Scala 3 a PartialFunction is already a valid pattern, so the
39+
// Scala 3 `Compat.Extractor` provides an equivalent extension instead.
40+
libraryDependencies ++= {
41+
if (scalaBinaryVersion.value == "2.12")
42+
Seq("com.thoughtworks.extractor" %% "extractor" % "2.1.3")
43+
else
44+
Seq.empty
45+
}
46+
3747
libraryDependencies += "org.scalatest" %% "scalatest" % "3.2.20" % "test"
3848

3949
scriptedBufferLog := false

src/main/scala-2.12/com/thoughtworks/sbtApiMappings/Compat.scala

Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import sbtcompat.PluginCompat
99
/** sbt 1.x specific bindings: only the pieces that genuinely differ from sbt
1010
* 2.x. Everything that sbt2-compat can express uniformly is plain shared code.
1111
*/
12-
object Compat {
12+
private[sbtApiMappings] object Compat {
1313

1414
/** The value type of the `apiMappings` map. */
1515
type DocUrl = URL
@@ -20,22 +20,9 @@ object Compat {
2020
def fileToDocKey: Def.Initialize[Task[File => PluginCompat.FileRef]] =
2121
Def.task { (file: File) => file }
2222

23-
// On Scala 2.12 a function/partial function cannot be used as a pattern
24-
// directly, so `.extract` adapts it into an extractor object.
25-
26-
final class Extractor[A, B](unlifted: A => Option[B]) {
27-
def unapply(a: A): Option[B] = unlifted(a)
28-
}
29-
30-
implicit final class FunctionExtractOps[A, B](private val f: A => Option[B])
31-
extends AnyVal {
32-
def extract: Extractor[A, B] = new Extractor(f)
33-
}
34-
35-
implicit final class PartialFunctionExtractOps[A, B](
36-
private val pf: PartialFunction[A, B]
37-
) extends AnyVal {
38-
def extract: Extractor[A, B] = new Extractor(pf.lift)
39-
}
40-
23+
/** The `.extract` pattern support, opted into with
24+
* `import Compat.Extractor._`. On Scala 2.12 it simply re-exports the
25+
* `com.thoughtworks.extractor` library.
26+
*/
27+
val Extractor = com.thoughtworks.Extractor
4128
}

src/main/scala-3/com/thoughtworks/sbtApiMappings/Compat.scala

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import xsbti.HashedVirtualFileRef
1010
/** sbt 2.x specific bindings: only the pieces that genuinely differ from sbt
1111
* 1.x. Everything that sbt2-compat can express uniformly is plain shared code.
1212
*/
13-
object Compat:
13+
private[sbtApiMappings] object Compat:
1414

1515
/** The value type of the `apiMappings` map. */
1616
type DocUrl = URI
@@ -27,11 +27,13 @@ object Compat:
2727
HashedVirtualFileRef.of(file.toPath.toString, ""): PluginCompat.FileRef
2828
}
2929

30-
// On Scala 3 a PartialFunction is already a valid pattern, so `.extract` turns
31-
// a function (or partial function) into one.
32-
33-
extension [A, B](f: A => Option[B])
34-
def extract: PartialFunction[A, B] = Function.unlift(f)
35-
36-
extension [A, B](pf: PartialFunction[A, B])
37-
def extract: PartialFunction[A, B] = pf
30+
/** The `.extract` pattern support, opted into with `import Compat.Extractor._`.
31+
* The `com.thoughtworks.extractor` library has no Scala 3 build, but on Scala
32+
* 3 a [[scala.PartialFunction]] is already a valid pattern, so a function (or
33+
* partial function) only needs to be turned into one.
34+
*/
35+
object Extractor:
36+
extension [A, B](f: A => Option[B])
37+
def extract: PartialFunction[A, B] = Function.unlift(f)
38+
extension [A, B](pf: PartialFunction[A, B])
39+
def extract: PartialFunction[A, B] = pf

src/main/scala/com/thoughtworks/sbtApiMappings/ApiMappings.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ package com.thoughtworks.sbtApiMappings
1818

1919
import sbt._
2020
import Keys._
21-
import Compat._
21+
import Compat.Extractor._
2222
import sbt.plugins.JvmPlugin
2323
import sbtcompat.PluginCompat
2424
// Brings `Def.uncached`, which sbt2-compat backfills on sbt 1.x (native on 2.x).

src/main/scala/com/thoughtworks/sbtApiMappings/JavadocIoApiMappingRule.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package com.thoughtworks.sbtApiMappings
22

33
import sbt._
4-
import Compat._
4+
import Compat.Extractor._
55
import sbtcompat.PluginCompat
66
import sbt.internal.librarymanagement.mavenint.PomExtraDependencyAttributes
77

src/main/scala/com/thoughtworks/sbtApiMappings/PlayApiMappingRule.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package com.thoughtworks.sbtApiMappings
22

33
import sbt._
4-
import Compat._
4+
import Compat.Extractor._
55
import sbtcompat.PluginCompat
66

77
/** @author

src/main/scala/com/thoughtworks/sbtApiMappings/ScalaApiMappingRule.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ package com.thoughtworks.sbtApiMappings
22

33
import sbt.{AutoPlugin, ModuleID, VersionNumber, _}
44
import Ordering.Implicits._
5-
import Compat._
5+
import Compat.Extractor._
66
import sbtcompat.PluginCompat
77

88
/** @author

src/main/scala/com/thoughtworks/sbtApiMappings/SonatypeApiMappingRule.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package com.thoughtworks.sbtApiMappings
22

33
import sbt._
4-
import Compat._
4+
import Compat.Extractor._
55
import sbtcompat.PluginCompat
66
import sbt.internal.librarymanagement.mavenint.PomExtraDependencyAttributes
77

src/main/scala/com/thoughtworks/sbtApiMappings/SonatypeApiMappingRuleForSbtPlugins.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package com.thoughtworks.sbtApiMappings
22

33
import sbt._
4-
import Compat._
4+
import Compat.Extractor._
55
import sbtcompat.PluginCompat
66
import sbt.internal.librarymanagement.mavenint.PomExtraDependencyAttributes
77

src/main/scala/com/thoughtworks/sbtApiMappings/SparkApiMappingRule.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package com.thoughtworks.sbtApiMappings
22

33
import sbt.{AutoPlugin, ModuleID, _}
4-
import Compat._
4+
import Compat.Extractor._
55
import sbtcompat.PluginCompat
66

77
/** @author

0 commit comments

Comments
 (0)