scalajarsbtpackagingartifact

How to packaging specific directory in scala?


Now I have scala project directory like below:

my-project
ᄂsrc/main/scala
   ᄂ com.foo.bar
       ├ foo1
       │  ᄂ (...classes)
       ᄂ foo2

Then I want to package to jar file just 'com.foo.bar.foo1' directory files. But if i use sbt package, sbt make all directories below the src/main/scala.

If I command sbt package:

target
ᄂ some-name-package.jar
    ᄂ com.foo.bar
       ├ foo1
       │  ᄂ (...classes)
       ᄂ foo2

I want to know how to package like below:

target
ᄂ some-specific-package.jar
    ᄂ com.foo.bar
       ├ foo1
          ᄂ (...classes)

But I cannot change build.sbt file.

How can I package specific directory?


Solution

  • You can specify mappings

    Compile / packageBin / mappings := {
      val original = (Compile / packageBin / mappings).value
      original.filter {
        case (file, toPath) =>
          toPath.startsWith("com/foo/bar/foo1")
      }
    }
    

    Then executing sbt package creates a jar with classes only from com.foo.bar.foo1.*

    https://www.scala-sbt.org/1.x/docs/Howto-Package.html#Modify+the+contents+of+the+package

    How to create a custom package task to jar a subset of classes in SBT

    How to create custom "package" task to jar up only specific package in SBT?


    Alternatively, you can divide your project into two subprojects. Then the directory structure will be

    my-project
    ᄂsubproject1
      ᄂsrc/main/scala
         ᄂ com.foo.bar
             ᄂ foo1
                ᄂ (...classes)
    ᄂsubproject2
      ᄂsrc/main/scala
         ᄂ com.foo.bar
             ᄂ foo2
    

    build.sbt

    lazy val subproject1 = (project in file("subproject1"))
      .dependsOn(...)
      .settings(
        name := "subproject1",
        ...
      )
    
    lazy val subproject2 = (project in file("subproject2"))
      .dependsOn(...)
      .settings(
        name := "subproject2",
        ...
      )
    

    https://www.scala-sbt.org/1.x/docs/Multi-Project.html

    It will be enough to execute sbt subproject1/package then.