From ee439cdc67034d35762d54a6d87d51844fcf6dde Mon Sep 17 00:00:00 2001 From: Christopher Vogt Date: Tue, 14 Jun 2016 22:15:52 -0400 Subject: turn Build base classes into traits for less verbosity and uniform usage with any other plugin --- README.md | 12 ++--- build/build.scala | 2 +- examples/build-scalatest/build/build.scala | 2 +- examples/build-scalatest/build/build/build.scala | 2 +- plugins/scalajs/ScalaJs.scala | 2 +- plugins/scalajs/ScalaJsInformation.scala | 2 +- plugins/scalatest/ScalaTest.scala | 4 +- plugins/scalatest/build/build.scala | 2 +- stage2/BasicBuild.scala | 7 ++- stage2/BuildBuild.scala | 2 +- stage2/Lib.scala | 6 +-- stage2/PackageBuild.scala | 32 ------------ stage2/PackageJars.scala | 33 ++++++++++++ stage2/Publish.scala | 64 ++++++++++++++++++++++++ stage2/PublishBuild.scala | 64 ------------------------ stage2/SbtDependencyDsl.scala | 2 +- stage2/Scaffold.scala | 14 +++--- stage2/mixins.scala | 8 +-- test/build/build.scala | 2 +- test/multi-build/build/build.scala | 2 +- test/simple/build/build.scala | 2 +- 21 files changed, 135 insertions(+), 131 deletions(-) delete mode 100644 stage2/PackageBuild.scala create mode 100644 stage2/PackageJars.scala create mode 100644 stage2/Publish.scala delete mode 100644 stage2/PublishBuild.scala diff --git a/README.md b/README.md index 94b52a8..73a0594 100644 --- a/README.md +++ b/README.md @@ -15,9 +15,9 @@ easy custom code. If you integrate something, consider doing it as traits that you make available as a library that other builds can depend on and mix in. -Slides from CBT talk from NEScala 2016: +Slides and video from CBT talk from NEScala 2016: https://github.com/cvogt/talks/raw/master/2016-03-04_NEScala-2016_A-Vision-For-Scala-Builds.pdf -(video coming soon...) +https://www.youtube.com/watch?v=5HfKw3hgdOM Getting started --------------- @@ -44,13 +44,13 @@ that describes your build. Here is an example ```scala // build/build.scala import cbt._ -class Build(context: cbt.Context) extends PackageBuild(context){ - override def version = "0.6.1-SNAPSHOT" +class Build(val context: cbt.Context) extends BaseBuild{ + override def version = "0.6.1" override def groupId = "org.cvogt" override def artifactId = "play-json-extensions" override def dependencies = - super.dependencies :+ - resolver(mavenCentral).bind( + super.dependencies ++ + Resolver(mavenCentral).bind( // encouraged way to declare dependencies ScalaDependency("com.typesafe.play", "play-json", "2.4.4"), MavenDependency("joda-time", "joda-time", "2.9.2") diff --git a/build/build.scala b/build/build.scala index 0f93733..cb6886b 100644 --- a/build/build.scala +++ b/build/build.scala @@ -3,7 +3,7 @@ import java.net.URL import java.io.File import scala.collection.immutable.Seq -class Build(context: Context) extends BasicBuild(context){ +class Build(val context: Context) extends BaseBuild{ // FIXME: somehow consolidate this with cbt's own boot-strapping from source. override def dependencies = { super.dependencies ++ Resolver(mavenCentral).bind( diff --git a/examples/build-scalatest/build/build.scala b/examples/build-scalatest/build/build.scala index ed486f0..6cc013d 100644 --- a/examples/build-scalatest/build/build.scala +++ b/examples/build-scalatest/build/build.scala @@ -3,7 +3,7 @@ import java.net.URL import java.io.File import scala.collection.immutable.Seq -class Build( context: Context ) extends BasicBuild( context ) with SbtLayout { +class Build(val context: Context) extends SbtLayout { override def dependencies = ( super.dependencies ++ diff --git a/examples/build-scalatest/build/build/build.scala b/examples/build-scalatest/build/build/build.scala index 6b1a98e..c17686a 100644 --- a/examples/build-scalatest/build/build/build.scala +++ b/examples/build-scalatest/build/build/build.scala @@ -3,7 +3,7 @@ import java.net.URL import java.io.File import scala.collection.immutable.Seq -class Build( context: Context ) extends BuildBuild( context ){ +class Build(val context: Context) extends BuildBuild{ override def dependencies = ( super.dependencies ++ diff --git a/plugins/scalajs/ScalaJs.scala b/plugins/scalajs/ScalaJs.scala index bde3307..1a31683 100644 --- a/plugins/scalajs/ScalaJs.scala +++ b/plugins/scalajs/ScalaJs.scala @@ -14,7 +14,7 @@ trait ScalaJsSbtDependencyDsl extends SbtDependencyDsl { self: ScalaJsBuild => } } -trait ScalaJsBuild extends BasicBuild with ScalaJsSbtDependencyDsl with ScalaJsInformation { outer => +trait ScalaJsBuild extends BaseBuild with ScalaJsSbtDependencyDsl with ScalaJsInformation { outer => def sharedFolder = projectDirectory ++ "/shared" def jvmFolder = projectDirectory ++ "/jvm" diff --git a/plugins/scalajs/ScalaJsInformation.scala b/plugins/scalajs/ScalaJsInformation.scala index 938d207..ada3baf 100644 --- a/plugins/scalajs/ScalaJsInformation.scala +++ b/plugins/scalajs/ScalaJsInformation.scala @@ -1,6 +1,6 @@ import cbt._ -trait ScalaJsInformation extends BasicBuild { outer => +trait ScalaJsInformation extends BaseBuild { outer => val sjsVersion = "0.6.8" final private val sjsMajorVersion: String = lib.libMajorVersion(sjsVersion) diff --git a/plugins/scalatest/ScalaTest.scala b/plugins/scalatest/ScalaTest.scala index 53c6446..7f1c77a 100644 --- a/plugins/scalatest/ScalaTest.scala +++ b/plugins/scalatest/ScalaTest.scala @@ -11,7 +11,7 @@ import org.scalatest Probably by adding support for subfolders to "GitDependency" */ -trait SbtLayout extends BasicBuild{ +trait SbtLayout extends BaseBuild{ outer => override def sources = Seq( projectDirectory ++ "/src/main/scala" ) def testSources = projectDirectory ++ "/src/test/scala" @@ -28,7 +28,7 @@ trait SbtLayout extends BasicBuild{ else None } -trait ScalaTest extends BasicBuild{ +trait ScalaTest extends BaseBuild{ override def run: ExitCode = { import ScalaTestLib._ val _classLoader = classLoader(context.classLoaderCache) diff --git a/plugins/scalatest/build/build.scala b/plugins/scalatest/build/build.scala index 1377fa8..55d5818 100644 --- a/plugins/scalatest/build/build.scala +++ b/plugins/scalatest/build/build.scala @@ -3,7 +3,7 @@ import java.net.URL import java.io.File import scala.collection.immutable.Seq -class Build(context: Context) extends BasicBuild(context){ +class Build(val context: Context) extends BaseBuild{ override def dependencies = super.dependencies ++ Resolver( mavenCentral ).bind( diff --git a/stage2/BasicBuild.scala b/stage2/BasicBuild.scala index 978f604..49a73ef 100644 --- a/stage2/BasicBuild.scala +++ b/stage2/BasicBuild.scala @@ -10,7 +10,7 @@ import java.util.jar._ import scala.collection.immutable.Seq import scala.util._ -trait Recommended extends BasicBuild{ +trait Recommended extends BaseBuild{ override def scalacOptions = super.scalacOptions ++ Seq( "-feature", "-deprecation", @@ -21,7 +21,10 @@ trait Recommended extends BasicBuild{ "-language:existentials" ) } -class BasicBuild(val context: Context) extends DependencyImplementation with BuildInterface with TriggerLoop with SbtDependencyDsl{ +class BasicBuild(val context: Context) extends BaseBuild +trait BaseBuild extends DependencyImplementation with BuildInterface with TriggerLoop with SbtDependencyDsl{ + def context: Context + // library available to builds implicit protected final val logger: Logger = context.logger implicit protected final val classLoaderCache: ClassLoaderCache = context.classLoaderCache diff --git a/stage2/BuildBuild.scala b/stage2/BuildBuild.scala index bab8d88..c6d45d3 100644 --- a/stage2/BuildBuild.scala +++ b/stage2/BuildBuild.scala @@ -3,7 +3,7 @@ import java.io.File import java.nio.file._ import scala.collection.immutable.Seq -class BuildBuild(context: Context) extends BasicBuild(context){ +trait BuildBuild extends BaseBuild{ override def dependencies = super.dependencies :+ context.cbtDependency def managedBuildDirectory: File = lib.realpath( projectDirectory.parent ) diff --git a/stage2/Lib.scala b/stage2/Lib.scala index 2a108ab..cec302a 100644 --- a/stage2/Lib.scala +++ b/stage2/Lib.scala @@ -49,7 +49,7 @@ final class Lib(logger: Logger) extends Stage1Lib(logger) with Scaffold{ val rootBuildClassName = if( useBasicBuildBuild ) buildBuildClassName else buildClassName try{ - if(useBasicBuildBuild) default( context ) else new cbt.BuildBuild( context.copy( projectDirectory = start ) ) + if(useBasicBuildBuild) default( context ) else new cbt.BasicBuild( context.copy( projectDirectory = start ) ) with BuildBuild } catch { case e:ClassNotFoundException if e.getMessage == rootBuildClassName => throw new Exception(s"no class $rootBuildClassName found in " ++ start.string) @@ -153,8 +153,8 @@ final class Lib(logger: Logger) extends Stage1Lib(logger) with Scaffold{ def usage(buildClass: Class[_], show: String): String = { val baseTasks = Seq( classOf[BasicBuild], - classOf[PackageBuild], - classOf[PublishBuild], + classOf[PackageJars], + classOf[Publish], classOf[Recommended] ).flatMap(lib.taskNames).distinct.sorted val thisTasks = lib.taskNames(buildClass) diff baseTasks diff --git a/stage2/PackageBuild.scala b/stage2/PackageBuild.scala deleted file mode 100644 index 583809c..0000000 --- a/stage2/PackageBuild.scala +++ /dev/null @@ -1,32 +0,0 @@ -package cbt -import java.io.File -import scala.collection.immutable.Seq -abstract class PackageBuild(context: Context) extends BasicBuild(context) with ArtifactInfo{ - def name: String - def artifactId = name - def defaultVersion: String - final def version = context.version getOrElse defaultVersion - def `package`: Seq[File] = lib.concurrently( enableConcurrency )( - Seq(() => jar, () => docJar, () => srcJar) - )( _() ).flatten - - private object cacheJarBasicBuild extends Cache[Option[File]] - def jar: Option[File] = cacheJarBasicBuild{ - compile.flatMap( lib.jar( artifactId, scalaMajorVersion, version, _, jarTarget ) ) - } - - private object cacheSrcJarBasicBuild extends Cache[Option[File]] - def srcJar: Option[File] = cacheSrcJarBasicBuild{ - lib.srcJar( sourceFiles, artifactId, scalaMajorVersion, version, scalaTarget ) - } - - private object cacheDocBasicBuild extends Cache[Option[File]] - def docJar: Option[File] = cacheDocBasicBuild{ - lib.docJar( - context.cbtHasChanged, - scalaVersion, sourceFiles, dependencyClasspath, apiTarget, - jarTarget, artifactId, scalaMajorVersion, version, - scalacOptions, context.classLoaderCache, context.paths.mavenCache - ) - } -} diff --git a/stage2/PackageJars.scala b/stage2/PackageJars.scala new file mode 100644 index 0000000..8e3f424 --- /dev/null +++ b/stage2/PackageJars.scala @@ -0,0 +1,33 @@ +package cbt +import java.io.File +import scala.collection.immutable.Seq +// would love to call this just `Package` but that conflicts with scala package objects. +trait PackageJars extends BaseBuild with ArtifactInfo{ + def name: String + def artifactId = name + def defaultVersion: String + final def version = context.version getOrElse defaultVersion + def `package`: Seq[File] = lib.concurrently( enableConcurrency )( + Seq(() => jar, () => docJar, () => srcJar) + )( _() ).flatten + + private object cacheJarBasicBuild extends Cache[Option[File]] + def jar: Option[File] = cacheJarBasicBuild{ + compile.flatMap( lib.jar( artifactId, scalaMajorVersion, version, _, jarTarget ) ) + } + + private object cacheSrcJarBasicBuild extends Cache[Option[File]] + def srcJar: Option[File] = cacheSrcJarBasicBuild{ + lib.srcJar( sourceFiles, artifactId, scalaMajorVersion, version, scalaTarget ) + } + + private object cacheDocBasicBuild extends Cache[Option[File]] + def docJar: Option[File] = cacheDocBasicBuild{ + lib.docJar( + context.cbtHasChanged, + scalaVersion, sourceFiles, dependencyClasspath, apiTarget, + jarTarget, artifactId, scalaMajorVersion, version, + scalacOptions, context.classLoaderCache, context.paths.mavenCache + ) + } +} diff --git a/stage2/Publish.scala b/stage2/Publish.scala new file mode 100644 index 0000000..2f7d2fe --- /dev/null +++ b/stage2/Publish.scala @@ -0,0 +1,64 @@ +package cbt +import java.io.File +import java.net.URL +import java.nio.file.Files.readAllBytes +import scala.collection.immutable.Seq + +trait Publish extends PackageJars{ + def description: String + def url: URL + def developers: Seq[Developer] + def licenses: Seq[License] + def scmUrl: String + def scmConnection: String + def inceptionYear: Int + def organization: Option[Organization] + + // ========== package ========== + + /** put additional xml that should go into the POM file in here */ + def pom: File = lib.pom( + groupId = groupId, + artifactId = artifactId, + version = version, + scalaMajorVersion = scalaMajorVersion, + name = name, + description = description, + url = url, + developers = developers, + licenses = licenses, + scmUrl = scmUrl, + scmConnection = scmConnection, + inceptionYear, + organization, + dependencies = dependencies, + jarTarget = jarTarget + ) + + // ========== publish ========== + final protected def releaseFolder = s"/${groupId.replace(".","/")}/${artifactId}_$scalaMajorVersion/$version/" + private def snapshotUrl = new URL("https://oss.sonatype.org/content/repositories/snapshots") + private def releaseUrl = new URL("https://oss.sonatype.org/service/local/staging/deploy/maven2") + def publishUrl = if(version.endsWith("-SNAPSHOT")) snapshotUrl else releaseUrl + override def copy(context: Context) = super.copy(context).asInstanceOf[Publish] + + protected def sonatypeCredentials = { + // FIXME: this should probably not use cbtHome, but some reference to the system's host cbt + new String(readAllBytes((context.cbtRootHome ++ "/sonatype.login").toPath)).trim + } + + def publishSnapshot: Unit = { + copy( context.copy(version = Some(version+"-SNAPSHOT")) ).publishUnsigned + } + + def publishUnsigned: Unit = { + lib.publishUnsigned( + sourceFiles, `package` :+ pom, publishUrl ++ releaseFolder, sonatypeCredentials + ) + } + def publishSigned: Unit = { + lib.publishSigned( + sourceFiles, `package` :+ pom, publishUrl ++ releaseFolder, sonatypeCredentials + ) + } +} diff --git a/stage2/PublishBuild.scala b/stage2/PublishBuild.scala deleted file mode 100644 index d744a08..0000000 --- a/stage2/PublishBuild.scala +++ /dev/null @@ -1,64 +0,0 @@ -package cbt -import java.io.File -import java.net.URL -import java.nio.file.Files.readAllBytes -import scala.collection.immutable.Seq - -abstract class PublishBuild(context: Context) extends PackageBuild(context){ - def description: String - def url: URL - def developers: Seq[Developer] - def licenses: Seq[License] - def scmUrl: String - def scmConnection: String - def inceptionYear: Int - def organization: Option[Organization] - - // ========== package ========== - - /** put additional xml that should go into the POM file in here */ - def pom: File = lib.pom( - groupId = groupId, - artifactId = artifactId, - version = version, - scalaMajorVersion = scalaMajorVersion, - name = name, - description = description, - url = url, - developers = developers, - licenses = licenses, - scmUrl = scmUrl, - scmConnection = scmConnection, - inceptionYear, - organization, - dependencies = dependencies, - jarTarget = jarTarget - ) - - // ========== publish ========== - final protected def releaseFolder = s"/${groupId.replace(".","/")}/${artifactId}_$scalaMajorVersion/$version/" - private def snapshotUrl = new URL("https://oss.sonatype.org/content/repositories/snapshots") - private def releaseUrl = new URL("https://oss.sonatype.org/service/local/staging/deploy/maven2") - def publishUrl = if(version.endsWith("-SNAPSHOT")) snapshotUrl else releaseUrl - override def copy(context: Context) = super.copy(context).asInstanceOf[PublishBuild] - - protected def sonatypeCredentials = { - // FIXME: this should probably not use cbtHome, but some reference to the system's host cbt - new String(readAllBytes((context.cbtRootHome ++ "/sonatype.login").toPath)).trim - } - - def publishSnapshot: Unit = { - copy( context.copy(version = Some(version+"-SNAPSHOT")) ).publishUnsigned - } - - def publishUnsigned: Unit = { - lib.publishUnsigned( - sourceFiles, `package` :+ pom, publishUrl ++ releaseFolder, sonatypeCredentials - ) - } - def publishSigned: Unit = { - lib.publishSigned( - sourceFiles, `package` :+ pom, publishUrl ++ releaseFolder, sonatypeCredentials - ) - } -} diff --git a/stage2/SbtDependencyDsl.scala b/stage2/SbtDependencyDsl.scala index 4c95308..05cb709 100644 --- a/stage2/SbtDependencyDsl.scala +++ b/stage2/SbtDependencyDsl.scala @@ -1,5 +1,5 @@ package cbt -trait SbtDependencyDsl{ self: BasicBuild => +trait SbtDependencyDsl{ self: BaseBuild => /** SBT-like dependency builder DSL for syntax compatibility */ class DependencyBuilder2( groupId: String, artifactId: String, scalaVersion: Option[String] ){ def %(version: String) = scalaVersion.map( diff --git a/stage2/Scaffold.scala b/stage2/Scaffold.scala index 78242fc..2c46d0a 100644 --- a/stage2/Scaffold.scala +++ b/stage2/Scaffold.scala @@ -32,7 +32,7 @@ import java.net.URL import java.io.File import scala.collection.immutable.Seq -class Build( context: Context ) extends BasicBuild( context ){ +class Build(val context: Context) extends BaseBuild{ /* override def dependencies = ( super.dependencies // don't forget super.dependencies here @@ -65,7 +65,7 @@ import java.net.URL import java.io.File import scala.collection.immutable.Seq -class Build( context: Context ) extends BuildBuild( context ){ +class Build(val context: Context) extends BuildBuild{ /* override def dependencies = ( super.dependencies // don't forget super.dependencies here @@ -97,7 +97,7 @@ import java.net.URL import java.io.File import scala.collection.immutable.Seq -class Build(context: Context) extends BuildBuild(context){ +class Build(val context: Context) extends BuildBuild{ override def dependencies = super.dependencies ++ Seq( BuildDependency( projectDirectory.parent ++ "/build-shared") // , "com.lihaoyi" %% "ammonite-ops" % "0.5.5" @@ -117,7 +117,7 @@ import java.net.URL import java.io.File import scala.collection.immutable.Seq -class Build(context: cbt.Context) extends BasicBuild(context) with BuildShared/* with cbt.mixins.ScalaTest*/{ +class Build(val context: Context) extends BaseBuild with BuildShared/* with mixins.ScalaTest*/{ // def scalaTestVersion = "2.2.6" override def dependencies = super.dependencies ++ Seq( @@ -131,7 +131,7 @@ import java.net.URL import java.io.File import scala.collection.immutable.Seq -class Build(context: Context) extends BuildBuild(context){ +class Build(val context: Context) extends BuildBuild{ override def scalaVersion: String = "2.11.8" override def dependencies = super.dependencies ++ Seq( @@ -146,7 +146,7 @@ import java.net.URL import java.io.File import scala.collection.immutable.Seq -class Build(context: Context) extends BasicBuild(context){ +class Build(val context: Context) extends BaseBuild{ override def scalaVersion: String = "$scalaVersion" override def dependencies = super.dependencies ++ Seq( // don't forget super.dependencies here @@ -161,7 +161,7 @@ import java.net.URL import java.io.File import scala.collection.immutable.Seq -trait BuildShared extends BasicBuild{ +trait BuildShared extends BaseBuild{ override def scalaVersion: String = "$scalaVersion" override def enableConcurrency = false // enable for speed, disable for debugging diff --git a/stage2/mixins.scala b/stage2/mixins.scala index 70e472f..9d5fdb2 100644 --- a/stage2/mixins.scala +++ b/stage2/mixins.scala @@ -3,7 +3,7 @@ package mixins import java.net.URL import scala.collection.immutable.Seq import java.io._ -trait Test extends BasicBuild{ +trait Test extends BaseBuild{ lazy val testedBuild = BuildDependency( projectDirectory.parent ) override def dependencies = Seq( testedBuild ) ++ super.dependencies override def defaultScalaVersion = testedBuild.build.scalaVersion @@ -12,7 +12,7 @@ trait SbtTest extends Test{ override def sources = Vector( projectDirectory.parent ++ "/src/test/scala" ) } -trait ScalaParadise extends BasicBuild{ +trait ScalaParadise extends BaseBuild{ def scalaParadiseVersion = "2.1.0" private def scalaParadiseDependency = @@ -41,13 +41,13 @@ trait ScalaParadise extends BasicBuild{ ) } -trait Suggested extends BasicBuild{ +trait Suggested extends BaseBuild{ override def scalacOptions = super.scalacOptions ++ Seq( "-language:experimental.macros" ) } -trait Github extends PublishBuild{ +trait Github extends Publish{ def user: String def githubProject = name def githubUser = user diff --git a/test/build/build.scala b/test/build/build.scala index 8989431..42ae856 100644 --- a/test/build/build.scala +++ b/test/build/build.scala @@ -1,6 +1,6 @@ import cbt._ import java.io.File import scala.collection.immutable.Seq -class Build(context: cbt.Context) extends BasicBuild(context){ +class Build(val context: cbt.Context) extends BaseBuild{ override def dependencies = Seq( context.cbtDependency ) ++ super.dependencies } diff --git a/test/multi-build/build/build.scala b/test/multi-build/build/build.scala index 5b9f874..84e3f30 100644 --- a/test/multi-build/build/build.scala +++ b/test/multi-build/build/build.scala @@ -1,7 +1,7 @@ import cbt._ import scala.collection.immutable.Seq import java.io.File -class Build(context: Context) extends BasicBuild(context){ +class Build(val context: Context) extends BaseBuild{ override def dependencies = Seq( BuildDependency(projectDirectory++"/sub1"), BuildDependency(projectDirectory++"/sub2") diff --git a/test/simple/build/build.scala b/test/simple/build/build.scala index 15b63fb..f64d813 100644 --- a/test/simple/build/build.scala +++ b/test/simple/build/build.scala @@ -2,7 +2,7 @@ import cbt._ import scala.collection.immutable.Seq import java.io.File -class Build(context: cbt.Context) extends BasicBuild(context){ +class Build(val context: cbt.Context) extends BaseBuild{ override def dependencies = ( super.dependencies ++ -- cgit v1.2.3