Skip to content

Commit

Permalink
#23 add new "newVersion" and "oldVersion" attributes for more resilie…
Browse files Browse the repository at this point in the history
…nt and

simpler setup of old and new versions in case of checking just the current
artifact

#25 Don't perform analysis on projects with non-file artifacts - like
the ones with pom packaging.

Additionally don't WARN on missing config files, if not configured to
right out fail on their absence.
  • Loading branch information
Lukas Krejci committed Mar 21, 2016
1 parent d4dce52 commit eb7d36d
Show file tree
Hide file tree
Showing 8 changed files with 158 additions and 105 deletions.
14 changes: 14 additions & 0 deletions revapi-maven-plugin/api-changes.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"0.4.4": {
"revapi": {
"ignore": [
{
"code": "java.annotation.attributeRemoved",
"old": "field org.revapi.maven.ReportMojo.newArtifacts",
"new": "field org.revapi.maven.ReportMojo.newArtifacts",
"justification": "'defaultValue' of @Parameter has been removed. That is completely safe."
}
]
}
}
}
2 changes: 1 addition & 1 deletion revapi-maven-plugin/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<parent>
<groupId>org.revapi</groupId>
<artifactId>revapi-build</artifactId>
<version>18</version>
<version>19</version>
<relativePath>../revapi-build</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@ void checkVersion(File pom, String... versions) throws Exception {
if (line.startsWith("<version>") && versionCount < versions.length) {
String version = versions[versionCount++];
assert line.equals("<version>" + version + "</version>") :
"The " + versionCount + "th version tag in v2 pom should have been changed to " + version +
" but the line reads: " + line;
"The " + versionCount + "th version tag in v2 pom (" + pom.getAbsolutePath() + ") should have" +
" been changed to version but the line reads: " + line;
found = true;
return;
}
}

if (!found) {
throw new AssertionError("Failed to find the <version> tag in v2 pom.xml");
throw new AssertionError("Failed to find the <version> tag in v2 pom.xml (" + pom.getAbsolutePath() + ")");
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,6 @@
* @since 0.3.11
*/
abstract class AbstractRevapiMojo extends AbstractMojo {

public static final String BUILD_COORDINATES = "BUILD";
public static final String REVAPI_GROUP_ID = "org.revapi";
public static final String REVAPI_MAVEN_PLUGIN_ARTIFACT_ID = "revapi-maven-plugin";

/**
* The JSON configuration of various analysis options. The available options depend on what
* analyzers are present on the plugins classpath through the {@code &lt;dependencies&gt;}.
Expand Down Expand Up @@ -116,19 +111,39 @@ abstract class AbstractRevapiMojo extends AbstractMojo {
/**
* The coordinates of the old artifacts. Defaults to single artifact with the latest released version of the
* current project.
* <p/>
* If the this property is null, the {@link #oldVersion} property is checked for a value of the old version of the
* artifact being built.
*
* <p>If the coordinates are exactly "BUILD" (without quotes) the build artifacts are used.
* @see #oldVersion
*/
@Parameter(property = "revapi.oldArtifacts")
protected String[] oldArtifacts;

/**
* The coordinates of the new artifacts. Defaults to single artifact with the artifacts from the build.
* If the coordinates are exactly "BUILD" (without quotes) the build artifacts are used.
* If you don't want to compare a different artifact than the one being built, specifying the just the old version
* is simpler way of specifying the old artifact.
* <p/>
* The default value is "RELEASE" meaning that the old version is the last released version of the artifact being
* built.
*/
@Parameter(defaultValue = "RELEASE", property = "revapi.oldVersion")
protected String oldVersion;

/**
* The coordinates of the new artifacts. These are the full GAVs of the artifacts, which means that you can compare
* different artifacts than the one being built. If you merely want to specify the artifact being built, use
* {@link #newVersion} property instead.
*/
@Parameter(defaultValue = AbstractRevapiMojo.BUILD_COORDINATES, property = "revapi.newArtifacts")
@Parameter(property = "revapi.newArtifacts")
protected String[] newArtifacts;

/**
* The new version of the artifact. Defaults to "${project.version}".
*/
@Parameter(defaultValue = "${project.version}", property = "revapi.newVersion")
protected String newVersion;

/**
* Whether to skip the mojo execution.
*/
Expand Down Expand Up @@ -178,19 +193,62 @@ abstract class AbstractRevapiMojo extends AbstractMojo {
protected boolean failOnUnresolvedDependencies;

protected void analyze(Reporter reporter) throws MojoExecutionException, MojoFailureException {
Analyzer analyzer = prepareAnalyzer(reporter);

if (analyzer != null) {
analyzer.analyze();
}
}

protected Analyzer prepareAnalyzer(Reporter reporter) {
if (skip) {
return;
return null;
}

if (oldArtifacts == null || oldArtifacts.length == 0) {
oldArtifacts = new String[]{Analyzer.getProjectArtifactCoordinates(project, repositorySystemSession, "RELEASE")};
if (!initializeComparisonArtifacts()) {
return null;
}

Analyzer analyzer = new Analyzer(analysisConfiguration, analysisConfigurationFiles, oldArtifacts,
return new Analyzer(analysisConfiguration, analysisConfigurationFiles, oldArtifacts,
newArtifacts, project, repositorySystem, repositorySystemSession, reporter, Locale.getDefault(), getLog(),
failOnMissingConfigurationFiles, failOnUnresolvedArtifacts, failOnUnresolvedDependencies,
alwaysCheckForReleaseVersion);
}

/**
* @return true if artifacts are initialized, false if not and the analysis should not proceed
*/
protected boolean initializeComparisonArtifacts() {
if (oldArtifacts == null || oldArtifacts.length == 0) {
//non-intuitively, we need to initialize the artifacts even if we will not proceed with the analysis itself
//that's because we need know the versions when figuring out the version modifications -
//see AbstractVersionModifyingMojo
oldArtifacts = new String[]{
Analyzer.getProjectArtifactCoordinates(project, repositorySystemSession, oldVersion)};

//bail out quickly for POM artifacts (or any other packaging without a file result) - there's nothing we can
//analyze there
//only do it here, because oldArtifacts might point to another artifact.
//if we end up here in this branch, we know we'll be comparing the current artifact with something.
if (project.getArtifact().getFile() == null) {
return false;
}
}

if (newArtifacts == null || newArtifacts.length == 0) {
newArtifacts = new String[]{
Analyzer.getProjectArtifactCoordinates(project, repositorySystemSession, newVersion)};

//bail out quickly for POM artifacts (or any other packaging without a file result) - there's nothing we can
//analyze there
//again, do this check only here, because oldArtifact might point elsewhere. But if we end up here, it
//means that oldArtifacts would be compared against the current artifact (in some version). Comparing
//against a POM artifact is always no-op.
if (project.getArtifact().getFile() == null) {
return false;
}
}

analyzer.analyze();
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.eclipse.aether.artifact.DefaultArtifact;
import org.revapi.ApiAnalyzer;
import org.revapi.DifferenceTransform;
import org.revapi.ElementFilter;
Expand Down Expand Up @@ -121,13 +122,16 @@ public boolean isSingleVersionForAllModules() {
if (skip) {
return;
}
AnalysisResults analysisResults;

if (oldArtifacts == null || oldArtifacts.length == 0) {
oldArtifacts = new String[]{Analyzer.getProjectArtifactCoordinates(project, repositorySystemSession,
"RELEASE")};
if (!initializeComparisonArtifacts()) {
//we've got non-file artifacts, for which there is no reason to run analysis
DefaultArtifact oldArtifact = new DefaultArtifact(oldArtifacts[0]);
analysisResults = new AnalysisResults(ApiChangeLevel.NO_CHANGE, oldArtifact.getVersion());
} else {
analysisResults = analyzeProject(project);
}

AnalysisResults analysisResults = analyzeProject(project);
if (analysisResults == null) {
return;
}
Expand Down
62 changes: 3 additions & 59 deletions revapi-maven-plugin/src/main/java/org/revapi/maven/Analyzer.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@
import org.eclipse.aether.RepositorySystem;
import org.eclipse.aether.RepositorySystemSession;
import org.eclipse.aether.artifact.Artifact;
import org.eclipse.aether.artifact.DefaultArtifact;
import org.eclipse.aether.repository.RepositoryPolicy;
import org.eclipse.aether.resolution.ArtifactResolutionException;
import org.jboss.dmr.ModelNode;
Expand All @@ -59,8 +58,6 @@
* @since 0.1
*/
final class Analyzer {
private static final String BUILD_COORDINATES = "BUILD";

private final String analysisConfiguration;

private final Object[] analysisConfigurationFiles;
Expand Down Expand Up @@ -173,7 +170,8 @@ void validateConfiguration() throws MojoExecutionException {
@SuppressWarnings("unchecked")
void resolveArtifacts() {
if (resolvedOldApi == null) {
final BuildAwareArtifactResolver resolver = new BuildAwareArtifactResolver();
final ArtifactResolver resolver = new ArtifactResolver(repositorySystem, repositorySystemSession,
project.getRemoteProjectRepositories());

//Ok, what on Earth is this?
//We're building with Java8 and I really like lambdas but Maven in the version we're using doesn't like
Expand Down Expand Up @@ -344,7 +342,7 @@ private void gatherConfig(AnalysisContext.Builder ctxBld) throws MojoExecutionEx
if (failOnMissingConfigurationFiles) {
throw new MojoExecutionException(message);
} else {
log.warn(message);
log.debug(message);
continue;
}
}
Expand Down Expand Up @@ -379,67 +377,13 @@ private void gatherConfig(AnalysisContext.Builder ctxBld) throws MojoExecutionEx
}
}

class BuildAwareArtifactResolver extends ArtifactResolver {

public BuildAwareArtifactResolver() {
super(repositorySystem, repositorySystemSession, project.getRemoteProjectRepositories());
}

@Override
protected void collectTransitiveDeps(String gav, Set<Artifact> resolvedArtifacts, Set<Exception> exceptions)
throws RepositoryException {

if (BUILD_COORDINATES.equals(gav)) {
Artifact a = resolveArtifact(gav);
super.collectTransitiveDeps(a.toString(), resolvedArtifacts, exceptions);
} else {
super.collectTransitiveDeps(gav, resolvedArtifacts, exceptions);
}
}

@Override
public Artifact resolveArtifact(String gav) throws ArtifactResolutionException {
if (BUILD_COORDINATES.equals(gav)) {
Artifact ret = toAetherArtifact(project.getArtifact(), repositorySystemSession);

//project.getArtifact().getFile() returns null for pom-packaged projects
if ("pom".equals(project.getArtifact().getType())) {
ret = ret.setFile(new File(project.getBasedir(), "pom.xml"));
} else {
ret = ret.setFile(project.getArtifact().getFile());
}

return ret;
} else {
return super.resolveArtifact(gav);
}
}

private Artifact toAetherArtifact(org.apache.maven.artifact.Artifact artifact, RepositorySystemSession session) {
String extension = session.getArtifactTypeRegistry().get(artifact.getType()).getExtension();
return new DefaultArtifact(artifact.getGroupId(), artifact.getArtifactId(), artifact.getClassifier(), extension,
artifact.getVersion());
}
}

private static class MarkerException extends RuntimeException {
public MarkerException() {
}

public MarkerException(Throwable cause) {
super(cause);
}

public MarkerException(String message) {
super(message);
}

public MarkerException(String message, Throwable cause) {
super(message, cause);
}

public MarkerException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}
}
62 changes: 53 additions & 9 deletions revapi-maven-plugin/src/main/java/org/revapi/maven/ReportMojo.java
Original file line number Diff line number Diff line change
Expand Up @@ -128,21 +128,42 @@ public class ReportMojo extends AbstractMavenReport {

/**
* The coordinates of the old artifacts. Defaults to single artifact with the latest released version of the
* current
* project.
* current project.
* <p/>
* If the coordinates are exactly "BUILD" (without quotes) the build artifacts are used.
* <p/>
* If the this property is null, the {@link #oldVersion} property is checked for a value of the old version of the
* artifact being built.
*
* <p>If the coordinates are exactly "BUILD" (without quotes) the build artifacts are used.
* @see #oldVersion
*/
@Parameter(property = "revapi.oldArtifacts")
private String[] oldArtifacts;

/**
* The coordinates of the new artifacts. Defaults to single artifact with the artifacts from the build.
* If the coordinates are exactly "BUILD" (without quotes) the build artifacts are used.
* If you don't want to compare a different artifact than the one being built, specifying the just the old version
* is simpler way of specifying the old artifact.
* <p/>
* The default value is "RELEASE" meaning that the old version is the last released version of the artifact being
* built.
*/
@Parameter(defaultValue = "RELEASE", property = "revapi.oldVersion")
private String oldVersion;

/**
* The coordinates of the new artifacts. These are the full GAVs of the artifacts, which means that you can compare
* different artifacts than the one being built. If you merely want to specify the artifact being built, use
* {@link #newVersion} property instead.
*/
@Parameter(defaultValue = AbstractRevapiMojo.BUILD_COORDINATES, property = "revapi.newArtifacts")
@Parameter(property = "revapi.newArtifacts")
private String[] newArtifacts;

/**
* The new version of the artifact. Defaults to "${project.version}".
*/
@Parameter(defaultValue = "${project.version}", property = "revapi.newVersion")
private String newVersion;

/**
* Problems with this or higher severity will be included in the report.
* Possible values: nonBreaking, potentiallyBreaking, breaking.
Expand Down Expand Up @@ -265,12 +286,34 @@ public String getDescription(Locale locale) {

private void ensureAnalyzed(Locale locale) {
if (reporter == null) {
reporter = new ReportTimeReporter(reportSeverity.asDifferenceSeverity());

if (oldArtifacts == null || oldArtifacts.length == 0) {
oldArtifacts = new String[]{Analyzer.getProjectArtifactCoordinates(project, repositorySystemSession,
"RELEASE")};
//bail out quickly for POM artifacts (or any other packaging without a file result) - there's nothing we can
//analyze there
//only do it here, because oldArtifacts might point to another artifact.
//if we end up here in this branch, we know we'll be comparing the current artifact with something.
if (project.getArtifact().getFile() == null) {
return;
}

oldArtifacts = new String[]{
Analyzer.getProjectArtifactCoordinates(project, repositorySystemSession, oldVersion)};
}

reporter = new ReportTimeReporter(reportSeverity.asDifferenceSeverity());
if (newArtifacts == null || newArtifacts.length == 0) {
//bail out quickly for POM artifacts (or any other packaging without a file result) - there's nothing we can
//analyze there
//again, do this check only here, because oldArtifact might point elsewhere. But if we end up here, it
//means that oldArtifacts would be compared against the current artifact (in some version). Comparing
//against a POM artifact is always no-op.
if (project.getArtifact().getFile() == null) {
return;
}

newArtifacts = new String[]{
Analyzer.getProjectArtifactCoordinates(project, repositorySystemSession, newVersion)};
}

Analyzer analyzer = new Analyzer(analysisConfiguration, analysisConfigurationFiles, oldArtifacts,
newArtifacts, project, repositorySystem, repositorySystemSession, reporter, locale, getLog(),
Expand All @@ -287,6 +330,7 @@ private void ensureAnalyzed(Locale locale) {
}
}
}

private ResourceBundle getBundle(Locale locale) {
return ResourceBundle.getBundle("revapi-report", locale, this.getClass().getClassLoader());
}
Expand Down

0 comments on commit eb7d36d

Please sign in to comment.