In SBT I create a new config, called katebush
, as follows:
lazy val KateBush: Configuration = config("katebush")
When I try to run katebush:compile
I get an error. That's what I expect.
> katebush:compile
[error] No such setting/task
[error] katebush:compile
[error] ^
Now I extend Compile
in my config definition, and I expect to pick up the compile from the inherited scope.
lazy val KateBush: Configuration = config("katebush") extend Compile
Except it doesn't work:
> katebush:compile
[error] No such setting/task
[error] katebush:compile
[error] ^
But if I add in the defaults to the config (in build.sbt
) so it looks as follows:
lazy val KateBush: Configuration = config("katebush") extend Compile
inConfig(KateBush)(Defaults.compileSettings)
it works fine:
> katebush:compile
[info] Updating {file:/Users/jacek/sandbox/so-25596360/}so-25596360...
[info] Resolving org.fusesource.jansi#jansi;1.4 ...
[info] Done updating.
[success] Total time: 0 s, completed Aug 31, 2014 11:35:47 PM
So, my question is, what exactly does extend
for a configuration do?
DISCLAIMER I've got a rather basic understanding of the config
concept of sbt.
tl;dr Extending a configuration is solely to inherit the dependencies groups not settings.
From the sources of final case class Configuration:
def extend(configs: Configuration*) = Configuration(name, description, isPublic, configs.toList ::: extendsConfigs, transitive)
By default, extendsConfigs
is Nil
as can be seen in the sbt.Configurations object:
def config(name: String) = new Configuration(name)
that resolves to (note Nil
)
def this(name: String) = this(name, "", true, Nil, true)
In sbt.IvySbt.toIvyConfiguration:
import org.apache.ivy.core.module.descriptor.{ Configuration => IvyConfig }
and that's where the support of the config
concept ends in sbt and Ivy steps in. That's where you'd have to look at the documentation of Ivy.
But before that read Advanced configurations example where it says:
This is an example .scala build definition that demonstrates using Ivy configurations to group dependencies.
That's the beginning of the explanation. Ivy configurations are to group dependencies and extend
ing a configuration is to extend the grouping.
From the official documentation of Ivy about the conf element:
a configuration is a way to use or construct a module.(...) a module may need some other modules and artifacts only at build time, and some others at runtime. All those differents ways to use or build a module are called in Ivy module configurations.
Reading along you can find the answer to your question (that I'm myself yet to digest, too):
A configuration can also extend one or several other ones of the same module. When a configuration extends another one, then all artifacts required in the extended configuration will also be required in the configuration that extends the other one. For instance, if configuration B extends configuration A, and if artifacts art1 and art2 are required in configuration A, then they will be automatically required in configuration B. On the other hand, artifacts required in configuration B are not necessarily required in configuration A.
This notion is very helpful to define configurations which are similar with some differences.
At the bottom of the page, there's the Examples section with an example with runtime
config that has "runtime will be composed of all dependencies, all transitively, including the dependencies declared only in compile."
With this, you can now understand the config
concept in sbt as a dependencies groups and what's grouped in Compile
is available in Runtime
as its definition looks as follows:
lazy val Runtime = config("runtime") extend (Compile)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With