Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

-Added a helper class to test and debug Mojos in an IDE #65

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 33 additions & 6 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@
<properties>
<!-- Plugin dependencies versions-->
<maven.required.version>3.6</maven.required.version>
<maven.version>3.3.9</maven.version>
<maven.artifact.transfer.version>0.10.0</maven.artifact.transfer.version>
<maven.resolver.version>1.3.1</maven.resolver.version>
<maven.enforcer.plugin.version>1.4.1</maven.enforcer.plugin.version>
<maven.source.plugin.version>3.0.1</maven.source.plugin.version>
<maven.javadoc.plugin.version>3.0.1</maven.javadoc.plugin.version>
<maven.version>3.6.3</maven.version>
<maven.plugin-testing.version>3.3.0</maven.plugin-testing.version>
<maven.artifact.transfer.version>0.13.1</maven.artifact.transfer.version>
<maven.resolver.version>1.4.1</maven.resolver.version>
<maven.enforcer.plugin.version>3.0.0-M3</maven.enforcer.plugin.version>
<maven.source.plugin.version>3.2.1</maven.source.plugin.version>
<maven.javadoc.plugin.version>3.2.0</maven.javadoc.plugin.version>
<maven.gpg.plugin.version>1.6</maven.gpg.plugin.version>

<!-- Builder dependencies versions -->
Expand Down Expand Up @@ -265,6 +266,26 @@
<version>${maven.resolver.version}</version>
</dependency>

<dependency>
<groupId>org.apache.maven.plugin-testing</groupId>
<artifactId>maven-plugin-testing-harness</artifactId>
<version>${maven.plugin-testing.version}</version>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</exclusion>
</exclusions>
</dependency>

<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-compat</artifactId>
<version>${maven.version}</version>
<scope>test</scope>
</dependency>

<!-- dependencies to annotations -->
<dependency>
<groupId>org.apache.maven.plugin-tools</groupId>
Expand Down Expand Up @@ -430,6 +451,12 @@
<version>3.7.1</version>
</plugin>
</plugins>
<testResources>
<testResource>
<directory>src/it</directory>
<filtering>true</filtering>
</testResource>
</testResources>
</build>

<distributionManagement>
Expand Down
2 changes: 1 addition & 1 deletion src/it/hello-world-reactor/lib/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,4 @@
</plugins>
</pluginManagement>
</build>
</project>
</project>
29 changes: 28 additions & 1 deletion src/it/hello-world-reactor/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,31 @@
<url>https://oss.sonatype.org/content/repositories/google-snapshots/</url>
</repository>
</repositories>
</project>

<build>
<plugins>
<!--
Define settings to use when running dev mode. these aren't inherited, so they won't affect other modules
when they run. Note that if an app specifies something, it automatically overrides anything here - use
profiles to swap between dev and prod configuration instead.
-->
<plugin>
<groupId>com.vertispan.j2cl</groupId>
<artifactId>j2cl-maven-plugin</artifactId>
<inherited>false</inherited>
<executions>
<execution>
<id>build-js</id><phase>prepare-package</phase>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
<configuration>
<webappDirectory>target/gwt/launcherDir</webappDirectory>
</configuration>
</plugin>
</plugins>
</build>

</project>
26 changes: 26 additions & 0 deletions src/it/transitive-dependencies/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,30 @@
<url>https://oss.sonatype.org/content/repositories/google-snapshots/</url>
</repository>
</repositories>

<build>
<plugins>
<!--
Define settings to use when running dev mode. these aren't inherited, so they won't affect other modules
when they run. Note that if an app specifies something, it automatically overrides anything here - use
profiles to swap between dev and prod configuration instead.
-->
<plugin>
<groupId>com.vertispan.j2cl</groupId>
<artifactId>j2cl-maven-plugin</artifactId>
<inherited>false</inherited>
<executions>
<execution>
<id>build-js</id><phase>prepare-package</phase>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
<configuration>
<webappDirectory>target/gwt/launcherDir</webappDirectory>
</configuration>
</plugin>
</plugins>
</build>
</project>
136 changes: 136 additions & 0 deletions src/test/java/net/cardosi/mojo/MojoTester.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
package net.cardosi.mojo;

import java.io.File;
import java.lang.reflect.Method;
import java.nio.file.Files;
import java.util.List;
import java.util.Map;

import org.apache.maven.DefaultMaven;
import org.apache.maven.Maven;
import org.apache.maven.execution.DefaultMavenExecutionRequest;
import org.apache.maven.execution.DefaultMavenExecutionResult;
import org.apache.maven.execution.MavenExecutionRequest;
import org.apache.maven.execution.MavenExecutionRequestPopulator;
import org.apache.maven.execution.MavenExecutionResult;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.graph.GraphBuilder;
import org.apache.maven.model.Plugin;
import org.apache.maven.plugin.ContextEnabled;
import org.apache.maven.plugin.Mojo;
import org.apache.maven.plugin.MojoExecution;
import org.apache.maven.plugin.descriptor.MojoDescriptor;
import org.apache.maven.plugin.descriptor.PluginDescriptor;
import org.apache.maven.plugin.testing.AbstractMojoTestCase;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.ProjectBuilder;
import org.eclipse.aether.DefaultRepositorySystemSession;
import org.eclipse.aether.RepositorySystemSession;
import org.eclipse.aether.internal.impl.SimpleLocalRepositoryManagerFactory;
import org.eclipse.aether.repository.LocalRepository;
import org.junit.Ignore;
import org.junit.Test;

public class MojoTester
extends AbstractMojoTestCase {

protected void setUp() throws Exception {
// required for mojo lookups to work
super.setUp();
}

public static void main(String[] args) throws Exception {
MojoTester test = new MojoTester();
test.setUp();
test.testMojoGoal();
}

protected MavenSession newMavenSession() {
try {
MavenExecutionRequest request = new DefaultMavenExecutionRequest();
MavenExecutionResult result = new DefaultMavenExecutionResult();

// populate sensible defaults, including repository basedir and remote repos
MavenExecutionRequestPopulator populator;
populator = getContainer().lookup( MavenExecutionRequestPopulator.class );
populator.populateDefaults( request );

// this is needed to allow java profiles to get resolved; i.e. avoid during project builds:
// [ERROR] Failed to determine Java version for profile java-1.5-detected @ org.apache.commons:commons-parent:22, /Users/alex/.m2/repository/org/apache/commons/commons-parent/22/commons-parent-22.pom, line 909, column 14
request.setSystemProperties( System.getProperties() );

// and this is needed so that the repo session in the maven session
// has a repo manager, and it points at the local repo
// (cf MavenRepositorySystemUtils.newSession() which is what is otherwise done)
DefaultMaven maven = (DefaultMaven) getContainer().lookup(Maven.class);
DefaultRepositorySystemSession repoSession =
(DefaultRepositorySystemSession) maven.newRepositorySession( request );
repoSession.setLocalRepositoryManager(
new SimpleLocalRepositoryManagerFactory().newInstance(repoSession,
new LocalRepository(request.getLocalRepository().getBasedir() )));

@SuppressWarnings("deprecation")
MavenSession session = new MavenSession( getContainer(),
repoSession,
request, result );
return session;
} catch (Exception e) {
throw new RuntimeException(e);
}
}

/** As {@link #lookupConfiguredMojo(MavenProject, String)} but taking the pom file
* and creating the {@link MavenProject}. */
protected Mojo lookupConfiguredMojo(File pom, String goal) throws Exception {
assertNotNull( pom );
assertTrue( pom.exists() );

MavenSession session = newMavenSession();
session.getRequest().setPom(pom);
session.getProjectBuildingRequest().setResolveDependencies(true);

GraphBuilder gbuilder = getContainer().lookup(GraphBuilder.class);
gbuilder.build(session);

List<MavenProject> mavenProjects = session.getProjects();

ProjectBuilder projectBuilder = lookup(ProjectBuilder.class);
Method method = projectBuilder.getClass().getDeclaredMethod("resolveDependencies", MavenProject.class, RepositorySystemSession.class);
method.setAccessible(true);

for (MavenProject mavenProject : mavenProjects) {
method.invoke(projectBuilder, mavenProject, session.getRepositorySession());
}

final MojoExecution mojoExecution = newMojoExecution(goal);

MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor();
PluginDescriptor pluginDescriptor = mojoDescriptor.getPluginDescriptor();

Plugin plugin = session.getCurrentProject().getBuild().getPluginsAsMap().get(pluginDescriptor.getGroupId() + ":" + pluginDescriptor.getArtifactId());
pluginDescriptor.setPlugin(plugin);

AbstractBuildMojo mojo = (AbstractBuildMojo) lookupConfiguredMojo( session, newMojoExecution( goal ) );
Map<String, Object> pluginContext = mojo.mavenSession.getPluginContext(pluginDescriptor, session.getCurrentProject());
pluginContext.put( "project", session.getCurrentProject() );
pluginContext.put( "pluginDescriptor", pluginDescriptor );
( (ContextEnabled) mojo ).setPluginContext(pluginContext);

return mojo;
}

@Test
@Ignore
public void testMojoGoal() throws Exception
{
File testPom = new File(getBasedir(),
"target/test-classes/hello-world-reactor/pom.xml" );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if this is targetting just that parent pom, why the changes to the transitive-dependencies parent pom?

the next iter will have the actual building code in a plain java jar library (maven agnostic, so you could build some IDE tooling too in theory), and will be used by the mojo - this tooling will be helpful, but we'll be able to actually write plain tests too, and actually edit some temp files and see what happens.


Files.exists(testPom.toPath());

final WatchMojo mojo = (WatchMojo) this.lookupConfiguredMojo(testPom, "watch");
mojo.execute();
}


}