From d86e52830e0f1353230501c49255c8b20fd8338e Mon Sep 17 00:00:00 2001 From: Tim Harper Date: Sun, 17 Jan 2016 20:51:10 -0700 Subject: [PATCH 1/3] Amend contributing build instructions to help solve potential build problems --- CONTRIBUTING.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 31daacd87..d601513ac 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -149,6 +149,10 @@ Build from source 4. If a project has `project/build.properties` defined, either delete the file or change `sbt.version` to `0.13.10-SNAPSHOT`. +## Diagnosing build failures + +Globally included plugins can interfere building `sbt`; if you are getting errors building sbt, try disabling all globally included plugins and try again. + Building Documentation ---------------------- From d6c80ba1bd1da28d760a9de27699e1995ddcb395 Mon Sep 17 00:00:00 2001 From: Tim Harper Date: Mon, 18 Jan 2016 14:18:53 -0700 Subject: [PATCH 2/3] add notes on running tests --- CONTRIBUTING.md | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d601513ac..314e1079c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -153,7 +153,39 @@ Build from source Globally included plugins can interfere building `sbt`; if you are getting errors building sbt, try disabling all globally included plugins and try again. +Running Tests +============= + +sbt has an extensive test suite of Unit tests and Integration tests! + +Unit / Functional tests +----------------------- + +Various functional and unit tests are defined throughout the +project. To run all of them, run `sbt test`. You can run a single test +suite with `sbt testOnly` + +Integration tests +----------------- + +Scripted integration tests reside in `sbt/src/sbt-test` and are +written using the same testing infrastructure sbt plugin authors can +use to test their own plugins with sbt. You can read more about this +style of tests [here](http://eed3si9n.com/testing-sbt-plugins). + +You can run the integration tests with the `sbt scripted` sbt +command. To run a single test, such as the test in +`sbt/src/sbt-test/project/global-plugin`, simply run: + + sbt scripted project/global-plugin + +Please note that these tests run PAINFULLY slow if the version set in +`build.sbt` is set to SNAPSHOT, as every time the scripted test boots +up a test instance of sbt, remote mirrors are scanned for possible +updates. It is recommended that you set the version suffix to +`-devel`, as in `0.13.10-devel`. + Building Documentation ----------------------- +====================== The scala-sbt.org site documentation is a separate project [website](https://github.com/sbt/website). Follow [the steps in the README](https://github.com/sbt/website#scala-sbtorg) to generate the documentation. From 7d86bc70d3f19b9587772bd19575713829b9621b Mon Sep 17 00:00:00 2001 From: Tim Harper Date: Mon, 18 Jan 2016 00:21:26 -0700 Subject: [PATCH 3/3] bugfix - apply autoImports for global plugins at global configuration stage Previously, the autoimports for globally defined plugins were not imported for global configuration files, although they were imported for project configuration files. This patch causes an additional plugin discovery phase to happen during global config evaluation, so that auto-plugins can be detected and their imports subsequently included. --- main/src/main/scala/sbt/Load.scala | 23 ++++++++++++++++++- notes/0.13.10.markdown | 4 ++++ .../global-plugin/global/plugins/A.scala | 10 ++++++++ .../global-plugin/global/plugins/B.scala | 7 ++++++ .../global/useGlobalAutoPlugin.sbt | 2 ++ .../global/useGlobalLegacyPlugin.sbt | 5 ++++ 6 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 sbt/src/sbt-test/project/global-plugin/global/plugins/B.scala create mode 100644 sbt/src/sbt-test/project/global-plugin/global/useGlobalAutoPlugin.sbt create mode 100644 sbt/src/sbt-test/project/global-plugin/global/useGlobalLegacyPlugin.sbt diff --git a/main/src/main/scala/sbt/Load.scala b/main/src/main/scala/sbt/Load.scala index 3f41f5546..e5d8a5113 100755 --- a/main/src/main/scala/sbt/Load.scala +++ b/main/src/main/scala/sbt/Load.scala @@ -74,7 +74,10 @@ object Load { def buildGlobalSettings(base: File, files: Seq[File], config: sbt.LoadBuildConfiguration): ClassLoader => Seq[Setting[_]] = { val eval = mkEval(data(config.globalPluginClasspath), base, defaultEvalOptions) - val imports = BuildUtil.baseImports ++ BuildUtil.importAllRoot(config.globalPluginNames) + + val imports = BuildUtil.baseImports ++ + config.detectedGlobalPlugins.imports + loader => { val loaded = EvaluateConfigurations(eval, files, imports)(loader) // TODO - We have a potential leak of config-classes in the global directory right now. @@ -701,10 +704,13 @@ object Load { loadedPlugins: sbt.LoadedPlugins, eval: () => Eval, memoSettings: mutable.Map[File, LoadedSbtFile]): DiscoveredProjects = { + // Default sbt files to read, if needed lazy val defaultSbtFiles = configurationSources(projectBase) + // Classloader of the build val loader = loadedPlugins.loader + // How to load an individual file for use later. // TODO - We should import vals defined in other sbt files here, if we wish to // share. For now, build.sbt files have their own unique namespace. @@ -713,11 +719,13 @@ object Load { // How to merge SbtFiles we read into one thing def merge(ls: Seq[LoadedSbtFile]): LoadedSbtFile = (LoadedSbtFile.empty /: ls) { _ merge _ } // Loads a given file, or pulls from the cache. + def memoLoadSettingsFile(src: File): LoadedSbtFile = memoSettings.getOrElse(src, { val lf = loadSettingsFile(src) memoSettings.put(src, lf.clearProjects) // don't load projects twice lf }) + // Loads a set of sbt files, sorted by their lexical name (current behavior of sbt). def loadFiles(fs: Seq[File]): LoadedSbtFile = merge(fs.sortBy(_.getName).map(memoLoadSettingsFile)) @@ -954,6 +962,19 @@ final case class LoadBuildConfiguration( log: Logger) { lazy val (globalPluginClasspath, globalPluginLoader) = Load.pluginDefinitionLoader(this, Load.globalPluginClasspath(globalPlugin)) lazy val globalPluginNames = if (globalPluginClasspath.isEmpty) Nil else Load.getPluginNames(globalPluginClasspath, globalPluginLoader) + + private[sbt] lazy val globalPluginDefs = { + val pluginData = globalPlugin match { + case Some(x) => PluginData(x.data.fullClasspath, x.data.internalClasspath, Some(x.data.resolvers), Some(x.data.updateReport), Nil) + case None => PluginData(globalPluginClasspath, Nil, None, None, Nil) + } + val baseDir = globalPlugin match { + case Some(x) => x.base + case _ => stagingDirectory + } + Load.loadPluginDefinition(baseDir, this, pluginData) + } + lazy val detectedGlobalPlugins = globalPluginDefs.detected } final class IncompatiblePluginsException(msg: String, cause: Throwable) extends Exception(msg, cause) diff --git a/notes/0.13.10.markdown b/notes/0.13.10.markdown index c787503cd..b42df40fa 100644 --- a/notes/0.13.10.markdown +++ b/notes/0.13.10.markdown @@ -12,6 +12,7 @@ [@hgiddens]: https://github.com/hgiddens [@DavidPerezIngeniero]: https://github.com/DavidPerezIngeniero [@romanowski]: https://github.com/romanowski + [@timcharper]: https://github.com/timcharper [2302]: https://github.com/sbt/sbt/issues/2302 [2303]: https://github.com/sbt/sbt/pull/2303 [1967]: https://github.com/sbt/sbt/issues/1967 @@ -71,6 +72,8 @@ [1616]: https://github.com/sbt/sbt/issues/1616 [2313]: https://github.com/sbt/sbt/pull/2313 [2343]: https://github.com/sbt/sbt/pull/2343 + [2120]: https://github.com/sbt/sbt/issues/2120 + [2399]: https://github.com/sbt/sbt/pull/2399 ### Fixes with compatibility implications @@ -128,6 +131,7 @@ - Fixes launcher configuration to add `sbt-ivy-snapshots` repository to resolve nightly builds. [@eed3si9n][@eed3si9n] - Fixes performance issues during tree traversal in the incremental compiler. [#2343][2343] by [@adriaanm][@adriaanm] - Fixes the tracking of self types and F-bounded existential types in the incremental compiler. [#2343][2343] by [@adriaanm][@adriaanm] +- Fixes autoImports for AutoPlugins for global configuration files. [#2120][2120]/[#2399][2399] by [@timcharper][@timcharper] ### Def.settings diff --git a/sbt/src/sbt-test/project/global-plugin/global/plugins/A.scala b/sbt/src/sbt-test/project/global-plugin/global/plugins/A.scala index b75a623b5..bbf9fc243 100644 --- a/sbt/src/sbt-test/project/global-plugin/global/plugins/A.scala +++ b/sbt/src/sbt-test/project/global-plugin/global/plugins/A.scala @@ -1,5 +1,15 @@ package test +import sbt._ + object Global { val x = 3 } + +object GlobalAutoPlugin extends AutoPlugin { + + object autoImport { + lazy val globalAutoPluginSetting = settingKey[String]("A top level setting declared in a plugin.") + } + +} diff --git a/sbt/src/sbt-test/project/global-plugin/global/plugins/B.scala b/sbt/src/sbt-test/project/global-plugin/global/plugins/B.scala new file mode 100644 index 000000000..9d28ecc84 --- /dev/null +++ b/sbt/src/sbt-test/project/global-plugin/global/plugins/B.scala @@ -0,0 +1,7 @@ +import sbt._ + +object GlobalLegacyPlugin extends sbt.Plugin { + import sbt.Keys._ + val globalLegacyPluginSetting = SettingKey[String]("A top level setting declared by a legacy plugin") + val useGlobalLegacyPluginSetting = globalLegacyPluginSetting in Global +} diff --git a/sbt/src/sbt-test/project/global-plugin/global/useGlobalAutoPlugin.sbt b/sbt/src/sbt-test/project/global-plugin/global/useGlobalAutoPlugin.sbt new file mode 100644 index 000000000..db85875ab --- /dev/null +++ b/sbt/src/sbt-test/project/global-plugin/global/useGlobalAutoPlugin.sbt @@ -0,0 +1,2 @@ +// If the GlobalAutoPlugin.autoImport._ does not get brought in, this will fail: +globalAutoPluginSetting := "bar" diff --git a/sbt/src/sbt-test/project/global-plugin/global/useGlobalLegacyPlugin.sbt b/sbt/src/sbt-test/project/global-plugin/global/useGlobalLegacyPlugin.sbt new file mode 100644 index 000000000..d17e24a85 --- /dev/null +++ b/sbt/src/sbt-test/project/global-plugin/global/useGlobalLegacyPlugin.sbt @@ -0,0 +1,5 @@ +/* + If the GlobalLegacyPlugin 'in' statements do not register and get + brought in to the global scope, this will fail + */ +globalLegacyPluginSetting := "foo"