diff options
author | Guillaume Massé <masgui@gmail.com> | 2018-03-01 05:28:48 +0100 |
---|---|---|
committer | Li Haoyi <haoyi.sg@gmail.com> | 2018-02-28 20:28:48 -0800 |
commit | a6bd3dbe0f9f6d58326f0ffaa0737d07d5a3821f (patch) | |
tree | 3defba186bc48369269eb618cbca3802ea7bab1e | |
parent | c7b2fff6badcc595c177f85c7331cc4868c73412 (diff) | |
download | mill-a6bd3dbe0f9f6d58326f0ffaa0737d07d5a3821f.tar.gz mill-a6bd3dbe0f9f6d58326f0ffaa0737d07d5a3821f.tar.bz2 mill-a6bd3dbe0f9f6d58326f0ffaa0737d07d5a3821f.zip |
Add dsl for SCM (now called VersionControl) (#168)
The scm url syntax is a source of confusion for developper. I added VersionControl.github() to simplify this process. We can add other common VersionControl url scheme like Bazar, etc.
-rwxr-xr-x | build.sc | 3 | ||||
-rw-r--r-- | docs/example-2/build.sc | 5 | ||||
-rw-r--r-- | docs/pages/1 - Intro to Mill.md | 5 | ||||
-rw-r--r-- | docs/pages/3 - Common Project Layouts.md | 5 | ||||
-rw-r--r-- | integration/test/resources/acyclic/build.sc | 7 | ||||
-rw-r--r-- | integration/test/resources/upickle/build.sc | 5 | ||||
-rw-r--r-- | scalajslib/test/src/mill/scalajslib/HelloJSWorldTests.scala | 7 | ||||
-rw-r--r-- | scalalib/src/mill/scalalib/publish/JsonFormatters.scala | 2 | ||||
-rw-r--r-- | scalalib/src/mill/scalalib/publish/Pom.scala | 26 | ||||
-rw-r--r-- | scalalib/src/mill/scalalib/publish/settings.scala | 140 | ||||
-rw-r--r-- | scalalib/test/src/mill/scalalib/HelloWorldTests.scala | 6 |
11 files changed, 176 insertions, 35 deletions
@@ -28,6 +28,9 @@ trait MillPublishModule extends PublishModule{ "git://github.com/lihaoyi/mill.git", "scm:git://github.com/lihaoyi/mill.git" ), + // TODO 0.1.4: + // versionControl = VersionControl.github("lihaoyi", "mill") + developers = Seq( Developer("lihaoyi", "Li Haoyi","https://github.com/lihaoyi") ) diff --git a/docs/example-2/build.sc b/docs/example-2/build.sc index 9457b51a..e8cb27ef 100644 --- a/docs/example-2/build.sc +++ b/docs/example-2/build.sc @@ -10,10 +10,7 @@ object foo extends PublishModule{ organization = "com.lihaoyi", url = "https://github.com/lihaoyi/example", licenses = Seq(License.MIT), - scm = SCM( - "git://github.com/lihaoyi/example.git", - "scm:git://github.com/lihaoyi/example.git" - ), + versionControl = VersionControl.github("lihaoyi", "example"), developers = Seq( Developer("lihaoyi", "Li Haoyi","https://github.com/lihaoyi") ) diff --git a/docs/pages/1 - Intro to Mill.md b/docs/pages/1 - Intro to Mill.md index b2ffe0ec..6de57ac9 100644 --- a/docs/pages/1 - Intro to Mill.md +++ b/docs/pages/1 - Intro to Mill.md @@ -488,10 +488,7 @@ object foo extends PublishModule{ organization = "com.lihaoyi", url = "https://github.com/lihaoyi/example", licenses = Seq(License.MIT), - scm = SCM( - "git://github.com/lihaoyi/example.git", - "scm:git://github.com/lihaoyi/example.git" - ), + versionControl = VersionControl.github("lihaoyi", "example"), developers = Seq( Developer("lihaoyi", "Li Haoyi","https://github.com/lihaoyi") ) diff --git a/docs/pages/3 - Common Project Layouts.md b/docs/pages/3 - Common Project Layouts.md index 275971a6..3af47a45 100644 --- a/docs/pages/3 - Common Project Layouts.md +++ b/docs/pages/3 - Common Project Layouts.md @@ -130,10 +130,7 @@ object foo extends ScalaModule with PublishModule{ organization = "com.lihaoyi", url = "https://github.com/lihaoyi/mill", licenses = Seq(License.MIT), - scm = SCM( - "git://github.com/lihaoyi/mill.git", - "scm:git://github.com/lihaoyi/mill.git" - ), + versionControl = VersionControl.github("lihaoyi", "mill"), developers = Seq( Developer("lihaoyi", "Li Haoyi","https://github.com/lihaoyi") ) diff --git a/integration/test/resources/acyclic/build.sc b/integration/test/resources/acyclic/build.sc index de228b24..ce69f05d 100644 --- a/integration/test/resources/acyclic/build.sc +++ b/integration/test/resources/acyclic/build.sc @@ -1,6 +1,6 @@ import mill.Cross import mill.scalalib.{SbtModule, PublishModule, Dep, CrossSbtModule, DepSyntax} -import mill.scalalib.publish.{PomSettings, License, Developer, SCM} +import mill.scalalib.publish.{PomSettings, License, Developer, VersionControl} object acyclic extends Cross[AcyclicModule]("2.10.6", "2.11.8", "2.12.3", "2.12.4") class AcyclicModule(val crossScalaVersion: String) extends CrossSbtModule with PublishModule { @@ -13,10 +13,7 @@ class AcyclicModule(val crossScalaVersion: String) extends CrossSbtModule with P organization = "com.lihaoyi", url = "https://github.com/lihaoyi/acyclic", licenses = Seq(License.MIT), - scm = SCM( - "git://github.com/lihaoyi/acyclic.git", - "scm:git://github.com/lihaoyi/acyclic.git" - ), + versionControl = VersionControl.github("lihaoyi", "acyclic"), developers = Seq( Developer("lihaoyi", "Li Haoyi","https://github.com/lihaoyi") ) diff --git a/integration/test/resources/upickle/build.sc b/integration/test/resources/upickle/build.sc index cd0b4d03..e1383771 100644 --- a/integration/test/resources/upickle/build.sc +++ b/integration/test/resources/upickle/build.sc @@ -13,10 +13,7 @@ trait UpickleModule extends CrossSbtModule with PublishModule{ organization = "com.lihaoyi", url = "https://github.com/lihaoyi/upickle", licenses = Seq(License.MIT), - scm = SCM( - "git://github.com/lihaoyi/upickle.git", - "scm:git://github.com/lihaoyi/upickle.git" - ), + versionControl = VersionControl.github("lihaoyi", "upickle"), developers = Seq( Developer("lihaoyi", "Li Haoyi","https://github.com/lihaoyi") ) diff --git a/scalajslib/test/src/mill/scalajslib/HelloJSWorldTests.scala b/scalajslib/test/src/mill/scalajslib/HelloJSWorldTests.scala index df4b940d..23db8cf6 100644 --- a/scalajslib/test/src/mill/scalajslib/HelloJSWorldTests.scala +++ b/scalajslib/test/src/mill/scalajslib/HelloJSWorldTests.scala @@ -7,7 +7,7 @@ import mill._ import mill.define.Discover import mill.eval.{Evaluator, Result} import mill.scalalib.{CrossScalaModule, DepSyntax, Lib, PublishModule, TestRunner} -import mill.scalalib.publish.{Developer, License, PomSettings, SCM} +import mill.scalalib.publish.{Developer, License, PomSettings, VersionControl} import mill.util.{TestEvaluator, TestUtil} import utest._ @@ -39,10 +39,7 @@ object HelloJSWorldTests extends TestSuite { description = "hello js world ready for real world publishing", url = "https://github.com/lihaoyi/hello-world-publish", licenses = Seq(License.Common.Apache2), - scm = SCM( - "https://github.com/lihaoyi/hello-world-publish", - "scm:git:https://github.com/lihaoyi/hello-world-publish" - ), + versionControl = VersionControl.github("lihaoyi", "hello-world-publish"), developers = Seq(Developer("lihaoyi", "Li Haoyi", "https://github.com/lihaoyi")) ) diff --git a/scalalib/src/mill/scalalib/publish/JsonFormatters.scala b/scalalib/src/mill/scalalib/publish/JsonFormatters.scala index cf1af557..8fc90632 100644 --- a/scalalib/src/mill/scalalib/publish/JsonFormatters.scala +++ b/scalalib/src/mill/scalalib/publish/JsonFormatters.scala @@ -6,6 +6,6 @@ trait JsonFormatters { implicit lazy val artifactFormat: RW[Artifact] = upickle.default.macroRW implicit lazy val developerFormat: RW[Developer] = upickle.default.macroRW implicit lazy val licenseFormat: RW[License] = upickle.default.macroRW - implicit lazy val scmFormat: RW[SCM] = upickle.default.macroRW + implicit lazy val versionControlFormat: RW[VersionControl] = upickle.default.macroRW implicit lazy val pomSettingsFormat: RW[PomSettings] = upickle.default.macroRW } diff --git a/scalalib/src/mill/scalalib/publish/Pom.scala b/scalalib/src/mill/scalalib/publish/Pom.scala index 895e1686..382db56a 100644 --- a/scalalib/src/mill/scalalib/publish/Pom.scala +++ b/scalalib/src/mill/scalalib/publish/Pom.scala @@ -2,7 +2,7 @@ package mill.scalalib.publish import mill.util.Loose.Agg -import scala.xml.{Elem, NodeSeq, PrettyPrinter} +import scala.xml.{Atom, Elem, NodeSeq, PrettyPrinter} object Pom { @@ -13,6 +13,24 @@ object Pom { dependencies: Agg[Dependency], name: String, pomSettings: PomSettings): String = { + + // source: https://stackoverflow.com/a/5254068/449071 + implicit def optionElem(e: Elem) = new { + def optionnal : NodeSeq = { + require(e.child.length == 1) + e.child.head match { + case atom: Atom[Option[_]] => atom.data match { + case None => NodeSeq.Empty + case Some(x) => e.copy(child = x match { + case n: NodeSeq => n + case x => new Atom(x) + }) + } + case _ => e + } + } + } + val xml = <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" @@ -32,8 +50,10 @@ object Pom { {pomSettings.licenses.map(renderLicense)} </licenses> <scm> - <url>{pomSettings.scm.url}</url> - <connection>{pomSettings.scm.connection}</connection> + <connection>{pomSettings.versionControl.connection}</connection>.optionnal + <developerConnection>{pomSettings.versionControl.developerConnection}</developerConnection>.optionnal + <tag>{pomSettings.versionControl.tag}</tag>.optionnal + <url>{pomSettings.versionControl.browsableRepository}</url>.optionnal </scm> <developers> {pomSettings.developers.map(renderDeveloper)} diff --git a/scalalib/src/mill/scalalib/publish/settings.scala b/scalalib/src/mill/scalalib/publish/settings.scala index 0327b132..665e0ed6 100644 --- a/scalalib/src/mill/scalalib/publish/settings.scala +++ b/scalalib/src/mill/scalalib/publish/settings.scala @@ -52,11 +52,125 @@ case class Dependency( scope: Scope ) +// https://maven.apache.org/pom.html#SCM +/* + * @param browsableRepository: a publicly browsable repository + * (example: https://github.com/lihaoyi/mill) + * @param connection: read-only connection to repository + * (example: scm:git:git://github.com/lihaoyi/mill.git) + * @param developerConnection: read-write connection to repository + * (example: scm:git:git@github.com:lihaoyi/mill.git) + * @param tag: tag that was created for this release. This is useful for + * git and mercurial since it's not possible to include the tag in + * the connection url. + * (example: v2.12.4, HEAD, my-branch, fd8a2567ad32c11bcf8adbaca85bdba72bb4f935, ...) + */ +case class VersionControl( + browsableRepository: Option[String] = None, + connection: Option[String] = None, + developerConnection: Option[String] = None, + tag: Option[String] = None +) + +@deprecated("use VersionControl", "0.1.3") case class SCM( url: String, connection: String ) +object VersionControl { + def github(owner: String, repo: String, tag: Option[String] = None): VersionControl = + VersionControl( + browsableRepository = Some(s"https://github.com/$owner/$repo"), + connection = Some(VersionControlConnection.gitGit("github.com", "$owner/$repo.git")), + developerConnection = Some(VersionControlConnection.gitSsh("github.com", "$owner/$repo.git")), + tag = tag + ) +} + +object VersionControlConnection { + def network(scm: String, + protocol: String, + hostname: String, + path: String, + username: Option[String] = None, + password: Option[String] = None, + port: Option[Int] = None): String = { + val portPart = port.map(":" + _).getOrElse("") + val credentials = + username match { + case Some(user) => + val pass = password.map(":" + _).getOrElse("") + s"${user}${pass}" + case None => + password match { + case Some(p) => sys.error(s"no username set for password: $p") + case _ => "" + } + } + + s"${scm}:${protocol}://${credentials}${hostname}${portPart}/$path" + } + + def file(scm: String, hostname: Option[String], path: String): String = { + val hostnamePart = hostname.getOrElse("") + "scm:$scm:file://${hostnamePart}/$path" + } + + def gitGit(hostname: String, + path: String, + port: Option[Int] = None): String = + network("git", "git", hostname, path, port = port) + + def gitHttp(hostname: String, + path: String, + port: Option[Int] = None): String = + network("git", "http", hostname, path, port = port) + + def gitHttps(hostname: String, + path: String, + port: Option[Int] = None): String = + network("git", "https", hostname, path, port = port) + + def gitSsh(hostname: String, + path: String, + port: Option[Int] = None): String = + network("git", "ssh", hostname, path, port = port) + + def gitFile(hostname: Option[String], path: String): String = + file("git", hostname, path) + + def svnSsh(hostname: String, + path: String, + username: Option[String], + port: Option[Int]): String = + network("svn", "svn+ssh", hostname, path, username, None, port) + + def svnHttp(hostname: String, + path: String, + port: Option[Int], + username: Option[String], + password: Option[String]): String = + network("svn", "http", hostname, path, username, password) + + def svnHttps(hostname: String, + path: String, + port: Option[Int], + username: Option[String], + password: Option[String]): String = + network("svn", "https", hostname, path, username, password) + + def svnSvn(username: Option[String], + password: Option[String], + hostname: String, + port: Option[Int], + path: String): String = + network("svn", "svn", hostname, path, username, password) + + def svnFile(hostname: Option[String], path: String): String = + file("svn", hostname, path) +} + case class Developer( id: String, name: String, @@ -70,6 +184,30 @@ case class PomSettings( organization: String, url: String, licenses: Seq[License], - scm: SCM, + versionControl: VersionControl, developers: Seq[Developer] ) + +object PomSettings { + @deprecated("use VersionControl instead of SCM", "0.1.3") + def apply(description: String, + organization: String, + url: String, + licenses: Seq[License], + scm: SCM, + developers: Seq[Developer]): PomSettings = { + PomSettings( + description = description, + organization = organization, + url = url, + licenses = licenses, + versionControl = VersionControl( + browsableRepository = Some(scm.url), + connection = Some(scm.connection), + developerConnection = None, + tag = None + ), + developers = developers + ) + } +} diff --git a/scalalib/test/src/mill/scalalib/HelloWorldTests.scala b/scalalib/test/src/mill/scalalib/HelloWorldTests.scala index 2bb51ad6..4fb5f5a5 100644 --- a/scalalib/test/src/mill/scalalib/HelloWorldTests.scala +++ b/scalalib/test/src/mill/scalalib/HelloWorldTests.scala @@ -9,6 +9,7 @@ import mill.define.{Discover, Target} import mill.eval.{Evaluator, Result} import mill.scalalib.publish._ import mill.util.{TestEvaluator, TestUtil} +import mill.scalalib.publish.VersionControl import utest._ import utest.framework.TestPath @@ -86,10 +87,7 @@ object HelloWorldTests extends TestSuite { description = "hello world ready for real world publishing", url = "https://github.com/lihaoyi/hello-world-publish", licenses = Seq(License.Common.Apache2), - scm = SCM( - "https://github.com/lihaoyi/hello-world-publish", - "scm:git:https://github.com/lihaoyi/hello-world-publish" - ), + versionControl = VersionControl.github("lihaoyi", "hello-world-publish"), developers = Seq(Developer("lihaoyi", "Li Haoyi", "https://github.com/lihaoyi")) ) |