From 846eb0bda2c71de77bde1dfaf9fd5c19ffdcc4bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20L=C3=A4ubrich?= Date: Sat, 31 Aug 2024 08:26:48 +0200 Subject: [PATCH] Suggest version updates from API tools Currently API Tool errors can only be printed but not handled by tycho-versions-plugin:bump-versions. This now adds a first bunch of version problems to be identified and transformed into version bump suggestions. This also fix the case where log messages are enhanced but then no other checks are performed and adds property definitions for some parameters. --- .../tycho/apitools/ApiAnalysisMojo.java | 72 +++++++++++++++---- 1 file changed, 59 insertions(+), 13 deletions(-) diff --git a/tycho-apitools-plugin/src/main/java/org/eclipse/tycho/apitools/ApiAnalysisMojo.java b/tycho-apitools-plugin/src/main/java/org/eclipse/tycho/apitools/ApiAnalysisMojo.java index 76bf4e0107..0510ad49ff 100644 --- a/tycho-apitools-plugin/src/main/java/org/eclipse/tycho/apitools/ApiAnalysisMojo.java +++ b/tycho-apitools-plugin/src/main/java/org/eclipse/tycho/apitools/ApiAnalysisMojo.java @@ -24,6 +24,7 @@ import java.util.Optional; import java.util.Set; import java.util.function.Consumer; +import java.util.function.Function; import java.util.stream.Collectors; import org.apache.maven.artifact.Artifact; @@ -51,6 +52,7 @@ import org.eclipse.tycho.core.EcJLogFileEnhancer; import org.eclipse.tycho.core.EcJLogFileEnhancer.Source; import org.eclipse.tycho.core.TychoProjectManager; +import org.eclipse.tycho.core.exceptions.VersionBumpRequiredException; import org.eclipse.tycho.core.osgitools.DefaultReactorProject; import org.eclipse.tycho.model.project.EclipseProject; import org.eclipse.tycho.osgi.framework.EclipseApplication; @@ -58,6 +60,7 @@ import org.eclipse.tycho.osgi.framework.EclipseWorkspace; import org.eclipse.tycho.osgi.framework.EclipseWorkspaceManager; import org.osgi.framework.BundleException; +import org.osgi.framework.Version; /** * Performs a PDE-API Tools analysis of this project. @@ -114,25 +117,28 @@ public class ApiAnalysisMojo extends AbstractMojo { @Parameter(defaultValue = "${project.build.directory}/compile-logs") private File logDirectory; - @Parameter(defaultValue = "true") + @Parameter(defaultValue = "true", property = "tycho.apitools.printProblems") private boolean printProblems; - @Parameter(defaultValue = "true") + @Parameter(defaultValue = "true", property = "tycho.apitools.printSummary") private boolean printSummary; @Parameter(defaultValue = "false") private boolean failOnResolutionError; - @Parameter(defaultValue = "true") + @Parameter(defaultValue = "true", property = "tycho.apitools.failOnError") private boolean failOnError; - @Parameter(defaultValue = "false") + @Parameter(defaultValue = "false", property = "tycho.apitools.failOnWarning") private boolean failOnWarning; + @Parameter(defaultValue = "false", property = "tycho.apitools.failOnVersion") + private boolean failOnVersion; + @Parameter(defaultValue = "false") private boolean parallel; - @Parameter(defaultValue = "false") + @Parameter(defaultValue = "false", property = "tycho.apitools.enhanceLogs") private boolean enhanceLogs; @Component @@ -218,7 +224,6 @@ public void execute() throws MojoExecutionException, MojoFailureException { try (EcJLogFileEnhancer enhancer = EcJLogFileEnhancer.create(logDirectory)) { enhanceLog(enhancer, problemsMap); } - return; } } catch (IOException e) { log.warn("Can't enhance logs in directory " + logDirectory); @@ -229,13 +234,11 @@ public void execute() throws MojoExecutionException, MojoFailureException { log.info(warnings.size() + " API warnings"); } if (errors.size() > 0 && failOnError) { - String msg = errors.stream().map(problem -> { - if (problem.getResourcePath() == null) { - return problem.getMessage(); - } - return problem.getResourcePath() + ":" + problem.getLineNumber() + " " + problem.getMessage(); - }).collect(Collectors.joining(System.lineSeparator())); - throw new MojoFailureException("There are API errors:" + System.lineSeparator() + msg); + throw getApiError(errors); + } + if (errors.size() > 0 && failOnVersion + && errors.stream().anyMatch(problem -> problem.getCategory() == IApiProblem.CATEGORY_VERSION)) { + throw getApiError(errors); } if (warnings.size() > 0 && failOnWarning) { String msg = warnings.stream().map(problem -> { @@ -249,6 +252,49 @@ public void execute() throws MojoExecutionException, MojoFailureException { } } + private MojoFailureException getApiError(List errors) { + String problems = errors.stream().map(problem -> { + if (problem.getResourcePath() == null) { + return problem.getMessage(); + } + return problem.getResourcePath() + ":" + problem.getLineNumber() + " " + problem.getMessage(); + }).collect(Collectors.joining(System.lineSeparator())); + String message = "There are API errors:" + System.lineSeparator() + problems; + for (IApiProblem problem : errors) { + if (problem.getCategory() == IApiProblem.CATEGORY_VERSION) { + switch (problem.getKind()) { + case IApiProblem.REEXPORTED_MAJOR_VERSION_CHANGE: + case IApiProblem.REEXPORTED_REMOVAL_OF_REEXPORT_MAJOR_VERSION_CHANGE: + case IApiProblem.MAJOR_VERSION_CHANGE: + return new VersionBumpRequiredException(message, project, + getSuggestedVersion(current -> new Version(current.getMajor() + 1, 0, 0))); + case IApiProblem.MINOR_VERSION_CHANGE: + case IApiProblem.MINOR_VERSION_CHANGE_EXECUTION_ENV_CHANGED: + case IApiProblem.REEXPORTED_MINOR_VERSION_CHANGE: + return new VersionBumpRequiredException(message, project, + getSuggestedVersion(current -> new Version(current.getMajor(), current.getMinor() + 1, 0))); + default: + break; + } + } + } + return new MojoFailureException(message); + } + + private Version getSuggestedVersion(Function update) { + try { + Optional key = projectManager.getArtifactKey(project); + if (key.isPresent()) { + String version = key.get().getVersion(); + Version current = Version.parseVersion(version); + return update.apply(current); + } + } catch(RuntimeException e) { + getLog().warn("Can't determine suggested version!"); + } + return null; + } + private void enhanceLog(EcJLogFileEnhancer enhancer, Map> problemsMap) { Log log = getLog(); int notMapped = 0;