编写自定义规则

使用maven-enforcer-rule-api可以轻松制定自定义规则。然后可以使用maven-enforcer-plugin调用这些规则。

注意:下面显示的文件可以在这里下载:custom-rule.zip

  1. 首先从下面的示例 pom 开始创建一个新的 jar 项目:
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <groupId>custom-rule</groupId>
      <artifactId>custom-rule-sample</artifactId>
      <packaging>jar</packaging>
      <version>1.0</version>
      <name>My Custom Rule</name>
      <description>This is my custom rule.</description>
      <properties>
        <api.version>3.0.0</api.version>
        <maven.version>3.1.1</maven.version>
      </properties>
      <dependencies>
        <dependency>
          <groupId>org.apache.maven.enforcer</groupId>
          <artifactId>enforcer-api</artifactId>
          <version>${api.version}</version>
        </dependency>
        <dependency>
          <groupId>org.apache.maven</groupId>
          <artifactId>maven-core</artifactId>
          <version>${maven.version}</version>
        </dependency>
        <dependency>
          <groupId>org.apache.maven</groupId>
          <artifactId>maven-plugin-api</artifactId>
          <version>${maven.version}</version>
        </dependency>
        <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>3.8.1</version>
          <scope>test</scope>
        </dependency>
      </dependencies>
      <build>
      </build>
    </project>
    
  2. 创建您的规则类。该规则必须实现EnforcerRule接口。该规则可以通过EnforcerRuleHelper接口访问组件和日志。此外,该规则必须为允许在 pom.xml 文件中配置的每个参数提供一个 setter 方法(如第5 点所示 的参数shouldIfail )。

    如果规则成功,它应该只是简单地返回。如果规则失败,它应该抛出带有描述性消息的EnforcerRuleException,告诉用户规则失败的原因。

    有几种与缓存相关的方法必须实现。

    下面是一个示例类,展示了如何访问帮助器方法并从帮助器中按类名检索组件:

    package org.apache.maven.enforcer.rule;
    
    import org.apache.maven.ProjectDependenciesResolver;
    import org.apache.maven.enforcer.rule.api.EnforcerRule;
    import org.apache.maven.enforcer.rule.api.EnforcerRuleException;
    import org.apache.maven.enforcer.rule.api.EnforcerRuleHelper;
    import org.apache.maven.execution.MavenSession;
    import org.apache.maven.plugin.logging.Log;
    import org.apache.maven.project.MavenProject;
    import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluationException;
    import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
    
    /**
     * @author <a href="mailto:brianf@apache.org">Brian Fox</a>
     * @author <a href="mailto:belingueres@gmail.com">Gabriel Belingueres</a>
     */
    public class MyCustomRule
        implements EnforcerRule
    {
        /**
         * Simple param. This rule fails if the value is true.
         */
        private boolean shouldIfail = false;
    
        public void execute( EnforcerRuleHelper helper )
            throws EnforcerRuleException
        {
            Log log = helper.getLog();
    
            try
            {
                // get the various expressions out of the helper.
                MavenProject project = (MavenProject) helper.evaluate( "${project}" );
                MavenSession session = (MavenSession) helper.evaluate( "${session}" );
                String target = (String) helper.evaluate( "${project.build.directory}" );
                String artifactId = (String) helper.evaluate( "${project.artifactId}" );
                String mavenVersion = (String) helper.evaluate( "${maven.version}" );
    
                // retrieve any component out of the session directly
                ProjectDependenciesResolver resolver = helper.getComponent( ProjectDependenciesResolver.class );
    
                log.info( "Retrieved Target Folder: " + target );
                log.info( "Retrieved ArtifactId: " +artifactId );
                log.info( "Retrieved Project: " + project );
                log.info( "Retrieved Maven version: " + mavenVersion );
                log.info( "Retrieved Session: " + session );
                log.info( "Retrieved Resolver: " + resolver );
    
                if ( this.shouldIfail )
                {
                    throw new EnforcerRuleException( "Failing because my param said so." );
                }
            }
            catch ( ComponentLookupException e )
            {
                throw new EnforcerRuleException( "Unable to lookup a component " + e.getLocalizedMessage(), e );
            }
            catch ( ExpressionEvaluationException e )
            {
                throw new EnforcerRuleException( "Unable to lookup an expression " + e.getLocalizedMessage(), e );
            }
        }
    
        /**
         * If your rule is cacheable, you must return a unique id when parameters or conditions
         * change that would cause the result to be different. Multiple cached results are stored
         * based on their id.
         * 
         * The easiest way to do this is to return a hash computed from the values of your parameters.
         * 
         * If your rule is not cacheable, then the result here is not important, you may return anything.
         */
        public String getCacheId()
        {
            //no hash on boolean...only parameter so no hash is needed.
            return Boolean.toString( this.shouldIfail );
        }
    
        /**
         * This tells the system if the results are cacheable at all. Keep in mind that during
         * forked builds and other things, a given rule may be executed more than once for the same
         * project. This means that even things that change from project to project may still 
         * be cacheable in certain instances.
         */
        public boolean isCacheable()
        {
            return false;
        }
    
        /**
         * If the rule is cacheable and the same id is found in the cache, the stored results
         * are passed to this method to allow double checking of the results. Most of the time 
         * this can be done by generating unique ids, but sometimes the results of objects returned
         * by the helper need to be queried. You may for example, store certain objects in your rule
         * and then query them later.
         */
        public boolean isResultValid( EnforcerRule rule )
        {
            return false;
        }
    
        /**
         * Injects the value of the shouldIfail parameter into the custom rule.
         * 
         * @param shouldIfail set to true if you want the rule to fail. false to succeed.
         */
        public void setShouldIfail( boolean shouldIfail )
        {
            this.shouldIfail = shouldIfail;
        }
    
    }
    
  3. 构建和安装或部署您的自定义规则。
  4. 将您的自定义规则工件添加为构建 中maven-enforcer-plugin的依赖项:
    <project>
      ...
      <build>
        <plugins>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-enforcer-plugin</artifactId>
            <version>3.0.0</version>
            <dependencies>
              <dependency>
                <groupId>custom-rule</groupId>
                <artifactId>custom-rule-sample</artifactId>
                <version>1.0</version>
              </dependency>
            </dependencies>
            ...
          </plugin>   
        </plugins>
      </build>
      ...
    </project>
    
  5. 将您的规则添加到maven-enforcer-plugin的配置部分。您的类的名称将是规则的名称,并且您必须添加一个包含完全限定类名称的实现提示:
            ...
            <configuration>
              <rules>
                <myCustomRule implementation="org.apache.maven.enforcer.rule.MyCustomRule">
                  <shouldIfail>true</shouldIfail>
                </myCustomRule>
              </rules>
            </configuration>
            ...
    
  6. 而已。完整的插件配置可能如下所示:
    <project>
      ...
      <build>
        <plugins>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-enforcer-plugin</artifactId>
            <version>3.0.0</version>
            <dependencies>
              <dependency>
                <groupId>custom-rule</groupId>
                <artifactId>custom-rule-sample</artifactId>
                <version>1.0</version>
              </dependency>
            </dependencies>
            <executions>
              <execution>
                <id>enforce</id>
                <configuration>
                  <rules>
                    <myCustomRule implementation="org.apache.maven.enforcer.rule.MyCustomRule">
                      <shouldIfail>false</shouldIfail>
                    </myCustomRule>
                  </rules>
                </configuration>
                <goals>
                  <goal>enforce</goal>
                </goals>
              </execution>
            </executions>
          </plugin>
        </plugins>
      </build>
      ...
    </project>