You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by rf...@apache.org on 2021/05/21 13:41:43 UTC

[maven-enforcer] branch MENFORCER-384 created (now a6cf1a9)

This is an automated email from the ASF dual-hosted git repository.

rfscholte pushed a change to branch MENFORCER-384
in repository https://gitbox.apache.org/repos/asf/maven-enforcer.git.


      at a6cf1a9  [MENFORCER-384] Introduce Maven Enforcer Extension

This branch includes the following new commits:

     new a6cf1a9  [MENFORCER-384] Introduce Maven Enforcer Extension

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


[maven-enforcer] 01/01: [MENFORCER-384] Introduce Maven Enforcer Extension

Posted by rf...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rfscholte pushed a commit to branch MENFORCER-384
in repository https://gitbox.apache.org/repos/asf/maven-enforcer.git

commit a6cf1a910997bb91fc0c6304387bcb3e2ea11598
Author: rfscholte <rf...@apache.org>
AuthorDate: Fri May 21 15:41:28 2021 +0200

    [MENFORCER-384] Introduce Maven Enforcer Extension
---
 maven-enforcer-extension/pom.xml                   | 124 +++++++++++++++
 maven-enforcer-extension/src/it/mrm/settings.xml   |  73 +++++++++
 .../projects/defaults/.mvn/enforcer-extension.xml  |  42 +++++
 .../src/it/projects/defaults/.mvn/extensions.xml   |  28 ++++
 .../src/it/projects/defaults/pom.xml               |  29 ++++
 .../src/it/projects/invoker.properties             |  19 +++
 .../extensions/enforcer/EnforceExtension.java      | 176 +++++++++++++++++++++
 maven-enforcer-extension/src/site/apt/index.apt    |  46 ++++++
 .../src/site/markdown/usage.md.vm                  |  54 +++++++
 maven-enforcer-extension/src/site/site.xml         |  34 ++++
 pom.xml                                            |   1 +
 11 files changed, 626 insertions(+)

diff --git a/maven-enforcer-extension/pom.xml b/maven-enforcer-extension/pom.xml
new file mode 100644
index 0000000..354fbed
--- /dev/null
+++ b/maven-enforcer-extension/pom.xml
@@ -0,0 +1,124 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  * Licensed to the Apache Software Foundation (ASF) under one
+  * or more contributor license agreements. See the NOTICE file
+  * distributed with this work for additional information
+  * regarding copyright ownership. The ASF licenses this file
+  * to you under the Apache License, Version 2.0 (the
+  * "License"); you may not use this file except in compliance
+  * with the License. You may obtain a copy of the License at
+  *
+  * http://www.apache.org/licenses/LICENSE-2.0
+  *
+  * Unless required by applicable law or agreed to in writing,
+  * software distributed under the License is distributed on an
+  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  * KIND, either express or implied. See the License for the
+  * specific language governing permissions and limitations
+  * under the License.
+  *
+-->
+<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.apache.maven.enforcer</groupId>
+    <artifactId>enforcer</artifactId>
+    <version>3.0.0-M4-SNAPSHOT</version>
+  </parent>
+  <groupId>org.apache.maven.extensions</groupId>
+  <artifactId>maven-enforcer-extension</artifactId>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.eclipse.sisu</groupId>
+        <artifactId>sisu-maven-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>index-project</id>
+            <goals>
+              <goal>main-index</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.maven</groupId>
+      <artifactId>maven-core</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven.plugin-tools</groupId>
+      <artifactId>maven-plugin-annotations</artifactId>
+      <scope>provided</scope>
+    </dependency>
+  </dependencies>
+  
+  <profiles>
+    <profile>
+      <id>run-its</id>
+      <properties>
+        <maven.it.failure.ignore>false</maven.it.failure.ignore>
+      </properties>
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-invoker-plugin</artifactId>
+            <version>3.2.2</version>
+            <configuration>
+              <showErrors>true</showErrors>
+              <projectsDirectory>src/it/projects</projectsDirectory>
+              <cloneProjectsTo>${project.build.directory}/it</cloneProjectsTo>
+              <preBuildHookScript>setup</preBuildHookScript>
+              <postBuildHookScript>verify</postBuildHookScript>
+              <localRepositoryPath>${project.build.directory}/local-repo</localRepositoryPath>
+              <settingsFile>src/it/mrm/settings.xml</settingsFile>
+              <ignoreFailures>${maven.it.failure.ignore}</ignoreFailures>
+              <goals>
+                <goal>validate</goal>
+              </goals>
+            </configuration>
+            <executions>
+              <execution>
+                <id>integration-test</id>
+                <goals>
+                  <goal>install</goal>
+                  <goal>run</goal>
+                </goals>
+              </execution>
+            </executions>
+          </plugin>
+          <plugin>
+            <groupId>org.codehaus.mojo</groupId>
+            <artifactId>mrm-maven-plugin</artifactId>
+            <version>1.2.0</version>
+            <executions>
+              <execution>
+                <goals>
+                  <goal>start</goal>
+                  <goal>stop</goal>
+                </goals>
+              </execution>
+            </executions>
+            <configuration>
+              <propertyName>repository.proxy.url</propertyName>
+              <repositories>
+                <mockRepo>
+                  <source>src/it/mrm/repository</source>
+                </mockRepo>
+                <proxyRepo />
+              </repositories>
+            </configuration>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+  </profiles>
+</project>
\ No newline at end of file
diff --git a/maven-enforcer-extension/src/it/mrm/settings.xml b/maven-enforcer-extension/src/it/mrm/settings.xml
new file mode 100644
index 0000000..80734c5
--- /dev/null
+++ b/maven-enforcer-extension/src/it/mrm/settings.xml
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  * Licensed to the Apache Software Foundation (ASF) under one
+  * or more contributor license agreements.  See the NOTICE file
+  * distributed with this work for additional information
+  * regarding copyright ownership.  The ASF licenses this file
+  * to you under the Apache License, Version 2.0 (the
+  * "License"); you may not use this file except in compliance
+  * with the License.  You may obtain a copy of the License at
+  *
+  * http://www.apache.org/licenses/LICENSE-2.0
+  *
+  * Unless required by applicable law or agreed to in writing,
+  * software distributed under the License is distributed on an
+  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  * KIND, either express or implied.  See the License for the
+  * specific language governing permissions and limitations
+  * under the License. 
+  *
+-->
+<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
+                      http://maven.apache.org/xsd/settings-1.0.0.xsd">
+  <mirrors>
+    <mirror>
+      <id>mrm-maven-plugin</id>
+      <name>Mock Repository Manager</name>
+      <url>@repository.proxy.url@</url>
+      <mirrorOf>*</mirrorOf>
+    </mirror>
+  </mirrors>
+  <profiles>
+    <profile>
+      <id>it-repo</id>
+      <repositories>
+        <repository>
+          <id>snapshots</id>
+          <url>@repository.proxy.url@</url>
+          <releases>
+            <enabled>true</enabled>
+            <checksumPolicy>ignore</checksumPolicy>
+            <updatePolicy>never</updatePolicy>
+          </releases>
+          <snapshots>
+            <enabled>true</enabled>
+            <checksumPolicy>ignore</checksumPolicy>
+            <updatePolicy>always</updatePolicy>
+          </snapshots>
+        </repository>
+      </repositories>
+      <pluginRepositories>
+        <pluginRepository>
+          <id>snapshots</id>
+          <url>@repository.proxy.url@</url>
+          <releases>
+            <enabled>true</enabled>
+            <checksumPolicy>ignore</checksumPolicy>
+            <updatePolicy>never</updatePolicy>
+          </releases>
+          <snapshots>
+            <enabled>true</enabled>
+            <checksumPolicy>ignore</checksumPolicy>
+            <updatePolicy>always</updatePolicy>
+          </snapshots>
+        </pluginRepository>
+      </pluginRepositories>
+    </profile>
+  </profiles>
+  <activeProfiles>
+    <activeProfile>it-repo</activeProfile>
+  </activeProfiles>
+</settings>
\ No newline at end of file
diff --git a/maven-enforcer-extension/src/it/projects/defaults/.mvn/enforcer-extension.xml b/maven-enforcer-extension/src/it/projects/defaults/.mvn/enforcer-extension.xml
new file mode 100644
index 0000000..8e86524
--- /dev/null
+++ b/maven-enforcer-extension/src/it/projects/defaults/.mvn/enforcer-extension.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<extension>
+  <executions>
+    <!-- defaults -->
+    <execution>
+      <configuration>
+        <rules>
+          <AlwaysPass />
+        </rules>
+      </configuration>
+    </execution>
+    <!-- configured -->
+    <execution>
+      <id>custom-id</id>
+      <phase>process-classes</phase>
+      <configuration>
+        <rules>
+          <AlwaysFail/>
+        </rules>
+      </configuration>
+    </execution>
+  </executions>
+</extension>
\ No newline at end of file
diff --git a/maven-enforcer-extension/src/it/projects/defaults/.mvn/extensions.xml b/maven-enforcer-extension/src/it/projects/defaults/.mvn/extensions.xml
new file mode 100644
index 0000000..da62f81
--- /dev/null
+++ b/maven-enforcer-extension/src/it/projects/defaults/.mvn/extensions.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  * Licensed to the Apache Software Foundation (ASF) under one
+  * or more contributor license agreements. See the NOTICE file
+  * distributed with this work for additional information
+  * regarding copyright ownership. The ASF licenses this file
+  * to you under the Apache License, Version 2.0 (the
+  * "License"); you may not use this file except in compliance
+  * with the License. You may obtain a copy of the License at
+  *
+  * http://www.apache.org/licenses/LICENSE-2.0
+  *
+  * Unless required by applicable law or agreed to in writing,
+  * software distributed under the License is distributed on an
+  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  * KIND, either express or implied. See the License for the
+  * specific language governing permissions and limitations
+  * under the License.
+  *
+-->
+<extensions xmlns="http://maven.apache.org/EXTENSIONS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/EXTENSIONS/1.0.0 http://maven.apache.org/xsd/core-extensions-1.0.0.xsd">
+  <extension>
+    <groupId>org.apache.maven.extensions</groupId>
+    <artifactId>maven-enforcer-extension</artifactId>
+    <version>@project.version@</version>
+  </extension>
+</extensions>
\ No newline at end of file
diff --git a/maven-enforcer-extension/src/it/projects/defaults/pom.xml b/maven-enforcer-extension/src/it/projects/defaults/pom.xml
new file mode 100644
index 0000000..2c4a137
--- /dev/null
+++ b/maven-enforcer-extension/src/it/projects/defaults/pom.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project>
+  <modelVersion>4.0.0</modelVersion>
+
+  <groupId>org.apache.maven.its.enforcer</groupId>
+  <artifactId>test</artifactId>
+  <version>1.0</version>
+
+</project>
diff --git a/maven-enforcer-extension/src/it/projects/invoker.properties b/maven-enforcer-extension/src/it/projects/invoker.properties
new file mode 100644
index 0000000..9bbbd74
--- /dev/null
+++ b/maven-enforcer-extension/src/it/projects/invoker.properties
@@ -0,0 +1,19 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+invoker.goals.1 = validate
+invoker.goals.2 = verify
+invoker.buildResult.2 = failure
diff --git a/maven-enforcer-extension/src/main/java/org/apache/maven/extensions/enforcer/EnforceExtension.java b/maven-enforcer-extension/src/main/java/org/apache/maven/extensions/enforcer/EnforceExtension.java
new file mode 100644
index 0000000..b5aff43
--- /dev/null
+++ b/maven-enforcer-extension/src/main/java/org/apache/maven/extensions/enforcer/EnforceExtension.java
@@ -0,0 +1,176 @@
+package org.apache.maven.extensions.enforcer;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Properties;
+
+import javax.inject.Named;
+
+import org.apache.maven.AbstractMavenLifecycleParticipant;
+import org.apache.maven.MavenExecutionException;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.model.Build;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.model.PluginExecution;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+import org.codehaus.plexus.util.xml.Xpp3DomBuilder;
+import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
+
+/**
+ * Extends every MavenProject with the maven-enforcer-plugin, adding executions as defined in 
+ * <code>.mvn/enforcer-extension.xml</code>
+ * 
+ * @since 3.0.0
+ */
+@Named( "enforcer" )
+public class EnforceExtension extends AbstractMavenLifecycleParticipant
+{
+    private static final String ENFORCER_EXTENSION_XML = ".mvn/enforcer-extension.xml";
+
+    private static final String POM_PROPERTIES =
+        "/META-INF/maven/org.apache.maven.extensions/maven-enforcer-extension/pom.properties";
+
+    @Override
+    public void afterProjectsRead( MavenSession session )
+        throws MavenExecutionException
+    {
+        Xpp3Dom configuration;
+        Path config = Paths.get( session.getExecutionRootDirectory(), ENFORCER_EXTENSION_XML );
+        if ( Files.isRegularFile( config ) )
+        {
+            try ( Reader reader = Files.newBufferedReader( config, StandardCharsets.UTF_8 ) )
+            {
+                configuration = Xpp3DomBuilder.build( reader );
+            }
+            catch ( XmlPullParserException | IOException e )
+            {
+                throw new MavenExecutionException( "Failed to read " + ENFORCER_EXTENSION_XML, e );
+            }
+        }
+        else
+        {
+            return;
+        }
+
+        List<PluginExecution> executions = null;
+        Xpp3Dom executionsDom = configuration.getChild( "executions" );
+        if ( executionsDom != null )
+        {
+            executions = new ArrayList<>();
+            for ( Xpp3Dom executionDom : executionsDom.getChildren( "execution" ) )
+            {
+                executions.add( getPluginExecution( executionDom ) );
+
+            }
+        }
+
+        if ( executions == null )
+        {
+            return;
+        }
+
+        for ( MavenProject project : session.getProjects() )
+        {
+            Plugin enforcerPlugin = null;
+            for ( Plugin plugin : project.getBuildPlugins() )
+            {
+                if ( "maven-enforcer-plugin".equals( plugin.getArtifactId() )
+                    && "org.apache.maven.plugins".equals( plugin.getGroupId() ) )
+                {
+                    enforcerPlugin = plugin;
+                }
+            }
+            
+            if ( enforcerPlugin == null )
+            {
+                enforcerPlugin = new Plugin();
+                enforcerPlugin.setGroupId( "org.apache.maven.plugins" );
+                enforcerPlugin.setArtifactId( "maven-enforcer-plugin" );
+
+                try ( InputStream is = EnforceExtension.class.getResourceAsStream( POM_PROPERTIES ) )
+                {
+                    Properties properties = new Properties();
+                    properties.load( is );
+                    enforcerPlugin.setVersion( properties.getProperty( "version" ) );
+                }
+                catch ( IOException e )
+                {
+                    // noop
+                }
+                
+                if ( project.getBuildPlugins().isEmpty() )
+                {
+                    Build build = project.getBuild();
+                    if ( build == null )
+                    {
+                        build = new Build();
+                        project.setBuild( build );
+                    }
+                    build.setPlugins( Collections.singletonList( enforcerPlugin ) );
+                }
+                else
+                {
+                    List<Plugin> buildPlugins = new ArrayList<>( project.getBuildPlugins() );
+                    buildPlugins.add( enforcerPlugin );
+                    project.getBuild().setPlugins( buildPlugins );
+                }
+            }
+
+            for ( PluginExecution pe : executions )
+            {
+                enforcerPlugin.addExecution( pe );
+            }
+        }
+    }
+
+    private static PluginExecution getPluginExecution( Xpp3Dom execution )
+    {
+        PluginExecution pluginExecution = new PluginExecution();
+        pluginExecution.setId( get( execution, "id", "default-extension" ) );
+        pluginExecution.addGoal( "enforce" );
+        pluginExecution.setPhase( get( execution, "phase", "validate" ) );
+        // here we must use Mavens internal configuration implementation
+        pluginExecution.setConfiguration( execution.getChild( "configuration" ) );
+        return pluginExecution;
+    }
+
+    private static String get( Xpp3Dom elm, String name, String defaultValue )
+    {
+        if ( elm == null || elm.getChild( name ) == null )
+        {
+            return defaultValue;
+        }
+        else
+        {
+            return elm.getChild( name ).getValue();
+        }
+    }
+}
diff --git a/maven-enforcer-extension/src/site/apt/index.apt b/maven-enforcer-extension/src/site/apt/index.apt
new file mode 100644
index 0000000..1d00ac3
--- /dev/null
+++ b/maven-enforcer-extension/src/site/apt/index.apt
@@ -0,0 +1,46 @@
+~~ Licensed to the Apache Software Foundation (ASF) under one
+~~ or more contributor license agreements.  See the NOTICE file
+~~ distributed with this work for additional information
+~~ regarding copyright ownership.  The ASF licenses this file
+~~ to you under the Apache License, Version 2.0 (the
+~~ "License"); you may not use this file except in compliance
+~~ with the License.  You may obtain a copy of the License at
+~~
+~~ http://www.apache.org/licenses/LICENSE-2.0
+~~
+~~ Unless required by applicable law or agreed to in writing,
+~~ software distributed under the License is distributed on an
+~~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+~~ KIND, either express or implied.  See the License for the
+~~ specific language governing permissions and limitations
+~~ under the License.
+
+  ------
+  Introduction
+  ------
+  Robert Scholte
+  ------
+  May 2021
+  ------
+
+Maven Enforcer Extension - The Extended Loving Iron Fist of Maven\x99
+
+  The Enforcer Extension provides a way to globally define rules without making use of pom inheritence.
+  This way you don't have to adjust the pom.xml , but you can enforce a set of rules.   
+  
+* Usage
+
+  General instructions on how to use the Enforcer Plugin can be found on the {{{./usage.html}usage page}}.
+  
+  In case you still have questions regarding the plugin's usage, please have a look at the {{{./faq.html}FAQ}} and feel
+  free to contact the {{{./mailing-lists.html}user mailing list}}. The posts to the mailing list are archived and could
+  already contain the answer to your question as part of an older thread. Hence, it is also worth browsing/searching
+  the {{{./mailing-lists.html}mail archive}}.
+
+  If you feel like the plugin is missing a feature or has a defect, you can fill a feature request or bug report in our
+  {{{./issue-management.html}issue tracker}}. When creating a new issue, please provide a comprehensive description of your
+  concern. Especially for fixing bugs it is crucial that the developers can reproduce your problem. For this reason,
+  entire debug logs, POMs or most preferably little demo projects attached to the issue are very much appreciated.
+  Of course, patches are welcome, too. Contributors can check out the project from our
+  {{{./scm.html}source repository}} and will find supplementary information in the
+  {{{/guides/development/guide-helping.html}guide to helping with Maven}}.
diff --git a/maven-enforcer-extension/src/site/markdown/usage.md.vm b/maven-enforcer-extension/src/site/markdown/usage.md.vm
new file mode 100644
index 0000000..a9a4ec9
--- /dev/null
+++ b/maven-enforcer-extension/src/site/markdown/usage.md.vm
@@ -0,0 +1,54 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+Usage
+=====
+
+To use the maven-enforcer-extension, you must register the extension and configuration.
+
+Maven Extension
+---------------
+
+You have 2 ways to use Maven extensions within your builds:
+
+* add `maven-enforcer-extension-${project.version}.jar` in `${maven.home}/lib/ext` (no extra dependencies required),
+
+* (since Maven 3.3.1) configure your extension in [.mvn/extensions.xml](https://maven.apache.org/ref/current/maven-embedder/core-extensions.html).
+
+There is actually a third way: add the extension to the `pom.xml`, but in that case it makes more sense to use the [maven-enforcer-plugin](../maven-enforcer-plugin/) instead.
+
+Enforcer Extension
+------------------
+
+The `.mvn/enforcer-extension.xml` in the root of your Maven project is where you define your rules.
+It's content is similar to an execution-block of the maven-enforcer-plugin
+
+```xml
+<extension>
+  <executions>
+    <execution>
+      <id/> <!-- default: default-extension -->
+      <phase/> <!-- default: validate -->
+      <configuration> <!-- see Plugin Configuration -->
+        <rules/>
+      </configuration>
+    </execution>
+  </executions>
+</extension>
+```
diff --git a/maven-enforcer-extension/src/site/site.xml b/maven-enforcer-extension/src/site/site.xml
new file mode 100644
index 0000000..3929b21
--- /dev/null
+++ b/maven-enforcer-extension/src/site/site.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<project xmlns="http://maven.apache.org/DECORATION/1.0.0"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/DECORATION/1.0.0 http://maven.apache.org/xsd/decoration-1.0.0.xsd"
+  name="Maven Enforcer plugin">
+  <body>
+    <menu name="Overview">
+      <item name="Introduction" href="index.html"/>
+      <item name="Usage" href="usage.html"/>
+      <!-- According to https://issues.apache.org/jira/browse/MNGSITE-152 -->
+      <item name="License" href="http://www.apache.org/licenses/"/>
+      <item name="Download" href="../download.html"/>
+    </menu>
+  </body>
+</project>
diff --git a/pom.xml b/pom.xml
index 6902e5c..d98ac64 100644
--- a/pom.xml
+++ b/pom.xml
@@ -40,6 +40,7 @@
     <module>enforcer-api</module>
     <module>enforcer-rules</module>
     <module>maven-enforcer-plugin</module>
+    <module>maven-enforcer-extension</module>
   </modules>
 
   <scm>