Search code examples
sbtdirectory-structuresbt-plugin

Sbt in project plugin, how to structure them?


We do have a custom plugin as a single file in our project folder:

acme-project
 |- ...
 |- project
 |   |- CustomPlugin.scala

object CustomPlugin extends AutoPlugin { 
  // ...

That was simple and easy until that plugin started to grow...

In the first step, we added more classes/objects to the same source file. However, it continues to grow and I would like to add more structure via packages.

acme-project
 |- ...
 |- project
 |   |- CustomPlugin.scala
 |   |- SupportingClass.scala
 |   |- acme
 |   |   |- plugin
 |   |   |   |- PackagedClass.scala

My CustomPlugin seems to be able to use the SupportingClass from the folder, whenever this class declare another package. However, I cannot use the PackagedClass :

[error] /~/acme-project/project/CustomPlugin.scala:1:8: not found: object acme
[error] import mega.plugin.PackagedClass
[error]             ^

I tried to add one src/main/scala folder but have the same kind of import errors.

So, I would like to know if there are ways to create large/structured plugins inside a project without making a complete one?

I would like to keep the simplicity of this format where I do not have to publish my plugin. Having it inside a dedicated module would be ok.

Thanks


Solution

  • One way to do this is to restructure your plugin as its own sbt project, then load it as a module dependency in your project's plugins.sbt.


    Move the code to its own directory. This can be anywhere you like, e.g.:

    • acme-project/project/my-custom-plugin/
    • acme-project/my-custom-plugin/
    • some-other-path/my-custom-plugin/

    Write a my-custom-plugin/build.sbt with at least these settings:

    enablePlugins(SbtPlugin)
    sbtPlugin := true
    scalaVersion := "2.12.16"
    name := "my-custom-plugin"
    

    Add it to your project as a module dependency in acme-project/project/plugins.sbt:

    // For acme-project/project/my-custom-plugin/
    val myCustomPlugin =
      project in file("my-custom-plugin")
    
    // For acme-project/my-custom-plugin/
    val myCustomPlugin =
      ProjectRef(file("../../my-custom-plugin"), "my-custom-plugin")
    
    // For some-other-path/my-custom-plugin/
    val myCustomPlugin =
      ProjectRef(file("/path/to/my-custom-plugin", "my-custom-plugin")
    
    dependsOn(myCustomPlugin)
    

    You only need one of those val myCustomPlugin = lines, depending on where you put your my-custom-plugin/ directory.