diff options
author | Sheng Chen <shengcer@gmail.com> | 2018-04-02 16:43:44 -0400 |
---|---|---|
committer | Nikolay Tatarinov <5min4eq.unity@gmail.com> | 2018-04-02 23:43:44 +0300 |
commit | 8cdc9f1480200bec07b8b05c1e78ee1e1b6a21de (patch) | |
tree | a1976fc77533291f5de29252658ed4958ab088c7 | |
parent | f972d712c76bc19c158ea77084abdcbf520d762e (diff) | |
download | mill-8cdc9f1480200bec07b8b05c1e78ee1e1b6a21de.tar.gz mill-8cdc9f1480200bec07b8b05c1e78ee1e1b6a21de.tar.bz2 mill-8cdc9f1480200bec07b8b05c1e78ee1e1b6a21de.zip |
revive #254 and fix #268 (#274)
-rw-r--r-- | scalalib/src/mill/scalalib/Dep.scala | 14 | ||||
-rw-r--r-- | scalalib/src/mill/scalalib/publish/Ivy.scala | 8 | ||||
-rw-r--r-- | scalalib/src/mill/scalalib/publish/Pom.scala | 28 | ||||
-rw-r--r-- | scalalib/src/mill/scalalib/publish/settings.scala | 16 | ||||
-rw-r--r-- | scalalib/test/src/mill/scalalib/ResolveDepsTests.scala | 18 | ||||
-rw-r--r-- | scalalib/test/src/mill/scalalib/publish/IvyTests.scala | 60 | ||||
-rw-r--r-- | scalalib/test/src/mill/scalalib/publish/PomTests.scala | 12 |
7 files changed, 141 insertions, 15 deletions
diff --git a/scalalib/src/mill/scalalib/Dep.scala b/scalalib/src/mill/scalalib/Dep.scala index bd7fce4f..f67eed03 100644 --- a/scalalib/src/mill/scalalib/Dep.scala +++ b/scalalib/src/mill/scalalib/Dep.scala @@ -3,6 +3,20 @@ import mill.util.JsonFormatters._ import upickle.default.{macroRW, ReadWriter => RW} sealed trait Dep { def configure(attributes: coursier.Attributes): Dep + def exclude(exclusions: (String, String)*): Dep = + this match { + case dep : Dep.Java => dep.copy(dep = dep.dep.copy(exclusions = dep.dep.exclusions ++ exclusions)) + case dep : Dep.Scala => dep.copy(dep = dep.dep.copy(exclusions = dep.dep.exclusions ++ exclusions)) + case dep : Dep.Point => dep.copy(dep = dep.dep.copy(exclusions = dep.dep.exclusions ++ exclusions)) + } + def excludeOrg(organizations: String*): Dep = exclude(organizations.map(_ -> "*"): _*) + def excludeName(names: String*): Dep = exclude(names.map("*" -> _): _*) + def withConfiguration(configuration: String): Dep = + this match { + case dep : Dep.Java => dep.copy(dep = dep.dep.copy(configuration = configuration)) + case dep : Dep.Scala => dep.copy(dep = dep.dep.copy(configuration = configuration)) + case dep : Dep.Point => dep.copy(dep = dep.dep.copy(configuration = configuration)) + } } object Dep{ diff --git a/scalalib/src/mill/scalalib/publish/Ivy.scala b/scalalib/src/mill/scalalib/publish/Ivy.scala index 644e2c53..22e26ff6 100644 --- a/scalalib/src/mill/scalalib/publish/Ivy.scala +++ b/scalalib/src/mill/scalalib/publish/Ivy.scala @@ -41,8 +41,12 @@ object Ivy { } private def renderDependency(dep: Dependency) = { - val scope = scopeToConf(dep.scope) - <dependency org={dep.artifact.group} name={dep.artifact.id} rev={dep.artifact.version} conf={s"$scope->default(compile)"}></dependency> + if (dep.exclusions.isEmpty) + <dependency org={dep.artifact.group} name={dep.artifact.id} rev={dep.artifact.version} conf={s"${scopeToConf(dep.scope)}->${dep.configuration.getOrElse("default(compile)")}"} /> + else + <dependency org={dep.artifact.group} name={dep.artifact.id} rev={dep.artifact.version} conf={s"${scopeToConf(dep.scope)}->${dep.configuration.getOrElse("default(compile)")}"}> + {dep.exclusions.map(ex => <exclude org={ex._1} name={ex._2} matcher="exact"/>)} + </dependency> } private def scopeToConf(s: Scope): String = s match { diff --git a/scalalib/src/mill/scalalib/publish/Pom.scala b/scalalib/src/mill/scalalib/publish/Pom.scala index 1a86e7de..84cf0632 100644 --- a/scalalib/src/mill/scalalib/publish/Pom.scala +++ b/scalalib/src/mill/scalalib/publish/Pom.scala @@ -90,12 +90,28 @@ object Pom { case Scope.Test => <scope>test</scope> case Scope.Runtime => <scope>runtime</scope> } - <dependency> - <groupId>{d.artifact.group}</groupId> - <artifactId>{d.artifact.id}</artifactId> - <version>{d.artifact.version}</version> - {scope} - </dependency> + if (d.exclusions.isEmpty) + <dependency> + <groupId>{d.artifact.group}</groupId> + <artifactId>{d.artifact.id}</artifactId> + <version>{d.artifact.version}</version> + {scope} + </dependency> + else + <dependency> + <groupId>{d.artifact.group}</groupId> + <artifactId>{d.artifact.id}</artifactId> + <version>{d.artifact.version}</version> + <exclusions> + {d.exclusions.map(ex => + <exclude> + <groupId>{ex._1}</groupId> + <artifactId>{ex._2}</artifactId> + </exclude> + )} + </exclusions> + {scope} + </dependency> } } diff --git a/scalalib/src/mill/scalalib/publish/settings.scala b/scalalib/src/mill/scalalib/publish/settings.scala index 1076fb41..34f7e7ad 100644 --- a/scalalib/src/mill/scalalib/publish/settings.scala +++ b/scalalib/src/mill/scalalib/publish/settings.scala @@ -15,7 +15,9 @@ object Artifact { case Dep.Java(dep, cross) => Dependency( Artifact(dep.module.organization, dep.module.name, dep.version), - Scope.Compile + Scope.Compile, + if (dep.configuration == "" ) None else Some(dep.configuration), + dep.exclusions.toList ) case Dep.Scala(dep, cross) => Dependency( @@ -24,7 +26,9 @@ object Artifact { s"${dep.module.name}_${scalaBin}", dep.version ), - Scope.Compile + Scope.Compile, + if (dep.configuration == "") None else Some(dep.configuration), + dep.exclusions.toList ) case Dep.Point(dep, cross) => Dependency( @@ -33,7 +37,9 @@ object Artifact { s"${dep.module.name}_${scalaFull}", dep.version ), - Scope.Compile + Scope.Compile, + if (dep.configuration == "") None else Some(dep.configuration), + dep.exclusions.toList ) } } @@ -49,7 +55,9 @@ object Scope { case class Dependency( artifact: Artifact, - scope: Scope + scope: Scope, + configuration: Option[String] = None, + exclusions: Seq[(String, String)] = Nil ) case class Developer( diff --git a/scalalib/test/src/mill/scalalib/ResolveDepsTests.scala b/scalalib/test/src/mill/scalalib/ResolveDepsTests.scala index 97fcbd50..861fa312 100644 --- a/scalalib/test/src/mill/scalalib/ResolveDepsTests.scala +++ b/scalalib/test/src/mill/scalalib/ResolveDepsTests.scala @@ -34,6 +34,24 @@ object ResolveDepsTests extends TestSuite { assert(paths.exists(_.path.toString.contains("byte-buddy"))) } + 'excludeTransitiveDeps - { + val deps = Agg(ivy"com.lihaoyi::pprint:0.5.3".exclude("com.lihaoyi" -> "fansi_2.12")) + val Success(paths) = evalDeps(deps) + assert(!paths.exists(_.path.toString.contains("fansi_2.12"))) + } + + 'excludeTransitiveDepsByOrg - { + val deps = Agg(ivy"com.lihaoyi::pprint:0.5.3".excludeOrg("com.lihaoyi")) + val Success(paths) = evalDeps(deps) + assert(!paths.exists(path => path.path.toString.contains("com/lihaoyi") && !path.path.toString.contains("pprint_2.12"))) + } + + 'excludeTransitiveDepsByName - { + val deps = Agg(ivy"com.lihaoyi::pprint:0.5.3".excludeName("fansi_2.12")) + val Success(paths) = evalDeps(deps) + assert(!paths.exists(_.path.toString.contains("fansi_2.12"))) + } + 'errOnInvalidOrgDeps - { val deps = Agg(ivy"xxx.yyy.invalid::pprint:0.5.3") val Failure(errMsg, _) = evalDeps(deps) diff --git a/scalalib/test/src/mill/scalalib/publish/IvyTests.scala b/scalalib/test/src/mill/scalalib/publish/IvyTests.scala new file mode 100644 index 00000000..0f275dd9 --- /dev/null +++ b/scalalib/test/src/mill/scalalib/publish/IvyTests.scala @@ -0,0 +1,60 @@ +package mill.scalalib.publish + +import utest._ +import mill._ + +import scala.xml.{Node, NodeSeq, XML} + +object IvyTests extends TestSuite { + + def tests: Tests = Tests { + val artifactId = "mill-scalalib_2.12" + val artifact = + Artifact("com.lihaoyi", "mill-scalalib_2.12", "0.0.1") + val deps = Agg( + Dependency(Artifact("com.lihaoyi", "mill-main_2.12", "0.1.4"), + Scope.Compile), + Dependency(Artifact("org.scala-sbt", "test-interface", "1.0"), + Scope.Compile), + Dependency(Artifact("com.lihaoyi", "pprint_2.12", "0.5.3"), + Scope.Compile, exclusions = List("com.lihaoyi" -> "fansi_2.12", "*" -> "sourcecode_2.12")) + ) + + 'fullIvy - { + val fullIvy = XML.loadString(Ivy(artifact, deps)) + + 'topLevel - { + val info = singleNode(fullIvy \ "info") + assert( + singleAttr(info, "organisation") == artifact.group + , singleAttr(info, "module") == artifact.id + , singleAttr(info, "revision") == artifact.version + ) + } + + 'dependencies - { + val dependencies = fullIvy \ "dependencies" \ "dependency" + val ivyDeps = deps.indexed + + assert(dependencies.size == ivyDeps.size) + + dependencies.zipWithIndex.foreach { case (dep, index) => + assert( + singleAttr(dep, "org") == ivyDeps(index).artifact.group + , singleAttr(dep, "name") == ivyDeps(index).artifact.id + , singleAttr(dep, "rev") == ivyDeps(index).artifact.version + , (dep \ "exclude").zipWithIndex forall { case (exclude, j) => + singleAttr(exclude, "org") == ivyDeps(index).exclusions(j)._1 && + singleAttr(exclude, "name") == ivyDeps(index).exclusions(j)._2 + } + ) + } + } + } + } + + def singleNode(seq: NodeSeq): Node = + seq.headOption.getOrElse(throw new RuntimeException("empty seq")) + def singleAttr(node: Node, attr: String): String = + node.attribute(attr).flatMap(_.headOption.map(_.text)).getOrElse(throw new RuntimeException(s"empty attr $attr")) +} diff --git a/scalalib/test/src/mill/scalalib/publish/PomTests.scala b/scalalib/test/src/mill/scalalib/publish/PomTests.scala index 31e87446..c15ff172 100644 --- a/scalalib/test/src/mill/scalalib/publish/PomTests.scala +++ b/scalalib/test/src/mill/scalalib/publish/PomTests.scala @@ -15,7 +15,9 @@ object PomTests extends TestSuite { Dependency(Artifact("com.lihaoyi", "mill-main_2.12", "0.1.4"), Scope.Compile), Dependency(Artifact("org.scala-sbt", "test-interface", "1.0"), - Scope.Compile) + Scope.Compile), + Dependency(Artifact("com.lihaoyi", "pprint_2.12", "0.5.3"), + Scope.Compile, exclusions = List("com.lihaoyi" -> "fansi_2.12", "*" -> "sourcecode_2.12")) ) val settings = PomSettings( description = "mill-scalalib", @@ -104,7 +106,7 @@ object PomTests extends TestSuite { 'dependencies - { val dependencies = fullPom \ "dependencies" \ "dependency" - assert(dependencies.size == 2) + assert(dependencies.size == 3) val pomDeps = deps.indexed @@ -114,7 +116,11 @@ object PomTests extends TestSuite { singleText(dep \ "groupId") == pomDeps(index).artifact.group, singleText(dep \ "artifactId") == pomDeps(index).artifact.id, singleText(dep \ "version") == pomDeps(index).artifact.version, - optText(dep \ "scope").isEmpty + optText(dep \ "scope").isEmpty, + (dep \ "exclusions").zipWithIndex.forall { case (node, j) => + singleText(node \ "exclude" \ "groupId") == pomDeps(index).exclusions(j)._1 && + singleText(node \ "exclude" \ "artifactId") == pomDeps(index).exclusions(j)._2 + } ) } } |