Search code examples
scalasbtsbt-plugin

Overridings mappings in an SBT plugin


I'm trying to write a very basic SBT-plugin to publish and consume a source-only package to deliver thrift IDL-files to other services that want to call my API. Why is a long story, but this question is about SBT and not thrift.

When I write the following in build.sbt works as intended (only files under src/main are included in the jar:

name := "test-dep2"

scalaVersion := "2.12.5"

lazy val root = (project in file(".")).
  settings(
    inThisBuild(List(
      organization := "com.example",
      scalaVersion := "2.12.4",
      version      := "0.1.1-SNAPSHOT")),
    name := "test-dep2",
    mappings in (Compile, packageBin) := {
      (sourceDirectory.value / "main" ** "*.*").get. map { file =>
        (file, file.relativeTo(baseDirectory.value).get.toString )
      }
    }
 )

The below build.sbt however does not work (ie. the jar contains the compiled classes, as normal):

name := "test-dep2"

scalaVersion := "2.12.5"

lazy val root = (project in file(".")).
  settings(
    inThisBuild(List(
      organization := "com.example",
      scalaVersion := "2.12.4",
      version      := "0.1.1-SNAPSHOT")),
    name := "test-dep2"
  ).enablePlugins(com.example.sbt.MyPlugin)

This is MyPlugin:

package com.example

import sbt.Keys._
import sbt._

object MyPlugin extends AutoPlugin {

  object autoImport {
    val someTask = taskKey[Unit]("Some task")
  }

  import autoImport._

  val sbtSourceSettings: Seq[Setting[_]] = Seq(
    someTask := {
      println("I'm doing something!")
    },
    mappings in (Compile, packageBin) := {
      (sourceDirectory.value / "main" ** "*.*").get. map { file =>
        (file, file.relativeTo(baseDirectory.value).get.toString )}
    }
  )

  override lazy val projectSettings: Seq[Def.Setting[_]] = sbtSourceSettings
}

The plugin is added to the project through project/plugins.sbt, containing the below:

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

lazy val assemblyPlugin = RootProject(uri("file:///home/tjarvstrand/src/sbt-source-only-dependency"))

I know that the plugin is loaded because I can run sbt root/someTask and it prints I'm doing something. What am I doing wrong?


Solution

  • I am not that sure how it works, but plugins that define the same settings can override each other. If you want to override the settings of AutoPlugin 'X' you will have to add 'X' to the dependencies of your AutoPlugin by overriding requires:

    override def requires = X
    

    The AutoPlugin with the most basic settings is the JvmPlugin. Adding this to requires helped me in a similar situation where I tried to add additional artifacts to my library via AutoPlugin. So it might help you, too.

    override def requires = JvmPlugin
    

    Otherwise, you might want to look which other plugins enabled in your build modify mappings in (Compile, packageBin).