Skip to content
Permalink
Browse files
COMMONSSITE-97: how to do development on the plugin
  • Loading branch information
Rob Tompkins committed Jan 10, 2018
1 parent f7041c0 commit 827a19da14217197f2762e19065193220440793a
Showing 1 changed file with 70 additions and 45 deletions.
@@ -39,69 +39,94 @@
<section name="New Mojos">

<p>
Each Mojo is a java file that extends <code>Abstract</code>
<ul>
<li>An ant build file
<ul><li>[naming convention: <i>basename</i><b>.build.xml</b>]</li></ul>
</li>
<li>A <i>mapping document</i> which wires the build file into maven's plugin framework
<ul><li>[naming convention: <i>basename</i><b>.mojos.xml</b>]</li></ul>
</li>
</ul>
Each Mojo is a java file that extends <code>AbstractMojo</code> that contains an annotation specifying
the goal name for the mojo and the maven lifecycle phase that it executes under by default. For, example
<source><![CDATA[
package org.apache.commons.release.plugin.mojos;
@Mojo(name = "detach-distributions", defaultPhase = LifecyclePhase.VERIFY, threadSafe = true)
public class CommonsDistributionDetachmentMojo extends AbstractMojo {
.....
}]]></source>
specifies the goal <code>commons-release:detach-distributions</code> that is to occur during the VERIFY maven
lifecycle.
</p>

<p>
So if you want to add a new <i>foo-bar</i> ant script you would create a <code>foo-bar.build.xml</code>
ant script file and <code>foo-bar.mojos.xml</code> mapping document.
</p>

<p>
Both these files should be located in the
<a href="http://svn.apache.org/repos/asf/commons/proper/commons-build-plugin/trunk/src/main/scripts/">src/main/scripts</a>
directory.
</p>

<p>
If you want to access variables from the component's <code>pom.xml</code> in the ant script
then you need to do two things in the <i>mapping document</i>:
<ul>
<li>Add the <code>&lt;requiresProject&gt;true&lt;/requiresProject&gt;</code></li>
<li>Add <code>&lt;parameter&gt;</code> elements for each of the variables you
want to use.</li>
</ul>
</p>

</section>

<section name="Goal Prefix">

<p>
This plugin uses <code>commons</code> as the goal prefix. So if you add a new <code>foo-bar</code>
goal, then it can be executed on the command line using <code>mvn commons:foo-bar</code>. This prefix
is defined in this plugin's
<a href="http://svn.apache.org/repos/asf/commons/proper/commons-build-plugin/trunk/pom.xml">pom.xml</a>.
The variables in the mojo that are declared as private with the annotations <code>@Parameter</code> get
imported to the Mojo by the existent maven variables or the declared <code>&lt;configuration&gt;</code>. For
example, we have a boolean variable named <code>dryRun</code> declared as:
<source><![CDATA[
@Parameter
private Boolean dryRun;
]]></source>
that can be configured by
<source><![CDATA[
<plugin>
<groupId>org.apache.commons</groupId>
<artifactId>commons-release-plugin</artifactId>
<version>0.1-SNAPSHOT</version>
<configuration>
<dryRun>true</dryRun>
</configuration>
</plugin>]]></source>
</p>

</section>

<section name="Modifying Existing Scripts">
<section name="Unit testing">

<p>
Not alot to say about this except, if you need access to additional variables from the component's
<code>pom.xml</code> in the ant build script then you will need to define additional <i>parameters</i>
for these in the associated <i>mapping document</i>.
We've declared mock maven poms in the <code>resources</code> directory of the <code>src/test</code> folder,
under which we've stored in subdirectories corresponding to the names of the mojos that they are testing. All
variables that you wish to be available to your mojo must be specifically declared in the mock pom file. For
example, we need to use the already existent <code>MavenProject</code> in the maven runtime by instead, in a
test package declaring a class extending <code>MavenProjectStub</code> that returns values we wish to be used
in testing. We then add this to our pom in the following declaration of the plugin:
<source><![CDATA[
<plugin>
<groupId>org.apache.commons</groupId>
<artifactId>commons-release-plugin</artifactId>
<configuration>
<project implementation="org.apache.commons.release.plugin.stubs.DistributionDetachmentProjectStub" />
<workingDirectory>target/commons-release-plugin</workingDirectory>
<distSvnStagingUrl>mockDistSvnStagingUrl</distSvnStagingUrl>
</configuration>
</plugin>]]></source>
Also note here we are declaring other values that we are using in the testing of the plugin. We then retrieve
our instantiated mojo by declaring a <code>MojoRule</code> in our test class,
<source><![CDATA[
@Rule
public MojoRule rule = new MojoRule() {
@Override
protected void before() throws Throwable {
}
@Override
protected void after() {
}
};]]></source>
and then retrieve the mojo by newing up a <code>File</code> pointed to the path of the mock pom, and then
making the following call:
<source><![CDATA[
mojo = (CommonsSiteCompressionMojo) rule.lookupMojo("compress-site", testPom);
]]></source>
where we are trying to get the mojo with the <code>compress-site</code> goal.
</p>

</section>

<section name="Debugging">

<p>
The <i>message level</i> for ant is <i>info</i> by default. Running the plugin goal using a message
level of <i>debug</i> can help in discovering problems - for example:
Maven ships with a debugger under the hood. It is suggested that you have a sandbox project in which you can
run the goals or the plugin configuration. Once you have that set up you can run something like
<source><![CDATA[
mvn commons:jira-page -DantMessageLevel=debug
mvnDebug commons-release:detach-distributions
]]></source>
which exposes a remote debugger on port 8000 and halts the maven process until you attach a remote debugger
to that port. Once you have a remote debugger attached the maven process continues and stops at any
breakpoints that you have set up in your project.
</p>

</section>

0 comments on commit 827a19d

Please sign in to comment.