Search code examples
scalaconfigurationsbtsettingssbt-plugin

SBT plugin - User defined configuration for Command via their build.sbt


I'm writing an SBT Plugin that adds a Command and would like users to be able to configure this Command by setting variables in their build.sbt. What is the simplest way to achieve this?

Here is an simplified example of what the Plugin looks like:

import sbt.Keys._
import sbt._

object MyPlugin extends Plugin {

  override lazy val settings = Seq(commands += Command.args("mycommand", "myarg")(myCommand))

  def myCommand = (state: State, args: Seq[String]) => {

    //Logic for command...

    state
  }
}

I would like someone to be able to add the follow to their build.sbt file:

newSetting := "light"

How do I make this available as a String variable from inside the myCommand Command above?


Solution

  • Take a look at the example here: http://www.scala-sbt.org/release/docs/Extending/Plugins.html#example-plugin

    In this example, a task and setting are defined:

    val newTask = TaskKey[Unit]("new-task")
    val newSetting = SettingKey[String]("new-setting")
    
    val newSettings = Seq(
      newSetting := "test",
      newTask <<= newSetting map { str => println(str) }
    )
    

    A user of your plugin could then provide their own value for the newSetting setting in their build.sbt:

    newSetting := "light"
    

    EDIT

    Here's another example, closer to what you're going for:

    Build.scala:

    import sbt._                                                
    import Keys._                                               
    
    object HelloBuild extends Build {                           
    
        val newSetting = SettingKey[String]("new-setting", "a new setting!")
    
        val myTask = TaskKey[State]("my-task")                  
    
        val mySettings = Seq(                                   
          newSetting := "default",                              
          myTask <<= (state, newSetting) map { (state, newSetting) =>  
            println("newSetting: " + newSetting)                
            state
          }
        )
    
        lazy val root =
          Project(id = "hello",
                  base = file("."),
                  settings = Project.defaultSettings ++ mySettings)            
    }
    

    With this configuration, you can run my-task at the sbt prompt, and you'll see newSetting: default printed to the console.

    You can override this setting in build.sbt:

    newSetting := "modified"
    

    Now, when you run my-task at the sbt prompt, you'll see newSetting: modified printed to the console.

    EDIT 2

    Here's a stand-alone version of the example above: https://earldouglas.com/ext/stackoverflow.com/questions/17038663/