Skip to content

Commit fa7ca73

Browse files
committed
Extract common code to AbstractEclipseBuildMojo so it can be reused
Currently EclipseBuildMojo performs the boilerplate to perform an eclipse like build inside tycho build, but this can be useful for other scenarios as well. This now extracts the common code into an AbstractEclipseBuildMojo so it can be reused.
1 parent d0109ca commit fa7ca73

File tree

4 files changed

+259
-209
lines changed

4 files changed

+259
-209
lines changed
Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2025 Christoph Läubrich and others.
3+
* This program and the accompanying materials
4+
* are made available under the terms of the Eclipse Public License 2.0
5+
* which accompanies this distribution, and is available at
6+
* https://www.eclipse.org/legal/epl-2.0/
7+
*
8+
* SPDX-License-Identifier: EPL-2.0
9+
*
10+
* Contributors:
11+
* Christoph Läubrich - initial API and implementation
12+
*******************************************************************************/
13+
package org.eclipse.tycho.eclipsebuild;
14+
15+
import java.io.Serializable;
16+
import java.lang.reflect.InvocationTargetException;
17+
import java.nio.file.Path;
18+
import java.util.Collection;
19+
import java.util.HashSet;
20+
import java.util.List;
21+
import java.util.Set;
22+
import java.util.concurrent.Callable;
23+
import java.util.function.Consumer;
24+
25+
import org.apache.maven.model.Repository;
26+
import org.apache.maven.plugin.AbstractMojo;
27+
import org.apache.maven.plugin.MojoExecutionException;
28+
import org.apache.maven.plugin.MojoFailureException;
29+
import org.apache.maven.plugin.logging.Log;
30+
import org.apache.maven.plugins.annotations.Component;
31+
import org.apache.maven.plugins.annotations.Parameter;
32+
import org.apache.maven.project.MavenProject;
33+
import org.eclipse.core.resources.IMarker;
34+
import org.eclipse.core.runtime.CoreException;
35+
import org.eclipse.tycho.TargetPlatform;
36+
import org.eclipse.tycho.core.TychoProjectManager;
37+
import org.eclipse.tycho.osgi.framework.Bundles;
38+
import org.eclipse.tycho.osgi.framework.EclipseApplication;
39+
import org.eclipse.tycho.osgi.framework.EclipseApplicationManager;
40+
import org.eclipse.tycho.osgi.framework.EclipseFramework;
41+
import org.eclipse.tycho.osgi.framework.EclipseWorkspaceManager;
42+
import org.eclipse.tycho.osgi.framework.Features;
43+
import org.osgi.framework.BundleException;
44+
45+
/**
46+
* An abstract mojo baseclass that can be used to perform actions on an eclipse
47+
* project that requires the build infrastructure.
48+
*
49+
* @param <Result> the rsult type
50+
*/
51+
public abstract class AbstractEclipseBuildMojo<Result extends EclipseBuildResult> extends AbstractMojo {
52+
53+
static final String PARAMETER_LOCAL = "local";
54+
55+
@Parameter()
56+
private Repository eclipseRepository;
57+
58+
@Parameter(defaultValue = "false", property = "tycho.eclipsebuild.skip")
59+
private boolean skip;
60+
61+
@Parameter(defaultValue = "false", property = "tycho.eclipsebuild.debug")
62+
protected boolean debug;
63+
64+
/**
65+
* Controls if the local target platform of the project should be used to
66+
* resolve the eclipse application
67+
*/
68+
@Parameter(defaultValue = "false", property = "tycho.eclipsebuild.local", name = PARAMETER_LOCAL)
69+
private boolean local;
70+
71+
@Parameter(defaultValue = "true", property = "tycho.eclipsebuild.printMarker")
72+
private boolean printMarker;
73+
74+
@Parameter
75+
private List<String> bundles;
76+
77+
@Parameter
78+
private List<String> features;
79+
80+
@Parameter(property = "project", readonly = true)
81+
protected MavenProject project;
82+
83+
@Component
84+
private EclipseWorkspaceManager workspaceManager;
85+
86+
@Component
87+
private EclipseApplicationManager eclipseApplicationManager;
88+
89+
@Component
90+
private TychoProjectManager projectManager;
91+
92+
@Override
93+
public final void execute() throws MojoExecutionException, MojoFailureException {
94+
95+
Collection<Path> projectDependencies;
96+
try {
97+
projectDependencies = projectManager.getProjectDependencies(project);
98+
} catch (Exception e) {
99+
throw new MojoFailureException("Can't resolve project dependencies", e);
100+
}
101+
EclipseApplication application;
102+
Bundles bundles = new Bundles(getBundles());
103+
Features features = new Features(getFeatures());
104+
if (local) {
105+
TargetPlatform targetPlatform = projectManager.getTargetPlatform(project).orElseThrow(
106+
() -> new MojoFailureException("Can't get target platform for project " + project.getId()));
107+
application = eclipseApplicationManager.getApplication(targetPlatform, bundles, features, getName());
108+
} else {
109+
application = eclipseApplicationManager.getApplication(eclipseRepository, bundles, features, getName());
110+
}
111+
try (EclipseFramework framework = application.startFramework(workspaceManager
112+
.getWorkspace(EclipseApplicationManager.getRepository(eclipseRepository).getURL(), this), List.of())) {
113+
if (debug) {
114+
framework.printState();
115+
}
116+
if (framework.hasBundle(Bundles.BUNDLE_PDE_CORE)) {
117+
framework.execute(new SetTargetPlatform(projectDependencies, debug));
118+
} else {
119+
getLog().info("Skip set Target Platform because " + Bundles.BUNDLE_PDE_CORE
120+
+ " is not part of the framework...");
121+
}
122+
Result result = framework.execute(createExecutable());
123+
if (printMarker) {
124+
Log log = getLog();
125+
result.markers().filter(marker -> marker.getAttribute(IMarker.SEVERITY, -1) == IMarker.SEVERITY_INFO)
126+
.forEach(info -> printMarker(info, result, log::info));
127+
result.markers().filter(marker -> marker.getAttribute(IMarker.SEVERITY, -1) == IMarker.SEVERITY_WARNING)
128+
.forEach(warn -> printMarker(warn, result, log::warn));
129+
result.markers().filter(marker -> marker.getAttribute(IMarker.SEVERITY, -1) == IMarker.SEVERITY_ERROR)
130+
.forEach(error -> printMarker(error, result, log::error));
131+
}
132+
handleResult(result);
133+
} catch (BundleException e) {
134+
throw new MojoFailureException("Can't start framework!", e);
135+
} catch (InvocationTargetException e) {
136+
Throwable cause = e.getCause();
137+
if (cause.getClass().getName().equals(CoreException.class.getName())) {
138+
throw new MojoFailureException(cause.getMessage(), cause);
139+
}
140+
throw new MojoExecutionException(cause);
141+
}
142+
}
143+
144+
protected abstract void handleResult(Result result) throws MojoFailureException;
145+
146+
protected abstract <X extends Callable<R> & Serializable, R extends Serializable> R createExecutable();
147+
148+
protected Set<String> getFeatures() {
149+
Set<String> set = new HashSet<>();
150+
if (features != null) {
151+
set.addAll(features);
152+
}
153+
return set;
154+
}
155+
156+
protected Set<String> getBundles() {
157+
Set<String> set = new HashSet<>();
158+
set.add("org.eclipse.core.resources");
159+
set.add("org.eclipse.core.runtime");
160+
set.add("org.eclipse.core.jobs");
161+
if (bundles != null) {
162+
set.addAll(bundles);
163+
}
164+
return set;
165+
}
166+
167+
private static void printMarker(IMarker marker, EclipseBuildResult result, Consumer<CharSequence> consumer) {
168+
consumer.accept(asString(marker, result).toString().trim());
169+
}
170+
171+
protected static StringBuilder asString(IMarker marker, EclipseBuildResult result) {
172+
StringBuilder sb = new StringBuilder();
173+
String path = result.getMarkerPath(marker);
174+
if (path != null) {
175+
sb.append(path);
176+
int line = marker.getAttribute("lineNumber", -1);
177+
if (line > -1) {
178+
sb.append(":");
179+
sb.append(line);
180+
}
181+
sb.append(" ");
182+
}
183+
String message = marker.getAttribute("message", "");
184+
if (!message.isBlank()) {
185+
sb.append(message);
186+
sb.append(" ");
187+
}
188+
String sourceId = marker.getAttribute("sourceId", "");
189+
if (!sourceId.isBlank()) {
190+
sb.append(sourceId);
191+
sb.append(" ");
192+
}
193+
return sb;
194+
}
195+
196+
protected abstract String getName();
197+
198+
}

tycho-eclipse-plugin/src/main/java/org/eclipse/tycho/eclipsebuild/EclipseBuildInstallableUnitProvider.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ public class EclipseBuildInstallableUnitProvider implements InstallableUnitProvi
3838
@Override
3939
public Collection<IInstallableUnit> getInstallableUnits(MavenProject project, MavenSession session)
4040
throws CoreException {
41-
Configuration configuration = configurationHelper.getConfiguration(EclipseBuildMojo.class, project, session);
42-
Optional<Boolean> local = configuration.getBoolean(EclipseBuildMojo.PARAMETER_LOCAL);
41+
Configuration configuration = configurationHelper.getConfiguration(EclipseBuildProjectMojo.class, project, session);
42+
Optional<Boolean> local = configuration.getBoolean(EclipseBuildProjectMojo.PARAMETER_LOCAL);
4343
if (local.isPresent() && local.get()) {
4444
// for local target resolution the bundles become requirements...
4545
Optional<List<String>> list = configuration.getStringList("bundles");

0 commit comments

Comments
 (0)