Make one sbt config depend on another

折月煮酒 提交于 2021-01-27 07:36:16

问题


The sbt documentation shows example of how to declare dependency only between projects. But I'm positive that there are ways to declare one config be dependent on another, just like the Test configuration uses classpath from the Compile configuration.

How can I declare my own configuration so that it would depend on the Compile config generated classpath?


I take a more close look to suggested solution and bunch of question arose again. So I reopen the question

I can not deduce sbt behavior solely from the delegate relation between Test and Compile config.

The source directories turn out to be completely different for Test and Compile config despite being delegated.

> show test:unmanagedSourceDirectories
[info] List(./src/test/scala, ./src/test/java)
> show test:scalaSource
[info] ./src/test/scala
> show test:javaSource
[info] ./src/test/java
> show compile:unmanagedSourceDirectories
[info] List(./src/main/scala, ./src/main/java)
> show compile:scalaSource
[info] ./src/main/scala
> show compile:javaSource
[info] ./src/main/java

And other significant keys such as unmanagementClasspath and fullClasspath are not SettingsKeys that may be naturally stacked with delegating. They are full-fledged TaskKeys that stores complex procedure for generating class-paths behind them.

So, the question is still actual: How can I mimic exporting classes from Compile to Test config for my custom defined config? And there is closely related optional question: how this is actually done for aforementioned pre-defined configs?


回答1:


You can make one configuration extend another. You do that by using extend method.

lazy val MyConfig = config("myConfig") extend(Compile)

lazy val root = project.in(file(".")).
    configs(MyConfig).
    settings(inConfig(MyConfig)(Defaults.compileSettings ++ Defaults.compileInputsSettings): _*)

Extend will delegate to Compile in this case, for settings which are undefined in the MyConfig configuration.

You can check it by running SBT and executing for example show myConfig:managedClasspath, the output should be exactly the same as for show compile:managedClasspath.

If you inspect your new configuration's managedClasspath you'll see that it delegates to the compile.

[info] Delegates:
[info]  myConfig:managedClasspath
[info]  compile:managedClasspath
[info]  *:managedClasspath
[info]  {.}/myConfig:managedClasspath
[info]  {.}/compile:managedClasspath
[info]  {.}/*:managedClasspath
[info]  */myConfig:managedClasspath
[info]  */compile:managedClasspath
[info]  */*:managedClasspath

As I've stated above, SBT will only delegate to the setting if it's not defined in the given configuration.

For example, if you do not define any specific compiler options for myConfig the settings will be taken from compile.

> show compile:scalacOptions
[info] List()
> show myConfig:scalacOptions
[info] List()

Changing setting in compile configuration will have an effect on myConfig:

> set scalacOptions in Compile += "-Xexperimental"
> show compile:scalacOptions
[info] List(-Xexperimental)
> show myConfig:scalacOptions
[info] List(-Xexperimental)

Overriding the setting in myConfig will make SBT to use the setting defined in that configuration, while Compile will have its own value:

> set scalacOptions in MyConfig  := Seq("-Xcheck-null")
> show compile:scalacOptions
[info] List(-Xexperimental)
> show myConfig:scalacOptions
[info] List(-Xcheck-null)

Note the delegation is one way. Change to the MyConfig has no influence on the Compile configuration.

You can check the documentation for details.



来源:https://stackoverflow.com/questions/23586436/make-one-sbt-config-depend-on-another

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!