Skip to content

Commit

Permalink
Cross-build with Scala 3.2.2 (#332)
Browse files Browse the repository at this point in the history
Take macro implementations from izumi

Subsumes #181
  • Loading branch information
neko-kai authored Feb 20, 2024
1 parent c445f41 commit 771b093
Show file tree
Hide file tree
Showing 11 changed files with 126 additions and 59 deletions.
19 changes: 13 additions & 6 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -82,24 +82,31 @@ val scalaOpts = scalacOptions ++= ((isSnapshot.value, scalaVersion.value) match
"-Wvalue-discard",
"-Wunused:_",
)
case (_, ScalaVersions.scala_3) => Seq(
"-no-indent",
"-explain",
)
case (_, _) => Seq.empty
})

lazy val sbtmeta = (project in file("sbtmeta"))
.settings(
crossScalaVersions := Seq(ScalaVersions.scala_213, ScalaVersions.scala_212),
crossScalaVersions := Seq(ScalaVersions.scala_3, ScalaVersions.scala_213, ScalaVersions.scala_212),
scalaVersion := crossScalaVersions.value.head,
libraryDependencies += "org.scala-lang" % "scala-reflect" % scalaVersion.value % Provided,
libraryDependencies ++= {
if (scalaVersion.value.startsWith("2"))
Seq("org.scala-lang" % "scala-reflect" % scalaVersion.value % Provided)
else Seq.empty
},
scalaOpts,
)

lazy val sbtgen = (project in file("sbtgen"))
.dependsOn(sbtmeta)
.settings(
crossScalaVersions := Seq(ScalaVersions.scala_213, ScalaVersions.scala_212),
crossScalaVersions := Seq(ScalaVersions.scala_3, ScalaVersions.scala_213, ScalaVersions.scala_212),
scalaVersion := crossScalaVersions.value.head,
// libraryDependencies += "com.github.scopt" %% "scopt" % "4.0.0-RC2",
libraryDependencies += "com.github.scopt" %% "scopt" % "3.7.1",
libraryDependencies += "com.github.scopt" %% "scopt" % "4.1.0",
libraryDependencies += "org.scala-lang.modules" %% "scala-collection-compat" % "2.11.0",
(ThisBuild / libraryDependencies) += "org.scalatest" %% "scalatest" % "3.2.18" % Test,
scalacOptions ++= Seq(
Expand Down Expand Up @@ -216,7 +223,7 @@ lazy val `izumi-sbtgen` = (project in file("."))
action = { st: State =>
val extracted = Project.extract(st)
val ref = extracted.get(`sbt-tests` / thisProjectRef)
extracted.runInputTask((ref / (Global / scripted)), "", st)._1
extracted.runInputTask(ref / (Global / scripted), "", st)._1
}
),
setReleaseVersion, // : ReleaseStep
Expand Down
1 change: 1 addition & 0 deletions project/ScalaVersions.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
object ScalaVersions {
val scala_212 = "2.12.18"
val scala_213 = "2.13.12"
val scala_3 = "3.2.2"

val scalaJsVersion = "1.15.0"
val scalaNativeVersion = "0.4.17"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,46 +1,20 @@
package izumi.sbtgen.sbtmeta

import java.nio.file.{Path, Paths}
import java.time.LocalDateTime
import scala.annotation.tailrec
import scala.reflect.macros.blackbox

object ProjectAttributeMacro {

def buildTimestampMacro(c: blackbox.Context)(): c.Expr[LocalDateTime] = {
import c.universe._

val time = LocalDateTime.now()
c.Expr[LocalDateTime] {
q"{_root_.java.time.LocalDateTime.of(${time.getYear}, ${time.getMonthValue}, ${time.getDayOfMonth}, ${time.getHour}, ${time.getMinute}, ${time.getSecond}, ${time.getNano})}"
}
}

def extractAttrMacro(c: blackbox.Context)(name: c.Expr[String]): c.Expr[Option[String]] = {
val nameStr = TreeTools.stringLiteral(c)(c.universe)(name.tree)
extractAttr(c, nameStr, force = true)
}

def extractProjectGroupIdMacro(c: blackbox.Context)(): c.Expr[Option[String]] = {
extractAttr(c, "product-group")
}

def extractSbtVersionMacro(c: blackbox.Context)(): c.Expr[Option[String]] = {
extractAttr(c, "sbt-version")
}

def extractScalatestVersionMacro(c: blackbox.Context)(): c.Expr[Option[String]] = {
extractAttr(c, "scalatest-version")
}

def extractScalaVersionsMacro(c: blackbox.Context)(): c.Expr[Option[String]] = {
extractAttr(c, "scala-versions")
}

def extractScalaVersionMacro(c: blackbox.Context)(): c.Expr[Option[String]] = {
extractAttr(c, "scala-version")
}

def extractProjectVersionMacro(c: blackbox.Context)(): c.Expr[Option[String]] = {
extractAttr(c, "product-version")
}
Expand Down
13 changes: 13 additions & 0 deletions sbtmeta/src/main/scala-2/izumi/sbtgen/sbtmeta/SbtgenMeta.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package izumi.sbtgen.sbtmeta

import scala.language.experimental.macros

object SbtgenMeta {
def projectRoot(): Option[String] = macro ProjectAttributeMacro.findProjectRootMacro

def extractSbtProjectVersion(): Option[String] = macro ProjectAttributeMacro.extractProjectVersionMacro

def extractScalaVersions(): Option[String] = macro ProjectAttributeMacro.extractScalaVersionsMacro

def extractMandatory(name: String): Option[String] = macro ProjectAttributeMacro.extractAttrMacro
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package izumi.sbtgen.sbtmeta

import java.time.LocalDateTime

object BuildAttributes {

inline def sbtProjectRoot(): Option[String] = ${ BuildAttributesImpl.sbtProjectRoot() }

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package izumi.sbtgen.sbtmeta

import java.nio.file.Path
import java.time.LocalDateTime

import scala.annotation.tailrec
import scala.quoted.{Expr, Quotes}

object BuildAttributesImpl {

def sbtProjectRoot()(using quotes: Quotes): Expr[Option[String]] = {
import quotes.reflect.*

val result = SourceFile.current.getJPath
.flatMap(findProjectRoot)
.map(_.toFile.getCanonicalPath)

Expr(result)
}

@tailrec
private def findProjectRoot(cp: Path): Option[Path] = {
if (cp.resolve("build.sbt").toFile.exists()) {
Some(cp)
} else {
val parent = cp.getParent

if (parent == null || parent == cp.getRoot) {
None
} else {
findProjectRoot(parent)
}
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package izumi.sbtgen.sbtmeta

import scala.quoted.{Expr, Quotes, Type}

object MacroParameters {

inline def scalaCrossVersions(): Option[String] = macroSetting("scala-versions")

inline def artifactVersion(): Option[String] = macroSetting("product-version")

inline def macroSetting(inline name: String): Option[String] = {
${ MacroParametersImpl.extractString('{ name }) }
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package izumi.sbtgen.sbtmeta

import scala.annotation.experimental
import scala.quoted.{Expr, Quotes, Type}

@experimental
object MacroParametersImpl {

def extractString(name: Expr[String])(using quotes: Quotes): Expr[Option[String]] = {
Expr(extract(name.valueOrAbort))
}

def extractBool(name: Expr[String])(using quotes: Quotes): Expr[Option[Boolean]] = {
val value = extract(name.valueOrAbort)
val isTrue = value.map(_.toLowerCase).map(v => v == "true" || v == "1")
Expr(isTrue)
}

private def extract(name: String)(using quotes: Quotes): Option[String] = {
import quotes.reflect.*
val prefix = s"$name="
val value = CompilationInfo.XmacroSettings.filter(_.startsWith(prefix)).map(_.stripPrefix(prefix)).lastOption
if (value.isEmpty) {
report.info(s"Undefined macro parameter $name, add `-Xmacro-settings:$prefix<value>` into `scalac` options")
}
value
}
}
11 changes: 11 additions & 0 deletions sbtmeta/src/main/scala-3/izumi.sbtgen.sbtmeta/SbtgenMeta.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package izumi.sbtgen.sbtmeta

object SbtgenMeta {
inline def projectRoot(): Option[String] = ${ BuildAttributesImpl.sbtProjectRoot() }

inline def extractSbtProjectVersion(): Option[String] = MacroParameters.artifactVersion()

inline def extractScalaVersions(): Option[String] = MacroParameters.scalaCrossVersions()

inline def extractMandatory(inline name: String): Option[String] = MacroParameters.macroSetting(name)
}
27 changes: 0 additions & 27 deletions sbtmeta/src/main/scala/izumi/sbtgen/sbtmeta/SbtgenMeta.scala

This file was deleted.

0 comments on commit 771b093

Please sign in to comment.