如何处理多个构建目标,例如开发,测试,主要? [英] How to handle multiple build targets, e.g. dev, test, main?

查看:108
本文介绍了如何处理多个构建目标,例如开发,测试,主要?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在从Maven迁移到SBT,并且正在努力了解如何处理多个构建目标(开发,测试,培训,生产等).

I'm currently migrating from Maven to SBT, and I'm struggling to understand how I can handle multiple build targets (dev, test, train, prod etc).

例如,我有一个persistence.xml看起来像这样:

For example, I have a persistence.xml that looks like this:

<properties>
    <property name="javax.persistence.jdbc.driver" value="oracle.jdbc.driver.OracleDriver"/>
    <property name="javax.persistence.jdbc.url" value="${db.connectionURL}"/>
    <property name="javax.persistence.jdbc.user" value="${db.username}"/>
    <property name="javax.persistence.jdbc.password" value="${db.password}"/>
    <property name="eclipselink.target-database" value="Oracle10"/>
</properties>

使用Maven,使用配置文件非常容易处理此问题.

With Maven, it was really easy to handle this using profiles.

我已经尝试了SBT的建议,但是这种方法没有任何成功. 如何将环境配置文件配置添加到SBT .

I've already tried what was suggested here for SBT, but I'm not having any success with that approach. How to Add Environment Profile Config to SBT.

此外,使用这种方法,我将为每个新环境需要一个新目录.我只是认为必须有一种更好的方法来使用SBT处理此类设置?

Also, using that approach I would need a new directory for each new environment. I just think that there has to be a better way to handle this kind of setup using SBT?

推荐答案

tl; dr 使用ivyConfigurations添加自定义配置,使用resourceGenerators处理每个环境中的文件.

tl;dr Use ivyConfigurations to add custom configs and resourceGenerators to process files per environment.

所有功劳归于 Eugene Yokota ,以获取

All credits goes to Eugene Yokota for the answer to How to Add Environment Profile Config to SBT. There are some modification that make the solution of mine...cough...cough...slightly better.

以下build.sbt定义了两个新配置- dev qa .它还为每个配置定义了resourceGenerators,从而有效地提供了一种方式来访问新resourceGenerator在其中执行的配置:

The following build.sbt defines two new configurations - dev and qa. It also defines resourceGenerators per configuration that effectively gives a way to access what configuration the new resourceGenerator executes in:

val Dev = config("dev") extend Runtime

val Qa  = config("qa") extend Runtime

ivyConfigurations ++= Seq(Dev, Qa)

// http://www.scala-sbt.org/0.13.5/docs/Howto/generatefiles.html#resources
lazy val bareResourceGenerators: Seq[Setting[_]] = Seq(
  resourceGenerators += Def.task {
    val file = resourceManaged.value / "demo" / "myapp.properties"
    println(s"Inside ${configuration.value}")
    val contents = s"config=${configuration.value}"
    IO.write(file, contents)
    Seq(file)
  }.taskValue
)

inConfig(Dev)(Defaults.configSettings ++ bareResourceGenerators)

inConfig(Qa)(Defaults.configSettings ++ bareResourceGenerators)

在新的resourceGenerator内部,您可以执行所需的任何操作,并且可以通过configuration设置进行按配置的处理,该设置为您提供了配置的名称:

Inside the new resourceGenerator you can do whatever you want and the per-configuration processing is possible with the configuration setting that gives you the name of the configuration:

> show dev:configuration
[info] dev
> show qa:configuration
[info] qa

现在,当执行show qa:resources时,您会看到用target/scala-2.10/resource_managed/qa/demo/myapp.properties生成的两个文件具有特定于配置的内容:

Now when you execute show qa:resources you'll see that there are two files generated with target/scala-2.10/resource_managed/qa/demo/myapp.properties with the content that's specific to a configuration:

> show qa:resources
Inside qa
[info] List(/Users/jacek/sandbox/envs/target/scala-2.10/resource_managed/qa/demo/myapp.properties, /Users/jacek/sandbox/envs/src/qa/resources)

现在的诀窍是使用resourceGenerator来满足您的需求,并且由于您使用的是Scala代码,因此您可以做任何您想做的事情-只需将configuration.value用作特定于配置的代码的限定符即可.

The trick now is to use the resourceGenerator to meet your needs and since you're in Scala code you can do whatever you want - just use configuration.value as the qualifier for a configuration-specific code.

说,您要在标准src/main/resources目录中使用特定于qa的属性文件.只知道该值绑定到何处(该值来自什么配置和设置).只是compile:resourceDirectory.

Say, you want to use a qa-specific properties file in the standard src/main/resources directory. Just know where the value is bound to (what configuration and setting the value comes from). It's just compile:resourceDirectory.

> show compile:resourceDirectory
[info] /Users/jacek/sandbox/envs/src/main/resources

只要需要src/main/resources之类的稳定"( aka 配置固定)值,就只需使用resourceDirectory in Compile.

Just use resourceDirectory in Compile whenever you need a "stable" (aka configuration-fixed) value like src/main/resources.

val props = (resourceDirectory in Compile).value / s"${configuration.value.name}.properties"
println(s"Read files from $props")

使用上面的几行,您将获得:

With the above lines you'd get:

> show qa:resources
Inside qa
Read files from /Users/jacek/sandbox/envs/src/main/resources/qa.properties
[info] List(/Users/jacek/sandbox/envs/target/scala-2.10/resource_managed/qa/demo/myapp.properties, /Users/jacek/sandbox/envs/src/qa/resources)

> show dev:resources
Inside dev
Read files from /Users/jacek/sandbox/envs/src/main/resources/dev.properties
[info] List(/Users/jacek/sandbox/envs/target/scala-2.10/resource_managed/dev/demo/myapp.properties, /Users/jacek/sandbox/envs/src/dev/resources)

这篇关于如何处理多个构建目标,例如开发,测试,主要?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆