强制执行两个Maven配置文件中的一个

San*_*gen 10 maven maven-profiles

我有一个Maven项目,它定义了两个独立的配置文件,developer并且release(当然你得到了漂移,这里).我想要随时激活这两个配置文件中的一个,但绝不会同时激活.如果两者都以某种方式被激活,那么这个构建没有意义,应该失败.如果两者都没有被激活,那么这个构建也没有意义,应该失败.

我确信我可以编写一些自定义插件代码来实现这一点,我可能最终会这样做,但我有兴趣使用POM配置(可以使用Maven Central的现有插件)来实现这一点.

应该可以使用-P(--activate-profiles)激活插件,因此<activation>通过属性不是有效的解决方案.使用的解决方案activeByDefault也无效,因为activeByDefault通常称为陷阱,不可靠(我们实际上可能激活其他配置文件,因此activateByDefault无法使用).

您的建议非常感谢.

khm*_*ise 5

解决此类问题的最简单的解决方案是使用maven-enforcer-plugin,它恰好具有这样的规则来强制激活两个或多个配置文件中的至少一个。

不幸的是,requireActiveProfile 目前有一个错误。但目前正在准备新版本来解决这个问题。

更新上述bug已在1.4版本(2015年发布)中修复。


Ste*_*ers 5

我有一个类似的需求(即两个配置文件的互斥性)并通过将两个目标配置文件视为不应在命令行中指定的内部配置文件来解决它:相反,可以指定或不指定控制系统属性. 例如,让我们假设默认情况下您希望“开发”配置文件处于活动状态。然后我们可以根据是否指定选项来激活/停用相关的内部配置文件-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>
Run Code Online (Sandbox Code Playgroud)


aym*_*ens 5

这仍然可以使用Maven Enforcer 插件来完成

尽管正如 @khmarbaise 所报告的那样,互斥<requireActiveProfile>...<all>false</all>...是有问题的,但仍然有一个<evaluateBeanshell/>内置规则可以让人们为所欲为。

我专门为这种情况写了一个:两个配置文件的异或。我希望它有帮助。

            <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>
Run Code Online (Sandbox Code Playgroud)

棘手的部分是循环活动配置文件,我已经在这里完成了。如果需要,您可以将其扩展到两个以上的配置文件。但是您必须编写长 xor 表达式,因为 beanshell 不实现 Java xor ^运算符。