summaryrefslogtreecommitdiff
path: root/scalaplugin/src
diff options
context:
space:
mode:
authordos65 <qtankle@gmail.com>2017-11-28 01:56:42 +0300
committerNikolay Tatarinov <5min4eq.unity@gmail.com>2017-12-20 01:17:16 +0300
commit6a7f6cf910362cadf6b39f8c0795c46745e08742 (patch)
tree5473fc949137771ab3f82cc259a83fb0966555f5 /scalaplugin/src
parent2ecfb282365f7fd8168bfb845cdbb403c00e9615 (diff)
downloadmill-6a7f6cf910362cadf6b39f8c0795c46745e08742.tar.gz
mill-6a7f6cf910362cadf6b39f8c0795c46745e08742.tar.bz2
mill-6a7f6cf910362cadf6b39f8c0795c46745e08742.zip
publishLocal - looks like it works
Diffstat (limited to 'scalaplugin/src')
-rw-r--r--scalaplugin/src/main/scala/mill/scalaplugin/ScalaModule.scala49
-rw-r--r--scalaplugin/src/main/scala/mill/scalaplugin/publish/IvyFile.scala63
-rw-r--r--scalaplugin/src/main/scala/mill/scalaplugin/publish/PomFile.scala90
-rw-r--r--scalaplugin/src/main/scala/mill/scalaplugin/publish/Publisher.scala62
-rw-r--r--scalaplugin/src/main/scala/mill/scalaplugin/publish/settings.scala90
-rw-r--r--scalaplugin/src/test/scala/mill/scalaplugin/AcyclicTests.scala7
6 files changed, 355 insertions, 6 deletions
diff --git a/scalaplugin/src/main/scala/mill/scalaplugin/ScalaModule.scala b/scalaplugin/src/main/scala/mill/scalaplugin/ScalaModule.scala
index ce7b5e00..f7cb8963 100644
--- a/scalaplugin/src/main/scala/mill/scalaplugin/ScalaModule.scala
+++ b/scalaplugin/src/main/scala/mill/scalaplugin/ScalaModule.scala
@@ -198,13 +198,37 @@ trait ScalaModule extends Module with TaskModule{ outer =>
Seq(resources(), compile().classes)).map(_.path).filter(exists)
}
def assembly = T{
- createAssembly(assemblyClasspath(), prependShellScript = prependShellScript())
+ val outDir = T.ctx().dest/up
+ val n = name()
+ val v = version()
+ val jarName = s"${n}-${v}.jar"
+ val dest = outDir/jarName
+ createAssembly(dest, assemblyClasspath(), prependShellScript = prependShellScript())
}
def classpath = T{ Seq(resources(), compile().classes) }
def jar = T{
- createJar(Seq(resources(), compile().classes).map(_.path).filter(exists), mainClass())
+ val outDir = T.ctx().dest/up
+ val n = name()
+ val v = version()
+ val jarName = s"${n}-${v}.jar"
+ val dest = outDir/jarName
+ createJar(dest, Seq(resources(), compile().classes).map(_.path).filter(exists), mainClass())
+ PathRef(dest)
+ }
+
+ def sourcesJar = T{
+ val outDir = T.ctx().dest/up
+ val n = name()
+ val v = version()
+ val jarName = s"${n}-${v}-sources.jar"
+ val dest = outDir/jarName
+
+ val inputs = Seq(sources(), resources()).map(_.path).filter(exists)
+
+ createJar(dest, inputs)
+ PathRef(dest)
}
def run() = T.command{
@@ -223,6 +247,27 @@ trait ScalaModule extends Module with TaskModule{ outer =>
options = Seq("-usejavacp")
)
}
+
+ def organization: T[String] = "acme"
+ def name: T[String] = pwd.last.toString
+ def version: T[String] = "0.0.1-SNAPSHOT"
+
+ // build artifact name as "mill-2.12.4" instead of "mill-2.12"
+ def useFullScalaVersionForPublish: Boolean = false
+
+ def publishLocal() = T.command {
+ import publish._
+ val file = jar()
+ val scalaFull = scalaVersion()
+ val scalaBin = scalaBinaryVersion()
+ val useFullVersion = useFullScalaVersionForPublish
+ val deps = ivyDeps()
+ val dependencies = deps.map(d => Artifact.fromDep(d, scalaFull, scalaBin))
+ val artScalaVersion = if (useFullVersion) scalaFull else scalaBin
+ val artifact = ScalaArtifact(organization(), name(), version(), artScalaVersion)
+ LocalPublisher.publish(file, artifact, dependencies)
+ }
+
}
trait SbtScalaModule extends ScalaModule { outer =>
def basePath: Path
diff --git a/scalaplugin/src/main/scala/mill/scalaplugin/publish/IvyFile.scala b/scalaplugin/src/main/scala/mill/scalaplugin/publish/IvyFile.scala
new file mode 100644
index 00000000..c9f36ebe
--- /dev/null
+++ b/scalaplugin/src/main/scala/mill/scalaplugin/publish/IvyFile.scala
@@ -0,0 +1,63 @@
+package mill.scalaplugin.publish
+
+trait IvyFile {
+
+ val head = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+
+ def generateIvy(
+ artifact: Artifact,
+ dependencies: Seq[Dependency],
+ pomSettings: PomSettings
+ ): String = {
+ val xml = ivyXml(artifact, dependencies, pomSettings)
+ head + xml
+ }
+
+ // can't use scala-xml
+ // it escapes '->' inside dependency conf
+ def ivyXml(
+ artifact: Artifact,
+ dependencies: Seq[Dependency],
+ pomSettings: PomSettings
+ ): String = {
+ val deps = dependencies.map(d => {
+ import d.artifact._
+ val scope = scopeToConf(d.scope)
+ s""" <dependency org="${group}" name="${id}" rev="${version}" conf="${scope}->default(compile)">
+ | </dependency> """.stripMargin
+ }).mkString("\n")
+ s"""<ivy-module version="2.0" xmlns:e="http://ant.apache.org/ivy/extra">
+ | <info organisation="${artifact.group}" module="${artifact.id}" revision="${artifact.version}"
+ | status="release">
+ | <description/>
+ | </info>
+ | <configurations>
+ | <conf name="pom" visibility="public" description=""/>
+ | <conf extends="runtime" name="test" visibility="public" description=""/>
+ | <conf name="provided" visibility="public" description=""/>
+ | <conf name="optional" visibility="public" description=""/>
+ | <conf name="compile" visibility="public" description=""/>
+ | <conf extends="compile" name="runtime" visibility="public" description=""/>
+ | </configurations>
+ |
+ | <publications>
+ | <artifact name="${artifact.id}" type="pom" ext="pom" conf="pom"/>
+ | <artifact name="${artifact.id}" type="jar" ext="jar" conf="compile"/>
+ | </publications>
+ | <dependencies>
+ |${deps}
+ | </dependencies>
+ |</ivy-module>
+ """.stripMargin
+ }
+
+ private def scopeToConf(s: Scope): String = s match {
+ case Scope.Compile => "compile"
+ case Scope.Provided => "provided"
+ case Scope.Test => "test"
+ case Scope.Runtime => "runtime"
+ }
+
+}
+
+object IvyFile extends IvyFile
diff --git a/scalaplugin/src/main/scala/mill/scalaplugin/publish/PomFile.scala b/scalaplugin/src/main/scala/mill/scalaplugin/publish/PomFile.scala
new file mode 100644
index 00000000..95f05761
--- /dev/null
+++ b/scalaplugin/src/main/scala/mill/scalaplugin/publish/PomFile.scala
@@ -0,0 +1,90 @@
+package mill.scalaplugin.publish
+
+import scala.xml.{Elem, NodeSeq}
+
+
+trait PomFile {
+
+ val head = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+
+ //TODO - not only jar packaging support?
+ //TODO - description
+ def generatePom(
+ artifact: Artifact,
+ dependencies: Seq[Dependency],
+ pomSettings: PomSettings
+ ): String = {
+ val xml =
+ <project
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+ xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns ="http://maven.apache.org/POM/4.0.0">
+
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>{artifact.id}</artifactId>
+ <packaging>jar</packaging>
+ <description></description>
+
+ <version>{artifact.version}</version>
+ <url>{pomSettings.url}</url>
+ <licenses>
+ {pomSettings.licenses.map(renderLicense)}
+ </licenses>
+ <scm>
+ <url>{pomSettings.scm.url}</url>
+ <connection>{pomSettings.scm.connection}</connection>
+ </scm>
+ <developers>
+ {pomSettings.developers.map(renderDeveloper)}
+ </developers>
+ <dependencies>
+ {dependencies.map(renderDependency)}
+ </dependencies>
+ </project>
+
+ val pp = new scala.xml.PrettyPrinter(120, 4)
+ val data = pp.format(xml)
+ head + data
+ }
+
+ private def renderLicense(l: License): Elem = {
+ import l._
+ <license>
+ <name>{name}</name>
+ <url>{url}</url>
+ <distribution>{distribution}</distribution>
+ </license>
+ }
+
+ private def renderDeveloper(d: Developer): Elem = {
+ import d._
+ <developer>
+ <id>{id}</id>
+ <name>{name}</name>
+ <organization>{organization}</organization>
+ <organizationUrl>{organizationUrl}</organizationUrl>
+ </developer>
+ }
+
+ private def renderDependency(d: Dependency): Elem = {
+ import d._
+ import artifact._
+
+ val scope = d.scope match {
+ case Scope.Compile => NodeSeq.Empty
+ case Scope.Provided => <scope>provided</scope>
+ case Scope.Test => <scope>test</scope>
+ case Scope.Runtime => <scope>runtime</scope>
+ }
+ <dependency>
+ <groupId>{group}</groupId>
+ <artifactId>{id}</artifactId>
+ <version>{version}</version>
+ {scope}
+ </dependency>
+ }
+
+}
+
+object PomFile extends PomFile
+
diff --git a/scalaplugin/src/main/scala/mill/scalaplugin/publish/Publisher.scala b/scalaplugin/src/main/scala/mill/scalaplugin/publish/Publisher.scala
new file mode 100644
index 00000000..99cd13b5
--- /dev/null
+++ b/scalaplugin/src/main/scala/mill/scalaplugin/publish/Publisher.scala
@@ -0,0 +1,62 @@
+package mill.scalaplugin.publish
+
+import java.io.File
+import java.nio.file.{Files, StandardCopyOption, StandardOpenOption}
+import java.security.MessageDigest
+
+import ammonite.ops._
+import mill.eval.PathRef
+
+object LocalPublisher {
+
+ val root: Path = {
+ val ivy2 = {
+ // a bit touchy on Windows... - don't try to manually write down the URI with s"file://..."
+ val str = new File(sys.props("user.home") + "/.ivy2/").toString
+ if (str.endsWith("/")) str else str + "/"
+ }
+ Path(ivy2 + "local/")
+ }
+
+ def publish(
+ file: PathRef,
+ artifact: Artifact,
+ dependencies: Seq[Dependency]
+ ): String = {
+ val sett = PomSettings("mill", "url", Seq.empty, SCM("", ""), Seq.empty)
+ val f = file.path
+ val pomData = PomFile.generatePom(artifact, dependencies, sett)
+ val ivyData = IvyFile.generateIvy(artifact, dependencies, sett)
+
+
+ val dir = root/artifact.group/artifact.id/artifact.version
+
+ val jars = dir/"jars"
+ val poms = dir/"poms"
+ val ivys = dir/"ivys"
+
+ val fileName = artifact match {
+ case j: JavaArtifact => j.name
+ case sa: ScalaArtifact =>
+ val postfix = {
+ val arr = sa.scalaVersion.split('.')
+ val erased = if (arr.length > 2) arr.dropRight(1) else arr
+ erased.mkString(".")
+ }
+ s"${sa.name}_$postfix"
+ }
+
+ Seq(dir, jars, poms, ivys).foreach(d => if (!d.toIO.exists()) mkdir(d))
+
+ Files.copy(f.toNIO, (dir/"jars"/s"$fileName.jar").toNIO, StandardCopyOption.REPLACE_EXISTING)
+ Files.write((dir/"poms"/s"$fileName.pom").toNIO, pomData.getBytes(),
+ StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING
+ )
+ Files.write((dir/"ivys"/"ivy.xml").toNIO, ivyData.getBytes(),
+ StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING
+ )
+
+ dir.toString()
+ }
+
+}
diff --git a/scalaplugin/src/main/scala/mill/scalaplugin/publish/settings.scala b/scalaplugin/src/main/scala/mill/scalaplugin/publish/settings.scala
new file mode 100644
index 00000000..ece7fbd1
--- /dev/null
+++ b/scalaplugin/src/main/scala/mill/scalaplugin/publish/settings.scala
@@ -0,0 +1,90 @@
+package mill.scalaplugin.publish
+
+import mill.scalaplugin.Dep
+import mill.util.JsonFormatters
+
+trait Artifact extends Serializable with Product {
+ def group: String
+ def name: String
+ def id: String
+ def version: String
+}
+
+object Artifact {
+
+ def fromDep(dep: Dep, scalaFull: String, scalaBin: String): Dependency = {
+ dep match {
+ case d: Dep.Java =>
+ import d.dep._
+ val art = JavaArtifact(module.organization, module.name, version)
+ Dependency(art, Scope.Compile)
+ case d: Dep.Scala =>
+ import d.dep._
+ val art = ScalaArtifact(module.organization, module.name, version, scalaBin)
+ Dependency(art, Scope.Compile)
+ case d: Dep.Point =>
+ import d.dep._
+ val art = ScalaArtifact(module.organization, module.name, version, scalaFull)
+ Dependency(art, Scope.Compile)
+ }
+ }
+}
+
+case class JavaArtifact(
+ group: String,
+ name: String,
+ version: String
+) extends Artifact {
+ override def id: String = name
+}
+
+case class ScalaArtifact(
+ group: String,
+ name: String,
+ version: String,
+ scalaVersion: String,
+) extends Artifact {
+
+ override def id: String = s"${name}_$scalaVersion"
+}
+
+sealed trait Scope
+object Scope {
+ case object Compile extends Scope
+ case object Provided extends Scope
+ case object Runtime extends Scope
+ case object Test extends Scope
+}
+
+case class Dependency(
+ artifact: Artifact,
+ scope: Scope
+)
+
+case class License(
+ name: String,
+ url: String,
+ distribution: String = "repo"
+)
+
+case class SCM(
+ url: String,
+ connection: String
+)
+
+case class Developer(
+ id: String,
+ name: String,
+ url: String,
+ organization: String,
+ organizationUrl: String
+)
+
+case class PomSettings(
+ organization: String,
+ url: String,
+ licenses: Seq[License],
+ scm: SCM,
+ developers: Seq[Developer]
+)
+
diff --git a/scalaplugin/src/test/scala/mill/scalaplugin/AcyclicTests.scala b/scalaplugin/src/test/scala/mill/scalaplugin/AcyclicTests.scala
index 185cffc8..18f20852 100644
--- a/scalaplugin/src/test/scala/mill/scalaplugin/AcyclicTests.scala
+++ b/scalaplugin/src/test/scala/mill/scalaplugin/AcyclicTests.scala
@@ -12,10 +12,9 @@ object AcyclicBuild{
for(crossVersion <- Cross("2.10.6", "2.11.8", "2.12.3", "2.12.4"))
yield new SbtScalaModule{outer =>
def basePath = AcyclicTests.workspacePath
- def organization = "com.lihaoyi"
- def name = "acyclic"
-
- def version = "0.1.7"
+ override def organization = "com.lihaoyi"
+ override def name = "acyclic"
+ override def version = "0.1.7"
def scalaVersion = crossVersion
def ivyDeps = Seq(
Dep.Java("org.scala-lang", "scala-compiler", scalaVersion())