Skip to content

Commit 47d5a0f

Browse files
authored
Merge pull request #180 from martingd/feature-nopredefimport
Remove default import of `scala.Predef._` + new option ImportScalaPredef to reintroduce it.
2 parents 9a1439a + 965a7d0 commit 47d5a0f

File tree

22 files changed

+297
-15
lines changed

22 files changed

+297
-15
lines changed

README.markdown

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,6 @@ When you reload the settings and compile, this generates the following:
3838
```scala
3939
package hello
4040

41-
import scala.Predef._
42-
4341
/** This object was generated by sbt-buildinfo. */
4442
case object BuildInfo {
4543
/** The value is "helloworld". */
@@ -163,6 +161,7 @@ val builtAtMillis: Long = 1438227016849L
163161
```
164162

165163
### BuildInfoOption.PackagePrivate
164+
166165
Set the package using `buildInfoPackage` and use the option `BuildInfoOption.PackagePrivate`
167166

168167
```scala
@@ -199,6 +198,29 @@ case object BuildInfo {
199198

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

201+
### BuildInfoOption.ImportScalaPredef
202+
203+
Add the following option
204+
205+
```scala
206+
buildInfoOptions += BuildInfoOption.ImportScalaPredef
207+
```
208+
209+
to explicitly import `scala.Predef._` in the generated code.
210+
211+
```scala
212+
package hello
213+
214+
import scala.Predef._
215+
216+
/** This object was generated by sbt-buildinfo. */
217+
case object BuildInfo {
218+
...
219+
}
220+
```
221+
222+
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 `*`.
223+
202224
License
203225
-------
204226

src/main/scala/sbtbuildinfo/BuildInfoOption.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,10 @@ object BuildInfoOption {
99
case object BuildTime extends BuildInfoOption
1010
case object PackagePrivate extends BuildInfoOption
1111
case object ConstantValue extends BuildInfoOption
12+
13+
/**
14+
* Explicitly import `scala.Predef._` in generated code.
15+
* This is useful if compiling with option `-Yno-imports`.
16+
*/
17+
case object ImportScalaPredef extends BuildInfoOption
1218
}

src/main/scala/sbtbuildinfo/ScalaCaseClassRenderer.scala

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,20 +13,24 @@ case class ScalaCaseClassRenderer(options: Seq[BuildInfoOption], pkg: String, ob
1313
// fully qualify every reference. Note it is NOT safe to use `import scala._` because of the possibility of
1414
// the project using `-Ywarn-unused-import` because we do not always generated references that are part of
1515
// `scala` such as `scala.Option`.
16+
val importScalaPredef = options.contains(BuildInfoOption.ImportScalaPredef)
1617
def header = List(
1718
"// $COVERAGE-OFF$",
1819
s"package $pkg",
19-
"",
20+
""
21+
)
22+
val imports = if (importScalaPredef) List(
2023
"import scala.Predef._",
21-
"import scala.Any",
22-
"",
24+
""
25+
) else Nil
26+
val generateComment = List(
2327
s"/** This file was generated by sbt-buildinfo. */"
2428
)
2529

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

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

4448
private def caseClassParameter(r: BuildInfoResult): Seq[String] = {
45-
val typeDecl = getType(r.typeExpr) getOrElse "Any"
49+
val typeDecl = getType(r.typeExpr) getOrElse "scala.Any"
4650

4751
List(
4852
s" ${r.identifier}: $typeDecl"

src/main/scala/sbtbuildinfo/ScalaCaseObjectRenderer.scala

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,25 @@ case class ScalaCaseObjectRenderer(options: Seq[BuildInfoOption], pkg: String, o
1414
// fully qualify every reference. Note it is NOT safe to use `import scala._` because of the possibility of
1515
// the project using `-Ywarn-unused-import` because we do not always generated references that are part of
1616
// `scala` such as `scala.Option`.
17+
val importScalaPredef = options.contains(BuildInfoOption.ImportScalaPredef)
1718
def header = List(
1819
"// $COVERAGE-OFF$",
1920
s"package $pkg",
20-
"",
21+
""
22+
)
23+
val imports = if (importScalaPredef) List(
2124
"import scala.Predef._",
22-
"",
25+
""
26+
) else Nil
27+
val objectHeader = List(
2328
s"/** This object was generated by sbt-buildinfo. */",
2429
withPkgPriv(s"case object $obj$objTraits {")
2530
)
2631

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

2934
override def renderKeys(buildInfoResults: Seq[BuildInfoResult]) =
30-
header ++
35+
header ++ imports ++ objectHeader ++
3136
buildInfoResults.flatMap(line) ++
3237
Seq(toStringLines(buildInfoResults)) ++
3338
toMapLines(buildInfoResults) ++

src/sbt-test/sbt-buildinfo/append/build.sbt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ lazy val root = (project in file("."))
1515
libraryDependencies, libraryDependencies in Test),
1616
buildInfoKeys += BuildInfoKey(resolvers),
1717
buildInfoPackage := "hello",
18+
buildInfoOptions := Seq(BuildInfoOption.ImportScalaPredef),
1819
resolvers ++= Seq("Sonatype Public" at "https://oss.sonatype.org/content/groups/public"),
1920
check := {
2021
val f = (sourceManaged in Compile).value / "sbt-buildinfo" / ("%s.scala" format "BuildInfo")

src/sbt-test/sbt-buildinfo/buildtime/build.sbt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@ lazy val root = (project in file("."))
1818
scalaVersion
1919
),
2020
buildInfoPackage := "hello",
21-
buildInfoOptions := Seq(BuildInfoOption.BuildTime),
21+
buildInfoOptions := Seq(
22+
BuildInfoOption.BuildTime,
23+
BuildInfoOption.ImportScalaPredef,
24+
),
2225
scalacOptions ++= Seq("-Xlint", "-Xfatal-warnings", "-Yno-imports"),
2326
check := {
2427
val f = (sourceManaged in Compile).value / "sbt-buildinfo" / ("%s.scala" format "BuildInfo")

src/sbt-test/sbt-buildinfo/caching/build.sbt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ lazy val root = (project in file("."))
1212
name := "helloworld",
1313
buildInfoKeys := Seq(name, version),
1414
buildInfoPackage := "hello",
15+
buildInfoOptions := Seq(BuildInfoOption.ImportScalaPredef),
1516
scalacOptions ++= Seq("-Xlint", "-Xfatal-warnings", "-Yno-imports"),
1617
check := {
1718
val dir = (sourceManaged in Compile).value

src/sbt-test/sbt-buildinfo/caseclassrenderer/build.sbt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ lazy val root = (project in file("."))
2828
BuildInfoOption.ToJson,
2929
BuildInfoOption.ToMap,
3030
BuildInfoOption.Traits("traits.MyCustomTrait"),
31+
BuildInfoOption.ImportScalaPredef,
3132
),
3233
buildInfoRenderFactory := ScalaCaseClassRenderer.apply,
3334
buildInfoPackage := "hello",
@@ -41,12 +42,11 @@ lazy val root = (project in file("."))
4142
"""package hello""" ::
4243
"""""" ::
4344
"""import scala.Predef._""" ::
44-
"""import scala.Any""" ::
4545
"""""" ::
4646
"""/** This file was generated by sbt-buildinfo. */""" ::
4747
"""case class BuildInfo(""" ::
4848
""" name: String,""" ::
49-
""" projectVersion: Any,""" ::
49+
""" projectVersion: scala.Any,""" ::
5050
""" scalaVersion: String,""" ::
5151
""" ivyXML: scala.xml.NodeSeq,""" ::
5252
""" homepage: scala.Option[java.net.URL],""" ::

src/sbt-test/sbt-buildinfo/constantvalue/build.sbt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,11 @@ lazy val root = (project in file(".")).
2525
BuildInfoKey.action("buildTime") { 1234L },
2626
TaskKey[Classpath]("someCp"),
2727
target),
28-
buildInfoOptions ++= Seq(BuildInfoOption.Traits("traits.MyCustomTrait"), BuildInfoOption.ConstantValue),
28+
buildInfoOptions ++= Seq(
29+
BuildInfoOption.Traits("traits.MyCustomTrait"),
30+
BuildInfoOption.ConstantValue,
31+
BuildInfoOption.ImportScalaPredef,
32+
),
2933
buildInfoPackage := "hello",
3034
scalacOptions ++= Seq("-Xlint", "-Xfatal-warnings", "-Yno-imports"),
3135
libraryDependencies += "org.scala-lang.modules" %% "scala-xml" % "1.3.0",

src/sbt-test/sbt-buildinfo/multi/build.sbt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ lazy val app = (project in file("app"))
1919
BuildInfoKey.map(homepage) { case (n, opt) => n -> opt.get },
2020
scalaVersion),
2121
buildInfoPackage := "hello",
22+
buildInfoOptions := Seq(BuildInfoOption.ImportScalaPredef),
2223
scalacOptions ++= Seq("-Xlint", "-Xfatal-warnings", "-Yno-imports"),
2324
check := {
2425
val sv = scalaVersion.value

src/sbt-test/sbt-buildinfo/options/build.sbt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ lazy val root = (project in file("."))
1717
BuildInfoOption.ToMap,
1818
BuildInfoOption.Traits("TestTrait1", "TestTrait2"),
1919
BuildInfoOption.Traits("TestTrait3"),
20-
BuildInfoOption.PackagePrivate),
20+
BuildInfoOption.PackagePrivate,
21+
BuildInfoOption.ImportScalaPredef,
22+
),
2123
homepage := Some(url("http://example.com")),
2224
licenses := Seq("MIT License" -> url("https://github.com/sbt/sbt-buildinfo/blob/master/LICENSE")),
2325
scalacOptions ++= Seq("-Xlint", "-Xfatal-warnings", "-Yno-imports"),

src/sbt-test/sbt-buildinfo/simple/build.sbt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ lazy val root = (project in file("."))
2626
target
2727
),
2828
buildInfoPackage := "hello",
29+
buildInfoOptions := Seq(BuildInfoOption.ImportScalaPredef),
2930
scalacOptions ++= Seq("-Xlint", "-Xfatal-warnings", "-Yno-imports"),
3031
libraryDependencies += "org.scala-lang.modules" %% "scala-xml" % "1.3.0",
3132
check := {
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
import sbtbuildinfo.ScalaCaseClassRenderer
2+
3+
lazy val check = taskKey[Unit]("checks this plugin")
4+
5+
ThisBuild / version := "0.1"
6+
ThisBuild / scalaVersion := "2.12.12"
7+
ThisBuild / homepage := Some(url("http://example.com"))
8+
ThisBuild / licenses := Seq("MIT License" -> url("https://github.com/sbt/sbt-buildinfo/blob/master/LICENSE"))
9+
10+
lazy val root = (project in file("."))
11+
.enablePlugins(BuildInfoPlugin)
12+
.settings(
13+
name := "helloworld",
14+
buildInfoKeys := Seq(
15+
name,
16+
BuildInfoKey.map(version) { case (n, v) => "projectVersion" -> v.toDouble },
17+
scalaVersion,
18+
ivyXML,
19+
homepage,
20+
licenses,
21+
apiMappings,
22+
isSnapshot,
23+
"year" -> 2012,
24+
"sym" -> 'Foo,
25+
BuildInfoKey.action("buildTime") { 1234L },
26+
target),
27+
buildInfoOptions ++= Seq(
28+
BuildInfoOption.ToJson,
29+
BuildInfoOption.ToMap,
30+
BuildInfoOption.Traits("traits.MyCustomTrait"),
31+
),
32+
buildInfoRenderFactory := ScalaCaseClassRenderer.apply,
33+
buildInfoPackage := "hello",
34+
scalacOptions ++= Seq("-Ywarn-unused-import", "-Xfatal-warnings"),
35+
libraryDependencies += "org.scala-lang.modules" %% "scala-xml" % "1.0.5",
36+
check := {
37+
val f = (sourceManaged in Compile).value / "sbt-buildinfo" / ("%s.scala" format "BuildInfo")
38+
val lines = scala.io.Source.fromFile(f).getLines.toList
39+
lines match {
40+
case """// $COVERAGE-OFF$""" ::
41+
"""package hello""" ::
42+
"""""" ::
43+
"""/** This file was generated by sbt-buildinfo. */""" ::
44+
"""case class BuildInfo(""" ::
45+
""" name: String,""" ::
46+
""" projectVersion: scala.Any,""" ::
47+
""" scalaVersion: String,""" ::
48+
""" ivyXML: scala.xml.NodeSeq,""" ::
49+
""" homepage: scala.Option[java.net.URL],""" ::
50+
""" licenses: scala.collection.immutable.Seq[(String, java.net.URL)],""" ::
51+
""" apiMappings: Map[java.io.File, java.net.URL],""" ::
52+
""" isSnapshot: scala.Boolean,""" ::
53+
""" year: scala.Int,""" ::
54+
""" sym: scala.Symbol,""" ::
55+
""" buildTime: scala.Long,""" ::
56+
""" target: java.io.File""" ::
57+
""") extends traits.MyCustomTrait {""" ::
58+
"""""" ::
59+
""" val toMap: Map[String, scala.Any] = Map[String, scala.Any](""" ::
60+
""" "name" -> name,""" ::
61+
""" "projectVersion" -> projectVersion,""" ::
62+
""" "scalaVersion" -> scalaVersion,""" ::
63+
""" "ivyXML" -> ivyXML,""" ::
64+
""" "homepage" -> homepage,""" ::
65+
""" "licenses" -> licenses,""" ::
66+
""" "apiMappings" -> apiMappings,""" ::
67+
""" "isSnapshot" -> isSnapshot,""" ::
68+
""" "year" -> year,""" ::
69+
""" "sym" -> sym,""" ::
70+
""" "buildTime" -> buildTime,""" ::
71+
""" "target" -> target)""" ::
72+
"""""" ::
73+
""" private def quote(x: scala.Any): String = "\"" + x + "\""""" ::
74+
""" private def toJsonValue(value: scala.Any): String = {""" ::
75+
""" value match {""" ::
76+
""" case elem: scala.collection.Seq[_] => elem.map(toJsonValue).mkString("[", ",", "]")""" ::
77+
""" case elem: scala.Option[_] => elem.map(toJsonValue).getOrElse("null")""" ::
78+
""" case elem: scala.collection.Map[_, scala.Any] => elem.map {""" ::
79+
""" case (k, v) => toJsonValue(k.toString) + ":" + toJsonValue(v)""" ::
80+
""" }.mkString("{", ", ", "}")""" ::
81+
""" case d: scala.Double => d.toString""" ::
82+
""" case f: scala.Float => f.toString""" ::
83+
""" case l: scala.Long => l.toString""" ::
84+
""" case i: scala.Int => i.toString""" ::
85+
""" case s: scala.Short => s.toString""" ::
86+
""" case bool: scala.Boolean => bool.toString""" ::
87+
""" case str: String => quote(str)""" ::
88+
""" case other => quote(other.toString)""" ::
89+
""" }""" ::
90+
""" }""" ::
91+
"""""" ::
92+
""" val toJson: String = toJsonValue(toMap)""" ::
93+
"""}""" ::
94+
"""""" ::
95+
"""case object BuildInfo {""" ::
96+
""" def apply(): BuildInfo = new BuildInfo(""" ::
97+
""" name = "helloworld",""" ::
98+
""" projectVersion = 0.1,""" ::
99+
""" scalaVersion = "2.12.12",""" ::
100+
""" ivyXML = scala.xml.NodeSeq.Empty,""" ::
101+
""" homepage = scala.Some(new java.net.URL("http://example.com")),""" ::
102+
""" licenses = scala.collection.immutable.Seq(("MIT License" -> new java.net.URL("https://github.com/sbt/sbt-buildinfo/blob/master/LICENSE"))),""" ::
103+
""" apiMappings = Map(),""" ::
104+
""" isSnapshot = false,""" ::
105+
""" year = 2012,""" ::
106+
""" sym = scala.Symbol("Foo"),""" ::
107+
""" buildTime = 1234L,""" ::
108+
targetInfo ::
109+
""" val get = apply()""" ::
110+
""" val value = apply()""" ::
111+
"""}""" ::
112+
"""// $COVERAGE-ON$""" :: Nil if (targetInfo contains "target = new java.io.File(") =>
113+
case _ => sys.error("unexpected output: \n" + lines.mkString("\n"))
114+
}
115+
()
116+
}
117+
)
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
val pluginVersion = System.getProperty("plugin.version")
3+
if(pluginVersion == null)
4+
throw new RuntimeException("""|The system property 'plugin.version' is not defined.
5+
|Specify this property using the scriptedLaunchOpts -D.""".stripMargin)
6+
else addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % pluginVersion)
7+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package traits
2+
3+
trait MyCustomTrait {}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
> compile
2+
$ exists target/scala-2.12/src_managed/main/sbt-buildinfo/BuildInfo.scala
3+
4+
> check

0 commit comments

Comments
 (0)