Is there any way to use SBT's resolver only for subset of artifacts? - scala

Is there any way to define custom resolver that would be used only for subset of artifacts, more specifically to fetch artifacts only with predefined groupId?
For example, project defines a custom FooResolver that should be used only for artifacts with groupId org.foo but all other artifacts should be resolved using the default resolver.

To add unmanaged dependencies to an SBT project, the simplest solution is to just put the jars in the lib folder in your project. All libraries in the lib folder will be in the classpath by default.
If you want to use another folder instead of lib, you can redefine it:
unmanagedBase := // provide a java.io.File here.
If you want to do something more complex: SBT retrieves unmanaged libraries with the unmanagedJars task, so you can always redefine that task (but that would probably be a sign that you're trying to do something too complicated to reasonably use unmanaged dependencies...).

Related

What is the correct way of using static assets in a Scala SBT project?

What is the best way of using static resources in an SBT based Scala project with a packaging plugin such as sbt-assembly or sbt-native-packager.
We know that by using TypeSafe-Config with sbt-native-packager's universal plugin, we can just put the configuration file in the resources directory under sources. However, what if I wanted my application to have other static sources such as JSON files containing mappings, and models?
I understand that I can just reference the resources directory and read from the file, but would that still work after packaging the application with plugins (assuming the universal or docker plugin in this case)?
If not, what is the correct way to achieve this?
You could use
unmanagedResourceDirectories += (baseDirectory in <project>).value / some / path
to add more directories that are later mapped into the jar as static resources.
Put it into the resources directory, but don't "reference the resources directory and read from the file": use ClassLoader.getResourceAsStream() (or getResources, depending on your requirements) instead. This is the same technique TypeSafe Config and innumerable other libraries use. For this it doesn't matter if you use sbt-native-packager or not.
This approach runs into problems if you need to make these resources available specifically as files (e.g. to feed them to an external process). In this case add them to mappings as shown here:
mappings in Universal in packageBin += file("README") -> "README"
(obviously replacing "README" with the file(s) you need).

How to import directory of .scala files in sbt (unmanaged)?

I have a directory that I want to use as a dependancy for an sbt project however its comprised of .scala files which means I can't place it inside a jar (from what I understand) so then how can I use it as a dependancy for my project?
(sbt doesn't have it as a managed dependancy)
thanks in advance
as written in the manual, you can customize the sources (or source directories) pretty freely. by default, sbt will expect to have scala and java sources under a source directory.
you can customize that too. depending on your exact use case, maybe you want these sources under a different configuration? if it's just extra sources to compile and package, you can simply use:
sourceDirectories in Compile += file("/path/to/your/sources")
or:
unmanagedSourceDirectories in Compile += file("/path/to/your/sources")
use the first when the sources are managed, e.g: if these sources are generated by some other program, or retrieved as a dependency, etc'...
use the second when these are plain sources not managed by anything.

Specify plugins in Build.scala

If I want to use a build.scala file in order to build my project (instead of build.sbt)
how do I specify the plugins?
I want to use the sbt-assmbly plugin. and I am aware that I can create a plugins.sb file and do a addSbtPlugin there.
But i want to put all my build logic in build.scala instead of the sbt files.
No, you can't. You can put it in project/project/Build.scala, which would let you avoid .sbt files, but probably isn't what you want.
The thing is, project directory is itself an SBT project, and SBT handles project/*.sbt files and project/project/*.scala files in it just the same as it does on the top level; but by the time it's working with project/Build.scala, it's too late to add plugins.

Sbt building distribution for a project

Is there an easy way to create a distribution for a SBT project, which collects all dependency jars into a single directory like lib and the main project jar file refers to all its dependencies using manifest entries? It would be nice if one could define a main class.
This answere says how to do part of what you want. Namely get the managed dependencies into lib_managed directory. Basically just add:
retrieveManaged := true
to your build.sbt file.
Alternatively you could look at a One-jar plugin https://github.com/sbt/sbt-onejar It might do a bit more than you want though.

Managing custom client builds with SBT

We have an application that is extensible via modules. The (multi-project) SBT build produces a distribution artifact that is easy to deploy.
Some custom deployments for clients do require specific modules to be part of the build (in other words, an additional set of dependencies). I'm wondering what would be the best approach to create such custom builds - in other words, is there perhaps a way to extend the main Build and only add those dependencies?
Right now I am thinking of the following approach:
have the main application packaged (as ZIP) & released
in the custom build, fetch the ZIP file, extract it, magically add the additional JAR dependencies, and zip the artifact again ("magically" because I don't know how to get access to all JAR dependencies specified in the build)
But is there perhaps a more elegant way?
I think it would be easier to just declare a new sub-project along the main one that depends on it.
lazy val extra: Project = Project("extra", file("extra")) dependsOn(mainProject) settings(Seq(...))
Then on that package you can declare the extra dependencies. When you package this extra project everything should end up into the package automatically.