Question

I am switching from maven to sbt for a Scala project I am working on. I used to work with the maven assembly plugin where you can map any directory in the workspace to a target directory in the assembly. I didn't find any equivalent in sbt-native-package, it worth provide this feature for the Universe kind.

I understood that everything that is present in the universal subdirectory is copied to the package as such, and it works like a charm, but I lack something like the following snippet.

mappings in Universal += {
  directory("my/local/dir") -> "static/dirInPackage"
}

I would like to know if there is already a way to do that, in such case, I would be happy to know how to do it, and I propose my help to commit documentation for that part if you want. If there is no way to do this kind of customization, I will be happy to propose a patch for that after having discussed specifications.

By the way, great job, your packager is working very well, thanks !

Was it helpful?

Solution

After having discussed with the sbt-native-manager team and a first "rejected" pull request, here is the way to do this directory mapping in the build.sbt file (see pull request https://github.com/sbt/sbt-native-packager/pull/160 which provides mode detailed documentation) :

mappings in Universal <++= (packageBin in Compile, target ) map { (_, target) =>
    val dir = target / "scala-2.10" / "api"
    (dir.***) pair relativeTo(dir.getParentFile)
} 

To reduce verbosity of the above snippet, there is an issue (https://github.com/sbt/sbt-native-packager/issues/161) to propose a more human readable way to express this directory mapping:

mappings in Universal ++= allFilesRelativeTo(file(target / "scala-2.10" / "api"))

OTHER TIPS

From https://github.com/sbt/sbt-native-packager

If you'd like to add additional files to the installation dir, simply add them to the universal mappings:

import com.typesafe.sbt.SbtNativePackager.Universal

mappings in Universal += {
 file("my/local/conffile") -> "conf/my.conf"
}

You could use a simple map on top of the directory method result.

==> directory method documentation: MappingsHelper.directory

For example: // Packaging the content of /src/main/resources under conf add the following:

mappings in Universal ++= (directory("src/main/resources").map(t => (t._1, t._2.replace("resources", "conf"))))

This one seems to be the simplest example that worked for me

Takes all files in res/scripts/ and puts it in the bin/ directory when unzipped.

// In build.sbt
mappings in Universal <++= (packageBin in Compile) map { jar =>
  val scriptsDir = new java.io.File("res/scripts/")
  scriptsDir.listFiles.toSeq.map { f =>
    f -> ("bin/" + f.getName)
  }
}

If you choose a file that's not created, it will be created for you, for example assets/ will make a new assets folder with the files. If you want files inside of this one using this approach you'll have to make a new Seq at least that's what I did. Here's my example

assets/
├── scripts
│   └── install_dependencies.sh
└── urbangrizzly.database

and the appropriate build.sbt section:

mappings in Universal <++= (packageBin in Compile) map { jar =>
    val assetsDir = new java.io.File("assets/")
    val scriptsDir = new java.io.File("assets/scripts")
    assetsDir.listFiles.toSeq.map { files =>
        files -> ("assets/" + files.getName)
    } ++ scriptsDir.listFiles.toSeq.map { files =>
        files -> ("assets/scripts/" + files.getName)
    }
}

If you need more, just keep using the ++ operator to concatenate the lists

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top