我有一个Maven项目,它定义了两个单独的配置文件,developer
和release
(当然,你可以得到漂移)。我想要随时激活这两个配置文件中的一个,但绝不会同时激活。如果两者都以某种方式被激活,那么这个构建没有意义,应该失败。如果两者都没有被激活,那么这个版本也没有意义,应该失败。
我确信我可以编写一些自定义插件代码来实现这一点,我可能最终会这样做,但我有兴趣使用POM配置来实现这一点(可能是使用Maven Central的现有插件)。
应该可以使用-P
(--activate-profiles
)激活插件,因此<activation>
通过属性不是有效的解决方案。使用activeByDefault
的解决方案也无效,因为activeByDefault
通常被称为陷阱,不可靠(我们实际上可能会激活其他配置文件,从而导致activateByDefault
无法使用)。
非常感谢您的建议。
答案 0 :(得分:3)
我总是发出这样的构建命令:
mvn package -P-dev,prod
它显式禁用了dev配置文件并启用了生产配置文件。据我所知,如果另一个构建配置文件处于活动状态(这有点不幸),则无法有条件地启用它,因此您无法确保配置文件是互斥的。
答案 1 :(得分:3)
我有类似的需求(即两个配置文件的互斥),并通过将两个目标配置文件视为内部配置文件来解决它,不应在命令行中指定:相反,可以指定控制系统属性。例如。我们假设默认情况下您希望“dev”配置文件处于活动状态。然后,我们可以根据是否指定-Drelease
选项来激活/停用相关的内部配置文件:
<!-- Internal profile: FOR INTERNAL USE ONLY - active if -Drelease is *not* specified. -->
<profile>
<id>internal-dev</id>
<activation>
<!-- Activation via *absence* of a system property to ensure mutual exclusivity
of this profile with internal-release -->
<property>
<name>!release</name>
</property>
</activation>
...
</profile>
<!-- Internal profile: FOR INTERNAL USE ONLY - active if -Drelease *is* specified. -->
<profile>
<id>internal-release</id>
<activation>
<!-- Activation via *presence* of a system property to ensure mutual exclusivity
of this profile with internal-dev -->
<property>
<name>release</name>
</property>
</activation>
...
</profile>
答案 2 :(得分:2)
针对此类问题的最简单的解决方案是使用具有此类规则的maven-enforcer-plugin来强制激活两个或更多个配置文件中的至少一个。
不幸的是,requireActiveProfile目前有一个bug。但目前正在准备新版本,这解决了这一问题。
答案 3 :(得分:1)
我需要稍微更高级的此规则版本。我自己写完了。我已向他们提交了一个补丁,其中包含以下两条规则:
指定一组相互排斥的配置文件的能力(p1,p2:p1,p3意味着p1不能与p2或p3一起激活)。
禁止个人资料的能力(与requireActiveProfile
相反)。 p1,p2意味着p1和p2都不能用于此构建。
这两个规则都支持通配符并考虑继承的配置文件。这些是基于规则的v1.4。
答案 4 :(得分:0)
这仍然可以使用Maven Enforcer plugin
完成虽然互相排斥,<requireActiveProfile>...<all>false</all>...
正如@khmarbaise所报道的那样,但仍有<evaluateBeanshell/>
内置规则可以让人做任何他想做的事。
我特意写了一个案例:两个配置文件的XOR。我希望它有所帮助。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>1.4.1</version>
<executions>
<execution>
<id>enforce-PROFILE_ONE-XOR-PROFILE_TWO-is-active</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<requireActiveProfile>
<profiles>PROFILE_ONE,PROFILE_TWO</profiles>
<all>false</all>
</requireActiveProfile>
<evaluateBeanshell>
<condition><![CDATA[
// ensure PROFILE_ONE XOR PROFILE_TWO
print("Checking if only one of PROFILE_ONE and PROFILE_TWO profiles is active ...");
boolean profile1 = false, profile2 = false;
for(s: "${project.activeProfiles}".replaceAll("\\[?\\s?Profile \\{id: (?<profile>\\w+), source: \\w+\\}\\]?", "${profile}").split(",")) {
if("PROFILE_ONE".equalsIgnoreCase(s)){ profile1 = true;}
if("PROFILE_TWO".equalsIgnoreCase(s)){ profile2 = true;}
}
print("PROFILE_ONE XOR PROFILE_TWO: "+(profile1 != profile2));
return profile1 != profile2;
]]></condition>
</evaluateBeanshell>
</rules>
<failFast>true</failFast>
</configuration>
</execution>
</executions>
</plugin>
棘手的部分是循环活动配置文件,我已经在这里完成了。如果需要,您可以将其扩展到两个以上的配置文件。但是你必须编写long xor表达式,因为beanshell没有实现Java xor ^ 运算符。