diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index 71320e636..2e6622174 100755 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -192,7 +192,7 @@ object Defaults extends BuildCommon { allowMachinePath :== true, rootPaths := { val app = appConfiguration.value - val base = app.baseDirectory + val base = app.baseDirectory.getCanonicalFile val boot = app.provider.scalaProvider.launcher.bootDirectory val ih = app.provider.scalaProvider.launcher.ivyHome val coursierCache = csrCacheDirectory.value diff --git a/main/src/main/scala/sbt/Keys.scala b/main/src/main/scala/sbt/Keys.scala index 9265c223f..8756fab7c 100644 --- a/main/src/main/scala/sbt/Keys.scala +++ b/main/src/main/scala/sbt/Keys.scala @@ -537,6 +537,8 @@ object Keys { @deprecated("No longer used", "1.3.0") private[sbt] val executeProgress = settingKey[State => TaskProgress]("Experimental task execution listener.").withRank(DTask) val lintUnused = inputKey[Unit]("Check for keys unused by other settings and tasks.") + val lintIncludeFilter = settingKey[String => Boolean]("Filters key names that should be included in the lint check.") + val lintExcludeFilter = settingKey[String => Boolean]("Filters key names that should be excluded in the lint check.") val excludeLintKeys = settingKey[Set[Def.KeyedInitialize[_]]]("Keys excluded from lintUnused task") val includeLintKeys = settingKey[Set[Def.KeyedInitialize[_]]]("Task keys that are included into lintUnused task") val lintUnusedKeysOnLoad = settingKey[Boolean]("Toggles whether or not to check for unused keys during startup") diff --git a/main/src/main/scala/sbt/Main.scala b/main/src/main/scala/sbt/Main.scala index 68020cdb0..282d7b01f 100644 --- a/main/src/main/scala/sbt/Main.scala +++ b/main/src/main/scala/sbt/Main.scala @@ -39,6 +39,7 @@ import scala.concurrent.ExecutionContext import scala.concurrent.duration.Duration import scala.util.control.NonFatal import sbt.internal.io.Retry +import xsbti.AppProvider /** This class is the entry point for sbt. */ final class xMain extends xsbti.AppMain { @@ -46,6 +47,16 @@ final class xMain extends xsbti.AppMain { new XMainConfiguration().run("xMain", configuration) } private[sbt] object xMain { + private[sbt] def dealiasBaseDirectory(config: xsbti.AppConfiguration): xsbti.AppConfiguration = { + val dealiasedBase = config.baseDirectory.getCanonicalFile + if (config.baseDirectory == dealiasedBase) config + else + new xsbti.AppConfiguration { + override def arguments: Array[String] = config.arguments() + override val baseDirectory: File = dealiasedBase + override def provider: AppProvider = config.provider() + } + } private[sbt] def run(configuration: xsbti.AppConfiguration): xsbti.MainResult = try { import BasicCommandStrings.{ DashClient, DashDashClient, runEarly } @@ -60,18 +71,18 @@ private[sbt] object xMain { val isClient: String => Boolean = cmd => (cmd == DashClient) || (cmd == DashDashClient) val isBsp: String => Boolean = cmd => (cmd == "-bsp") || (cmd == "--bsp") if (userCommands.exists(isBsp)) { - BspClient.run(configuration) + BspClient.run(dealiasBaseDirectory(configuration)) } else { Terminal.withStreams { if (clientModByEnv || userCommands.exists(isClient)) { val args = userCommands.toList.filterNot(isClient) - NetworkClient.run(configuration, args) + NetworkClient.run(dealiasBaseDirectory(configuration), args) Exit(0) } else { val closeStreams = userCommands.exists(_ == BasicCommandStrings.CloseIOStreams) val state = StandardMain .initialState( - configuration, + dealiasBaseDirectory(configuration), Seq(defaults, early), runEarly(DefaultsCommand) :: runEarly(InitCommand) :: BootCommand :: Nil ) @@ -93,7 +104,7 @@ private[sbt] object ScriptMain { private[sbt] def run(configuration: xsbti.AppConfiguration): xsbti.MainResult = { import BasicCommandStrings.runEarly val state = StandardMain.initialState( - configuration, + xMain.dealiasBaseDirectory(configuration), BuiltinCommands.ScriptCommands, runEarly(Level.Error.toString) :: Script.Name :: Nil ) @@ -108,7 +119,7 @@ final class ConsoleMain extends xsbti.AppMain { private[sbt] object ConsoleMain { private[sbt] def run(configuration: xsbti.AppConfiguration): xsbti.MainResult = { val state = StandardMain.initialState( - configuration, + xMain.dealiasBaseDirectory(configuration), BuiltinCommands.ConsoleCommands, IvyConsole.Name :: Nil ) diff --git a/main/src/main/scala/sbt/internal/LintUnused.scala b/main/src/main/scala/sbt/internal/LintUnused.scala index ae33b6569..bb549918e 100644 --- a/main/src/main/scala/sbt/internal/LintUnused.scala +++ b/main/src/main/scala/sbt/internal/LintUnused.scala @@ -17,6 +17,14 @@ import sbt.Def._ object LintUnused { lazy val lintSettings: Seq[Setting[_]] = Seq( + lintIncludeFilter := { + val includes = includeLintKeys.value.map(_.scopedKey.key.label) + keyName => includes(keyName) + }, + lintExcludeFilter := { + val excludes = excludeLintKeys.value.map(_.scopedKey.key.label) + keyName => excludes(keyName) || keyName.startsWith("watch") + }, excludeLintKeys := Set( aggregate, concurrentRestrictions, @@ -50,8 +58,8 @@ object LintUnused { val _ = Def.spaceDelimited().parsed // not used yet val state = Keys.state.value val log = streams.value.log - val includeKeys = (includeLintKeys in Global).value map { _.scopedKey.key.label } - val excludeKeys = (excludeLintKeys in Global).value map { _.scopedKey.key.label } + val includeKeys = (lintIncludeFilter in Global).value + val excludeKeys = (lintExcludeFilter in Global).value val result = lintUnused(state, includeKeys, excludeKeys) if (result.isEmpty) log.success("ok") else lintResultLines(result) foreach { log.warn(_) } @@ -61,8 +69,8 @@ object LintUnused { def lintUnusedFunc(s: State): State = { val log = s.log val extracted = Project.extract(s) - val includeKeys = extracted.get(includeLintKeys in Global) map { _.scopedKey.key.label } - val excludeKeys = extracted.get(excludeLintKeys in Global) map { _.scopedKey.key.label } + val includeKeys = extracted.get(lintIncludeFilter in Global) + val excludeKeys = extracted.get(lintExcludeFilter in Global) if (extracted.get(lintUnusedKeysOnLoad in Global)) { val result = lintUnused(s, includeKeys, excludeKeys) lintResultLines(result) foreach { log.warn(_) } @@ -103,8 +111,8 @@ object LintUnused { def lintUnused( state: State, - includeKeys: Set[String], - excludeKeys: Set[String] + includeKeys: String => Boolean, + excludeKeys: String => Boolean ): Seq[(ScopedKey[_], String, Vector[SourcePosition])] = { val extracted = Project.extract(state) val structure = extracted.structure diff --git a/main/src/main/scala/sbt/internal/server/BuildServerProtocol.scala b/main/src/main/scala/sbt/internal/server/BuildServerProtocol.scala index d4d8af20a..31c0946a2 100644 --- a/main/src/main/scala/sbt/internal/server/BuildServerProtocol.scala +++ b/main/src/main/scala/sbt/internal/server/BuildServerProtocol.scala @@ -332,7 +332,7 @@ object BuildServerProtocol { private def internalDependencyConfigurationsSetting = Def.settingDyn { val directDependencies = Keys.internalDependencyConfigurations.value.map { case (project, rawConfigs) => - val configs = rawConfigs.flatMap(_.split(",")).map(ConfigKey.apply) + val configs = rawConfigs.flatMap(_.split(",")).map(name => ConfigKey(name.trim)) (project, configs) } val ref = Keys.thisProjectRef.value diff --git a/main/src/main/scala/sbt/plugins/Giter8TemplatePlugin.scala b/main/src/main/scala/sbt/plugins/Giter8TemplatePlugin.scala index e9492c561..a5cc5efce 100644 --- a/main/src/main/scala/sbt/plugins/Giter8TemplatePlugin.scala +++ b/main/src/main/scala/sbt/plugins/Giter8TemplatePlugin.scala @@ -26,7 +26,7 @@ object Giter8TemplatePlugin extends AutoPlugin { ModuleID( "org.scala-sbt.sbt-giter8-resolver", "sbt-giter8-resolver", - "0.12.0" + "0.13.1" ) cross CrossVersion.binary, "sbtgiter8resolver.Giter8TemplateResolver" )