diff options
Diffstat (limited to 'src/main/scala')
-rw-r--r-- | src/main/scala/xyz.driver.sbt/IntegrationTestPackaging.scala | 44 | ||||
-rw-r--r-- | src/main/scala/xyz.driver.sbt/Library.scala | 31 | ||||
-rw-r--r-- | src/main/scala/xyz.driver.sbt/Linting.scala | 82 | ||||
-rw-r--r-- | src/main/scala/xyz.driver.sbt/SbtSettings.scala | 390 | ||||
-rw-r--r-- | src/main/scala/xyz.driver.sbt/Service.scala | 75 | ||||
-rw-r--r-- | src/main/scala/xyz.driver.sbt/Versioning.scala | 31 |
6 files changed, 229 insertions, 424 deletions
diff --git a/src/main/scala/xyz.driver.sbt/IntegrationTestPackaging.scala b/src/main/scala/xyz.driver.sbt/IntegrationTestPackaging.scala index 7f0c557..c89dcec 100644 --- a/src/main/scala/xyz.driver.sbt/IntegrationTestPackaging.scala +++ b/src/main/scala/xyz.driver.sbt/IntegrationTestPackaging.scala @@ -2,23 +2,18 @@ package xyz.driver.sbt import java.nio.file._ -import scala.collection.JavaConverters._ - -import com.lucidchart.sbt.scalafmt.ScalafmtCorePlugin.autoImport._ -import com.typesafe.sbt.packager._ import com.typesafe.sbt.packager.Keys._ -import com.typesafe.sbt.packager.docker._ import com.typesafe.sbt.packager.docker.DockerPlugin.autoImport.Docker -import com.typesafe.sbt.packager.universal._ import com.typesafe.sbt.packager.universal.UniversalPlugin.autoImport._ -import sbt._ -import sbt.plugins._ import sbt.Keys._ +import sbt._ + +import scala.collection.JavaConverters._ object IntegrationTestPackaging extends AutoPlugin { - override def requires = UniversalPlugin && DockerPlugin - override def trigger = AllRequirements + override def requires = Service + override def trigger = allRequirements object autoImport { lazy val IntegrationTest = config("it") extend (Test) // make test classes available @@ -26,11 +21,11 @@ object IntegrationTestPackaging extends AutoPlugin { import autoImport._ private def list(base: Path): Seq[(Path, String)] = base match { - case _ if Files.isRegularFile(base) => Seq(base -> base.getFileName.toString) case _ if Files.isDirectory(base) => Files.walk(base).iterator().asScala.toSeq.map { file => file -> base.relativize(file).toString } + case file => Seq(file -> file.getFileName.toString) } private def configurationSettings = @@ -39,21 +34,8 @@ object IntegrationTestPackaging extends AutoPlugin { ivyConfigurations := overrideConfigs(IntegrationTest)(ivyConfigurations.value) ) - private def formatSettings = - inConfig(IntegrationTest)(scalafmtSettings) ++ - Seq( - scalafmt in Test := { - (scalafmt in Test).dependsOn(scalafmt in IntegrationTest).value - }, - // test:scalafmt::test -> tests scalafmt format in src/test + src/it - test in scalafmt in Test := { - (test in scalafmt in Test).dependsOn(test in scalafmt in IntegrationTest).value - } - ) - override def projectSettings = configurationSettings ++ - formatSettings ++ Seq( mappings in Universal ++= { val cp: Seq[(File, String)] = (dependencyClasspath in IntegrationTest).value @@ -94,16 +76,10 @@ object IntegrationTestPackaging extends AutoPlugin { cp ++ tests ++ Seq(scriptFile -> s"bin/${normalizedName.value}-it") }, - dockerCommands in Docker := { - (dockerCommands in Docker).value ++ Seq( - ExecCmd("RUN", "mkdir", "-p", "/test"), - ExecCmd("RUN", - "ln", - "-s", - s"${(defaultLinuxInstallLocation in Docker).value}/bin/${normalizedName.value}-it", - "/test/run_integration_test.sh") - ) - } + Service.autoImport.customCommands := List( + "mkdir -p test", + s"ln -s ${(defaultLinuxInstallLocation in Docker).value}/bin/${normalizedName.value}-it /test/run_integration_test.sh" + ) ) } diff --git a/src/main/scala/xyz.driver.sbt/Library.scala b/src/main/scala/xyz.driver.sbt/Library.scala new file mode 100644 index 0000000..4a5dc7c --- /dev/null +++ b/src/main/scala/xyz.driver.sbt/Library.scala @@ -0,0 +1,31 @@ +package xyz.driver.sbt + +import sbt.Keys._ +import sbt._ +import sbt.plugins.JvmPlugin + +/** Common settings for a library, Driver style. */ +object Library extends AutoPlugin { + + override def requires = JvmPlugin + + lazy val repositorySettings: Seq[Setting[_]] = Seq( + resolvers += "releases" at "https://drivergrp.jfrog.io/drivergrp/releases", + resolvers += "snapshots" at "https://drivergrp.jfrog.io/drivergrp/snapshots" + ) + + lazy val publicationSettings: Seq[Setting[_]] = Seq( + publishTo := { + val jfrog = "https://drivergrp.jfrog.io/drivergrp/" + if (isSnapshot.value) Some("snapshots" at jfrog + "snapshots;build.timestamp=" + new java.util.Date().getTime) + else Some("releases" at jfrog + "releases") + } + ) + + override def projectSettings: Seq[Def.Setting[_]] = repositorySettings ++ publicationSettings ++ Seq( + javacOptions ++= Seq("-target", "1.8"), + crossScalaVersions := List("2.12.6"), + scalaVersion := crossScalaVersions.value.last + ) + +} diff --git a/src/main/scala/xyz.driver.sbt/Linting.scala b/src/main/scala/xyz.driver.sbt/Linting.scala new file mode 100644 index 0000000..8a293b6 --- /dev/null +++ b/src/main/scala/xyz.driver.sbt/Linting.scala @@ -0,0 +1,82 @@ +package xyz.driver.sbt + +import com.lucidchart.sbt.scalafmt.ScalafmtCorePlugin.autoImport.{scalafmtConfig, _} +import com.lucidchart.sbt.scalafmt.ScalafmtPlugin +import org.scalastyle.sbt.ScalastylePlugin +import org.scalastyle.sbt.ScalastylePlugin.autoImport.{scalastyle, scalastyleConfig} +import sbt.Keys._ +import sbt._ + +import scala.collection.JavaConverters._ + +/** Enforces common formatting and catches compiler warnings. */ +object Linting extends AutoPlugin { + + override def requires = ScalafmtPlugin && ScalastylePlugin + override def trigger = allRequirements + + lazy val formatSettings: Seq[Def.Setting[_]] = Seq( + scalafmtConfig := { + val packaged = getClass.getClassLoader.getResourceAsStream("scalafmt.conf") + val out = file(".scalafmt.conf") + IO.write(out, IO.readBytes(packaged)) + out + }, + scalafmtTestOnCompile in Test := true + ) + + lazy val scalastyleSettings: Seq[Def.Setting[_]] = Seq( + scalastyleConfig := { + val stream = getClass.getClassLoader.getResourceAsStream("scalastyle-config.xml") + val out = file(".scalastyle-config.xml") + IO.write(out, IO.readBytes(stream)) + out + }, + test in Test := (test in Test).dependsOn((scalastyle in Test).toTask("")).value + ) + + lazy val scalacSettings: Seq[Def.Setting[_]] = Seq( + scalacOptions in Compile ++= Seq( + "-language:higherKinds", + "-language:implicitConversions", + "-language:postfixOps", + "-language:reflectiveCalls", // TODO this should be discouraged + "-unchecked", + "-deprecation", + "-feature", + "-encoding", + "utf8", + "-Xlint:_,-unused,-missing-interpolator", + "-Ywarn-numeric-widen", + "-Ywarn-dead-code", + "-Ywarn-unused:_,-explicits,-implicits" + ), + // Currently, scalac does not provide a way to fine-tune the treating of + // warnings as errors. Either all are considered errors + // (with -Xfatal-warnings), or none are. This hack analyzes the compiler's + // output and treats all warnings as errors, except for deprecations. + compile in Compile := { + val log = streams.value.log + val compiled = (compile in Compile).value + val problems = compiled.readSourceInfos().getAllSourceInfos.asScala.flatMap { + case (_, info) => info.getReportedProblems + } + var deprecationsOnly = true + problems.foreach { problem => + if (!problem.message().contains("is deprecated")) { + deprecationsOnly = false + log.error(s"[fatal warning] ${problem.message()}") + } + } + if (!deprecationsOnly) + throw new FatalWarningsException("Fatal warnings: some warnings other than deprecations were found.") + compiled + } + ) + + lazy val lintSettings = formatSettings ++ scalastyleSettings ++ scalacSettings + + override def projectSettings: Seq[Def.Setting[_]] = inConfig(Compile)(lintSettings) ++ inConfig(Test)(lintSettings) + +} +case class FatalWarningsException(message: String) extends Exception(message) diff --git a/src/main/scala/xyz.driver.sbt/SbtSettings.scala b/src/main/scala/xyz.driver.sbt/SbtSettings.scala deleted file mode 100644 index 96ee267..0000000 --- a/src/main/scala/xyz.driver.sbt/SbtSettings.scala +++ /dev/null @@ -1,390 +0,0 @@ -package xyz.driver.sbt - -import com.lucidchart.sbt.scalafmt.ScalafmtCorePlugin.autoImport._ -import com.typesafe.sbt.SbtGit.git -import com.typesafe.sbt.SbtNativePackager.autoImport._ -import com.typesafe.sbt.packager.archetypes._ -import com.typesafe.sbt.packager.docker.Cmd -import com.typesafe.sbt.packager.docker.DockerPlugin.autoImport._ -import com.typesafe.sbt.{GitBranchPrompt, GitVersioning} -import org.scalastyle.sbt.ScalastylePlugin.autoImport._ -import sbt.Keys._ -import sbt.{Project, State, _} -import sbtassembly.AssemblyKeys._ -import sbtassembly._ -import sbtbuildinfo.BuildInfoPlugin -import sbtbuildinfo.BuildInfoPlugin.autoImport.{BuildInfoKey, BuildInfoOption, _} -import sbtrelease.ReleasePlugin.autoImport.ReleaseKeys._ -import sbtrelease.ReleasePlugin.autoImport.ReleaseTransformations._ -import sbtrelease.ReleasePlugin.autoImport._ -import sbtrelease.{Version, _} -import scala.collection.JavaConverters._ -import IntegrationTestPackaging.autoImport.IntegrationTest - -// we hide the existing definition for setReleaseVersion to replace it with our own -import sbtrelease.ReleaseStateTransformations.{setReleaseVersion => recordReleaseVersion, inquireVersions => _} - -/** - * @see https://engineering.sharethrough.com/blog/2015/09/23/capturing-common-config-with-an-sbt-parent-plugin/ - */ -object SbtSettings extends AutoPlugin { - - val JMX_PORT = 8686 - - object autoImport { - lazy val formatSettings = { - val generateScalafmtConfTask = Def.task { - val scalafmtConfStream = getClass.getClassLoader.getResourceAsStream("scalafmt.conf") - val formatConfFile = file(".scalafmt.conf") - IO.write(formatConfFile, IO.readBytes(scalafmtConfStream)) - formatConfFile - } - - Seq( - scalafmtConfig := generateScalafmtConfTask.value, - scalafmt in Compile := { - (scalafmt in Compile).dependsOn(scalafmt in Test).value - }, - // scalafmt::test -> tests scalafmt format in src/main + src/test (added behavior) - test in scalafmt in Compile := { - (test in scalafmt in Compile).dependsOn(test in scalafmt in Test).value - }, - test in Test := { - (test in scalafmt in Compile).value - (test in Test).value - } - ) - } - - lazy val testScalastyle = taskKey[Unit]("testScalastyle") - - lazy val scalastyleSettings = { - val generateScalastyleConfTask = Def.task { - val stream = getClass.getClassLoader.getResourceAsStream("scalastyle-config.xml") - val styleFile = file("scalastyle-config.xml") - IO.write(styleFile, IO.readBytes(stream)) - Seq(styleFile) - } - Seq( - resourceGenerators in Compile += generateScalastyleConfTask.taskValue, - scalastyleConfig := file("scalastyle-config.xml"), - testScalastyle := scalastyle.in(Compile).toTask("").value, - testScalastyle in (Test, test) := { - generateScalastyleConfTask.value - (testScalastyle in (Test, test)).value - }, - testExecution in (Test, test) := { - generateScalastyleConfTask.value - (testScalastyle in Compile).value - (testScalastyle in Test).value - (testExecution in (Test, test)).value - } - ) - } - - val scalacLintingSettings = Seq( - scalacOptions ++= { - Seq( - "-Xlint:_,-unused,-missing-interpolator", - "-Ywarn-numeric-widen", - "-Ywarn-dead-code", - "-Ywarn-unused:_,-explicits,-implicits" - ) - }, - compile in Compile := { - val compiled = (compile in Compile).value - val problems = compiled.readSourceInfos().getAllSourceInfos.asScala.flatMap { - case (_, info) => - info.getReportedProblems - } - - val deprecationsOnly = problems.forall { problem => - problem.message().contains("is deprecated") - } - - if (!deprecationsOnly) sys.error("Fatal warnings: some warnings other than deprecations were found.") - compiled - } - ) - - lazy val lintingSettings = scalacLintingSettings ++ scalastyleSettings - - lazy val repositoriesSettings: Seq[Setting[_]] = { - Seq( - resolvers += "releases" at "https://drivergrp.jfrog.io/drivergrp/releases", - resolvers += "snapshots" at "https://drivergrp.jfrog.io/drivergrp/snapshots" - ) - } - - lazy val publicationSettings: Seq[Setting[_]] = Seq( - publishTo := { - val jfrog = "https://drivergrp.jfrog.io/drivergrp/" - - if (isSnapshot.value) Some("snapshots" at jfrog + "snapshots;build.timestamp=" + new java.util.Date().getTime) - else Some("releases" at jfrog + "releases") - } - ) - - private def setVersionOnly(selectVersion: Versions => String): ReleaseStep = { st: State => - val vs = st - .get(ReleaseKeys.versions) - .getOrElse(sys.error("No versions are set! Was this release part executed before inquireVersions?")) - val selected = selectVersion(vs) - - st.log.info("Setting version to '%s'." format selected) - val useGlobal = Project.extract(st).get(releaseUseGlobalVersion) - - reapply(Seq( - if (useGlobal) version in ThisBuild := selected else version := selected - ), - st) - } - - lazy val setReleaseVersion: ReleaseStep = setVersionOnly(_._1) - - // Remove the prompt for next version - lazy val inquireVersions: ReleaseStep = { st: State => - val extracted = Project.extract(st) - - val useDefs = st.get(useDefaults).getOrElse(false) - val currentV = extracted.get(version) - - val (_, releaseFunc) = extracted.runTask(releaseVersion, st) - val suggestedReleaseV = releaseFunc(currentV) - - // flatten the Option[Option[String]] as the get returns an Option, and the value inside is an Option - val releaseV = - readVersion(suggestedReleaseV, "Release version [%s] : ", useDefs, st.get(commandLineReleaseVersion).flatten) - val nextV = releaseV - - st.put(versions, (releaseV, nextV)) - - } - - def ServiceReleaseProcess = { - Seq[ReleaseStep]( - checkSnapshotDependencies, - inquireVersions, - runTest, - recordReleaseVersion, // set release version and persistent in version.sbt - commitReleaseVersion, // performs the initial git checks - tagRelease, - pushChanges // also checks that an upstream branch is properly configured - ) - } - - def LibraryReleaseProcess = { - Seq[ReleaseStep]( - checkSnapshotDependencies, - inquireVersions, - setReleaseVersion, - runTest, - tagRelease, - publishArtifacts, - pushChanges // also checks that an upstream branch is properly configured - ) - } - - def releaseSettings(releaseProcessSteps: Seq[ReleaseStep]): Seq[Setting[_]] = { - - val showReleaseVersion = taskKey[String]("the future version once releaseNextVersion has been applied to it") - Seq( - releaseCrossBuild := true, - releaseIgnoreUntrackedFiles := true, - // Check http://blog.byjean.eu/2015/07/10/painless-release-with-sbt.html for details - releaseVersionBump := sbtrelease.Version.Bump.Bugfix, - releaseVersion := { - case ver @ snapshotVersion if snapshotVersion.endsWith("-SNAPSHOT") => - Version(ver).map(_.withoutQualifier.string).getOrElse(versionFormatError) - case ver => - Version(ver).map(_.bumpBugfix.withoutQualifier.string).getOrElse(versionFormatError) - }, - showReleaseVersion := { - releaseVersion.value(version.value) - }, - releaseProcess := releaseProcessSteps - ) - } - - implicit class driverConfigurations(project: Project) { - - def gitPluginConfiguration: Project = { - val VersionRegex = "v([0-9]+.[0-9]+.[0-9]+)-?(.*)?".r - - project - .enablePlugins(GitVersioning, GitBranchPrompt) - .settings( - git.useGitDescribe := true, - git.baseVersion := "0.0.0", - git.gitTagToVersionNumber := { - case VersionRegex(v, "SNAPSHOT") => // There are not committed changes at tagged commit - val ver = Version(v) - .map(_.withoutQualifier) - .map(_.bump(sbtrelease.Version.Bump.Bugfix).string) - .getOrElse(versionFormatError) - - Some(s"$ver-SNAPSHOT") - - case VersionRegex(v, "") => - Some(v) - - case VersionRegex(v, s) => // Commit is ahead of the last tagged commit - val ver = Version(v) - .map(_.withoutQualifier) - .map(_.bump(sbtrelease.Version.Bump.Bugfix).string) - .getOrElse(versionFormatError) - - Some(s"$ver-$s-SNAPSHOT") - - case _ => None - } - ) - } - - def buildInfoConfiguration(packageName: String = "xyz.driver"): Project = { - project - .enablePlugins(BuildInfoPlugin) - .settings( - buildInfoKeys := Seq[BuildInfoKey](name, version, scalaVersion, sbtVersion, git.gitHeadCommit), - buildInfoPackage := packageName, - buildInfoOptions += BuildInfoOption.BuildTime - ) - } - - def packagingConfiguration: Project = { - project - .settings( // for assembly plugin - test in assembly := {}, - assemblyMergeStrategy in assembly := { - case PathList("org", "slf4j", "impl", xs @ _*) => MergeStrategy.first - case "logback.xml" => MergeStrategy.first - case strategy: String => - val oldStrategy = (assemblyMergeStrategy in assembly).value - oldStrategy(strategy) - } - ) - } - - def dockerConfiguration(imageName: String, - repository: String, - exposedPorts: Seq[Int], - baseImage: String = "java:8", - customCommands: List[String] = List.empty[String], - aggregateSubprojects: Boolean = false): Project = { - import com.typesafe.sbt.packager.Keys._ - - project - .enablePlugins(JavaAppPackaging) - .settings( - // Settings reference http://www.scala-sbt.org/sbt-native-packager/formats/docker.html - packageName in Docker := imageName, - version in Docker := version.value.stripSuffix("-SNAPSHOT"), - dockerRepository := Some(repository), - maintainer := "Driver Inc. <info@driver.xyz>", - dockerUpdateLatest := true, // to automatic update the latest tag - dockerExposedPorts := exposedPorts, - dockerBaseImage := baseImage, - daemonUser in Docker := "root", - dockerCommands := dockerCommands.value - .flatMap { // @see http://blog.codacy.com/2015/07/16/dockerizing-scala/ - case cmd @ Cmd("FROM", _) => cmd :: customCommands.map(customCommand => Cmd("RUN", customCommand)) - case other => List(other) - }, - aggregate in Docker := aggregateSubprojects // to include subprojects - ) - - // And then you can run "sbt docker:publish" - } - - def deploymentConfiguration(imageName: String, - exposedPorts: Seq[Int] = Seq(8080), - clusterName: String = "sand-uw1a-1", - clusterZone: String = "us-west1-a", - gCloudProject: String = "driverinc-sandbox", - baseImage: String = "java:8", - dockerCustomCommands: List[String] = List.empty[String], - aggregateSubprojects: Boolean = false) = { - - val repositoryName = "gcr.io/" + gCloudProject - - val keytoolCommand = - "keytool -import -alias driverincInternal -keystore $JAVA_HOME/jre/lib/security/cacerts " + - s"-file /etc/$imageName/ssl/issuing_ca -storepass changeit -noprompt" - - // If issuing_ca exists, import it into the internal default ca store - val importTrustStoreCommand = - s"if [ -f /etc/$imageName/ssl/issuing_ca ] ; then " + keytoolCommand + "; else echo \"No truststore customization.\"; fi" - - val dockerCommands = dockerCustomCommands // :+ importTrustStoreCommand - - val allExposedPorts = exposedPorts ++ Seq(JMX_PORT) - - dockerConfiguration(imageName, repositoryName, allExposedPorts, baseImage, dockerCommands, aggregateSubprojects) - .settings(NativePackagerKeys.bashScriptExtraDefines += importTrustStoreCommand) - .settings(NativePackagerKeys.bashScriptExtraDefines ++= Seq( - """addJava "-Dcom.sun.management.jmxremote"""", - s"""addJava "-Dcom.sun.management.jmxremote.port=$JMX_PORT"""", - """addJava "-Dcom.sun.management.jmxremote.local.only=false"""", - """addJava "-Dcom.sun.management.jmxremote.authenticate=false"""", - """addJava "-Dcom.sun.management.jmxremote.ssl=false"""" - )) - } - - def driverLibrary(libraryName: String): Project = { - project - .settings(name := libraryName) - .gitPluginConfiguration - .settings(repositoriesSettings ++ publicationSettings ++ releaseSettings(LibraryReleaseProcess)) - } - - def driverService(appName: String, - exposedPorts: Seq[Int] = Seq(8080), - clusterName: String = "sand-uw1a-1", - clusterZone: String = "us-west1-a", - gCloudProject: String = "driverinc-sandbox", - baseImage: String = "java:8", - dockerCustomCommands: List[String] = List.empty[String], - aggregateSubprojects: Boolean = false): Project = { - project - .settings(name := appName) - .settings(repositoriesSettings ++ releaseSettings(ServiceReleaseProcess)) - .buildInfoConfiguration() - .deploymentConfiguration(appName, - exposedPorts, - clusterName, - clusterZone, - gCloudProject, - baseImage, - dockerCustomCommands, - aggregateSubprojects) - } - } - } - - val scalacDefaultOptions = Seq("-unchecked", "-deprecation", "-feature", "-Xlint", "-encoding", "utf8") - - val scalacLanguageFeatures = Seq( - "-language:higherKinds", - "-language:implicitConversions", - "-language:postfixOps", - "-language:reflectiveCalls" - ) - - override def trigger: PluginTrigger = allRequirements - override def projectSettings: Seq[Setting[_]] = Seq( - organization := "xyz.driver", - crossScalaVersions := List("2.12.4"), - scalaVersion := crossScalaVersions.value.last, - scalacOptions := (scalacDefaultOptions ++ scalacLanguageFeatures), - scalacOptions in (Compile, console) := (scalacDefaultOptions ++ scalacLanguageFeatures), - scalacOptions in (Compile, consoleQuick) := (scalacDefaultOptions ++ scalacLanguageFeatures), - scalacOptions in (Compile, consoleProject) := (scalacDefaultOptions ++ scalacLanguageFeatures), - version := { - // Sbt release versioning based on git given double -SNAPSHOT suffix - // if current commit is not tagged AND there are uncommitted changes (e.g., some file is modified), - // this setting fixes that, by just removing double -SNAPSHOT if it happened somehow - Option(version.value).map(vv => vv.replaceAll("-SNAPSHOT-SNAPSHOT", "-SNAPSHOT")).getOrElse("0.0.0") - }, - fork := true - ) -} diff --git a/src/main/scala/xyz.driver.sbt/Service.scala b/src/main/scala/xyz.driver.sbt/Service.scala new file mode 100644 index 0000000..a0186e6 --- /dev/null +++ b/src/main/scala/xyz.driver.sbt/Service.scala @@ -0,0 +1,75 @@ +package xyz.driver.sbt + +import com.typesafe.sbt.GitPlugin.autoImport._ +import com.typesafe.sbt.packager.Keys.{ + dockerBaseImage => _, + dockerCommands => _, + dockerExposedPorts => _, + dockerRepository => _, + dockerUpdateLatest => _, + _ +} +import com.typesafe.sbt.packager.archetypes.JavaAppPackaging +import com.typesafe.sbt.packager.docker.DockerPlugin.autoImport._ +import com.typesafe.sbt.packager.docker.{Cmd, DockerPlugin} +import sbt.Keys._ +import sbt.{Def, _} +import sbtbuildinfo.BuildInfoPlugin +import sbtbuildinfo.BuildInfoPlugin.autoImport._ + +/** Common settings to a service. */ +object Service extends AutoPlugin { + + override def requires = BuildInfoPlugin && DockerPlugin && JavaAppPackaging + + object autoImport { + val customCommands = taskKey[List[String]]("Additional commands that are run as part of docker packaging.") + } + import autoImport._ + + lazy val buildInfoSettings = Seq( + buildInfoKeys := Seq[BuildInfoKey](name, version, scalaVersion, sbtVersion, git.gitHeadCommit), + buildInfoPackage := organization.value, + buildInfoOptions += BuildInfoOption.BuildTime + ) + + lazy val dockerSettings = Seq( + name in Docker := name.value, + // Settings reference http://www.scala-sbt.org/sbt-native-packager/formats/docker.html + maintainer in Docker := "Driver Inc. <info@driver.xyz>", + aggregate in Docker := true, // include subprojects, + dockerRepository := Some("gcr.io/driverinc-sandbox"), + dockerUpdateLatest := true, // automatically update the latest tag + dockerBaseImage := "openjdk:10", + dockerCommands := dockerCommands.value.flatMap { // @see http://blog.codacy.com/2015/07/16/dockerizing-scala/ + case cmd @ Cmd("FROM", _) => cmd :: customCommands.value.map(customCommand => Cmd("RUN", customCommand)) + case other => List(other) + }, + bashScriptExtraDefines += { + s"""|if [[ -f /etc/${name.value}/ssl/issuing_ca ]]; then + | keytool -import \ + | -alias driverincInternal \ + | -keystore $$JAVA_HOME/jre/lib/security/cacerts \ + | -file /etc/${name.value}/ssl/issuing_ca \ + | -storepass changeit -noprompt + |else + | echo "No truststore customization." >&2 + |fi + |""".stripMargin + } + ) + + override def projectSettings: Seq[Def.Setting[_]] = + Library.repositorySettings ++ buildInfoSettings ++ dockerSettings ++ Seq( + crossScalaVersions := List("2.12.6"), + scalaVersion := crossScalaVersions.value.last, + publish := { + streams.value.log.warn(s"Service ${name.value} won't be published.") + } + ) + + override def buildSettings: Seq[Def.Setting[_]] = + addCommandAlias("start", "reStart") ++ + addCommandAlias("stop", "reStop") + +} diff --git a/src/main/scala/xyz.driver.sbt/Versioning.scala b/src/main/scala/xyz.driver.sbt/Versioning.scala new file mode 100644 index 0000000..fe3a218 --- /dev/null +++ b/src/main/scala/xyz.driver.sbt/Versioning.scala @@ -0,0 +1,31 @@ +package xyz.driver.sbt + +import com.typesafe.sbt.GitPlugin +import com.typesafe.sbt.SbtGit.git +import sbt.Keys._ +import sbt.plugins.JvmPlugin +import sbt.{AutoPlugin, _} + +object Versioning extends AutoPlugin { + + override def requires = JvmPlugin + override def trigger = allRequirements + + // Get version from git unless a VERSION environment variable is set + lazy val versionSettings: Seq[Setting[_]] = sys.env.get("VERSION") match { + case None => + GitPlugin.autoImport.versionWithGit ++ Seq( + git.useGitDescribe := true, // get version from git + git.baseVersion := "0.0.0" // this version is used for new projects without any commits + ) + case Some(v) => + Seq( + version := v + ) + } + + override def buildSettings = versionSettings ++ Seq( + organization := "xyz.driver" + ) + +} |