mirror of https://github.com/sbt/sbt.git
Merge pull request #8432 from eed3si9n/bport/scala-version
[1.x] Show warnings when scalaVersion is missing
This commit is contained in:
commit
2e8e03eb0e
|
|
@ -364,7 +364,7 @@ lazy val utilPosition = (project in file("internal") / "util-position")
|
|||
utilCommonSettings,
|
||||
name := "Util Position",
|
||||
scalacOptions += "-language:experimental.macros",
|
||||
libraryDependencies ++= Seq(scalaReflect.value, scalatest % "test"),
|
||||
libraryDependencies ++= Seq(scalaReflect.value, hedgehog % Test),
|
||||
utilMimaSettings,
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -8,18 +8,26 @@
|
|||
|
||||
package sbt.internal.util
|
||||
|
||||
import org.scalatest.flatspec.AnyFlatSpec
|
||||
import hedgehog._
|
||||
import hedgehog.runner._
|
||||
|
||||
class SourcePositionSpec extends AnyFlatSpec {
|
||||
"SourcePosition()" should "return a sane SourcePosition" in {
|
||||
val filename = "SourcePositionSpec.scala"
|
||||
val lineNumber = 17
|
||||
SourcePosition.fromEnclosing() match {
|
||||
case LinePosition(path, startLine) => assert(path === filename && startLine === lineNumber)
|
||||
case RangePosition(path, range) => assert(path === filename && inRange(range, lineNumber))
|
||||
case NoPosition => fail("No source position found")
|
||||
}
|
||||
}
|
||||
object SourcePositionSpec extends Properties {
|
||||
override def tests: List[Test] = List(
|
||||
example(
|
||||
"SourcePosition() should return a SourcePosition", {
|
||||
val filename = "SourcePositionSpec.scala"
|
||||
// val lineNumber = 19
|
||||
val lineNumber = 21
|
||||
SourcePosition.fromEnclosing() match {
|
||||
case pos @ LinePosition(path, startLine) =>
|
||||
Result.assert( /* path == filename && */ startLine == lineNumber).log(pos.toString())
|
||||
case pos @ RangePosition(path, range) =>
|
||||
Result.assert(path == filename && inRange(range, lineNumber)).log(pos.toString())
|
||||
case NoPosition => Result.assert(false).log("No source position found")
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
private def inRange(range: LineRange, lineNo: Int) =
|
||||
range.start until range.end contains lineNo
|
||||
|
|
|
|||
|
|
@ -979,7 +979,11 @@ object BuiltinCommands {
|
|||
st => setupGlobalFileTreeRepository(addCacheStoreFactoryFactory(st))
|
||||
)
|
||||
val s4 = s3.put(Keys.useLog4J.key, Project.extract(s3).get(Keys.useLog4J))
|
||||
addSuperShellParams(CheckBuildSources.init(LintUnused.lintUnusedFunc(s4)))
|
||||
addSuperShellParams(
|
||||
CheckBuildSources.init(
|
||||
LintUnused.lintScalaVersion(LintUnused.lintUnusedFunc(s4))
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private val setupGlobalFileTreeRepository: State => State = { state =>
|
||||
|
|
|
|||
|
|
@ -11,11 +11,12 @@ package internal
|
|||
|
||||
import Keys._
|
||||
import Def.{ Setting, ScopedKey }
|
||||
import sbt.internal.util.{ FilePosition, NoPosition, SourcePosition }
|
||||
import sbt.internal.util.{ FilePosition, LinePosition, NoPosition, SourcePosition }
|
||||
import java.io.File
|
||||
import Scope.Global
|
||||
import sbt.SlashSyntax0._
|
||||
import sbt.Def._
|
||||
import scala.annotation.nowarn
|
||||
|
||||
object LintUnused {
|
||||
lazy val lintSettings: Seq[Setting[_]] = Seq(
|
||||
|
|
@ -164,14 +165,53 @@ object LintUnused {
|
|||
u
|
||||
}
|
||||
(unusedKeys map { u =>
|
||||
(u.scoped, display.show(u.scoped), u.positions)
|
||||
(u.scoped, display.show(u.scoped), u.positions.toVector)
|
||||
}).sortBy(_._2)
|
||||
}
|
||||
|
||||
def lintScalaVersion(state: State): State = {
|
||||
val log = state.log
|
||||
val extracted = Project.extract(state)
|
||||
val structure = extracted.structure
|
||||
val comp = structure.compiledMap
|
||||
for {
|
||||
p <- structure.allProjectRefs
|
||||
scope = (Scope.Global.in(p): @nowarn)
|
||||
key = scalaVersion.in(scope)
|
||||
definingScope = structure.data.definingScope(key.scope, key.key)
|
||||
definingScoped = definingScope match {
|
||||
case Some(sc) => Some(ScopedKey(sc, key.key))
|
||||
case _ => None
|
||||
}
|
||||
sv <- extracted.getOpt(key)
|
||||
isPlugin = extracted.get(sbtPlugin.in(scope))
|
||||
mb = extracted.get(isMetaBuild.in(scope))
|
||||
auto = extracted.get(autoScalaLibrary.in(scope))
|
||||
msi = extracted.get(managedScalaInstance.in(scope))
|
||||
(_, sk) = extracted.runTask(skip.in(scope.in(publish.key): @nowarn), state)
|
||||
display = p match {
|
||||
case ProjectRef(_, id) => id
|
||||
case _ | null => Reference.display(p)
|
||||
}
|
||||
c <- comp.get(definingScoped.getOrElse(key.scopedKey))
|
||||
setting <- c.settings.headOption
|
||||
} if (auto && msi && !isPlugin && !mb && !sk)
|
||||
setting.pos match {
|
||||
case LinePosition(path, _) if path.endsWith("Defaults.scala") =>
|
||||
log.warn(
|
||||
s"""scalaVersion for subproject $display fell back to a default value $sv; declare it explicitly in build.sbt:
|
||||
scalaVersion := "$sv""""
|
||||
)
|
||||
case _ => ()
|
||||
}
|
||||
else ()
|
||||
state
|
||||
}
|
||||
|
||||
private[this] case class UnusedKey(
|
||||
scoped: ScopedKey[_],
|
||||
positions: Vector[SourcePosition],
|
||||
data: Option[ScopedKeyData[_]]
|
||||
scoped: ScopedKey[?],
|
||||
positions: Seq[SourcePosition],
|
||||
data: Option[ScopedKeyData[?]]
|
||||
)
|
||||
|
||||
private def definedAtString(settings: Vector[Setting[_]]): Vector[SourcePosition] = {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,12 @@ import sbt.ExposeYourself._
|
|||
taskCancelStrategy := { (state: State) =>
|
||||
new TaskCancellationStrategy {
|
||||
type State = Unit
|
||||
override def onTaskEngineStart(canceller: RunningTaskEngine): Unit = canceller.cancelAndShutdown()
|
||||
override def onTaskEngineStart(canceller: RunningTaskEngine): Unit = {
|
||||
state.currentCommand match {
|
||||
case Some(e) if e.commandLine == "loadp" => ()
|
||||
case _ => canceller.cancelAndShutdown()
|
||||
}
|
||||
}
|
||||
override def onTaskEngineFinish(state: State): Unit = ()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,39 @@
|
|||
@transient
|
||||
lazy val checkScalaVersionWarning = taskKey[Unit]("")
|
||||
|
||||
// exempt publish skipped projects
|
||||
lazy val `scala-version-root` = (project in file("."))
|
||||
.settings(
|
||||
name := "scala-version-root",
|
||||
checkScalaVersionWarning := {
|
||||
val state = Keys.state.value
|
||||
val logging = state.globalLogging
|
||||
val sv = scalaVersion.value
|
||||
val contents = IO.read(logging.backing.file)
|
||||
assert(contents.contains(s"""scalaVersion for subproject nievab1 fell back to a default value $sv"""))
|
||||
assert(!contents.contains(s"""scalaVersion for subproject scala-version-root fell back to a default value $sv"""))
|
||||
assert(!contents.contains(s"""scalaVersion for subproject nievab2 fell back to a default value $sv"""))
|
||||
assert(!contents.contains(s"""scalaVersion for subproject nievab3 fell back to a default value $sv"""))
|
||||
assert(!contents.contains(s"""scalaVersion for subproject nievab4 fell back to a default value $sv"""))
|
||||
()
|
||||
},
|
||||
publish / skip := true,
|
||||
)
|
||||
|
||||
lazy val nievab1 = project
|
||||
|
||||
// exempt plugin projects
|
||||
lazy val nievab2 = project
|
||||
.enablePlugins(SbtPlugin)
|
||||
|
||||
// exempt Java projects
|
||||
lazy val nievab3 = project
|
||||
.settings(
|
||||
autoScalaLibrary := false,
|
||||
)
|
||||
|
||||
// exempt SCALA_HOME projects
|
||||
lazy val nievab4 = project
|
||||
.settings(
|
||||
managedScalaInstance := false,
|
||||
)
|
||||
|
|
@ -0,0 +1 @@
|
|||
> checkScalaVersionWarning
|
||||
Loading…
Reference in New Issue