diff --git a/.gitignore b/.gitignore index 2532f2ba..2f7896d1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1 @@ -/project/project/ target/ diff --git a/.travis.yml b/.travis.yml index 3f73a7c4..fd7a3d4f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,7 @@ language: scala jdk: # - openjdk6 - - oraclejdk7 + - oraclejdk8 sudo: false @@ -11,9 +11,9 @@ env: - JVM_OPTS="-Xms1024m -Xmx1024m -XX:ReservedCodeCacheSize=128m -XX:MaxPermSize=256m" script: - - sbt "^ test" - - sbt "^ publishLocal" - - sbt "^ it:test" + - sbt "test" + - sbt "publishLocal" + - sbt "it:test" notifications: email: diff --git a/CHANGELOG.md b/CHANGELOG.md index b115ff23..4f4feab3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,24 @@ # dbuild release notes +### 0.9.7 + +- This release is compatible with sbt 1.0.0-M4. The source + code and the build files have been reorganized, and + moved to the .sbt format. The supported sbt versions are + 1.0.0-M4 and 0.13.*; support for the old 0.12.4 has + been removed. + +- Fixes for issues #190, #158, #188 + +- The dbuild sbt plugin .pom no longer directly refers to + sbt jars, but uses those provided by the running sbt + environment. Fixes scala/community-builds#384. + +### 0.9.6 + +- Fixed the "deploy" option when the target is a Bintray + repository. + ### 0.9.5 - It is now possible to use different versions of the JDK on the diff --git a/README.md b/README.md index ae18bcec..c76127a4 100644 --- a/README.md +++ b/README.md @@ -12,15 +12,9 @@ though each of them may evolve independently. You can find the complete dbuild documentation at the [dbuild web site](http://typesafehub.github.com/dbuild). -To recompile, publish, etc., just type the following in the root project: - - ^command - -where command is one of compile, clean, test, publish, publishLocal, etc. - To create a dbuild release (if you belong to the Typesafe organization on Bintray): -1. Type "^release" (please do not use "^publish", as some additional preparation is necessary) +1. Type "release" (please do not use "^publish", as some additional preparation is necessary) 2. Check https://bintray.com/typesafe/ivy-releases/dbuild/view to ensure files are as expected (Optional) 3. Type "root/bintrayRelease" to make the release public @@ -43,8 +37,13 @@ Bintray yet, you can use: set every publishTo := Some(Resolver.url("somelabel", new URL("http://artifactoryhost/artifactory/repository/"))(Resolver.ivyStylePatterns)) set every credentials := Seq(Credentials(Path.userHome / "some" / "path" / "credentials-file")) -Then, proceed with "^release" as usual to issue the snapshot to your Artifactory server. +Then, proceed with "release" as usual to issue the snapshot to your Artifactory server. +IMPORTANT: the publishing process needs to be repeated twice, changing +project/build.properties in the meantime, in order to publish artifacts +for both sbt 0.13/scala 2.10 and sbt 1.0/scala 2.11 (currently 1.0.0-M4) +All the artifacts are published for 2.10, while only those relevant to +the sbt plugin are published for 2.11. ## Get Involved diff --git a/adapter/src/main/scala-2.10/Adapter.scala b/adapter/src/main/scala-2.10/Adapter.scala new file mode 100644 index 00000000..121a9cb5 --- /dev/null +++ b/adapter/src/main/scala-2.10/Adapter.scala @@ -0,0 +1,55 @@ +package sbt.dbuild.hack { +object DbuildHack { + val Load = sbt.Load +} +} + +package com.typesafe.dbuild.adapter { +import java.io.File + +object LoggingInterface { + val Level = sbt.Level + type Logger = sbt.Logger + type LogEvent = sbt.LogEvent + val ControlEvent = sbt.ControlEvent + val StackTrace = sbt.StackTrace + type BasicLogger = sbt.BasicLogger +} + +import LoggingInterface.Level._ +trait StreamLoggerAdapter { + def log(level: Value, message: => String): Unit + def log(label: String, message: String): Unit + def err(s: => String): Unit = log(Error, s) + def out(s: => String): Unit = log(Info.toString, s) +} + +object Adapter { + val IO = sbt.IO + val Path = sbt.Path + type RichFile = sbt.RichFile + type FileFilter = sbt.FileFilter + def toFF = sbt.FileFilter.globFilter _ + val DirectoryFilter = sbt.DirectoryFilter + type ExactFilter = sbt.ExactFilter + type NameFilter = sbt.NameFilter + type FileRepository = sbt.FileRepository + type Logger = sbt.Logger + import Path._ + def allPaths(f:File) = sbt.PathFinder(f).*** + val syntax = new {} + val syntaxio = syntax + type ModuleID = sbt.ModuleID + type Artifact = sbt.Artifact + type ProjectResolver = sbt.ProjectResolver + type ScalaInstance = sbt.ScalaInstance + lazy val ScalaInstance = sbt.ScalaInstance + lazy val Load = sbt.dbuild.hack.DbuildHack.Load + val applyCross: (String, Option[String => String]) => String = + sbt.CrossVersion.applyCross + def defaultID(base: File, prefix: String = "default") = + sbt.Build.defaultID(base, prefix) + def scalaInstance(libraryJar: File, compilerJar: File, launcher: xsbti.Launcher, extraJars: File*): ScalaInstance = + ScalaInstance(libraryJar, compilerJar, launcher, extraJars:_*) +} +} diff --git a/adapter/src/main/scala-2.11/Adapter.scala b/adapter/src/main/scala-2.11/Adapter.scala new file mode 100644 index 00000000..2a3542fb --- /dev/null +++ b/adapter/src/main/scala-2.11/Adapter.scala @@ -0,0 +1,86 @@ +package sbt.dbuild.hack { +object DbuildHack { + val Load = sbt.internal.Load + val applyCross: (String, Option[String => String]) => String = + sbt.librarymanagement.CrossVersion.applyCross + val defaultID: (java.io.File,String) => String = + sbt.internal.BuildDef.defaultID +} +} +package com.typesafe.dbuild.adapter { +import java.io.File + +object LoggingInterface { + val Level = sbt.util.Level + type Logger = sbt.util.Logger + type LogEvent = sbt.util.LogEvent + val ControlEvent = sbt.util.ControlEvent + val StackTrace = sbt.internal.util.StackTrace + type BasicLogger = sbt.internal.util.BasicLogger +} + +trait StreamLoggerAdapter + +object Adapter { + val IO = sbt.io.IO + val Path = sbt.io.Path + type RichFile = sbt.io.RichFile + type FileFilter = sbt.io.FileFilter + def toFF = sbt.io.FileFilter.globFilter _ + val DirectoryFilter = sbt.io.DirectoryFilter + type ExactFilter = sbt.io.ExactFilter + type NameFilter = sbt.io.NameFilter + type FileRepository = sbt.librarymanagement.FileRepository + type Logger = sbt.util.Logger + def allPaths(f:File) = sbt.io.PathFinder(f).allPaths + val syntaxio = sbt.io.syntax + val syntax = sbt.syntax + type ModuleID = sbt.librarymanagement.ModuleID + type Artifact = sbt.librarymanagement.Artifact + type ProjectResolver = sbt.internal.librarymanagement.ProjectResolver + type ScalaInstance = sbt.internal.inc.ScalaInstance + val ScalaInstance = sbt.internal.inc.ScalaInstance + val Load = sbt.dbuild.hack.DbuildHack.Load + val applyCross = sbt.dbuild.hack.DbuildHack.applyCross + def defaultID(base: File, prefix: String = "default") = + sbt.dbuild.hack.DbuildHack.defaultID(base, prefix) + +// these bits are inappropriately copied from zinc v1.0.0-X1, where they +// are private now, and exactly from: +// internal/zinc-classpath/src/main/scala/sbt/internal/inc/ScalaInstance.scala + private val VersionPrefix = "version " + private def fastActualVersion(scalaLoader: ClassLoader): String = + { + val stream = scalaLoader.getResourceAsStream("compiler.properties") + try { + val props = new java.util.Properties + props.load(stream) + props.getProperty("version.number") + } finally stream.close() + } + import java.net.{ URL, URLClassLoader } + private def scalaLoader(launcher: xsbti.Launcher): Seq[File] => ClassLoader = jars => + new URLClassLoader(jars.map(_.toURI.toURL).toArray[URL], launcher.topLoader) + private def actualVersion(scalaLoader: ClassLoader)(label: String) = + try fastActualVersion(scalaLoader) + catch { case e: Exception => slowActualVersion(scalaLoader)(label) } + private def slowActualVersion(scalaLoader: ClassLoader)(label: String) = + { + val v = try { Class.forName("scala.tools.nsc.Properties", true, scalaLoader).getMethod("versionString").invoke(null).toString } + catch { case cause: Exception => throw new sbt.internal.inc.InvalidScalaInstance("Scala instance doesn't exist or is invalid: " + label, cause) } + if (v.startsWith(VersionPrefix)) v.substring(VersionPrefix.length) else v + } +// +// The code below was deprecated and has been removed from ScalaInstance in zinc 1.0.x, +// however it may work for us. +// +// TODO: use one of the currently supported variants of ScalaInstance.apply() +// + def scalaInstance(libraryJar: File, compilerJar: File, launcher: xsbti.Launcher, extraJars: File*): ScalaInstance = { + val classLoader = scalaLoader(launcher) + val loader = classLoader(libraryJar :: compilerJar :: extraJars.toList) + val version = actualVersion(loader)(" (library jar " + libraryJar.getAbsolutePath + ")") + new ScalaInstance(VersionPrefix, loader, libraryJar, compilerJar, extraJars.toArray, None) + } +} +} diff --git a/build.sbt b/build.sbt new file mode 100644 index 00000000..f336e1c6 --- /dev/null +++ b/build.sbt @@ -0,0 +1,228 @@ +import Dependencies._ + +def MyVersion: String = "0.9.7-RC1" + +def SubProj(name: String) = ( + Project(name, file(if (name=="root") "." else name)) + configs( IntegrationTest ) + settings( Defaults.itSettings : _*) + settings( + version := MyVersion, + organization := "com.typesafe.dbuild", + selectScalaVersion, + libraryDependencies += specs2, + resolvers += Resolver.typesafeIvyRepo("releases"), + resolvers += "Typesafe Repository" at "http://repo.typesafe.com/typesafe/releases/", + publishMavenStyle := false, + licenses += ("Apache-2.0", url("http://opensource.org/licenses/Apache-2.0")), + bintrayReleaseOnPublish := false, + bintrayOrganization := Some("typesafe"), + bintrayRepository := "ivy-releases", + bintrayPackage := "dbuild" + ) +) + +import RemoteDepHelper._ + +def skip211 = Seq( + skip in compile := scalaVersion.value.startsWith("2.11"), + sources in doc in Compile := + { if((skip in compile).value) List() else (sources in doc in Compile).value } + ) + +def selectScalaVersion = + scalaVersion := { + val sb = (sbtVersion in sbtPlugin).value + if (sb.startsWith("0.13")) "2.10.6" else "2.11.8" + } + +lazy val root = ( + SubProj("root") + aggregate(adapter, graph, hashing, logging, actorLogging, proj, actorProj, deploy, + core, plugin, build, support, supportGit, repo, metadata, docs, dist, indexmeta) + settings(publish := (), publishLocal := (), version := MyVersion) + //settings(CrossPlugin.crossBuildingSettings:_*) + //settings(CrossBuilding.crossSbtVersions := Seq("0.13","1.0.0-M4"), selectScalaVersion) + settings(commands += Command.command("release") { state => + "clean" :: "publish" :: state + }) +) + +// This subproject only has dynamically +// generated source files, used to adapt +// the source file to sbt 0.13/1.0 +lazy val adapter = ( + SubProj("adapter") + dependsOnSbtProvided(sbtLogging, sbtIo, sbtLaunchInt, sbtIvy, sbtSbt) + dependsOnRemote(zincProvidedIf211:_*) + settings(sourceGenerators in Compile += task { + val dir = (sourceManaged in Compile).value + val fileName = "Default.scala" + val file = dir / fileName + val sv = scalaVersion.value + val v = sbtVersion.value + if(!dir.isDirectory) dir.mkdirs() + IO.write(file, ( +""" +package com.typesafe.dbuild.adapter +object Defaults { + val version = "%s" + val org = "%s" + val hash = "%s" +} +""" format (version.value, organization.value, scala.sys.process.Process("git log --pretty=format:%H -n 1").lines.head)) + +) + Seq(file) + }) +) + +lazy val graph = ( + SubProj("graph") +) + +lazy val hashing = ( + SubProj("hashing") + dependsOnRemote(typesafeConfig) +) + +lazy val indexmeta = ( + SubProj("indexmeta") +) + +lazy val logging = ( + SubProj("logging") + dependsOn(adapter,graph) + dependsOnSbtProvided(sbtLogging, sbtIo, sbtLaunchInt) +) + +lazy val actorLogging = ( + SubProj("actorLogging") + dependsOn(logging) + dependsOnRemote(akkaActor) + dependsOnSbtProvided(sbtLogging, sbtIo, sbtLaunchInt) + settings(skip211:_*) +) + +lazy val metadata = ( + SubProj("metadata") + dependsOn(graph, hashing, indexmeta, deploy) + dependsOnRemote(jackson, typesafeConfig, commonsLang, jacks) +) + +lazy val repo = ( + SubProj("repo") + dependsOn(adapter, metadata, logging) + dependsOnRemote(mvnAether, dispatch, aether, aetherApi, aetherSpi, aetherUtil, aetherImpl, aetherConnectorBasic, aetherFile, aetherHttp, aetherWagon, mvnAether) + dependsOnSbtProvided(sbtIo, sbtLaunchInt, sbtLogging) +) + +lazy val core = ( + SubProj("core") + dependsOnRemote(javaMail) + dependsOn(adapter,metadata, graph, hashing, logging, repo) + dependsOnSbtProvided(sbtIo, sbtLogging) +) + +lazy val proj = ( + SubProj("proj") + dependsOn(core, repo, logging) + dependsOnRemote(javaMail, commonsIO) + dependsOnSbtProvided(sbtIo, sbtIvy) +) + +lazy val actorProj = ( + SubProj("actorProj") + dependsOn(core, actorLogging, proj) + dependsOnSbtProvided(sbtIo, sbtIvy) + settings(skip211:_*) +) + +lazy val support = ( + SubProj("support") + dependsOn(core, repo, metadata, proj % "compile->compile;it->compile", logging % "it") + dependsOnRemote(mvnEmbedder, mvnWagon, javaMail, aether, aetherApi, aetherSpi, aetherUtil, + aetherImpl, aetherConnectorBasic, aetherFile, aetherHttp, slf4jSimple, ivy) + dependsOnSbtProvided(sbtLaunchInt, sbtIvy) + settings(SbtSupport.buildSettings:_*) + settings(SbtSupport.settings:_*) + settings( + // We hook the testLoader of it to make sure all the it tasks have a legit sbt plugin to use. + // Technically, this just pushes every project. We could outline just the plugin itself, but for now + // we don't care that much. + testLoader in IntegrationTest := { + val ignore = publishLocal.all(ScopeFilter(inAggregates(LocalRootProject, includeRoot=false))).value + (testLoader in IntegrationTest).value + }, + parallelExecution in IntegrationTest := false + ) +) + +// A separate support project for git/jgit +lazy val supportGit = ( + SubProj("supportGit") + dependsOn(core, repo, metadata, proj, support) + dependsOnRemote(mvnEmbedder, mvnWagon, javaMail, jgit) + dependsOnSbtProvided(sbtLaunchInt, sbtIvy) + settings(SbtSupport.buildSettings:_*) + settings(SbtSupport.settings:_*) + settings(skip211:_*) +) + +// SBT plugin +lazy val plugin = ( + SubProj("plugin") + settings(sbtPlugin := true) + dependsOn(adapter, support, metadata) + dependsOnSbtProvided(sbtIo) +) + +lazy val dist = ( + SubProj("dist") + settings(Packaging.settings(build,repo):_*) +) + +lazy val deploy = ( + SubProj("deploy") + dependsOn(adapter) + dependsOnRemote(jackson, typesafeConfig, commonsLang, aws, uriutil, dispatch, commonsIO, jsch, jacks) + dependsOnSbtProvided(sbtLogging, sbtIo) +) + +lazy val build = ( + SubProj("build") + dependsOn(actorProj, support, supportGit, repo, metadata, deploy, proj) + dependsOnRemote(aws, uriutil, dispatch, jsch, oro, scallop, commonsLang) + dependsOnRemote(gpgLibIf210:_*) + dependsOnSbt(sbtLaunchInt, sbtLauncher, sbtLogging, sbtIo, sbtIvy, sbtSbt) + settings(skip211:_*) + settings(SbtSupport.settings:_*) + settings( + // We hook the testLoader of it to make sure all the it tasks have a legit sbt plugin to use. + // Technically, this just pushes every project. We could outline just the plugin itself, but for now + // we don't care that much. + testLoader in IntegrationTest := { + val ignore = publishLocal.all(ScopeFilter(inAggregates(LocalRootProject, includeRoot=false))).value + (testLoader in IntegrationTest).value + }, + parallelExecution in IntegrationTest := false + ) +) + +lazy val docs:sbt.Project = ( + SubProj("docs") + settings(DocsSupport.settings:_*) +/* + settings(makeSite := Def.sequential( + task { + val file = (sourceDirectory in sphynx).value / "version.py" + val sv = scalaVersion.value + val v = sbtVersion.value + IO.write(sourceDirectory.value, ("release = '%s'\n" format (version.value))) + Seq(file) + }, + makeSite.value + )) +*/ +) + diff --git a/build/src/it/scala/com/typesafe/dbuild/build/RewireSpec.scala b/build/src/it/scala/com/typesafe/dbuild/build/RewireSpec.scala index fe59bb7e..b579ef3b 100644 --- a/build/src/it/scala/com/typesafe/dbuild/build/RewireSpec.scala +++ b/build/src/it/scala/com/typesafe/dbuild/build/RewireSpec.scala @@ -28,7 +28,7 @@ object RewireSpec extends Specification { | check-missing: [false, false, false] | cross-version: standard | space: test - | sbt-version: "0.13.7-M1" + | sbt-version: "0.13.8" | extraction-version: "2.11.1" | projects: [ | { diff --git a/build/src/main/scala/com/typesafe/dbuild/build/Comparison.scala b/build/src/main/scala/com/typesafe/dbuild/build/Comparison.scala index c891390d..3944e2d3 100644 --- a/build/src/main/scala/com/typesafe/dbuild/build/Comparison.scala +++ b/build/src/main/scala/com/typesafe/dbuild/build/Comparison.scala @@ -1,7 +1,9 @@ package com.typesafe.dbuild.build import sbt._ -import Path._ +import com.typesafe.dbuild.adapter.Adapter +import Adapter.{IO,allPaths} +import Adapter.syntaxio._ import com.typesafe.dbuild.model._ import com.typesafe.dbuild.logging.Logger import java.io.File @@ -13,6 +15,7 @@ import java.util.jar.JarFile import java.util.jar.JarEntry import java.io.FileInputStream import org.apache.oro.text.regex +import com.typesafe.dbuild.model.SeqStringH._ class Comparison(options: GeneralOptions, log: Logger) extends OptionTask(log) { def id = "Comparison" @@ -191,4 +194,4 @@ object JarFiles { } } -} \ No newline at end of file +} diff --git a/build/src/main/scala/com/typesafe/dbuild/build/DeployBuild.scala b/build/src/main/scala/com/typesafe/dbuild/build/DeployBuild.scala index 9c467cde..ef0f1835 100644 --- a/build/src/main/scala/com/typesafe/dbuild/build/DeployBuild.scala +++ b/build/src/main/scala/com/typesafe/dbuild/build/DeployBuild.scala @@ -1,7 +1,10 @@ package com.typesafe.dbuild.build import sbt._ -import Path._ +import com.typesafe.dbuild.adapter.Adapter +import Adapter.IO +import Adapter.syntaxio._ +import Adapter.allPaths import com.typesafe.dbuild.model._ import com.typesafe.dbuild.repo.core._ import java.io.File @@ -122,7 +125,7 @@ class DeployBuild(options: GeneralOptions, log: Logger) extends OptionTask(log) new PGPSecretKeyRing(new java.io.FileInputStream(secretRingFile)).getSecretKey } if (secretKey == null) sys.error("The key was not found in the pgp keyring.") - (dir.***).get.filter(f => !f.isDirectory && isNotChecksum(f.getName)) foreach { f => + (allPaths(dir)).get.filter(f => !f.isDirectory && isNotChecksum(f.getName)) foreach { f => SecretKey(secretKey).sign(f, new File(f.getAbsolutePath() + ".asc"), passPhrase.toArray) } } diff --git a/build/src/main/scala/com/typesafe/dbuild/build/LocalBuildMain.scala b/build/src/main/scala/com/typesafe/dbuild/build/LocalBuildMain.scala index 2a7b7106..aefa6a87 100644 --- a/build/src/main/scala/com/typesafe/dbuild/build/LocalBuildMain.scala +++ b/build/src/main/scala/com/typesafe/dbuild/build/LocalBuildMain.scala @@ -2,9 +2,9 @@ package com.typesafe.dbuild.build import java.io.File import akka.actor.{ ActorSystem, Props } -import akka.dispatch.Await +import scala.concurrent.Await import akka.util.Timeout -import akka.util.duration._ +import scala.concurrent.duration._ import com.typesafe.dbuild.model._ import com.typesafe.dbuild.model.Utils.{ readValue, writeValue } import com.typesafe.dbuild.repo.core._ @@ -12,7 +12,6 @@ import com.typesafe.dbuild.model.ClassLoaderMadness import com.typesafe.dbuild.project.dependencies.Extractor import com.typesafe.dbuild.support.BuildSystemCore import akka.pattern.ask -import akka.util.duration._ import com.typesafe.dbuild.repo.core.GlobalDirs.checkForObsoleteDirs import com.typesafe.dbuild.support import com.typesafe.dbuild.logging @@ -55,11 +54,11 @@ class LocalBuildMain(repos: List[xsbti.Repository], options: BuildRunOptions) { def build(conf: DBuildConfiguration, confName: String, buildTarget: Option[String]): BuildOutcome = { implicit val timeout: Timeout = Timeouts.dbuildTimeout val result = builder ? RunLocalBuild(conf, confName, buildTarget) - Await.result(result.mapTo[BuildOutcome], akka.util.Duration.Inf) + Await.result(result.mapTo[BuildOutcome], Duration.Inf) } def dispose(): Unit = { implicit val timeout: Timeout = 5.minutes - Await.result((logMgr ? "exit").mapTo[String], akka.util.Duration.Inf) + Await.result((logMgr ? "exit").mapTo[String], Duration.Inf) system.shutdown() // pro forma, as all loggers should already be stopped at this point try { system.awaitTermination(4.minute) diff --git a/build/src/main/scala/com/typesafe/dbuild/build/Notifications.scala b/build/src/main/scala/com/typesafe/dbuild/build/Notifications.scala index cdefe7e8..3b6a5fb4 100644 --- a/build/src/main/scala/com/typesafe/dbuild/build/Notifications.scala +++ b/build/src/main/scala/com/typesafe/dbuild/build/Notifications.scala @@ -11,6 +11,9 @@ import RecipientType._ import com.typesafe.dbuild.deploy.Creds.loadCreds import com.typesafe.dbuild.model.TemplateFormatter import dispatch.classic.{ Logger => _, _ } +import com.typesafe.dbuild.model.SeqNotificationH._ +import com.typesafe.dbuild.model.SeqSelectorElementH._ +import com.typesafe.dbuild.model.SeqStringH._ // // Ideally, the ConsoleNotification should become the mechanism by which the entire log of the diff --git a/build/src/main/scala/com/typesafe/dbuild/build/OptionTask.scala b/build/src/main/scala/com/typesafe/dbuild/build/OptionTask.scala index 5444d022..dbfd67d4 100644 --- a/build/src/main/scala/com/typesafe/dbuild/build/OptionTask.scala +++ b/build/src/main/scala/com/typesafe/dbuild/build/OptionTask.scala @@ -7,6 +7,7 @@ import Logger.prepareLogMsg import com.typesafe.dbuild.model._ import java.io.File import com.typesafe.dbuild.repo.core.{ LocalRepoHelper, Repository } +import com.typesafe.dbuild.model.SeqStringH._ /** * Defines a task that will run before or after the build, defined somewhere diff --git a/build/src/main/scala/com/typesafe/dbuild/build/SbtBuildMain.scala b/build/src/main/scala/com/typesafe/dbuild/build/SbtBuildMain.scala index b8640921..8c1ed6ca 100644 --- a/build/src/main/scala/com/typesafe/dbuild/build/SbtBuildMain.scala +++ b/build/src/main/scala/com/typesafe/dbuild/build/SbtBuildMain.scala @@ -13,7 +13,7 @@ import com.typesafe.config.ConfigValueFactory import com.typesafe.dbuild.model.Utils.readValueT import com.typesafe.dbuild.utils.Time.timed import collection.immutable.SortedMap -import com.typesafe.dbuild.repo.core.Defaults +import com.typesafe.dbuild.adapter.Defaults import com.typesafe.config.{ ConfigSyntax, ConfigFactory, ConfigParseOptions } import org.rogach.scallop._ import org.rogach.scallop.exceptions.ScallopException @@ -23,6 +23,8 @@ import java.util.TimeZone import collection.JavaConverters._ import scala.collection.JavaConversions._ import com.typesafe.config.ConfigRenderOptions +import com.typesafe.dbuild.model.SeqDBCH._ +import com.typesafe.dbuild.model.SeqStringH._ /** * These options are created by SbtBuildMain, and are propagated to most stages of building, as diff --git a/build/src/main/scala/com/typesafe/dbuild/build/SimpleBuildActor.scala b/build/src/main/scala/com/typesafe/dbuild/build/SimpleBuildActor.scala index 1f2847a7..7850d181 100644 --- a/build/src/main/scala/com/typesafe/dbuild/build/SimpleBuildActor.scala +++ b/build/src/main/scala/com/typesafe/dbuild/build/SimpleBuildActor.scala @@ -11,8 +11,9 @@ import com.typesafe.dbuild.hashing import com.typesafe.dbuild.graph import akka.actor.{ Actor, ActorRef, Props } import akka.pattern.{ ask, pipe } -import akka.dispatch.{ Future, Futures, Promise } -import akka.util.duration._ +import scala.concurrent.duration._ +import scala.concurrent.{ Future, Promise, ExecutionContext } +import ExecutionContext.Implicits.global import akka.util.Timeout import com.typesafe.dbuild.project.build.ActorPatterns.forwardingErrorsToFutures import sbt.Path._ @@ -20,6 +21,7 @@ import java.io.File import com.typesafe.dbuild.repo.core.GlobalDirs import org.apache.maven.execution.BuildFailure import Logger.prepareLogMsg +import com.typesafe.dbuild.model.SeqDBCH._ case class RunDBuild(conf: DBuildConfiguration, confName: String, buildTarget: Option[String], logger: Logger, options: BuildRunOptions) @@ -156,7 +158,7 @@ class SimpleBuildActor(extractor: ActorRef, builder: ActorRef, repository: Repos case Right(o) => o } - nest(RepeatableDBuildConfig.fromExtractionOutcome(extractionOutcome)) { fullBuild => + nest(RepeatableDBuildConfigH.fromExtractionOutcome(extractionOutcome)) { fullBuild => // what we call "RepeatableDBuildConfig" is actually only the portion of data that // affect the build. Further options that do /not/ affect the build, but control dbuild in // other ways (notifications, resolvers, etc), are in the GeneralOptions. diff --git a/build/src/main/scala/com/typesafe/dbuild/build/Timeouts.scala b/build/src/main/scala/com/typesafe/dbuild/build/Timeouts.scala index 41acd7a4..9e68fec9 100644 --- a/build/src/main/scala/com/typesafe/dbuild/build/Timeouts.scala +++ b/build/src/main/scala/com/typesafe/dbuild/build/Timeouts.scala @@ -2,11 +2,11 @@ package com.typesafe.dbuild.build import akka.actor.{ Actor, ActorRef, Props, Scheduler } import akka.pattern.{ ask, pipe } -import akka.util.duration._ +import scala.concurrent.duration._ import akka.util.Timeout -import akka.util.Duration -import akka.util.NonFatal -import akka.dispatch.{ ExecutionContext, Promise, Future } +import scala.util.control.NonFatal +import scala.concurrent.{ ExecutionContext, Promise, Future } +import ExecutionContext.Implicits.global object Timeouts { // overall timeout for the entire dbuild to complete; @@ -35,14 +35,14 @@ object Timeouts { * Returns a [[akka.dispatch.Future]] that will be completed with the success or failure of the provided value * after the specified duration. */ - def after[T](duration: Duration, using: Scheduler)(value: ⇒ Future[T])(implicit ec: ExecutionContext): Future[T] = + def after[T](duration: FiniteDuration, using: Scheduler)(value: ⇒ Future[T])(implicit ec: ExecutionContext): Future[T] = if (duration.isFinite() && duration.length < 1) value else { val p = Promise[T]() val c = using.scheduleOnce(duration) { - p completeWith { try value catch { case NonFatal(t) ⇒ Promise.failed(t) } } + p completeWith { try value catch { case NonFatal(t) ⇒ Promise.failed(t).future } } } - p onComplete { _ ⇒ c.cancel() } - p + p.future onComplete { _ ⇒ c.cancel() } + p.future } assert((extractionTimeout.duration + 5.minutes) < extractionPhaseTimeout.duration, "extractionTimeout must be a bit shorter than extractionPhaseTimeout") diff --git a/core/src/main/scala/com/typesafe/dbuild/project/BuildSystem.scala b/core/src/main/scala/com/typesafe/dbuild/project/BuildSystem.scala index 751d8e0e..0b4cc75b 100644 --- a/core/src/main/scala/com/typesafe/dbuild/project/BuildSystem.scala +++ b/core/src/main/scala/com/typesafe/dbuild/project/BuildSystem.scala @@ -3,7 +3,7 @@ package com.typesafe.dbuild.project import com.typesafe.dbuild.model._ import com.typesafe.dbuild.logging.Logger import java.io.File -import sbt.Path._ +import com.typesafe.dbuild.adapter.Adapter.Path._ case class BuildData(log: Logger, debug: Boolean) @@ -101,4 +101,4 @@ object BuildSystem { } build.flatMap {b => b.projects.map { expandProject(_, b) }} } -} \ No newline at end of file +} diff --git a/deploy/src/main/scala/com/typesafe/dbuild/deploy/Deploy.scala b/deploy/src/main/scala/com/typesafe/dbuild/deploy/Deploy.scala index fcc8a5ee..03570245 100644 --- a/deploy/src/main/scala/com/typesafe/dbuild/deploy/Deploy.scala +++ b/deploy/src/main/scala/com/typesafe/dbuild/deploy/Deploy.scala @@ -1,7 +1,6 @@ package com.typesafe.dbuild.deploy import sbt._ -import Path._ import java.io.File import java.net.URI import com.amazonaws.services.s3.AmazonS3Client @@ -11,12 +10,15 @@ import com.amazonaws.ClientConfiguration import com.amazonaws.Protocol import dispatch.classic.{ Logger => _, _ } import org.omg.PortableInterceptor.SUCCESSFUL -import sbt.Logger import Creds.loadCreds -import com.jcraft.jsch.{ IO => sshIO, _ } +import com.jcraft.jsch.{ IO => sshIO, Logger => _, _ } import java.util.Date import com.jcraft.jsch.ChannelSftp +import com.typesafe.dbuild.adapter.Adapter +import Adapter.{IO,Logger,allPaths} +import Adapter.syntaxio._ import com.lambdaworks.jacks.JacksMapper +import Adapter.Path._ /** * A generic (S3, http, https, etc) deploy location. @@ -133,7 +135,7 @@ abstract class IterativeDeploy[T](options: DeployInfo) extends Deploy[T](options // - finally, the checksums are uploaded after the main artifacts // - val allFiles = (dir.***).get.filter(f => !f.isDirectory) + val allFiles = allPaths(dir).get.filter(f => !f.isDirectory) val poms = allFiles.filter(f => f.getName.endsWith("-SNAPSHOT.pom")) // // we fold over the poms, reducing the set of files until we are left with just @@ -144,7 +146,7 @@ abstract class IterativeDeploy[T](options: DeployInfo) extends Deploy[T](options val thisDir = pomFile.getParentFile() if (thisDir == null) sys.error("Unexpected: file has not parent in deploy") // select the files in this directory (but not in subdirectories) - val theseFiles = (thisDir.***).get.filter(f => !f.isDirectory && f.getParentFile() == thisDir) + val theseFiles = allPaths(thisDir).get.filter(f => !f.isDirectory && f.getParentFile() == thisDir) // if there is a matching jar, upload the jar first val jarFile = new java.io.File(pomFile.getPath().replaceAll("\\.[^\\.]*$", ".jar")) val thisSeq = if (theseFiles contains jarFile) { @@ -285,7 +287,7 @@ class DeployHTTP(log: Logger, options: DeployInfo) extends IterativeDeploy[Unit] protected def deployItem(handler: Unit, relative: String, file: File, uri: URI) = { import dispatch._ val sender = - url(uri.toString).PUT.as(credentials.user, credentials.pass) <<< (file, "application/octet-stream") + dispatch.classic.url(uri.toString).PUT.as(credentials.user, credentials.pass) <<< (file, "application/octet-stream") val response = (new Http with NoLogging)(sender >- { str => Deploy.readSomePath[ArtifactoryResponse](str) }) @@ -331,7 +333,7 @@ class DeployBintray(log: Logger, options: DeployInfo) extends DeployHTTP(log, op val path = target.getPath val dest = new java.net.URI(bintrayBase + (if (path.head == '/') path.tail else path) + "/publish") val sender = - url(dest.toString).POST.as(credentials.user, credentials.pass) + dispatch.classic.url(dest.toString).POST.as(credentials.user, credentials.pass) val response = (new Http with NoLogging)(sender >- { str => Deploy.readSomePath[ArtifactoryResponse](str) }) diff --git a/dist/src/universal/samples/akka-on-2.10.x.dbuild b/dist/src/universal/samples/akka-on-2.10.x.dbuild deleted file mode 100644 index 0db6f639..00000000 --- a/dist/src/universal/samples/akka-on-2.10.x.dbuild +++ /dev/null @@ -1,27 +0,0 @@ -build.projects:[ - { - name: "scala", - system: "scala", - uri: "git://github.com/scala/scala.git#2.10.x" - }, { - name: "scalacheck", - system: "sbt", - uri: "git://github.com/jsuereth/scalacheck.git#origin/master" - },{ - name: "specs2-scalaz", - system: "sbt", - uri: "git://github.com/jsuereth/specs2-scalaz.git#origin/community" - },{ - name: "specs2", - system: "sbt", - uri: "git://github.com/jsuereth/specs2.git#origin/community" - },{ - name: "scala-stm", - system: "sbt", - uri: "git://github.com/nbronson/scala-stm.git#master" - },{ - name:"akka", - system:"sbt", - uri:"git://github.com/akka/akka.git#master" - } -] diff --git a/dist/src/universal/samples/ivyExample.dbuild b/dist/src/universal/samples/ivyExample.dbuild deleted file mode 100644 index 2eb2ab9e..00000000 --- a/dist/src/universal/samples/ivyExample.dbuild +++ /dev/null @@ -1,57 +0,0 @@ -build.projects:[ - { - name: scala-compiler - system: ivy - uri: "ivy:org.scala-lang#scala-compiler;2.10.2" - extra: { sources: true } - }, { - name: scala-reflect - system: ivy - uri: "ivy:org.scala-lang#scala-reflect;2.10.2" - }, { - name: scala-library - system: ivy - uri: "ivy:org.scala-lang#scala-library;2.10.2" - }, { - name: scala-actors - system: ivy - uri: "ivy:org.scala-lang#scala-actors;2.10.2" - }, { - name: jline - system: ivy - uri: "ivy:org.scala-lang#jline;2.10.2" - }, { - name: "scalacheck", - uri: "git://github.com/rickynils/scalacheck.git#1.10.1" - }, { - name: "sbinary", - uri: "git://github.com/harrah/sbinary.git#bdc555afbbb7657b4a9def7ae342d53881be2e2d" - extra: { projects: ["core"] } - }, { - name: "sbt", - uri: "git://github.com/sbt/sbt.git#f4a3904a4724dcd1fb8c8cd315c6b2f416bda3a3" - extra: { - projects: ["compiler-interface", - "classpath","logging","io","control","classfile", - "process","relation","interface","persist","api", - "compiler-integration","incremental-compiler","compile","launcher-interface" - ], - run-tests: false - } - }, { - name: "sbt-republish", - uri: "http://github.com/typesafehub/sbt-republish.git#2dc7afb6c84e5a55eb0ff7677343c6c301a38aeb", - set-version: "0.13.0-on-2.10.3-SNAPSHOT-for-IDE-SNAPSHOT" - }, { - name: "zinc", - uri: "https://github.com/typesafehub/zinc.git#f5912305a08fed3750f5ea7e77bc1efc27424f2a" - }, { - name: specs2 - system: ivy - uri: "ivy:org.specs2#specs2_2.10;1.12.3" - }, { - name: specs2-scalaz-core - system: ivy - uri: "ivy:org.specs2#specs2-scalaz-core_2.10.0-RC3;6.0.1" - } -] diff --git a/docs/src/sphinx/conf.py b/docs/src/sphinx/conf.py index b2b5e49f..5e770b3b 100644 --- a/docs/src/sphinx/conf.py +++ b/docs/src/sphinx/conf.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- import sys, os +from version import release sys.path.append(os.path.abspath('_sphinx/exts')) extensions = ['sphinxcontrib.issuetracker', 'sphinx.ext.extlinks', 'howto'] @@ -8,9 +9,6 @@ # Project variables project = 'dbuild' -version = '0.9.7' -release = '0.9.7-SNAPSHOT' -sbt_version = '0.12.4' # General settings @@ -66,10 +64,8 @@ .. _zip: %(dbuild_native_package_base)s/%(project)s/%(version)s/zips/%(project)s-%(version)s.zip .. _tgz: %(dbuild_native_package_base)s/%(project)s/%(version)s/tgzs/%(project)s-%(version)s.tgz .. |version| replace:: %(version)s -.. |sbtversion| replace:: %(sbtversion)s .. |addSbtplugin| replace:: addSbtPlugin(:s2:`"com.typesafe.dbuild"` %% :s2:`"plugin"` %% :s2:`"%(version)s"`) """ % { - 'sbtversion': sbt_version, 'version': release, 'project': project, 'dbuild_native_package_base': 'http://repo.typesafe.com/typesafe/ivy-releases/com.typesafe.dbuild', diff --git a/docs/src/sphinx/download.rst b/docs/src/sphinx/download.rst index 4e67981c..948d80ed 100644 --- a/docs/src/sphinx/download.rst +++ b/docs/src/sphinx/download.rst @@ -21,7 +21,6 @@ The archive contains the following files: ./bin/drepo ./bin/drepo.properties ./bin/sbt-launch.jar - ./samples/[...] Where ``dbuild`` is the build tool, and ``dbuild.properties`` is its configuration file. The ``bin`` directory also contains the ``drepo`` repository inspection tool, together with its configuration file; you can find more information in the diff --git a/logging/src/main/scala/com/typesafe/dbuild/logging/Logger.scala b/logging/src/main/scala/com/typesafe/dbuild/logging/Logger.scala index 8ab8e272..0ee5db2c 100644 --- a/logging/src/main/scala/com/typesafe/dbuild/logging/Logger.scala +++ b/logging/src/main/scala/com/typesafe/dbuild/logging/Logger.scala @@ -1,9 +1,10 @@ package com.typesafe.dbuild.logging -import sbt.{ Logger => SbtLogger, LogEvent } import sys.process.ProcessLogger -import sbt.Level._ import com.typesafe.dbuild.graph +import com.typesafe.dbuild.adapter.{LoggingInterface,StreamLoggerAdapter} +import LoggingInterface.{Logger=>SbtLogger,BasicLogger=>SbtBasicLogger,_} +import LoggingInterface.Level._ trait Logger extends SbtLogger with ProcessLogger { def newNestedLogger(name: String, projName: String = ""): Logger @@ -41,14 +42,10 @@ object ConsoleLogger { def apply(debug: Boolean): Logger = new StreamLogger(System.out, debug) } -// -// Below this line, unused code -// - -abstract class BasicLogger extends sbt.BasicLogger with Logger +abstract class BasicLogger extends SbtBasicLogger with Logger /** Logs to an output stream. */ -class StreamLogger(out: java.io.PrintStream, debug: Boolean) extends BasicLogger { +final class StreamLogger(out: java.io.PrintStream, debug: Boolean) extends BasicLogger with StreamLoggerAdapter { if (debug) setLevel(Debug) @@ -56,23 +53,21 @@ class StreamLogger(out: java.io.PrintStream, debug: Boolean) extends BasicLogger def trace(t: => Throwable): Unit = out.synchronized { val traceLevel = getTrace - if (traceLevel >= 0) out.print(sbt.StackTrace.trimmed(t, traceLevel)) + if (traceLevel >= 0) out.print(StackTrace.trimmed(t, traceLevel)) } def success(message: => String): Unit = if (successEnabled) log(SuccessLabel, message) def buffer[T](t: => T): T = t - def err(s: => String): Unit = - log(Error, s) - def out(s: => String): Unit = - log(Info.toString, s) - def control(event: sbt.ControlEvent.Value, message: => String): Unit = + def control(event: ControlEvent.Value, message: => String): Unit = log(Info.toString, message) def logAll(events: Seq[LogEvent]) = out.synchronized { events foreach log } - def log(level: sbt.Level.Value, message: => String): Unit = + def log(level: Level.Value, message: => String): Unit = if (atLevel(level)) log(level.toString, message) - private def log(label: String, message: String): Unit = + // The log(String,String) version should be protected or private, + // but we cannot make it such because of the Adapter trait mix-in + def log(label: String, message: String): Unit = out.synchronized { for (line <- message.split("""\n""")) { out.print("[") diff --git a/metadata/src/main/scala/com/typesafe/dbuild/model/Config.scala b/metadata/src/main/scala/com/typesafe/dbuild/model/Config.scala index 6e06f6fa..a556cd04 100644 --- a/metadata/src/main/scala/com/typesafe/dbuild/model/Config.scala +++ b/metadata/src/main/scala/com/typesafe/dbuild/model/Config.scala @@ -13,6 +13,13 @@ import collection.JavaConverters._ import com.typesafe.dbuild.deploy.DeployTarget import com.typesafe.dbuild.hashing +import SeqBooleanH._ +import SeqDBCH._ +import SeqDepsModifiersH._ +import SeqNotificationH._ +import SeqSelectorElementH._ +import SeqSeqStringH._ +import SeqStringH._ /** * Metadata about a build. This is extracted from a config file and contains enough information * to further extract information about a build. @@ -209,7 +216,7 @@ case class DBuildConfiguration( * empty record. */ @JsonDeserialize(using = classOf[VarDeserializer]) -case class Vars +case class Vars() class VarDeserializer extends JsonDeserializer[Vars] { override def deserialize(p: JsonParser, ctx: DeserializationContext): Vars = { val tf = ctx.getConfig.getTypeFactory() @@ -347,7 +354,7 @@ case class SeqString(override val s: Seq[String]) extends Flex[String](s) { } class SeqStringDeserializer extends SeqFlexDeserializer[String, SeqString] class SeqStringSerializer extends SeqFlexSerializer[String] -object SeqString { +object SeqStringH { implicit def SeqToSeqString(s: Seq[String]): SeqString = SeqString(s) implicit def SeqStringToSeq(a: SeqString): Seq[String] = a.s } @@ -362,7 +369,7 @@ case class SeqBoolean(override val s: Seq[Boolean]) extends Flex[Boolean](s) { } class SeqBooleanDeserializer extends SeqFlexDeserializer[Boolean, SeqBoolean] class SeqBooleanSerializer extends SeqFlexSerializer[Boolean] -object SeqBoolean { +object SeqBooleanH { implicit def SeqToSeqBoolean(s: Seq[Boolean]): SeqBoolean = SeqBoolean(s) implicit def SeqBooleanToSeq(a: SeqBoolean): Seq[Boolean] = a.s } @@ -376,7 +383,7 @@ object SeqBoolean { case class SeqDBC(override val s: Seq[DBuildConfig]) extends Flex[DBuildConfig](s) class SeqDBCDeserializer extends SeqFlexDeserializer[DBuildConfig, SeqDBC] class SeqDBCSerializer extends SeqFlexSerializer[DBuildConfig] -object SeqDBC { +object SeqDBCH { implicit def SeqToSeqDBC(s: Seq[DBuildConfig]): SeqDBC = SeqDBC(s) implicit def SeqDBCToSeq(a: SeqDBC): Seq[DBuildConfig] = a.s } @@ -389,7 +396,7 @@ object SeqDBC { case class SeqDepsModifiers(override val s: Seq[DepsModifiers]) extends Flex[DepsModifiers](s) class SeqDMDeserializer extends SeqFlexDeserializer[DepsModifiers, SeqDepsModifiers] class SeqDMSerializer extends SeqFlexSerializer[DepsModifiers] -object SeqDepsModifiers { +object SeqDepsModifiersH { implicit def SeqToSeqDM(s: Seq[DepsModifiers]): SeqDepsModifiers = SeqDepsModifiers(s) implicit def SeqDMToSeq(a: SeqDepsModifiers): Seq[DepsModifiers] = a.s implicit def OptToSeqDM(o: Option[DepsModifiers]): SeqDepsModifiers = SeqDepsModifiers(o.toSeq) @@ -407,7 +414,7 @@ case class SeqSeqString(override val s: Seq[SeqString]) extends Flex[SeqString]( // turn the SeqSeqString into a Seq[Seq[String]] def expand = s map {_.s} } -object SeqSeqString { +object SeqSeqStringH { implicit def SeqToSeqSeqString(s: Seq[SeqString]): SeqSeqString = SeqSeqString(s) implicit def SeqSeqStringToSeq(a: SeqSeqString): Seq[SeqString] = a.s } @@ -543,7 +550,7 @@ class ExtraSerializer extends JsonSerializer[ExtraConfig] { ScalaTypeSig(cfg.getTypeFactory, jt) match { case Some(sts) if sts.isCaseClass => // the "true" below is for options.caseClassSkipNulls - (new CaseClassSerializer(jt, sts.annotatedAccessors, true)).serialize(value.asInstanceOf[Product], g, p) + (new CaseClassSerializer(jt, sts.annotatedAccessors(cfg), true)).serialize(value.asInstanceOf[Product], g, p) case _ => throw new Exception("Internal error while serializing build system config. Please report.") } } @@ -702,7 +709,7 @@ class SelectorElementSerializer extends JsonSerializer[SelectorElement] { val jt = tf.constructType(classOf[SubProjects]) val Some(sts) = ScalaTypeSig(cfg.getTypeFactory, jt) // the "true" below is for options.caseClassSkipNulls - (new CaseClassSerializer(jt, sts.annotatedAccessors, true)).serialize(d, g, p) + (new CaseClassSerializer(jt, sts.annotatedAccessors(cfg), true)).serialize(d, g, p) case _ => throw new Exception("Internal error while serializing deploy projects. Please report.") } } @@ -779,7 +786,7 @@ case class SeqSelectorElement(override val s: Seq[SelectorElement]) extends Flex } class SeqElementDeserializer extends SeqFlexDeserializer[SelectorElement, SeqSelectorElement] class SeqElementSerializer extends SeqFlexSerializer[SelectorElement] -object SeqSelectorElement { +object SeqSelectorElementH { implicit def SeqToSeqSelectorElement(s: Seq[SelectorElement]): SeqSelectorElement = SeqSelectorElement(s) implicit def SeqSelectorElementToSeq(a: SeqSelectorElement): Seq[SelectorElement] = a.s } @@ -793,7 +800,7 @@ object SeqSelectorElement { case class SeqNotification(override val s: Seq[Notification]) extends Flex[Notification](s) class SeqNotificationDeserializer extends SeqFlexDeserializer[Notification, SeqNotification] class SeqNotificationSerializer extends SeqFlexSerializer[Notification] -object SeqNotification { +object SeqNotificationH { implicit def SeqToSeqNotification(s: Seq[Notification]): SeqNotification = SeqNotification(s) implicit def SeqNotificationToSeq(a: SeqNotification): Seq[Notification] = a.s } @@ -968,7 +975,7 @@ class NotificationKindSerializer extends JsonSerializer[NotificationKind] { ScalaTypeSig(cfg.getTypeFactory, jt) match { case Some(sts) if sts.isCaseClass => // the "true" below is for options.caseClassSkipNulls - (new CaseClassSerializer(jt, sts.annotatedAccessors, true)).serialize(value.asInstanceOf[Product], g, p) + (new CaseClassSerializer(jt, sts.annotatedAccessors(cfg), true)).serialize(value.asInstanceOf[Product], g, p) case _ => throw new Exception("Internal error while serializing NotificationKind. Please report.") } } @@ -976,7 +983,7 @@ class NotificationKindSerializer extends JsonSerializer[NotificationKind] { class NotificationDeserializer extends JsonDeserializer[Notification] { override def deserialize(p: JsonParser, ctx: DeserializationContext): Notification = { - val notificationKinds = NotificationKind.kinds + val notificationKinds = NotificationKindH.kinds val tf = ctx.getConfig.getTypeFactory() val d = ctx.findContextualValueDeserializer(tf.constructType(classOf[NotificationShadow]), null) @@ -1133,7 +1140,7 @@ case class Smtp( case class ConsoleNotification() extends NotificationKind -object NotificationKind { +object NotificationKindH { val kinds: Map[String, java.lang.Class[_ <: NotificationKind]] = Map( "console" -> classOf[ConsoleNotification], "flowdock" -> classOf[FlowdockNotification], diff --git a/metadata/src/main/scala/com/typesafe/dbuild/model/Extracted.scala b/metadata/src/main/scala/com/typesafe/dbuild/model/Extracted.scala index 5d943a3e..a0fa4084 100644 --- a/metadata/src/main/scala/com/typesafe/dbuild/model/Extracted.scala +++ b/metadata/src/main/scala/com/typesafe/dbuild/model/Extracted.scala @@ -1,6 +1,10 @@ package com.typesafe.dbuild.model import com.fasterxml.jackson.annotation.{ JsonCreator, JsonProperty } +// Note: all of the case classes in this file are serialized/deserialized +// by using the "jacks" library. For that library to work correctly, there +// must not be any companion objects defined for those case classes. + /** * A project dep is an extracted *external* build dependency. I.e. this is a * maven/ivy artifact that exists and is built external to a local build. @@ -70,7 +74,7 @@ case class ExtractedBuildMeta(@JsonProperty("proj-info") projInfo: Seq /*Levels* "%s -> (%s, %s, %s)" format (index, version, projects.mkString("\n\t", "\n\t", "\n"), subproj.mkString("\n ", ", ", "\n")) }) } -object ExtractedBuildMeta { +object ExtractedBuildMetaH { def apply(version: String, projects: Seq[Project], subproj: Seq[String] = Seq.empty): ExtractedBuildMeta = ExtractedBuildMeta(Seq /*Levels*/ (ProjMeta(version, projects, subproj))) -} \ No newline at end of file +} diff --git a/metadata/src/main/scala/com/typesafe/dbuild/model/RepeatableBuild.scala b/metadata/src/main/scala/com/typesafe/dbuild/model/RepeatableBuild.scala index 37711642..befa1a97 100644 --- a/metadata/src/main/scala/com/typesafe/dbuild/model/RepeatableBuild.scala +++ b/metadata/src/main/scala/com/typesafe/dbuild/model/RepeatableBuild.scala @@ -3,6 +3,7 @@ package com.typesafe.dbuild.model import Utils.{ writeValue, canSeeSpace } import com.fasterxml.jackson.annotation.JsonProperty import com.typesafe.dbuild.hashing +import com.typesafe.dbuild.model.SeqStringH._ /** * Information on how to build a project. Consists of both dbuild @@ -66,7 +67,7 @@ case class RepeatableDepInfo( // the two Seqs should probably be converted into a Seq[(String,String)]. ) -object RepeatableDBuildConfig { +object RepeatableDBuildConfigH { def fromExtractionOutcome(outcome: ExtractionOK) = RepeatableDBuildConfig(outcome.pces) } /** @@ -131,7 +132,13 @@ case class RepeatableDBuildConfig(builds: Seq[ProjectConfigAndExtracted]) { // more appropriate to print the actual subproject name, rather than the Project case class Origin(fromProject: String, spaces: SeqString) case class Info(artOrg: String, artName: String, origin: Origin) - val generatedArtifacts = builds flatMap { b => b.extracted.projects.map { a => Info(a.organization, a.name, Origin(b.config.name, b.getSpace.to)) } } + + // declare a collision if any artifacts in two distint projects have same organization and name + // (even if they differ in their extension or classifiers) + val generatedArtifacts = builds flatMap { b => b.extracted.projects.flatMap { _.artifacts.groupBy { + case ProjectRef(name, org, ext, classifier) => (org, name) + }.map { case ((org, name), _) => Info(org, name, Origin(b.config.name, b.getSpace.to)) } } } + val byArt = (generatedArtifacts.groupBy { case Info(org, name, origin) => (org, name) }).toSeq val collisions = byArt flatMap { case ((org, name), seqInfo) => diff --git a/metadata/src/test/scala/com/typesafe/dbuild/model/RepeatableBuildSpec.scala b/metadata/src/test/scala/com/typesafe/dbuild/model/RepeatableBuildSpec.scala index b9c88550..fdfddedc 100644 --- a/metadata/src/test/scala/com/typesafe/dbuild/model/RepeatableBuildSpec.scala +++ b/metadata/src/test/scala/com/typesafe/dbuild/model/RepeatableBuildSpec.scala @@ -2,6 +2,7 @@ package com.typesafe.dbuild.model import org.specs2.mutable.Specification import Utils.{writeValue,readValue} +import SeqDepsModifiersH._ import com.lambdaworks.jacks._ import JacksOption._ diff --git a/plugin/src/main/scala/com/typesafe/dbuild/plugin/DBuildPlugin.scala b/plugin/src/main/scala/com/typesafe/dbuild/plugin/DBuildPlugin.scala index 76d26fae..0b2e2827 100644 --- a/plugin/src/main/scala/com/typesafe/dbuild/plugin/DBuildPlugin.scala +++ b/plugin/src/main/scala/com/typesafe/dbuild/plugin/DBuildPlugin.scala @@ -2,9 +2,11 @@ package com.typesafe.dbuild.plugin import sbt._ -object DBuildPlugin extends Plugin { +object DBuildPlugin extends AutoPlugin { + override def trigger = allRequirements + override def requires = plugins.JvmPlugin override def buildSettings = ( DBuildRunner.buildSettings ) override def projectSettings = DBuildRunner.projectSettings -} \ No newline at end of file +} diff --git a/plugin/src/main/scala/com/typesafe/dbuild/plugin/DBuildRunner.scala b/plugin/src/main/scala/com/typesafe/dbuild/plugin/DBuildRunner.scala index 71ddb5f9..bf429d1e 100644 --- a/plugin/src/main/scala/com/typesafe/dbuild/plugin/DBuildRunner.scala +++ b/plugin/src/main/scala/com/typesafe/dbuild/plugin/DBuildRunner.scala @@ -2,6 +2,9 @@ package com.typesafe.dbuild.plugin import sbt._ +import com.typesafe.dbuild.adapter.Adapter +import Adapter.{ProjectResolver,scalaInstance,allPaths,Load,applyCross,ScalaInstance} +import Adapter.syntax._ import com.typesafe.dbuild.model import com.typesafe.dbuild.support.sbt.SbtBuildConfig import com.typesafe.dbuild.model.ArtifactLocation @@ -226,7 +229,7 @@ object DBuildRunner { val newSettings1 = { ptSettings map { s => - SbtUpdate.update(s.asInstanceOf[Setting[Option[sbt.Resolver]]].key) { + Def.update(s.asInstanceOf[Setting[Option[sbt.Resolver]]].key) { _ match { case Some(r: PatternsBasedRepository) if (!r.patterns.isMavenCompatible) => ivyRepo case _ => mavenRepo @@ -281,7 +284,7 @@ object DBuildRunner { } // as above, but assumes the transformation is a simple Project.update (aka: ~= ) - def fixGenericK2[K](k: Scoped, f: K => K) = fixGenericTransform2(k) { s: Setting[K] => SbtUpdate.update(s.key)(f) } _ + def fixGenericK2[K](k: Scoped, f: K => K) = fixGenericTransform2(k) { s: Setting[K] => Def.update(s.key)(f) } _ // Separate cases for settings and tasks (to keep the type inferencer happy) def fixGeneric2[K](k: SettingKey[K], m: String)(f: K => K) = fixGenericK2(k, f)(m) @@ -379,6 +382,12 @@ object DBuildRunner { def fixInterProjectResolver2 = fixGeneric2(Keys.projectResolver, "Disabling inter-project resolver") { _ map { _ => new RawRepository(new ProjectResolver("inter-project", Map.empty)) } } + // Some projects or plugins modify the "publish" task (for instance, to use Bintray), + // but we need the task to point to the standard definition, so that we can publish + // the files to the local directories + def fixStandardPublish2 = + fixGeneric2(Keys.publish, "Resetting publish task") { _ map { _ => sbt.Classpaths.publishTask(Keys.publishConfiguration, Keys.deliver) } } + // alternate version, which only removes the artifacts that are not part // of the selected subprojects. Might be more suitable for setupcmd; in this case, // local-publish-repo should not be added to the list of resolvers. @@ -440,7 +449,7 @@ object DBuildRunner { val sc = s.key.scope Keys.scalaInstance in sc <<= Keys.appConfiguration in sc map { app => val launcher = app.provider.scalaProvider.launcher - ScalaInstance(libraryJar(scalaHome), compilerJar(scalaHome), launcher, allJars(scalaHome): _*) + scalaInstance(libraryJar(scalaHome), compilerJar(scalaHome), launcher, allJars(scalaHome): _*) } }("Setting Scala instance")(oldSettings, log) } @@ -605,7 +614,7 @@ object DBuildRunner { // current set of files in the repository against the files we had previously val previousFiles = previous._1 val localRepo = config.info.outRepo.getAbsoluteFile - val currentFiles = (localRepo.***).get. + val currentFiles = (allPaths(localRepo)).get. filterNot(file => file.isDirectory || file.getName == "maven-metadata-local.xml") val newFilesShas = currentFiles.diff(previousFiles).map { LocalRepoHelper.makeArtifactSha(_, localRepo) } @@ -663,6 +672,7 @@ object DBuildRunner { private def preparePublishSettings(in: BuildInput, log: ConsoleLogger, oldSettings: Seq[Setting[_]]) = Seq[Fixer]( + fixStandardPublish2, fixPublishTos2(in.outRepo.getAbsoluteFile), fixPGPs2, fixVersions2(in)) flatMap { _(oldSettings, log) } @@ -757,7 +767,7 @@ object DBuildRunner { def extractArtifactLocations(org: String, version: String, artifacts: Map[Artifact, File], cross: CrossVersion, sv: String, sbv: String, sbtbv: String, isSbtPlugin: Boolean): Seq[model.ArtifactLocation] = { - val crossSuffix = CrossVersion.applyCross("", CrossVersion(cross, sv, sbv)) + val crossSuffix = applyCross("", CrossVersion(cross, sv, sbv)) for { (artifact, file) <- artifacts.toSeq } yield model.ArtifactLocation( diff --git a/plugin/src/main/scala/com/typesafe/dbuild/plugin/DependencyAnalysis.scala b/plugin/src/main/scala/com/typesafe/dbuild/plugin/DependencyAnalysis.scala index 50b95061..2ad5df3f 100644 --- a/plugin/src/main/scala/com/typesafe/dbuild/plugin/DependencyAnalysis.scala +++ b/plugin/src/main/scala/com/typesafe/dbuild/plugin/DependencyAnalysis.scala @@ -1,6 +1,9 @@ package com.typesafe.dbuild.plugin import sbt._ +import com.typesafe.dbuild.adapter.Adapter +import Adapter.syntaxio._ +import Adapter.defaultID import com.typesafe.dbuild.model import com.typesafe.dbuild.plugin.StateHelpers._ import com.typesafe.dbuild.support.sbt.ExtractionInput @@ -61,8 +64,9 @@ object DependencyAnalysis { def normalizedProjectName(s: ProjectRef, baseDirectory: File) = normalizedProjectNameString(s.project, baseDirectory) def normalizedProjectNameString(name: String, baseDirectory: File): String = { // we only cover the most common cases. The full logic for 0.13 may involve Load.scala (autoID) and the def default* in Build.scala - val base = StringUtilities.normalize(baseDirectory.getName) - val defaultIDs = Seq(Build.defaultID(baseDirectory), "root-" + base, base) + // This "toLowerCase" etc comes from the long deprecated "StringUtilities.normalize()" + val base = baseDirectory.getName.toLowerCase(java.util.Locale.ENGLISH).replaceAll("""\W+""", "-") + val defaultIDs = Seq(defaultID(baseDirectory), "root-" + base, base) val defaultName = "default-sbt-project" if (defaultIDs contains name) defaultName else { if (name.endsWith("-build") && base == "project" && normalizedProjectNameString(name.dropRight(6), baseDirectory.getParentFile) == defaultName) @@ -293,4 +297,4 @@ object DependencyAnalysis { log))(DBuildRunner.newState(state, extracted, prepareExtractionSettings)) } -} \ No newline at end of file +} diff --git a/proj/src/main/scala/com/typesafe/dbuild/project/build/BuildDirs.scala b/proj/src/main/scala/com/typesafe/dbuild/project/build/BuildDirs.scala index d26eeddf..6baa9124 100644 --- a/proj/src/main/scala/com/typesafe/dbuild/project/build/BuildDirs.scala +++ b/proj/src/main/scala/com/typesafe/dbuild/project/build/BuildDirs.scala @@ -1,7 +1,9 @@ package com.typesafe.dbuild.project.build import java.io.File import com.typesafe.dbuild.repo.core.GlobalDirs.buildDir -import sbt.Path._ +import com.typesafe.dbuild.adapter.Adapter +import Adapter.Path._ +import Adapter.syntaxio._ /** * dbuild-specific file names used during building. @@ -59,4 +61,4 @@ object BuildDirs { repo.mkdirs() repo } -} \ No newline at end of file +} diff --git a/proj/src/main/scala/com/typesafe/dbuild/project/build/LocalBuildRunner.scala b/proj/src/main/scala/com/typesafe/dbuild/project/build/LocalBuildRunner.scala index acf47cbb..5bd27ce4 100644 --- a/proj/src/main/scala/com/typesafe/dbuild/project/build/LocalBuildRunner.scala +++ b/proj/src/main/scala/com/typesafe/dbuild/project/build/LocalBuildRunner.scala @@ -6,7 +6,8 @@ import com.typesafe.dbuild.project.resolve.ProjectResolver import Logger.prepareLogMsg import java.io.File import com.typesafe.dbuild.repo.core._ -import sbt.Path._ +import com.typesafe.dbuild.adapter.Adapter +import Adapter.Path._ import com.typesafe.dbuild.project.dependencies.Extractor import com.typesafe.dbuild.project.cleanup.Recycling.{ updateTimeStamp, markSuccess } import com.typesafe.dbuild.project.BuildData diff --git a/proj/src/main/scala/com/typesafe/dbuild/project/dependencies/Extractor.scala b/proj/src/main/scala/com/typesafe/dbuild/project/dependencies/Extractor.scala index bd2dd0f5..2b4499f6 100644 --- a/proj/src/main/scala/com/typesafe/dbuild/project/dependencies/Extractor.scala +++ b/proj/src/main/scala/com/typesafe/dbuild/project/dependencies/Extractor.scala @@ -1,7 +1,8 @@ package com.typesafe.dbuild.project.dependencies -import sbt.IO -import sbt.Path._ +import com.typesafe.dbuild.adapter.Adapter +import Adapter.IO +import Adapter.Path._ import java.io.File import com.typesafe.dbuild.project.resolve.ProjectResolver import com.typesafe.dbuild.model.{ ProjectConfigAndExtracted, ProjectBuildConfig, ExtractedBuildMeta, SeqDepsModifiers } @@ -16,6 +17,8 @@ import com.typesafe.dbuild.project.cleanup.Recycling.{ updateTimeStamp, markSucc import com.typesafe.dbuild.model.ExtractionOK import org.apache.ivy.core.module.id.ModuleRevisionId import com.typesafe.dbuild.model.ProjectRef +import com.typesafe.dbuild.model.SeqDepsModifiersH._ +import com.typesafe.dbuild.model.SeqStringH._ /** This is used to extract dependencies from projects. */ class Extractor( diff --git a/project/Build.scala b/project/Build.scala deleted file mode 100644 index 75d2b1b2..00000000 --- a/project/Build.scala +++ /dev/null @@ -1,305 +0,0 @@ -import sbt._ -import Keys._ - -import Dependencies._ -import com.typesafe.sbt.SbtNativePackager.Universal -import com.typesafe.sbt.SbtSite.site -import com.typesafe.sbt.SbtGhPages.{ghpages, GhPagesKeys} -import com.typesafe.sbt.SbtGit.{git, GitKeys} -import com.typesafe.sbt.site.SphinxSupport -import com.typesafe.sbt.site.SphinxSupport.{ enableOutput, generatePdf, generatedPdf, generateEpub, generatedEpub, sphinxInputs, sphinxPackages, Sphinx } -import com.typesafe.sbt.S3Plugin -import net.virtualvoid.sbt.cross.CrossPlugin -import bintray.BintrayKeys._ - -object DBuilderBuild extends Build with BuildHelper { - - override def settings = super.settings ++ SbtSupport.buildSettings - - def MyVersion: String = "0.9.7-SNAPSHOT" - - lazy val root = ( - Proj("root") - aggregate(graph, hashing, logging, actorLogging, proj, actorProj, deploy, - core, plugin, build, support, supportGit, repo, metadata, docs, dist, indexmeta) - settings(publish := (), publishLocal := (), version := MyVersion) - settings(CrossPlugin.crossBuildingSettings:_*) - settings(CrossBuilding.crossSbtVersions := Seq("0.12","0.13"), selectScalaVersion) - settings(commands += Command.command("release") { state => - "clean" :: "publish" :: state - }) - ) - - lazy val dist = ( - Proj("dist") - /*, eclipse plugin bombs if we do this: settings = Packaging.settings */ - settings(Packaging.settings:_*) - settings( - mappings in Universal <+= (target, sourceDirectory, scalaVersion in build, version in build) map Packaging.makeDBuildProps, - mappings in Universal <+= (target, sourceDirectory, scalaVersion in repo, version in repo) map Packaging.makeDRepoProps, - version := MyVersion, - selectScalaVersion, - // disable the publication of artifacts in dist if 2.10 - // (we only retain the correct launcher, which is the - // one generated using 2.9) - // This is a pretty ugly hack, but it is quite difficult to prevent sbt from - // skipping publishing completely (including the ivy file) upon a given condition. - publishConfiguration <<= (publishConfiguration,scalaVersion) map { (p,sv) => - if (sv.startsWith("2.10")) new sbt.PublishConfiguration(None,p.resolverName,Map.empty,Seq.empty,p.logging) else p} - ) - ) - - // The component projects... - lazy val graph = ( - Proj("graph") - ) - lazy val hashing = ( - Proj("hashing") - dependsOnRemote(typesafeConfig) - ) - lazy val deploy = ( - Proj("deploy") - dependsOnRemote(jacks, jackson, typesafeConfig, commonsLang, aws, uriutil, dispatch, commonsIO, jsch) - dependsOnSbt(sbtLogging, sbtIo) - ) - - lazy val indexmeta = ( - Proj("indexmeta") - ) - - lazy val metadata = ( - Proj("metadata") - dependsOn(graph, hashing, indexmeta, deploy) - dependsOnRemote(jacks, jackson, typesafeConfig, /*sbtCollections,*/ commonsLang) - ) - - lazy val logging = ( - Proj("logging") - dependsOn(graph) - dependsOnSbt(sbtLogging, sbtIo, sbtLaunchInt) - ) - lazy val actorLogging = ( - Proj("actorLogging") - dependsOn(logging) - dependsOnAkka() - dependsOnSbt(sbtLogging, sbtIo, sbtLaunchInt) - settings(skip210:_*) - ) - lazy val core = ( - Proj("core") - dependsOnRemote(javaMail) - dependsOn(metadata, graph, hashing, logging, repo) - dependsOnSbt(sbtIo) - ) - lazy val proj = ( - Proj("proj") - dependsOn(core, repo, logging) - dependsOnRemote(javaMail, commonsIO) - dependsOnSbt(sbtIo, sbtIvy) - ) - lazy val actorProj = ( - Proj("actorProj") - dependsOn(core, actorLogging, proj) - dependsOnSbt(sbtIo, sbtIvy) - settings(skip210:_*) - ) - lazy val repo = ( - Proj("repo") - dependsOn(metadata, logging) - dependsOnRemote(mvnAether, dispatch, aether, aetherApi, aetherSpi, aetherUtil, aetherImpl, aetherConnectorBasic, aetherFile, aetherHttp, aetherWagon, mvnAether) - dependsOnSbt(sbtIo, sbtLaunchInt) - settings(sourceGenerators in Compile <+= (sourceManaged in Compile, version, organization, scalaVersion, streams) map { (dir, version, org, sv, s) => - val file = dir / "Defaults.scala" - if(!dir.isDirectory) dir.mkdirs() - s.log.info("Generating \"Defaults.scala\" for sbt "+sbtVer(sv)+" and Scala "+sv) - IO.write(file, """ -package com.typesafe.dbuild.repo.core - -object Defaults { - val version = "%s" - val org = "%s" - val hash = "%s" -} -""" format (version, org, Process("git log --pretty=format:%H -n 1").lines.head)) - Seq(file) - }) - ) - lazy val build = ( - Proj("build") - dependsOn(actorProj, support, supportGit, repo, metadata, deploy, proj) - dependsOnRemote(aws, uriutil, dispatch, gpgLib, jsch, oro, scallop, commonsLang) - dependsOnSbt(sbtLaunchInt, sbtLauncher) - settings(skip210:_*) - settings(SbtSupport.settings:_*) - settings( - // We hook the testLoader of it to make sure all the it tasks have a legit sbt plugin to use. - // Technically, this just pushes every project. We could outline just the plugin itself, but for now - // we don't care that much. - testLoader in IntegrationTest := { - val ignore = publishLocal.all(ScopeFilter(inAggregates(LocalRootProject, includeRoot=false))).value - (testLoader in IntegrationTest).value - }, - parallelExecution in IntegrationTest := false - ) - ) - - lazy val support = ( - Proj("support") - dependsOn(core, repo, metadata, proj % "compile->compile;it->compile", logging % "it") - dependsOnRemote(mvnEmbedder, mvnWagon, javaMail, aether, aetherApi, aetherSpi, aetherUtil, aetherImpl, aetherConnectorBasic, aetherFile, aetherHttp, slf4jSimple) - dependsOnSbt(sbtLaunchInt, sbtIvy) - settings(SbtSupport.settings:_*) - settings( - // We hook the testLoader of it to make sure all the it tasks have a legit sbt plugin to use. - // Technically, this just pushes every project. We could outline just the plugin itself, but for now - // we don't care that much. - testLoader in IntegrationTest := { - val ignore = publishLocal.all(ScopeFilter(inAggregates(LocalRootProject, includeRoot=false))).value - (testLoader in IntegrationTest).value - }, - parallelExecution in IntegrationTest := false - ) - ) - // A separate support project for git/jgit - lazy val supportGit = ( - Proj("supportGit") - dependsOn(core, repo, metadata, proj, support) - dependsOnRemote(mvnEmbedder, mvnWagon, javaMail, jgit) - dependsOnSbt(sbtLaunchInt, sbtIvy) - settings(SbtSupport.settings:_*) - settings(skip210:_*) - ) - - // SBT plugin - lazy val plugin = ( - Proj("plugin") - settings(sbtPlugin := true) - dependsOn(support, metadata) - settings(sourceGenerators in Compile <+= (sourceManaged in Compile, scalaVersion, streams) map { (dir, sv, s) => - val file = dir / "Update.scala" - if(!dir.isDirectory) dir.mkdirs() - s.log.info("Generating \"Update.scala\" for sbt "+sbtVer(sv)+" and Scala "+sv) - val where = if (sbtVer(sv).startsWith("0.12")) "Project" else "Def" - IO.write(file, """ -package com.typesafe.dbuild.plugin -object SbtUpdate { -def update[T]: (sbt.%s.ScopedKey[T]) => (T => T) => sbt.%s.Setting[T] = sbt.%s.update[T] -} -""" format (where, where, where)) - Seq(file) - }, - CrossBuilding.crossSbtVersions := Seq("0.12","0.13") - ) - settings(CrossPlugin.crossBuildingSettings:_*) - ) -} - - - -// Additional DSL -trait BuildHelper extends Build { - - def MyVersion: String - - // for dependencies - def sbtVer(scalaVersion:String) = if (scalaVersion.startsWith("2.9")) sbtVersion12 else sbtVersion13 - - def selectScalaVersion = - scalaVersion <<= (sbtVersion in sbtPlugin).apply( sb => if (sb.startsWith("0.12")) "2.9.2" else "2.10.2" ) - - def skip210 = - Seq(skip in compile <<= scalaVersion.map(_.startsWith("2.10")), - sources in doc in Compile <<= (sources in doc in Compile,skip in compile).map( (c,s) => - if(s) List() else c ) ) - - def defaultDSettings: Seq[Setting[_]] = Seq( - version := MyVersion, - organization := "com.typesafe.dbuild", - selectScalaVersion, - libraryDependencies += specs2, - resolvers += Resolver.typesafeIvyRepo("releases"), - resolvers += "Typesafe Repository" at "http://repo.typesafe.com/typesafe/releases/", - publishMavenStyle := false - ) - /** Create a project. */ - def Proj(name: String) = ( - Project(name, file(if (name=="root") "." else name)) - configs( IntegrationTest ) - settings( Defaults.itSettings : _*) - settings(defaultDSettings:_*) - settings( - licenses += ("Apache 2", url("http://www.apache.org/licenses/LICENSE-2.0")) - ) - settings( - bintrayReleaseOnPublish := false, - licenses += ("Apache-2.0", url("http://opensource.org/licenses/Apache-2.0")), - bintrayOrganization := Some("typesafe"), - bintrayRepository := "ivy-releases", - bintrayPackage := "dbuild" - ) - ) - - // DSL for adding remote deps like local deps. - implicit def p2remote(p: Project): RemoteDepHelper = new RemoteDepHelper(p) - class RemoteDepHelper(p: Project) { - def dependsOnRemote(ms: ModuleID*): Project = p.settings(libraryDependencies ++= ms) - def dependsOnSbt(ms: (String=>ModuleID)*): Project = p.settings(libraryDependencies <++= (scalaVersion) {sv => ms map {_(sbtVer(sv))}}) - def dependsOnAkka(): Project = p.settings(libraryDependencies <+= (scalaVersion) {sv => if (sv.startsWith("2.9")) akkaActor29 else akkaActor210}) - } - - lazy val docs = (Proj("docs") - settings(defaultDSettings ++ site.settings ++ site.sphinxSupport() ++ - ghpages.settings ++ Seq( -// enableOutput in generatePdf in Sphinx := true, -// enableOutput in generateEpub in Sphinx := true, - git.remoteRepo := "git@github.com:typesafehub/dbuild.git", - GhPagesKeys.synchLocal <<= Docs.synchLocalImpl, - publish := (), - publishLocal := () - ):_*)) - - - // based on the related sbt source code - object Docs { - val VersionPattern = """(\d+)\.(\d+)\.(\d+)(-.+)?""".r.pattern - - def synchLocalImpl = (mappings in GhPagesKeys.synchLocal, GhPagesKeys.updatedRepository, version, isSnapshot, streams) map { - (mappings, repo, v, snap, s) => - val versioned = repo / v - if(snap) { - s.log.info("Replacing docs for previous snapshot in: " + versioned.getAbsolutePath) - IO.delete(versioned) - } else if(versioned.exists) { - s.log.warn("Site for " + v + " was already in: " + versioned.getAbsolutePath) - s.log.info("Replacing previous docs...") - IO.delete(versioned) - } - IO.copy(mappings map { case (file, target) => (file, versioned / target) }) - IO.touch(repo / ".nojekyll") - IO.write(repo / "versions.js", versionsJs(sortVersions(collectVersions(repo)))) - if (!snap) IO.write(repo / "index.html", - """| - |