Skip to content

Remove default import of scala.Predef._ + new option ImportScalaPredef to reintroduce it. #180

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 24 additions & 2 deletions README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,6 @@ When you reload the settings and compile, this generates the following:
```scala
package hello

import scala.Predef._

/** This object was generated by sbt-buildinfo. */
case object BuildInfo {
/** The value is "helloworld". */
Expand Down Expand Up @@ -163,6 +161,7 @@ val builtAtMillis: Long = 1438227016849L
```

### BuildInfoOption.PackagePrivate

Set the package using `buildInfoPackage` and use the option `BuildInfoOption.PackagePrivate`

```scala
Expand Down Expand Up @@ -199,6 +198,29 @@ case object BuildInfo {

This is particular useful if the values must be constants – e.g., if you need to assign them to annotation arguments.

### BuildInfoOption.ImportScalaPredef

Add the following option

```scala
buildInfoOptions += BuildInfoOption.ImportScalaPredef
```

to explicitly import `scala.Predef._` in the generated code.

```scala
package hello

import scala.Predef._

/** This object was generated by sbt-buildinfo. */
case object BuildInfo {
...
}
```

This import is necessary only when using compiler option `-Yno-imports`. Please note, the generated import is not compatible when compiling with Scala 3 compiler option `-source:future` because import wildcards must be `*`.

License
-------

Expand Down
6 changes: 6 additions & 0 deletions src/main/scala/sbtbuildinfo/BuildInfoOption.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,10 @@ object BuildInfoOption {
case object BuildTime extends BuildInfoOption
case object PackagePrivate extends BuildInfoOption
case object ConstantValue extends BuildInfoOption

/**
* Explicitly import `scala.Predef._` in generated code.
* This is useful if compiling with option `-Yno-imports`.
*/
case object ImportScalaPredef extends BuildInfoOption
}
14 changes: 9 additions & 5 deletions src/main/scala/sbtbuildinfo/ScalaCaseClassRenderer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,24 @@ case class ScalaCaseClassRenderer(options: Seq[BuildInfoOption], pkg: String, ob
// fully qualify every reference. Note it is NOT safe to use `import scala._` because of the possibility of
// the project using `-Ywarn-unused-import` because we do not always generated references that are part of
// `scala` such as `scala.Option`.
val importScalaPredef = options.contains(BuildInfoOption.ImportScalaPredef)
def header = List(
"// $COVERAGE-OFF$",
s"package $pkg",
"",
""
)
val imports = if (importScalaPredef) List(
"import scala.Predef._",
"import scala.Any",
"",
""
) else Nil
val generateComment = List(
s"/** This file was generated by sbt-buildinfo. */"
)

def footer = List("// $COVERAGE-ON$")

override def renderKeys(buildInfoResults: Seq[BuildInfoResult]) =
header ++
header ++ imports ++ generateComment ++
caseClassDefinitionBegin ++
buildInfoResults.flatMap(caseClassParameter).mkString(",\n").split("\n") ++
caseClassDefinitionEnd ++
Expand All @@ -42,7 +46,7 @@ case class ScalaCaseClassRenderer(options: Seq[BuildInfoOption], pkg: String, ob
)

private def caseClassParameter(r: BuildInfoResult): Seq[String] = {
val typeDecl = getType(r.typeExpr) getOrElse "Any"
val typeDecl = getType(r.typeExpr) getOrElse "scala.Any"

List(
s" ${r.identifier}: $typeDecl"
Expand Down
11 changes: 8 additions & 3 deletions src/main/scala/sbtbuildinfo/ScalaCaseObjectRenderer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,25 @@ case class ScalaCaseObjectRenderer(options: Seq[BuildInfoOption], pkg: String, o
// fully qualify every reference. Note it is NOT safe to use `import scala._` because of the possibility of
// the project using `-Ywarn-unused-import` because we do not always generated references that are part of
// `scala` such as `scala.Option`.
val importScalaPredef = options.contains(BuildInfoOption.ImportScalaPredef)
def header = List(
"// $COVERAGE-OFF$",
s"package $pkg",
"",
""
)
val imports = if (importScalaPredef) List(
"import scala.Predef._",
"",
""
) else Nil
val objectHeader = List(
s"/** This object was generated by sbt-buildinfo. */",
withPkgPriv(s"case object $obj$objTraits {")
)

def footer = List("}", "// $COVERAGE-ON$")

override def renderKeys(buildInfoResults: Seq[BuildInfoResult]) =
header ++
header ++ imports ++ objectHeader ++
buildInfoResults.flatMap(line) ++
Seq(toStringLines(buildInfoResults)) ++
toMapLines(buildInfoResults) ++
Expand Down
1 change: 1 addition & 0 deletions src/sbt-test/sbt-buildinfo/append/build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ lazy val root = (project in file("."))
libraryDependencies, libraryDependencies in Test),
buildInfoKeys += BuildInfoKey(resolvers),
buildInfoPackage := "hello",
buildInfoOptions := Seq(BuildInfoOption.ImportScalaPredef),
resolvers ++= Seq("Sonatype Public" at "https://oss.sonatype.org/content/groups/public"),
check := {
val f = (sourceManaged in Compile).value / "sbt-buildinfo" / ("%s.scala" format "BuildInfo")
Expand Down
5 changes: 4 additions & 1 deletion src/sbt-test/sbt-buildinfo/buildtime/build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ lazy val root = (project in file("."))
scalaVersion
),
buildInfoPackage := "hello",
buildInfoOptions := Seq(BuildInfoOption.BuildTime),
buildInfoOptions := Seq(
BuildInfoOption.BuildTime,
BuildInfoOption.ImportScalaPredef,
),
scalacOptions ++= Seq("-Xlint", "-Xfatal-warnings", "-Yno-imports"),
check := {
val f = (sourceManaged in Compile).value / "sbt-buildinfo" / ("%s.scala" format "BuildInfo")
Expand Down
1 change: 1 addition & 0 deletions src/sbt-test/sbt-buildinfo/caching/build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ lazy val root = (project in file("."))
name := "helloworld",
buildInfoKeys := Seq(name, version),
buildInfoPackage := "hello",
buildInfoOptions := Seq(BuildInfoOption.ImportScalaPredef),
scalacOptions ++= Seq("-Xlint", "-Xfatal-warnings", "-Yno-imports"),
check := {
val dir = (sourceManaged in Compile).value
Expand Down
4 changes: 2 additions & 2 deletions src/sbt-test/sbt-buildinfo/caseclassrenderer/build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ lazy val root = (project in file("."))
BuildInfoOption.ToJson,
BuildInfoOption.ToMap,
BuildInfoOption.Traits("traits.MyCustomTrait"),
BuildInfoOption.ImportScalaPredef,
),
buildInfoRenderFactory := ScalaCaseClassRenderer.apply,
buildInfoPackage := "hello",
Expand All @@ -41,12 +42,11 @@ lazy val root = (project in file("."))
"""package hello""" ::
"""""" ::
"""import scala.Predef._""" ::
"""import scala.Any""" ::
"""""" ::
"""/** This file was generated by sbt-buildinfo. */""" ::
"""case class BuildInfo(""" ::
""" name: String,""" ::
""" projectVersion: Any,""" ::
""" projectVersion: scala.Any,""" ::
""" scalaVersion: String,""" ::
""" ivyXML: scala.xml.NodeSeq,""" ::
""" homepage: scala.Option[java.net.URL],""" ::
Expand Down
6 changes: 5 additions & 1 deletion src/sbt-test/sbt-buildinfo/constantvalue/build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@ lazy val root = (project in file(".")).
BuildInfoKey.action("buildTime") { 1234L },
TaskKey[Classpath]("someCp"),
target),
buildInfoOptions ++= Seq(BuildInfoOption.Traits("traits.MyCustomTrait"), BuildInfoOption.ConstantValue),
buildInfoOptions ++= Seq(
BuildInfoOption.Traits("traits.MyCustomTrait"),
BuildInfoOption.ConstantValue,
BuildInfoOption.ImportScalaPredef,
),
buildInfoPackage := "hello",
scalacOptions ++= Seq("-Xlint", "-Xfatal-warnings", "-Yno-imports"),
libraryDependencies += "org.scala-lang.modules" %% "scala-xml" % "1.3.0",
Expand Down
1 change: 1 addition & 0 deletions src/sbt-test/sbt-buildinfo/multi/build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ lazy val app = (project in file("app"))
BuildInfoKey.map(homepage) { case (n, opt) => n -> opt.get },
scalaVersion),
buildInfoPackage := "hello",
buildInfoOptions := Seq(BuildInfoOption.ImportScalaPredef),
scalacOptions ++= Seq("-Xlint", "-Xfatal-warnings", "-Yno-imports"),
check := {
val sv = scalaVersion.value
Expand Down
4 changes: 3 additions & 1 deletion src/sbt-test/sbt-buildinfo/options/build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ lazy val root = (project in file("."))
BuildInfoOption.ToMap,
BuildInfoOption.Traits("TestTrait1", "TestTrait2"),
BuildInfoOption.Traits("TestTrait3"),
BuildInfoOption.PackagePrivate),
BuildInfoOption.PackagePrivate,
BuildInfoOption.ImportScalaPredef,
),
homepage := Some(url("http://example.com")),
licenses := Seq("MIT License" -> url("https://github.com/sbt/sbt-buildinfo/blob/master/LICENSE")),
scalacOptions ++= Seq("-Xlint", "-Xfatal-warnings", "-Yno-imports"),
Expand Down
1 change: 1 addition & 0 deletions src/sbt-test/sbt-buildinfo/simple/build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ lazy val root = (project in file("."))
target
),
buildInfoPackage := "hello",
buildInfoOptions := Seq(BuildInfoOption.ImportScalaPredef),
scalacOptions ++= Seq("-Xlint", "-Xfatal-warnings", "-Yno-imports"),
libraryDependencies += "org.scala-lang.modules" %% "scala-xml" % "1.3.0",
check := {
Expand Down
117 changes: 117 additions & 0 deletions src/sbt-test/sbt-buildinfo/skipimportscaseclass/build.sbt
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import sbtbuildinfo.ScalaCaseClassRenderer

lazy val check = taskKey[Unit]("checks this plugin")

ThisBuild / version := "0.1"
ThisBuild / scalaVersion := "2.12.12"
ThisBuild / homepage := Some(url("http://example.com"))
ThisBuild / licenses := Seq("MIT License" -> url("https://github.com/sbt/sbt-buildinfo/blob/master/LICENSE"))

lazy val root = (project in file("."))
.enablePlugins(BuildInfoPlugin)
.settings(
name := "helloworld",
buildInfoKeys := Seq(
name,
BuildInfoKey.map(version) { case (n, v) => "projectVersion" -> v.toDouble },
scalaVersion,
ivyXML,
homepage,
licenses,
apiMappings,
isSnapshot,
"year" -> 2012,
"sym" -> 'Foo,
BuildInfoKey.action("buildTime") { 1234L },
target),
buildInfoOptions ++= Seq(
BuildInfoOption.ToJson,
BuildInfoOption.ToMap,
BuildInfoOption.Traits("traits.MyCustomTrait"),
),
buildInfoRenderFactory := ScalaCaseClassRenderer.apply,
buildInfoPackage := "hello",
scalacOptions ++= Seq("-Ywarn-unused-import", "-Xfatal-warnings"),
libraryDependencies += "org.scala-lang.modules" %% "scala-xml" % "1.0.5",
check := {
val f = (sourceManaged in Compile).value / "sbt-buildinfo" / ("%s.scala" format "BuildInfo")
val lines = scala.io.Source.fromFile(f).getLines.toList
lines match {
case """// $COVERAGE-OFF$""" ::
"""package hello""" ::
"""""" ::
"""/** This file was generated by sbt-buildinfo. */""" ::
"""case class BuildInfo(""" ::
""" name: String,""" ::
""" projectVersion: scala.Any,""" ::
""" scalaVersion: String,""" ::
""" ivyXML: scala.xml.NodeSeq,""" ::
""" homepage: scala.Option[java.net.URL],""" ::
""" licenses: scala.collection.immutable.Seq[(String, java.net.URL)],""" ::
""" apiMappings: Map[java.io.File, java.net.URL],""" ::
""" isSnapshot: scala.Boolean,""" ::
""" year: scala.Int,""" ::
""" sym: scala.Symbol,""" ::
""" buildTime: scala.Long,""" ::
""" target: java.io.File""" ::
""") extends traits.MyCustomTrait {""" ::
"""""" ::
""" val toMap: Map[String, scala.Any] = Map[String, scala.Any](""" ::
""" "name" -> name,""" ::
""" "projectVersion" -> projectVersion,""" ::
""" "scalaVersion" -> scalaVersion,""" ::
""" "ivyXML" -> ivyXML,""" ::
""" "homepage" -> homepage,""" ::
""" "licenses" -> licenses,""" ::
""" "apiMappings" -> apiMappings,""" ::
""" "isSnapshot" -> isSnapshot,""" ::
""" "year" -> year,""" ::
""" "sym" -> sym,""" ::
""" "buildTime" -> buildTime,""" ::
""" "target" -> target)""" ::
"""""" ::
""" private def quote(x: scala.Any): String = "\"" + x + "\""""" ::
""" private def toJsonValue(value: scala.Any): String = {""" ::
""" value match {""" ::
""" case elem: scala.collection.Seq[_] => elem.map(toJsonValue).mkString("[", ",", "]")""" ::
""" case elem: scala.Option[_] => elem.map(toJsonValue).getOrElse("null")""" ::
""" case elem: scala.collection.Map[_, scala.Any] => elem.map {""" ::
""" case (k, v) => toJsonValue(k.toString) + ":" + toJsonValue(v)""" ::
""" }.mkString("{", ", ", "}")""" ::
""" case d: scala.Double => d.toString""" ::
""" case f: scala.Float => f.toString""" ::
""" case l: scala.Long => l.toString""" ::
""" case i: scala.Int => i.toString""" ::
""" case s: scala.Short => s.toString""" ::
""" case bool: scala.Boolean => bool.toString""" ::
""" case str: String => quote(str)""" ::
""" case other => quote(other.toString)""" ::
""" }""" ::
""" }""" ::
"""""" ::
""" val toJson: String = toJsonValue(toMap)""" ::
"""}""" ::
"""""" ::
"""case object BuildInfo {""" ::
""" def apply(): BuildInfo = new BuildInfo(""" ::
""" name = "helloworld",""" ::
""" projectVersion = 0.1,""" ::
""" scalaVersion = "2.12.12",""" ::
""" ivyXML = scala.xml.NodeSeq.Empty,""" ::
""" homepage = scala.Some(new java.net.URL("http://example.com")),""" ::
""" licenses = scala.collection.immutable.Seq(("MIT License" -> new java.net.URL("https://github.com/sbt/sbt-buildinfo/blob/master/LICENSE"))),""" ::
""" apiMappings = Map(),""" ::
""" isSnapshot = false,""" ::
""" year = 2012,""" ::
""" sym = scala.Symbol("Foo"),""" ::
""" buildTime = 1234L,""" ::
targetInfo ::
""" val get = apply()""" ::
""" val value = apply()""" ::
"""}""" ::
"""// $COVERAGE-ON$""" :: Nil if (targetInfo contains "target = new java.io.File(") =>
case _ => sys.error("unexpected output: \n" + lines.mkString("\n"))
}
()
}
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
val pluginVersion = System.getProperty("plugin.version")
if(pluginVersion == null)
throw new RuntimeException("""|The system property 'plugin.version' is not defined.
|Specify this property using the scriptedLaunchOpts -D.""".stripMargin)
else addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % pluginVersion)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package traits

trait MyCustomTrait {}
4 changes: 4 additions & 0 deletions src/sbt-test/sbt-buildinfo/skipimportscaseclass/test
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
> compile
$ exists target/scala-2.12/src_managed/main/sbt-buildinfo/BuildInfo.scala

> check
Loading