diff --git a/project/BasicSettings.scala b/project/BasicSettings.scala index df74316..8d88582 100644 --- a/project/BasicSettings.scala +++ b/project/BasicSettings.scala @@ -15,14 +15,19 @@ sealed trait Basics { final val githubProject = "scalafx-utils" final val projectDescription = "ScalaFX Utilities" final val projectStartYear = 2015 + final val projectHomepage = None final val buildScalaVersion = "2.12.3" final val extraScalaVersions = Seq("2.11.11") final val minimumJavaVersion = "1.8" - final val defaultOptimize = false + final val defaultOptimize = true + final val defaultOptimizeGlobal = false + final val inlinePatterns = Seq("!akka.**,!slick.**") + final val autoAddCompileOptions = true - final val parallelBuild = false + final val parallelBuild = true final val cachedResolution = true + final val sonatypeResolver = true final val defaultNewBackend = false @@ -30,7 +35,7 @@ sealed trait Basics { lazy val githubPage = url(s"https://github.com/${githubOrganization}/${githubProject}") lazy val buildMetadata = Vector( licenses := Seq("Apache License, Version 2.0" -> url("http://www.apache.org/licenses/LICENSE-2.0.txt")), - homepage := Some(githubPage), + homepage := Some(projectHomepage.getOrElse(githubPage)), description := projectDescription, startYear := Some(projectStartYear), scmInfo := Some(ScmInfo(githubPage, s"scm:git:git@github.com:${githubOrganization}/${githubProject}.git")) @@ -62,8 +67,6 @@ object BasicSettings extends AutoPlugin with Basics { scalaVersion := buildScalaVersion, crossScalaVersions := buildScalaVersions, - addScalacOptions(), - addJavacOptions(), autoAPIMappings := true, updateOptions := updateOptions.value.withCachedResolution(cachedResolution), @@ -71,36 +74,49 @@ object BasicSettings extends AutoPlugin with Basics { evictionWarningOptions in update := EvictionWarningOptions.default.withWarnTransitiveEvictions(false).withWarnDirectEvictions(false).withWarnScalaVersionEviction(false) + ) ++ ( + if (autoAddCompileOptions) { + addScalacOptions() ++ addJavacOptions() + } else { + Seq.empty + } + ) ++ ( + if (sonatypeResolver) { + /* Many OSS projects push here and then appear in Maven Central later */ + Seq(resolvers += Resolver.sonatypeRepo("releases")) + } else { + Seq.empty + } ) ) /* Overridable flags */ - lazy val optimize = boolFlag("OPTIMIZE") orElse boolFlag("OPTIMISE") getOrElse defaultOptimize - lazy val deprecation = boolFlag("NO_DEPRECATION") map (!_) getOrElse true - lazy val inlineWarn = boolFlag("INLINE_WARNINGS") getOrElse false - lazy val debug = boolFlag("DEBUGGER") getOrElse false - lazy val debugPort = envOrNone("DEBUGGER_PORT") map { _.toInt } getOrElse 5050 - lazy val debugSuspend = boolFlag("DEBUGGER_SUSPEND") getOrElse true - lazy val unusedWarn = boolFlag("UNUSED_WARNINGS") getOrElse false - lazy val importWarn = boolFlag("IMPORT_WARNINGS") getOrElse false - lazy val java8Flag = boolFlag("BUILD_JAVA_8") getOrElse false - lazy val newBackend = boolFlag("NEW_BCODE_BACKEND") getOrElse defaultNewBackend + lazy val optimize = boolFlag("OPTIMIZE") orElse boolFlag("OPTIMISE") getOrElse defaultOptimize + lazy val optimizeGlobal = boolFlag("OPTIMIZE_GLOBAL") getOrElse defaultOptimizeGlobal + lazy val optimizeWarn = boolFlag("OPTIMIZE_WARNINGS") getOrElse false + lazy val noFatalWarn = boolFlag("NO_FATAL_WARNINGS") getOrElse false + lazy val deprecation = boolFlag("NO_DEPRECATION") map (!_) getOrElse true + lazy val inlineWarn = boolFlag("INLINE_WARNINGS") getOrElse false + lazy val debug = boolFlag("DEBUGGER") getOrElse false + lazy val debugPort = envOrNone("DEBUGGER_PORT") map { _.toInt } getOrElse 5050 + lazy val debugSuspend = boolFlag("DEBUGGER_SUSPEND") getOrElse true + lazy val unusedWarn = boolFlag("UNUSED_WARNINGS") getOrElse false + lazy val importWarn = boolFlag("IMPORT_WARNINGS") getOrElse false + lazy val java8Flag = boolFlag("BUILD_JAVA_8") getOrElse false + lazy val newBackend = boolFlag("NEW_BCODE_BACKEND") getOrElse defaultNewBackend lazy val buildScalaVersions = buildScalaVersion +: extraScalaVersions - def addScalacOptions(optim: Boolean = optimize) = Def.derive { + def basicScalacOptions = Def.derive { scalacOptions ++= { - val sv = SVer(scalaBinaryVersion.value) var options = Seq.empty[String] + val sv = sver.value options :+= "-unchecked" options :+= "-feature" if (deprecation) { options :+= "-deprecation" } - if (inlineWarn) { - options :+= "-Yinline-warnings" - } if (unusedWarn) { options :+= "-Ywarn-unused" } @@ -110,14 +126,7 @@ object BasicSettings extends AutoPlugin with Basics { if (!sv.requireJava8) { options :+= "-target:jvm-" + minimumJavaVersion } - if (optim) { - if (sv.newOptimize || sv.supportsNewBackend && newBackend) { - options :+= "-opt:l:project" - } else if (!sv.requireJava8) { - options :+= "-optimize" - } - } - if (sv.supportsNewBackend && newBackend && !sv.requireJava8) { + if (sv.backend == SupportsNewBackend && newBackend) { options :+= "-Ybackend:GenBCode" } @@ -125,6 +134,60 @@ object BasicSettings extends AutoPlugin with Basics { } } + def optimizationScalacOptions(optim: Boolean = optimize) = Def.derive { + scalacOptions ++= { + var options = Seq.empty[String] + val sv = sver.value + val fos = forceOldInlineSyntax.value + + if (optim) { + def doNewWarn(): Unit = { + if (optimizeWarn) { + options :+= "-opt-warnings:_" + } + } + + if (sv.backend == NewBackend && !fos) { + options :+= "-opt:l:inline" + + val inlineFrom = { + var patterns = Seq.empty[String] + if (optimizeGlobal) { + patterns :+= "**" + } else { + patterns :+= "" + } + patterns ++= inlinePatterns + patterns + } + + options :+= inlineFrom.mkString("-opt-inline-from:", ":", "") + + doNewWarn() + } else if (sv.backend == NewBackend && fos || sv.backend == SupportsNewBackend && newBackend) { + if (optimizeGlobal) { + options :+= "-opt:l:classpath" + } else { + options :+= "-opt:l:project" + } + doNewWarn() + } else { + options :+= "-optimize" + if (optimizeWarn) { + options :+= "-Yinline-warnings" + } + } + } + + options + } + } + + def addScalacOptions(optim: Boolean = optimize) = new Def.SettingList(Seq( + basicScalacOptions, + optimizationScalacOptions(optim) + )) + def addJavacOptions() = Def.derive { javacOptions ++= { val sv = SVer(scalaBinaryVersion.value) @@ -145,5 +208,14 @@ object BasicSettings extends AutoPlugin with Basics { options } } -} + def basicSiteSettings = Def.derive { + scalacOptions in (Compile,doc) ++= Seq( + "-groups", + "-implicits", + "-diagrams", + "-sourcepath", (baseDirectory in ThisBuild).value.getAbsolutePath, + "-doc-source-url", s"https://github.com/${githubOrganization}/${githubProject}/blob/master€{FILE_PATH}.scala" + ) + } +} diff --git a/project/Helpers.scala b/project/Helpers.scala index 4478066..4dfe0ef 100644 --- a/project/Helpers.scala +++ b/project/Helpers.scala @@ -1,3 +1,6 @@ +import sbt._ +import Keys._ + object Helpers { def getProp(name: String): Option[String] = sys.props.get(name) orElse sys.env.get(name) def parseBool(str: String): Boolean = Set("yes", "y", "true", "t", "1") contains str.trim.toLowerCase @@ -5,6 +8,9 @@ object Helpers { def boolFlag(name: String, default: Boolean): Boolean = boolFlag(name) getOrElse default def opts(names: String*): Option[String] = names.view.map(getProp _).foldLeft(None: Option[String]) { _ orElse _ } + lazy val buildNumberOpt = sys.env.get("BUILD_NUMBER") + lazy val isJenkins = buildNumberOpt.isDefined + import scala.xml._ def excludePomDeps(exclude: (String, String) => Boolean): Node => Node = { node: Node => val rewriteRule = new transform.RewriteRule { @@ -19,28 +25,59 @@ object Helpers { transformer.transform(node)(0) } + final lazy val sver: Def.Initialize[SVer] = { + Def.map(scalaBinaryVersion)(SVer.apply) + } + + final lazy val forceOldInlineSyntax: Def.Initialize[Boolean] = { + val pat = """(?x)^ 2\.12\.[0-2] (?:[^\d].*)? $""".r + Def.map(scalaVersion) { + case pat() => true + case _ => false + } + } + + sealed trait Backend + case object NewBackend extends Backend + case object SupportsNewBackend extends Backend + case object OldBackend extends Backend + sealed trait SVer { - val supportsNewBackend: Boolean = false - val requireJava8: Boolean = true - val newOptimize: Boolean = false + val backend: Backend + val requireJava8: Boolean + + def supportsNewBackend = backend match { + case NewBackend => true + case SupportsNewBackend => true + case OldBackend => false + } } object SVer { def apply(scalaVersion: String): SVer = { - scalaVersion match { - case "2.10" => SVer2_10 - case "2.11" => SVer2_11 - case "2.12" => SVer2_12 + CrossVersion.partialVersion(scalaVersion) match { + case Some((2, 10)) => SVer2_10 + case Some((2, 11)) => SVer2_11 + case Some((2, 12)) => SVer2_12 + case Some((2, n)) if n >= 13 => SVer2_13 + case _ => + throw new IllegalArgumentException(s"Scala version $scalaVersion is not supported") } } } case object SVer2_10 extends SVer { - override val requireJava8 = false + override final val backend = OldBackend + override final val requireJava8 = false } case object SVer2_11 extends SVer { - override val supportsNewBackend = true - override val requireJava8 = false + override final val backend = SupportsNewBackend + override final val requireJava8 = false } case object SVer2_12 extends SVer { - override val newOptimize = true + override final val backend = NewBackend + override final val requireJava8 = true + } + case object SVer2_13 extends SVer { + override final val backend = NewBackend + override final val requireJava8 = true } }