diff options
author | Li Haoyi <haoyi.sg@gmail.com> | 2018-12-12 16:56:02 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-12-12 16:56:02 -0800 |
commit | 9ba4cb69331386dfde9bac69dc2d5b22401face3 (patch) | |
tree | 120349e8015ae5717d36bd44209cde6ff9543518 /scalalib/src/Dep.scala | |
parent | ea7fceb6e56f53bde3517586dfc57e10a605a524 (diff) | |
download | mill-9ba4cb69331386dfde9bac69dc2d5b22401face3.tar.gz mill-9ba4cb69331386dfde9bac69dc2d5b22401face3.tar.bz2 mill-9ba4cb69331386dfde9bac69dc2d5b22401face3.zip |
collapse boilerplate folder structure within src/ folders (#505)
* collapse boilerplate folder structure within src/ folders
* .
Diffstat (limited to 'scalalib/src/Dep.scala')
-rw-r--r-- | scalalib/src/Dep.scala | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/scalalib/src/Dep.scala b/scalalib/src/Dep.scala new file mode 100644 index 00000000..714fa21e --- /dev/null +++ b/scalalib/src/Dep.scala @@ -0,0 +1,121 @@ +package mill.scalalib +import mill.util.JsonFormatters._ +import upickle.default.{macroRW, ReadWriter => RW} + +import CrossVersion._ + +case class Dep(dep: coursier.Dependency, cross: CrossVersion, force: Boolean) { + import mill.scalalib.api.Util.isDotty + + def artifactName(binaryVersion: String, fullVersion: String, platformSuffix: String) = { + val suffix = cross.suffixString(binaryVersion, fullVersion, platformSuffix) + dep.module.name + suffix + } + def configure(attributes: coursier.Attributes): Dep = copy(dep = dep.copy(attributes = attributes)) + def forceVersion(): Dep = copy(force = true) + def exclude(exclusions: (String, String)*) = copy(dep = dep.copy(exclusions = dep.exclusions ++ exclusions)) + def excludeOrg(organizations: String*): Dep = exclude(organizations.map(_ -> "*"): _*) + def excludeName(names: String*): Dep = exclude(names.map("*" -> _): _*) + def toDependency(binaryVersion: String, fullVersion: String, platformSuffix: String) = + dep.copy(module = dep.module.copy(name = artifactName(binaryVersion, fullVersion, platformSuffix))) + def withConfiguration(configuration: String): Dep = copy(dep = dep.copy(configuration = configuration)) + + /** + * If scalaVersion is a Dotty version, replace the cross-version suffix + * by the Scala 2.x version that the Dotty version is retro-compatible with, + * otherwise do nothing. + * + * This setting is useful when your build contains dependencies that have only + * been published with Scala 2.x, if you have: + * {{{ + * def ivyDeps = Agg(ivy"a::b:c") + * }}} + * you can replace it by: + * {{{ + * def ivyDeps = Agg(ivy"a::b:c".withDottyCompat(scalaVersion())) + * }}} + * This will have no effect when compiling with Scala 2.x, but when compiling + * with Dotty this will change the cross-version to a Scala 2.x one. This + * works because Dotty is currently retro-compatible with Scala 2.x. + */ + def withDottyCompat(scalaVersion: String): Dep = + cross match { + case cross: Binary if isDotty(scalaVersion) => + copy(cross = Constant(value = "_2.12", platformed = cross.platformed)) + case _ => + this + } +} + +object Dep { + + val DefaultConfiguration = "default(compile)" + + implicit def parse(signature: String): Dep = { + val parts = signature.split(';') + val module = parts.head + val attributes = parts.tail.foldLeft(coursier.Attributes()) { (as, s) => + s.split('=') match { + case Array("classifier", v) => as.copy(classifier = v) + case Array(k, v) => throw new Exception(s"Unrecognized attribute: [$s]") + case _ => throw new Exception(s"Unable to parse attribute specifier: [$s]") + } + } + (module.split(':') match { + case Array(a, b, c) => Dep(a, b, c, cross = empty(platformed = false)) + case Array(a, b, "", c) => Dep(a, b, c, cross = empty(platformed = true)) + case Array(a, "", b, c) => Dep(a, b, c, cross = Binary(platformed = false)) + case Array(a, "", b, "", c) => Dep(a, b, c, cross = Binary(platformed = true)) + case Array(a, "", "", b, c) => Dep(a, b, c, cross = Full(platformed = false)) + case Array(a, "", "", b, "", c) => Dep(a, b, c, cross = Full(platformed = true)) + case _ => throw new Exception(s"Unable to parse signature: [$signature]") + }).configure(attributes = attributes) + } + def apply(org: String, name: String, version: String, cross: CrossVersion, force: Boolean = false): Dep = { + apply(coursier.Dependency(coursier.Module(org, name), version, DefaultConfiguration), cross, force) + } + implicit def rw: RW[Dep] = macroRW +} + +sealed trait CrossVersion { + /** If true, the cross-version suffix should start with a platform suffix if it exists */ + def platformed: Boolean + + def isBinary: Boolean = + this.isInstanceOf[Binary] + def isConstant: Boolean = + this.isInstanceOf[Constant] + def isFull: Boolean = + this.isInstanceOf[Full] + + /** The string that should be appended to the module name to get the artifact name */ + def suffixString(binaryVersion: String, fullVersion: String, platformSuffix: String): String = { + val firstSuffix = if (platformed) platformSuffix else "" + this match { + case cross: Constant => + s"${firstSuffix}${cross.value}" + case cross: Binary => + s"${firstSuffix}_${binaryVersion}" + case cross: Full => + s"${firstSuffix}_${fullVersion}" + } + } +} +object CrossVersion { + case class Constant(value: String, platformed: Boolean) extends CrossVersion + object Constant { + implicit def rw: RW[Constant] = macroRW + } + case class Binary(platformed: Boolean) extends CrossVersion + object Binary { + implicit def rw: RW[Binary] = macroRW + } + case class Full(platformed: Boolean) extends CrossVersion + object Full { + implicit def rw: RW[Full] = macroRW + } + + def empty(platformed: Boolean) = Constant(value = "", platformed) + + implicit def rw: RW[CrossVersion] = RW.merge(Constant.rw, Binary.rw, Full.rw) +} |