Skip to content
Merged
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
19 changes: 10 additions & 9 deletions README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -53,16 +53,16 @@ You can try the Maven plugin without configuring anything in an existing project
mvn test-compile com.github.runeflobakk:record-matcher-maven-plugin::generate
----

The plugin attempts to discover records in a particular base package (more on this below). If the package is not present in your project, you are likely to get see the following error:
The plugin attempts to discover records in a particular base package (more on this below). If the package is not present in your project, you are likely to get see the following error:

> There was an error scanning for records in package(s) [the.attempted.pkg]: IllegalArgumentException 'One or more of the input resources are incorrect'. Ensure that the packages are correctly defined and exists.

You can specify a package (which includes sub-packages) to scan for records:

....
----
mvn test-compile com.github.runeflobakk:record-matcher-maven-plugin::generate\
-Drecordmatcher.scanPackages=pkg.in.your.project
....
-Drecordmatcher.scanPackages=pkg.in.your.project
----

Lastly, you can add `target/generated-sources/record-matchers` as a _source folder_ in your IDE to access and use the generated Hamcrest Matchers. Read on for how to configure Record Matcher Generator as an integral part of your Maven project.

Expand All @@ -83,10 +83,11 @@ Likely, you want to use this via the https://central.sonatype.com/artifact/com.g
<plugin>
<groupId>com.github.runeflobakk</groupId>
<artifactId>record-matcher-maven-plugin</artifactId>
<version>0.3.2</version> <!-- replace with any newer version -->
<version>0.4.0</version> <!-- replace with any newer version -->
<executions>
<execution>
<goals>
<goal>prepare-output-directory</goal>
<goal>generate</goal>
</goals>
</execution>
Expand All @@ -104,7 +105,7 @@ Using the `groupId` of your project as the base package for the plugin to discov
<plugin>
<groupId>com.github.runeflobakk</groupId>
<artifactId>record-matcher-maven-plugin</artifactId>
<version>0.3.2</version> <!-- replace with any newer version -->
<version>0.4.0</version> <!-- replace with any newer version -->
<configuration>
<scanPackages>
com.base.service
Expand Down Expand Up @@ -269,7 +270,7 @@ assertThat(effectiveJava).is(matching(aBook().withTitle("Effective Java").withAu
<!-- default: true
If you for some reason need to prevent the generated code
to be included as test sources in your project, set this to false -->
<includeGeneratedCodeAsTestSources>true</includeGeneratedCodeAsTestSources>
<includeAsTestSources>true</includeAsTestSources>

</configuration>
----
Expand All @@ -278,14 +279,14 @@ The following command can also be used anywhere to view the plugin’s own descr

[source,bash]
----
mvn com.github.runeflobakk:record-matcher-maven-plugin::help -Dgoal=generate -Ddetail
mvn com.github.runeflobakk:record-matcher-maven-plugin::help -Ddetail
----

Or the short form if you have already configured the plugin in your Maven project:

[source,bash]
----
mvn record-matcher:help
mvn record-matcher:help -Ddetail
----


Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package no.rune.record.matcher;

import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;

import java.io.File;
import java.util.Set;

abstract class CodeGeneratorBaseMojo extends AbstractMojo {

protected static final String PLUGIN_CONF_PROP_PREFIX = "recordmatcher.";

/**
* The directory where the generated code will be written to.
*/
@Parameter(required = true,
defaultValue = "${project.build.directory}/generated-test-sources/record-matchers",
property = PLUGIN_CONF_PROP_PREFIX + "outputDirectory")
private File outputDirectory;

/**
* Project packaging types where execution is skipped.
*/
@Parameter(required = true,
defaultValue = "pom",
property = PLUGIN_CONF_PROP_PREFIX + "skipForPackaging")
protected Set<String> skipForPackaging;


@Parameter(required = true, readonly = true,
defaultValue = "${project}")
protected MavenProject mavenProject;



OutputDirectory outputDirectory() {
return new OutputDirectory(outputDirectory.toPath());
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package no.rune.record.matcher;

import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Mojo;
Expand All @@ -17,7 +16,6 @@
import java.io.UncheckedIOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collection;
import java.util.List;
Expand All @@ -33,11 +31,15 @@
import static org.apache.maven.plugins.annotations.LifecyclePhase.GENERATE_TEST_SOURCES;
import static org.apache.maven.plugins.annotations.ResolutionScope.COMPILE;

@Mojo(name = "generate", defaultPhase = GENERATE_TEST_SOURCES, requiresDependencyResolution = COMPILE)
public class GenerateRecordMatcherMojo extends AbstractMojo {
@Mojo(
name = GenerateRecordMatcherMojo.GOAL_NAME,
defaultPhase = GENERATE_TEST_SOURCES,
requiresDependencyResolution = COMPILE)
public class GenerateRecordMatcherMojo extends CodeGeneratorBaseMojo {

static final String GOAL_NAME = "generate";

private static final Logger LOG = LoggerFactory.getLogger(GenerateRecordMatcherMojo.class);
private static final String PLUGIN_CONF_PROP_PREFIX = "recordmatcher.";

/**
* Specifies the fully qualified class names of the records to
Expand Down Expand Up @@ -73,37 +75,6 @@ public class GenerateRecordMatcherMojo extends AbstractMojo {
private Set<String> excludes;


/**
* The directory where the generated Hamcrest matchers will be written to.
*/
@Parameter(required = true,
defaultValue = "${project.build.directory}/generated-test-sources/record-matchers",
property = PLUGIN_CONF_PROP_PREFIX + "outputDirectory")
private File outputDirectory;


/**
* Whether the {@link #outputDirectory} should be included as a test sources root.
*/
@Parameter(required = true,
defaultValue = "true",
property = PLUGIN_CONF_PROP_PREFIX + "includeGeneratedCodeAsTestSources")
private boolean includeGeneratedCodeAsTestSources;


/**
* Project packaging types where execution is skipped.
*/
@Parameter(required = true,
defaultValue = "pom",
property = PLUGIN_CONF_PROP_PREFIX + "skipForPackaging")
private Set<String> skipForPackaging;


@Parameter(required = true, readonly = true,
defaultValue = "${project}")
private MavenProject mavenProject;


@Override
public void execute() throws MojoExecutionException, MojoFailureException {
Expand All @@ -112,19 +83,8 @@ public void execute() throws MojoExecutionException, MojoFailureException {
return;
}

Path outputDirectory = resolveOutputDirectory();
try {
Files.createDirectories(outputDirectory);
LOG.info("Generating Hamcrest matchers in {}", outputDirectory);
} catch (IOException e) {
throw new UncheckedIOException(
"Unable to create output directory " + outputDirectory + ", " +
"because " + e.getClass().getSimpleName() + ": " + e.getMessage(), e);
}
if (includeGeneratedCodeAsTestSources) {
mavenProject.addTestCompileSourceRoot(outputDirectory.toString());
LOG.debug("{} has been added as a compiler test sources directory", outputDirectory);
}
Path outputDirectory = outputDirectory().path();
LOG.info("Generating matchers in {}", outputDirectory);

var generator = new RecordMatcherGenerator();
var writtenFiles = resolveIncludedRecords()
Expand Down Expand Up @@ -154,8 +114,45 @@ public void execute() throws MojoExecutionException, MojoFailureException {

}

private Path resolveOutputDirectory() {
return outputDirectory.toPath();
@Override
protected OutputDirectory outputDirectory() {
var outputDirectory = super.outputDirectory();
if (!outputDirectory.exists()) {
outputDirectory.create();
LOG.warn("""
Directory {} was created because it did not already exist, but you need to use \
the {} goal in order to include it as test sources for the project.\
""",
outputDirectory.path(), PrepareOutputDirectoryMojo.GOAL_NAME);

LOG.info("""
From record-matcher-maven-plugin version >= 0.4.0, in order to include the generated \
matchers as compiled test code, it is required to configure the goal '{}' to create \
this directory separately before the '{}' goal is run. Please ensure the plugin's \
execution is configured like this:

<executions>
<execution>
<goals>
<goal>prepare-output-directory</goal>
<goal>generate</goal>
</goals>
</execution>
<execution>

If you are running the goal directly from the command line, you can try prepending \
the {} goal with the {} goal:

mvn record-matcher:{} record-matcher:{}

See the README at https://github.com/runeflobakk/record-matcher for further details on \
configuring and/or running standalone goals of the record-matcher-maven-plugin.
""",
PrepareOutputDirectoryMojo.GOAL_NAME, GenerateRecordMatcherMojo.GOAL_NAME,
GenerateRecordMatcherMojo.GOAL_NAME, PrepareOutputDirectoryMojo.GOAL_NAME,
PrepareOutputDirectoryMojo.GOAL_NAME, GenerateRecordMatcherMojo.GOAL_NAME);
}
return outputDirectory;
}


Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package no.rune.record.matcher;

import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.file.Files;
import java.nio.file.Path;

import static java.nio.file.Files.isDirectory;

record OutputDirectory(Path path) {

boolean exists() {
return isDirectory(path);
}

Path create() {
try {
return Files.createDirectories(path);
} catch (IOException e) {
throw new UncheckedIOException(
"Unable to create output directory " + path + ", " +
"because " + e.getClass().getSimpleName() + ": " + e.getMessage(), e);
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package no.rune.record.matcher;

import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static org.apache.maven.plugins.annotations.LifecyclePhase.GENERATE_TEST_SOURCES;

@Mojo(
name = PrepareOutputDirectoryMojo.GOAL_NAME,
defaultPhase = GENERATE_TEST_SOURCES)
public class PrepareOutputDirectoryMojo extends CodeGeneratorBaseMojo {

static final String GOAL_NAME = "prepare-output-directory";

private static final Logger LOG = LoggerFactory.getLogger(PrepareOutputDirectoryMojo.class);

/**
* Whether the {@link #outputDirectory} should be included as a test sources root.
*/
@Parameter(required = true,
defaultValue = "true",
property = PLUGIN_CONF_PROP_PREFIX + "includeAsTestSources")
private boolean includeAsTestSources;


@Override
public void execute() throws MojoExecutionException, MojoFailureException {

var outputDirectory = outputDirectory().create();

if (includeAsTestSources) {
mavenProject.addTestCompileSourceRoot(outputDirectory.toString());
LOG.info("Prepared output directory {}, and included as test sources", outputDirectory);
} else {
LOG.info("Prepared output directory {}, but not included as compilation source", outputDirectory);
}

}



}
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,25 @@
<pluginExecution>
<pluginExecutionFilter>
<goals>
<goal>generate</goal>
<goal>prepare-output-directory</goal>
</goals>
</pluginExecutionFilter>
<action>
<execute>
<runOnIncremental>true</runOnIncremental>
<runOnConfiguration>true</runOnConfiguration>
</execute>
</action>
</pluginExecution>
<pluginExecution>
<pluginExecutionFilter>
<goals>
<goal>generate</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore/>
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>