From 575e65796214e638571697c9cb97578dbab4b89b Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 25 Mar 2014 00:20:11 -0400 Subject: [PATCH] Default AutoPlugin to an empty root plugin --- main/src/main/scala/sbt/Plugins.scala | 8 +- .../main/scala/sbt/plugins/GlobalModule.scala | 3 +- .../main/scala/sbt/plugins/IvyModule.scala | 4 +- .../main/scala/sbt/plugins/JvmModule.scala | 4 +- .../project/auto-plugins/project/Q.scala | 28 +++--- .../binary-plugin/changes/define/A.scala | 9 +- src/sphinx/Extending/Plugins.rst | 87 +++++++++++-------- 7 files changed, 72 insertions(+), 71 deletions(-) diff --git a/main/src/main/scala/sbt/Plugins.scala b/main/src/main/scala/sbt/Plugins.scala index 9451940c3..63795bd6d 100644 --- a/main/src/main/scala/sbt/Plugins.scala +++ b/main/src/main/scala/sbt/Plugins.scala @@ -25,8 +25,8 @@ For example, the following will automatically add the settings in `projectSettin to a project that has both the `Web` and `Javascript` plugins enabled. object Plugin extends sbt.AutoPlugin { - def requires = Web && Javascript - def trigger = allRequirements + override def requires = Web && Javascript + override def trigger = allRequirements override def projectSettings = Seq(...) object autoImport { @@ -59,11 +59,11 @@ abstract class AutoPlugin extends Plugins.Basic with PluginsFunctions * * When this method returns `noTrigger`, and `requires` method returns `Web && Javascript`, this plugin * instance will be added only if the build user enables it, but it will automatically add both `Web` and `Javascript`. */ - def trigger: PluginTrigger + def trigger: PluginTrigger = noTrigger /** This AutoPlugin requires the plugins the [[Plugins]] matcher returned by this method. See [[trigger]]. */ - def requires: Plugins + def requires: Plugins = empty val label: String = getClass.getName.stripSuffix("$") diff --git a/main/src/main/scala/sbt/plugins/GlobalModule.scala b/main/src/main/scala/sbt/plugins/GlobalModule.scala index 00485a5e0..9ee80889e 100644 --- a/main/src/main/scala/sbt/plugins/GlobalModule.scala +++ b/main/src/main/scala/sbt/plugins/GlobalModule.scala @@ -10,8 +10,7 @@ import Def.Setting */ object GlobalModule extends AutoPlugin { // This is included by default - def requires = empty - def trigger = allRequirements + override def trigger = allRequirements override lazy val projectSettings: Seq[Setting[_]] = Defaults.coreDefaultSettings diff --git a/main/src/main/scala/sbt/plugins/IvyModule.scala b/main/src/main/scala/sbt/plugins/IvyModule.scala index 0b01f4670..58202c852 100644 --- a/main/src/main/scala/sbt/plugins/IvyModule.scala +++ b/main/src/main/scala/sbt/plugins/IvyModule.scala @@ -16,8 +16,8 @@ import Def.Setting object IvyModule extends AutoPlugin { // We are automatically included on everything that has the global module, // which is automatically included on everything. - def requires = GlobalModule - def trigger = allRequirements + override def requires = GlobalModule + override def trigger = allRequirements override lazy val projectSettings: Seq[Setting[_]] = Classpaths.ivyPublishSettings ++ Classpaths.ivyBaseSettings diff --git a/main/src/main/scala/sbt/plugins/JvmModule.scala b/main/src/main/scala/sbt/plugins/JvmModule.scala index f50fb1e7d..9cd1840ce 100644 --- a/main/src/main/scala/sbt/plugins/JvmModule.scala +++ b/main/src/main/scala/sbt/plugins/JvmModule.scala @@ -17,8 +17,8 @@ import Def.Setting object JvmModule extends AutoPlugin { // We are automatically enabled for any IvyModule project. We also require its settings // for ours to work. - def requires = IvyModule - def trigger = allRequirements + override def requires = IvyModule + override def trigger = allRequirements override lazy val projectSettings: Seq[Setting[_]] = Defaults.runnerSettings ++ diff --git a/sbt/src/sbt-test/project/auto-plugins/project/Q.scala b/sbt/src/sbt-test/project/auto-plugins/project/Q.scala index 5eb6f792c..f135d444b 100644 --- a/sbt/src/sbt-test/project/auto-plugins/project/Q.scala +++ b/sbt/src/sbt-test/project/auto-plugins/project/Q.scala @@ -6,13 +6,9 @@ package sbttest // you need package http://stackoverflow.com/questions/9822008/ object Imports { - trait EmptyAutoPlugin extends AutoPlugin { - def requires = empty - def trigger = noTrigger - } - object A extends EmptyAutoPlugin - object B extends EmptyAutoPlugin - object E extends EmptyAutoPlugin + object A extends AutoPlugin + object B extends AutoPlugin + object E extends AutoPlugin lazy val q = config("q") lazy val p = config("p").extend(q) @@ -25,21 +21,19 @@ object Imports object X extends AutoPlugin { val autoImport = Imports - def requires = Plugins.empty - def trigger = noTrigger } import Imports._ object D extends AutoPlugin { - def requires: Plugins = E - def trigger = allRequirements + override def requires: Plugins = E + override def trigger = allRequirements } object Q extends AutoPlugin { - def requires: Plugins = A && B - def trigger = allRequirements + override def requires: Plugins = A && B + override def trigger = allRequirements override def projectConfigurations: Seq[Configuration] = p :: @@ -67,8 +61,8 @@ object Q extends AutoPlugin object R extends AutoPlugin { // NOTE - Only plugins themselves support exclusions... - def requires = Q - def trigger = allRequirements + override def requires = Q + override def trigger = allRequirements override def projectSettings = Seq( // tests proper ordering: R requires Q, so Q settings should come first @@ -82,8 +76,8 @@ object R extends AutoPlugin // Unless explicitly loaded by the build user, this will not be activated. object S extends AutoPlugin { - def requires = Q - def trigger = noTrigger + override def requires = Q + override def trigger = noTrigger override def projectSettings = Seq( del in q += " S" diff --git a/sbt/src/sbt-test/project/binary-plugin/changes/define/A.scala b/sbt/src/sbt-test/project/binary-plugin/changes/define/A.scala index 7906da1f2..dde89c439 100644 --- a/sbt/src/sbt-test/project/binary-plugin/changes/define/A.scala +++ b/sbt/src/sbt-test/project/binary-plugin/changes/define/A.scala @@ -6,20 +6,17 @@ import Keys._ object C extends AutoPlugin { object autoImport { object bN extends AutoPlugin { - def requires = empty - def trigger = allRequirements + override def trigger = allRequirements } lazy val check = taskKey[Unit]("Checks that the AutoPlugin and Build are automatically added.") } - def requires = empty - def trigger = noTrigger } import C.autoImport._ object A extends AutoPlugin { - def requires = bN - def trigger = allRequirements + override def requires = bN + override def trigger = allRequirements override def projectSettings = Seq( check := {} ) diff --git a/src/sphinx/Extending/Plugins.rst b/src/sphinx/Extending/Plugins.rst index 77f5da73e..4b155b254 100644 --- a/src/sphinx/Extending/Plugins.rst +++ b/src/sphinx/Extending/Plugins.rst @@ -225,19 +225,17 @@ To make a plugin, create a project and configure `sbtPlugin` to `true`. Then, write the plugin code and publish your project to a repository. The plugin can be used as described in the previous section. -A plugin can implement `sbt.AutoImpot`. The contents of an AutoImport -singleton, declared like `object MyPlugin extends AutoImport`, are -wildcard imported in `set`, `eval`, and `.sbt` files. Typically, -this is used to provide new keys (SettingKey, TaskKey, or InputKey) or -core methods without requiring an import or qualification. - -In addition, a plugin can implement the `AutoPlugin` class. This has additoinal features, such as - +* Automatically importing selective names to `.sbt` files. * Specifying plugin dependencies. * Automatically activating itself when all dependencies are present. * Specifying `projectSettings`, `buildSettings`, and `globalSettings` as appropriate. -The AutoPlugin's `projectSettings` is automatically appended to each project's settings, when its dependencies also exist on that project +When an AutoPlugin provides a stable field such as `val` or `object` named `autoImport`, +the contents of the field are wildcard imported in in `set`, `eval`, and `.sbt` files. Typically, +this is used to provide new keys (SettingKey, TaskKey, or InputKey) or +core methods without requiring an import or qualification. + +The AutoPlugin's `projectSettings` is automatically appended to each project's settings, when its dependencies also exist on that project. The `requires` method defines the dependencies to other plugins. The `trigger` method defines the conditions by which this plugin's settings are automatically activated. The `buildSettings` is appended to each build's settings (that is, `in ThisBuild`). @@ -246,7 +244,6 @@ These allow a plugin to automatically provide new functionality or new defaults. One main use of this feature is to globally add commands, such as for IDE plugins. Use `globalSettings` to define the default value of a setting. - Example Plugin -------------- @@ -258,34 +255,51 @@ An example of a typical plugin: sbtPlugin := true - name := "example-plugin" + name := "sbt-obfuscate" organization := "org.example" -`MyPlugin.scala`: +`Plugin.scala`: :: + package sbtobfuscate + import sbt._ - object MyPlugin extends AutoPlugin + + object Plugin extends AutoPlugin { - // Only enable this plugin for projects which are JvmModules. - def trigger = allRequirements - def requires = sbt.plugins.JvmModule + // by definging autoImport, these are automatically imported into user's `*.sbt` + object autoImport + { + // configuration points, like the built in `version`, `libraryDependencies`, or `compile` + val obfuscate = taskKey[Seq[File]]("Obfuscates files.") + val obfuscateLiterals = settingKey[Boolean]("Obfuscate literals.") + + // default values for the tasks and settings + lazy val baseObfuscateSettings: Seq[sbt.Def.Setting[_]] = Seq( + obfuscate := { + Obfuscate(sources.value, (obfuscateLiterals in obfuscate).value) + }, + obfuscateLiterals in obfuscate := false + ) + } + + import autoImport._ + override def requires = sbt.plugins.JvmModule + + // This plugin is automatically enabled for projects which are JvmModules. + override def trigger = allRequirements - // configuration points, like the built in `version`, `libraryDependencies`, or `compile` - // by implementing Plugin, these are automatically imported in a user's `build.sbt` - val newTask = taskKey[Unit]("A new task.") - val newSetting = settingKey[String]("A new setting.") - // a group of settings that are automatically added to projects. - val projectSettings = Seq( - newSetting := "test", - newTask := println(newSetting.value) - ) + override val projectSettings = + inConfig(Compile)(baseObfucscateSettings) ++ + inConfig(Test)(baseObfuscateSettings) + } - // alternatively, by overriding `settings`, they could be automatically added to a Project - // override val settings = Seq(...) + object Obfuscate + { + def apply(sources: Seq[File]): Seq[File] := sources } Usage example @@ -293,20 +307,18 @@ Usage example A build definition that uses the plugin might look like: -`build.sbt` +`obfuscate.sbt` :: - MyPlugin.newSettings - - newSetting := "example" + obfuscateLiterals in obfuscate := true Root Plugins ------------ Some plugins should always be explicitly enabled on projects. Sbt calls these root plugins, i.e. plugins -that are "root" nodes in the plugin depdendency graph. To define a root plugin, set the `trigger` method to `noTrigger` and the `requires` method to `empty`. +that are "root" nodes in the plugin depdendency graph. `AutoPlugin` by default defines a root plugin. Example command root plugin ---------------------- @@ -319,21 +331,20 @@ A basic plugin that adds commands looks like: sbtPlugin := true - name := "example-plugin" + name := "sbt-sample" organization := "org.example" -`MyPlugin.scala` +`Plugin.scala` :: + package sbtsample + import sbt._ import Keys._ - object MyPlugin extends AutoPlugin + object Plugin extends AutoPlugin { - def trigger = noTrigger - def requires = empty - override lazy val projectSettings = Seq(commands += myCommand) lazy val myCommand =