Ford O.
Ford O.

Reputation: 1498

Sbt: How to define task for all projects?

I would like to be able to define a task for all projects in my sbt.build:

lazy val project1 = project.in(`.` /  "project1)
   ...
lazy val project2 = 
   ...

lazy val upload = taskKey[Unit]("upload a config file from project to server)
upload := { 
   val file = baseDirectory.value / "config.json"
   ...
}

The problem is this definition works only when I call sbt upload, but I would like to be able to call it for each subproject: sbt project1/upload and sbt project2/upload.

Is there a way to do it, without using inputKey?

Upvotes: 6

Views: 1251

Answers (2)

Eugene Yokota
Eugene Yokota

Reputation: 95624

See Organizing the build:

For more advanced users, another way of organizing your build is to define one-off auto plugins in project/*.scala. By defining triggered plugins, auto plugins can be used as a convenient way to inject custom tasks and commands across all subprojects.

project/UploadPlugin.scala

package something

import sbt._
import Keys._

object UploadPlugin extends AutoPlugin {
  override def requires = sbt.plugins.JvmPlugin
  override def trigger = allRequirements

  object autoImport {
    val upload = taskKey[Unit]("upload a config file from project to server")
  }
  import autoImport._

  override lazy val projectSettings = Seq(
    upload := {
      val n = name.value
      println(s"uploading $n..")
    }
  )
}

build.sbt

Here's how you can use it:

ThisBuild / organization := "com.example"
ThisBuild / scalaVersion := "2.12.5"
ThisBuild / version      := "0.1.0-SNAPSHOT"

lazy val root = (project in file("."))
  .aggregate(project1, project2)
  .settings(
    name := "Hello"
  )

lazy val project1 = (project in file("project1"))

lazy val project2 = (project in file("project2"))

build.sbt does not have to mention anything about UploadPlugin, since it's a triggered plugin. From the shell you can call:

sbt:Hello> project1/upload
uploading project1..
[success] Total time: 0 s, completed Jul 20, 2018
sbt:Hello> project2/upload
uploading project2..
[success] Total time: 0 s, completed Jul 20, 2018

Upvotes: 9

C4stor
C4stor

Reputation: 8026

You can add the task as a setting of the project you want :

lazy val uploadTask = {
   lazy val upload = taskKey[Unit]("upload a config file from project to server)
upload := { 
   val file = baseDirectory.value / "config.json"
   ...
   }
}

project.in(`.` /  "project1).settings(uploadTask)

Upvotes: -3

Related Questions