Carl
Carl

Reputation: 7554

sbt - basic local plugin setup?

I have a particular task I'd like to automate as part of a build process, but I'm stuck at grammar stage with sbt. I'm trying to do a helloworld-ish task using two local projects, one the plugin and one a test using that plugin, but I can't get the new task in the plugin (sampleIntTask) to be available when using sbt on the test project.

I have the following in the filesystem:

/plugin/
  Plugin.scala
  build.sbt
/test-using-plugin/
  build.sbt
  /project/plugins.sbt

For my helloworld-ish plugin: in Plugin.scala :

import sbt._
import Keys._
object MyPlugin extends Plugin {
  val sampleIntTask = taskKey[Int]("sum 1 and 2")
  sampleIntTask := {
    val sum = 1 + 2
    println("sum: " + sum)
    sum
  }
}

in plugin/build.sbt:

sbtPlugin := true

name := "myPlugin"

version := "0.1"

scalaVersion := "2.10.3"

and for testing it: in test-using-plugin/build.sbt:

name := "test-test-test"

version := "0.1"

scalaVersion := "2.10.3"

and in test-using-plugin/project/plugins.sbt:

lazy val root = project.in( file(".") ).dependsOn( testPlugin )

lazy val testPlugin = file("/Users/cap10/gitprojects/processing")

When I /test-project$ sbt sampleIntTask, I get:

[info] Set current project to test-using-plugin (in build ...)
> sampleIntTask
[error] Not a valid command: sampleIntTask
[error] Not a valid project ID: sampleIntTask
[error] Expected ':' (if selecting a configuration)
[error] Not a valid key: sampleIntTask (similar: compileInputs)
[error] sampleIntTask
[error]              ^

I feel like this is about the right level of complexity for this test (define plugin project config, define plugin project behavior, define test project config, add dependency on plugin project), but I'd be unsurprised if I'm totally off based on the grammar as I can't make heads or tails of the sbt intro.

Upvotes: 1

Views: 1008

Answers (1)

Eugene Yokota
Eugene Yokota

Reputation: 95624

build.sbt

If you do not need to share the settings across multiple builds, you can just add your settings to test-using-plugin/custom.sbt:

val sampleIntTask = taskKey[Int]("sum 1 and 2")

sampleIntTask := {
  val sum = 1 + 2
  println("sum: " + sum)
  sum
}

and forget about the plugin.

Local plugin way

I haven't tested the other parts, but your Plugin.scala is wrong. The setting expression needs to be in a setting sequence:

import sbt._
import Keys._

object MyPlugin extends Plugin {
  val sampleIntTask = taskKey[Int]("sum 1 and 2")

  lazy val baseMyPluginSettings: Seq[sbt.Def.Setting[_]] = Seq(
    sampleIntTask := {
      val sum = 1 + 2
      println("sum: " + sum)
      sum
    }
  )
  lazy val myPluginSettings: Seq[sbt.Def.Setting[_]] = baseMyPluginSettings
}

And in your test-using-plugin/build.sbt add:

myPluginSettings

If you have to share settings across the builds, you can make a plugin like this or put them in global sbt file. The use of global sbt should be limited to user-specific settings and commands, so that's out. Personally, I would publish the plugin locally using publishLocal so it doesn't depend on specific file path. You can use the locally published plugin like any other plugins:

addSbtPlugin("com.example" % "myPlugin" % "0.1" changing())

By using "-SNAPSHOT" version or by calling changing(), sbt will check for the latest.

Upvotes: 3

Related Questions