From 928a80fe95dcd05ac598e6d5908d0dcb619cfdf9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20L=C3=A4ubrich?= Date: Sun, 19 Jan 2025 19:57:14 +0100 Subject: [PATCH] [bp] Create new tycho-cleancode plugin Currently there are two categories in the IDE that allows automatic code changes: 1) QuickFix that allows to resolve an error/warning automatically 2) CleanUp that allows to modernize or fix a more generic form of problem Tycho now has support to apply these automatically to a given project codebase to automate this process especially when the code evolves or new warnings occur due to changed dependencies. --- RELEASE_NOTES.md | 2 + pom.xml | 1 + .../.settings/org.eclipse.jdt.core.prefs | 8 ++ tycho-cleancode-plugin/pom.xml | 64 +++++++++ .../org/eclipse/tycho/cleancode/CleanUp.java | 128 +++++++++++++++++ .../eclipse/tycho/cleancode/CleanUpMojo.java | 84 +++++++++++ .../tycho/cleancode/CleanupResult.java | 33 +++++ .../org/eclipse/tycho/cleancode/QuickFix.java | 132 ++++++++++++++++++ .../eclipse/tycho/cleancode/QuickFixMojo.java | 74 ++++++++++ .../tycho/cleancode/QuickFixResult.java | 42 ++++++ .../eclipsebuild/AbstractEclipseBuild.java | 10 ++ .../AbstractEclipseBuildMojo.java | 7 + 12 files changed, 585 insertions(+) create mode 100644 tycho-cleancode-plugin/.settings/org.eclipse.jdt.core.prefs create mode 100644 tycho-cleancode-plugin/pom.xml create mode 100644 tycho-cleancode-plugin/src/main/java/org/eclipse/tycho/cleancode/CleanUp.java create mode 100644 tycho-cleancode-plugin/src/main/java/org/eclipse/tycho/cleancode/CleanUpMojo.java create mode 100644 tycho-cleancode-plugin/src/main/java/org/eclipse/tycho/cleancode/CleanupResult.java create mode 100644 tycho-cleancode-plugin/src/main/java/org/eclipse/tycho/cleancode/QuickFix.java create mode 100644 tycho-cleancode-plugin/src/main/java/org/eclipse/tycho/cleancode/QuickFixMojo.java create mode 100644 tycho-cleancode-plugin/src/main/java/org/eclipse/tycho/cleancode/QuickFixResult.java diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index dcd59b0645..313d590327 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -43,6 +43,8 @@ This is now fixed, but might result in build previously working now fail due to backports: - Support for implicit dependencies in target definitions - Add tycho-baseline:check-dependencies mojo +- Add tycho-cleancode plugin + ## 4.0.10 diff --git a/pom.xml b/pom.xml index ef3300804f..5f7cf98da0 100644 --- a/pom.xml +++ b/pom.xml @@ -595,6 +595,7 @@ tycho-repository-plugin tycho-eclipse-plugin tycho-wrap-plugin + tycho-cleancode-plugin diff --git a/tycho-cleancode-plugin/.settings/org.eclipse.jdt.core.prefs b/tycho-cleancode-plugin/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000000..eeac0e762f --- /dev/null +++ b/tycho-cleancode-plugin/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,8 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=17 +org.eclipse.jdt.core.compiler.compliance=17 +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=17 diff --git a/tycho-cleancode-plugin/pom.xml b/tycho-cleancode-plugin/pom.xml new file mode 100644 index 0000000000..ed70a6d5f2 --- /dev/null +++ b/tycho-cleancode-plugin/pom.xml @@ -0,0 +1,64 @@ + + 4.0.0 + + org.eclipse.tycho + tycho + 4.0.11-SNAPSHOT + + tycho-cleancode-plugin + Tycho Eclipse Plugin + maven-plugin + + ${minimal-maven-version} + + Maven Plugins for performing automatic code clean options + + + org.apache.maven + maven-core + + + org.apache.maven + maven-plugin-api + + + org.apache.maven.plugin-tools + maven-plugin-annotations + + + org.eclipse.tycho + tycho-eclipse-plugin + ${project.version} + + + org.eclipse.jdt + org.eclipse.jdt.ui + 3.33.200 + + + org.eclipse.jdt + org.eclipse.jdt.core.manipulation + 1.21.300 + + + + + + + org.codehaus.plexus + plexus-component-metadata + + + org.apache.maven.plugins + maven-plugin-plugin + + + tycho-cleancode + + + + + \ No newline at end of file diff --git a/tycho-cleancode-plugin/src/main/java/org/eclipse/tycho/cleancode/CleanUp.java b/tycho-cleancode-plugin/src/main/java/org/eclipse/tycho/cleancode/CleanUp.java new file mode 100644 index 0000000000..6c85f26204 --- /dev/null +++ b/tycho-cleancode-plugin/src/main/java/org/eclipse/tycho/cleancode/CleanUp.java @@ -0,0 +1,128 @@ +/******************************************************************************* + * Copyright (c) 2025 Christoph Läubrich and others. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Christoph Läubrich - initial API and implementation + *******************************************************************************/ +package org.eclipse.tycho.cleancode; + +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.ProjectScope; +import org.eclipse.jdt.core.ICompilationUnit; +import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.core.IPackageFragment; +import org.eclipse.jdt.core.IPackageFragmentRoot; +import org.eclipse.jdt.core.JavaCore; +import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.jdt.internal.corext.fix.CleanUpPreferenceUtil; +import org.eclipse.jdt.internal.corext.fix.CleanUpRefactoring; +import org.eclipse.jdt.internal.ui.JavaPlugin; +import org.eclipse.jdt.internal.ui.fix.MapCleanUpOptions; +import org.eclipse.jdt.ui.cleanup.CleanUpOptions; +import org.eclipse.jdt.ui.cleanup.ICleanUp; +import org.eclipse.ltk.core.refactoring.Change; +import org.eclipse.ltk.core.refactoring.PerformChangeOperation; +import org.eclipse.ltk.core.refactoring.RefactoringStatus; +import org.eclipse.tycho.eclipsebuild.AbstractEclipseBuild; + +public class CleanUp extends AbstractEclipseBuild { + + private Map customProfile; + + CleanUp(Path projectDir, boolean debug, Map customProfile) { + super(projectDir, debug); + this.customProfile = customProfile; + } + + @Override + protected CleanupResult createResult(IProject project) throws Exception { + CleanupResult result = new CleanupResult(); + CleanUpOptions options = getOptions(project); + ICleanUp[] cleanups = getCleanups(result, options); + if (cleanups.length > 0) { + List units = getCompilationUnits(project); + final CleanUpRefactoring refactoring = new CleanUpRefactoring(project.getName()); + for (ICompilationUnit cu : units) { + refactoring.addCompilationUnit(cu); + } + refactoring.setUseOptionsFromProfile(false); + for (ICleanUp cleanUp : cleanups) { + refactoring.addCleanUp(cleanUp); + } + final RefactoringStatus status = refactoring.checkAllConditions(this); + if (status.isOK()) { + Change change = refactoring.createChange(this); + change.initializeValidationData(this); + PerformChangeOperation performChangeOperation = new PerformChangeOperation(change); + performChangeOperation.run(this); + } else if (status.hasError()) { + throw new RuntimeException("Refactoring failed: " + status); + } + } + return result; + } + + private List getCompilationUnits(IProject project) throws JavaModelException { + IJavaProject javaProject = JavaCore.create(project); + List units = new ArrayList(); + IPackageFragmentRoot[] packages = javaProject.getPackageFragmentRoots(); + for (IPackageFragmentRoot root : packages) { + if (root.getKind() == IPackageFragmentRoot.K_SOURCE) { + for (IJavaElement javaElement : root.getChildren()) { + if (javaElement.getElementType() == IJavaElement.PACKAGE_FRAGMENT) { + IPackageFragment pf = (IPackageFragment) javaElement; + ICompilationUnit[] compilationUnits = pf.getCompilationUnits(); + for (ICompilationUnit compilationUnit : compilationUnits) { + units.add(compilationUnit); + } + } + } + } + } + return units; + } + + private ICleanUp[] getCleanups(CleanupResult result, CleanUpOptions options) { + ICleanUp[] cleanUps = JavaPlugin.getDefault().getCleanUpRegistry().createCleanUps(); + for (ICleanUp cleanUp : cleanUps) { + try { + cleanUp.setOptions(options); + String[] descriptions = cleanUp.getStepDescriptions(); + if (descriptions != null) { + for (String description : descriptions) { + result.addCleanup(description); + } + } + } catch (Exception e) { + debug("Ignore cleanup '" + cleanUp + "' because of initialization error.", e); + } + } + return cleanUps; + } + + private CleanUpOptions getOptions(IProject project) { + Map options; + if (customProfile == null || customProfile.isEmpty()) { + options = CleanUpPreferenceUtil.loadOptions(new ProjectScope(project)); + } else { + options = customProfile; + } + debug("Cleanup Profile: " + options.entrySet().stream().map(e -> e.getKey() + " = " + e.getValue()) + .collect(Collectors.joining(System.lineSeparator()))); + return new MapCleanUpOptions(options); + } + +} diff --git a/tycho-cleancode-plugin/src/main/java/org/eclipse/tycho/cleancode/CleanUpMojo.java b/tycho-cleancode-plugin/src/main/java/org/eclipse/tycho/cleancode/CleanUpMojo.java new file mode 100644 index 0000000000..c76a103bed --- /dev/null +++ b/tycho-cleancode-plugin/src/main/java/org/eclipse/tycho/cleancode/CleanUpMojo.java @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright (c) 2023 Christoph Läubrich and others. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Christoph Läubrich - initial API and implementation + *******************************************************************************/ +package org.eclipse.tycho.cleancode; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugins.annotations.LifecyclePhase; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.Parameter; +import org.apache.maven.plugins.annotations.ResolutionScope; +import org.eclipse.tycho.eclipsebuild.AbstractEclipseBuildMojo; +import org.eclipse.tycho.model.project.EclipseProject; + +/** + * This mojo allows to perform eclipse cleanup action + */ +@Mojo(name = "cleanup", defaultPhase = LifecyclePhase.PROCESS_SOURCES, threadSafe = true, requiresDependencyCollection = ResolutionScope.COMPILE_PLUS_RUNTIME) +public class CleanUpMojo extends AbstractEclipseBuildMojo { + + @Parameter(defaultValue = "${project.build.directory}/cleanups.md", property = "tycho.cleanup.report") + private File reportFileName; + + /** + * Defines key value pairs of a cleanup profile, if not defined will use the + * project defaults + */ + @Parameter + private Map cleanUpProfile; + + @Override + protected String[] getRequireBundles() { + return new String[] { "org.eclipse.jdt.ui" }; + } + + @Override + protected String getName() { + return "Perform Cleanup"; + } + + @Override + protected CleanUp createExecutable() { + return new CleanUp(project.getBasedir().toPath(), debug, cleanUpProfile); + } + + @Override + protected void handleResult(CleanupResult result) + throws MojoFailureException { + List results = new ArrayList<>(); + results.add("The following cleanups where applied:"); + result.cleanups().forEach(cleanup -> { + results.add("- " + cleanup); + }); + try { + Files.writeString(reportFileName.toPath(), + results.stream().collect(Collectors.joining(System.lineSeparator()))); + } catch (IOException e) { + throw new MojoFailureException(e); + } + } + + @Override + protected boolean isValid(EclipseProject eclipseProject) { + // Cleanups can only be applied to java projects + return eclipseProject.hasNature("org.eclipse.jdt.core.javanature"); + } + +} diff --git a/tycho-cleancode-plugin/src/main/java/org/eclipse/tycho/cleancode/CleanupResult.java b/tycho-cleancode-plugin/src/main/java/org/eclipse/tycho/cleancode/CleanupResult.java new file mode 100644 index 0000000000..11b2d45623 --- /dev/null +++ b/tycho-cleancode-plugin/src/main/java/org/eclipse/tycho/cleancode/CleanupResult.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2025 Christoph Läubrich and others. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Christoph Läubrich - initial API and implementation + *******************************************************************************/ +package org.eclipse.tycho.cleancode; + +import java.util.Set; +import java.util.TreeSet; +import java.util.stream.Stream; + +import org.eclipse.tycho.eclipsebuild.EclipseBuildResult; + +public class CleanupResult extends EclipseBuildResult { + + private Set cleanups = new TreeSet(); + + public void addCleanup(String cleanup) { + cleanups.add(cleanup); + } + + public Stream cleanups() { + return this.cleanups.stream(); + } + +} diff --git a/tycho-cleancode-plugin/src/main/java/org/eclipse/tycho/cleancode/QuickFix.java b/tycho-cleancode-plugin/src/main/java/org/eclipse/tycho/cleancode/QuickFix.java new file mode 100644 index 0000000000..a76f23c22a --- /dev/null +++ b/tycho-cleancode-plugin/src/main/java/org/eclipse/tycho/cleancode/QuickFix.java @@ -0,0 +1,132 @@ +/******************************************************************************* + * Copyright (c) 2025 Christoph Läubrich and others. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Christoph Läubrich - initial API and implementation + *******************************************************************************/ +package org.eclipse.tycho.cleancode; + +import java.nio.file.Path; +import java.util.Arrays; +import java.util.Comparator; +import java.util.concurrent.atomic.AtomicReference; + +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.tycho.eclipsebuild.AbstractEclipseBuild; +import org.eclipse.ui.IMarkerResolution; +import org.eclipse.ui.IMarkerResolution2; +import org.eclipse.ui.IMarkerResolutionRelevance; +import org.eclipse.ui.ide.IDE; + +/** + * Applies the QuickFix with the highest relevance to a warning, because + * QuickFixes are not really optimized to run in a CI build we need to be very + * forgiving here and handle errors gracefully. + */ +public class QuickFix extends AbstractEclipseBuild { + + QuickFix(Path projectDir, boolean debug) { + super(projectDir, debug); + } + + @Override + protected QuickFixResult createResult(IProject project) throws Exception { + QuickFixResult result = new QuickFixResult(); + IMarker[] markers = project.findMarkers(IMarker.PROBLEM, true, IResource.DEPTH_INFINITE); + result.setNumberOfMarker(markers.length); + for (IMarker marker : markers) { + debug("Marker: " + marker); + try { + IMarkerResolution[] resolutions = IDE.getMarkerHelpRegistry().getResolutions(marker); + debug("Marker has " + resolutions.length + " resolutions"); + IMarkerResolution resolution = Arrays.stream(resolutions) + .max(Comparator.comparingInt(r -> getRelevance(r))).orElse(null); + if (resolution != null) { + debug("Apply best resolution to marker: " + getInfo(resolution)); + // must use an own thread to make sure it is not called as a job + AtomicReference error = new AtomicReference(); + Thread thread = new Thread(new Runnable() { + + @Override + public void run() { + try { + resolution.run(marker); + } catch (Throwable t) { + error.set(t); + } + } + }); + thread.start(); + thread.join(); + Throwable t = error.get(); + if (t == null) { + result.addFix(buildFixMessage(marker)); + } else { + debug("Marker could not be applied!", t); + } + } + } catch (Throwable t) { + debug("Marker resolutions could not be computed!", t); + } + } + return result; + } + + private String buildFixMessage(IMarker marker) { + StringBuilder sb = new StringBuilder(marker.getAttribute(IMarker.MESSAGE, "Unknown Problem")); + IResource resource = marker.getResource(); + if (resource != null) { + sb.append(" in "); + sb.append(resource.getFullPath()); + int line = marker.getAttribute(IMarker.LINE_NUMBER, -1); + if (line > 0) { + sb.append(" at line "); + sb.append(line); + } + } + return sb.toString(); + } + + private String getInfo(IMarkerResolution resolution) { + if (resolution instanceof IMarkerResolution2 res2) { + return resolution.getClass().getName() + ": " + getLabel(resolution) + " // " + getDescription(res2); + } else { + return resolution.getClass().getName() + ": " + getLabel(resolution); + } + } + + private int getRelevance(IMarkerResolution resolution) { + try { + if (resolution instanceof IMarkerResolutionRelevance relevance) { + return relevance.getRelevanceForResolution(); + } + } catch (RuntimeException e) { + } + return -1; + } + + private String getDescription(IMarkerResolution2 markerResolution) { + try { + return markerResolution.getDescription(); + } catch (RuntimeException e) { + return null; + } + } + + private String getLabel(IMarkerResolution resolution) { + try { + return resolution.getLabel(); + } catch (RuntimeException e) { + return resolution.getClass().getName(); + } + } + +} diff --git a/tycho-cleancode-plugin/src/main/java/org/eclipse/tycho/cleancode/QuickFixMojo.java b/tycho-cleancode-plugin/src/main/java/org/eclipse/tycho/cleancode/QuickFixMojo.java new file mode 100644 index 0000000000..5b4f5b96fc --- /dev/null +++ b/tycho-cleancode-plugin/src/main/java/org/eclipse/tycho/cleancode/QuickFixMojo.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * Copyright (c) 2025 Christoph Läubrich and others. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Christoph Läubrich - initial API and implementation + *******************************************************************************/ +package org.eclipse.tycho.cleancode; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugins.annotations.LifecyclePhase; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.Parameter; +import org.apache.maven.plugins.annotations.ResolutionScope; +import org.eclipse.tycho.eclipsebuild.AbstractEclipseBuildMojo; + +@Mojo(name = "quickfix", defaultPhase = LifecyclePhase.PROCESS_SOURCES, threadSafe = true, requiresDependencyCollection = ResolutionScope.COMPILE_PLUS_RUNTIME) +public class QuickFixMojo extends AbstractEclipseBuildMojo { + + @Parameter(defaultValue = "${project.build.directory}/quickfix.md", property = "tycho.quickfix.report") + private File reportFileName; + + @Override + protected void handleResult(QuickFixResult result) throws MojoFailureException { + List results = new ArrayList<>(); + if (result.getMarkers() == 0) { + results.add("Project is clean!"); + } else { + List fixes = result.fixes().toList(); + if (fixes.isEmpty()) { + results.add("Nothing has been resolved in this project."); + } else { + results.add("The following " + (fixes.size() > 0 ? "warnings" : "warning") + " has been resolved:"); + fixes.forEach(fix -> { + results.add("- " + fix); + }); + } + } + try { + Files.writeString(reportFileName.toPath(), + results.stream().collect(Collectors.joining(System.lineSeparator()))); + } catch (IOException e) { + throw new MojoFailureException(e); + } + } + + @Override + protected String[] getRequireBundles() { + return new String[] { "org.eclipse.ui.ide", "org.eclipse.jdt.ui" }; + } + + @Override + protected QuickFix createExecutable() { + return new QuickFix(project.getBasedir().toPath(), debug); + } + + @Override + protected String getName() { + return "Quick Fix"; + } + +} diff --git a/tycho-cleancode-plugin/src/main/java/org/eclipse/tycho/cleancode/QuickFixResult.java b/tycho-cleancode-plugin/src/main/java/org/eclipse/tycho/cleancode/QuickFixResult.java new file mode 100644 index 0000000000..8bacea8902 --- /dev/null +++ b/tycho-cleancode-plugin/src/main/java/org/eclipse/tycho/cleancode/QuickFixResult.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2025 Christoph Läubrich and others. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Christoph Läubrich - initial API and implementation + *******************************************************************************/ +package org.eclipse.tycho.cleancode; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Stream; + +import org.eclipse.tycho.eclipsebuild.EclipseBuildResult; + +public class QuickFixResult extends EclipseBuildResult { + + private List fixed = new ArrayList<>(); + private int markers; + + public Stream fixes() { + return fixed.stream(); + } + + public void addFix(String fix) { + fixed.add(fix); + } + + public void setNumberOfMarker(int markers) { + this.markers = markers; + } + + public int getMarkers() { + return markers; + } + +} diff --git a/tycho-eclipse-plugin/src/main/java/org/eclipse/tycho/eclipsebuild/AbstractEclipseBuild.java b/tycho-eclipse-plugin/src/main/java/org/eclipse/tycho/eclipsebuild/AbstractEclipseBuild.java index 199607b938..46c449db14 100644 --- a/tycho-eclipse-plugin/src/main/java/org/eclipse/tycho/eclipsebuild/AbstractEclipseBuild.java +++ b/tycho-eclipse-plugin/src/main/java/org/eclipse/tycho/eclipsebuild/AbstractEclipseBuild.java @@ -1,7 +1,9 @@ package org.eclipse.tycho.eclipsebuild; import java.io.IOException; +import java.io.PrintWriter; import java.io.Serializable; +import java.io.StringWriter; import java.nio.file.Path; import java.util.concurrent.Callable; @@ -83,6 +85,14 @@ protected void debug(String string) { } } + protected void debug(String string, Throwable t) { + if (debug) { + StringWriter writer = new StringWriter(); + t.printStackTrace(new PrintWriter(writer)); + debug(string + System.lineSeparator() + writer); + } + } + static String pathAsString(Path path) { if (path != null) { return path.toAbsolutePath().toString(); diff --git a/tycho-eclipse-plugin/src/main/java/org/eclipse/tycho/eclipsebuild/AbstractEclipseBuildMojo.java b/tycho-eclipse-plugin/src/main/java/org/eclipse/tycho/eclipsebuild/AbstractEclipseBuildMojo.java index c9e4717f3a..6fc02b9209 100644 --- a/tycho-eclipse-plugin/src/main/java/org/eclipse/tycho/eclipsebuild/AbstractEclipseBuildMojo.java +++ b/tycho-eclipse-plugin/src/main/java/org/eclipse/tycho/eclipsebuild/AbstractEclipseBuildMojo.java @@ -96,6 +96,9 @@ public final void execute() throws MojoExecutionException, MojoFailureException return; } EclipseProject eclipseProject = eclipseProjectValue.get(); + if (!isValid(eclipseProject)) { + return; + } Collection projectDependencies; try { projectDependencies = projectManager.getProjectDependencies(project); @@ -145,6 +148,10 @@ public final void execute() throws MojoExecutionException, MojoFailureException } } + protected boolean isValid(EclipseProject eclipseProject) { + return true; + } + protected abstract void handleResult(Result result) throws MojoFailureException; protected abstract AbstractEclipseBuild createExecutable();