Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[tycho-4.0.x] Add a javadoc dependency injector #3034

Merged
merged 1 commit into from
Nov 12, 2023
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
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,41 @@

public final class MavenDependencyInjector {

/**
* Injects a set of additional project dependencies into an existing maven project.
*
* @param project
* @param dependencyProjects
*/
public static void injectMavenProjectDependencies(MavenProject project, Iterable<MavenProject> dependencyProjects) {
Model model = project.getModel();
Set<String> existingDependencies = model.getDependencies().stream().map(MavenDependencyInjector::getProjectKey)
.collect(Collectors.toCollection(HashSet::new));
for (MavenProject dependencyProject : dependencyProjects) {
if (dependencyProject == project) {
continue;
}
Dependency dependency = new Dependency();
dependency.setArtifactId(dependencyProject.getArtifactId());
dependency.setGroupId(dependencyProject.getGroupId());
dependency.setVersion(dependencyProject.getVersion());
String packaging = dependencyProject.getPackaging();
dependency.setType(packaging);
dependency.setScope(Artifact.SCOPE_COMPILE);
dependency.setOptional(false);
if (existingDependencies.add(getProjectKey(dependency))) {
model.addDependency(dependency);
}
}
}

private static String getProjectKey(Dependency dependency) {

return dependency.getGroupId() + ":" + dependency.getArtifactId() + ":"
+ Objects.requireNonNullElse(dependency.getType(), "jar") + ":" + dependency.getVersion() + ":"
+ Objects.requireNonNullElse(dependency.getClassifier(), "");
}

/**
* Injects the dependencies of a project (as determined by the p2 dependency resolver) back into
* the Maven model.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
Expand All @@ -41,11 +40,8 @@

import org.apache.maven.AbstractMavenLifecycleParticipant;
import org.apache.maven.MavenExecutionException;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.execution.MavenExecutionRequest;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.model.Dependency;
import org.apache.maven.model.Model;
import org.apache.maven.model.Plugin;
import org.apache.maven.model.io.ModelWriter;
import org.apache.maven.project.MavenProject;
Expand Down Expand Up @@ -158,28 +154,13 @@ public void afterProjectsRead(MavenSession session) throws MavenExecutionExcepti
//do not inject additional dependencies for non Tycho managed projects!
continue;
}
Model model = project.getModel();
Set<String> existingDependencies = model.getDependencies().stream()
.map(TychoMavenLifecycleParticipant::getKey)
.collect(Collectors.toCollection(HashSet::new));
Collection<MavenProject> dependencyProjects = closure.getDependencyProjects(project);
for (MavenProject dependencyProject : dependencyProjects) {
Dependency dependency = new Dependency();
dependency.setArtifactId(dependencyProject.getArtifactId());
dependency.setGroupId(dependencyProject.getGroupId());
dependency.setVersion(dependencyProject.getVersion());
String packaging = dependencyProject.getPackaging();
dependency.setType(packaging);
dependency.setScope(Artifact.SCOPE_COMPILE);
dependency.setOptional(false);
if (existingDependencies.add(getKey(dependency))) {
model.addDependency(dependency);
}
}
MavenDependencyInjector.injectMavenProjectDependencies(project, dependencyProjects);
if (DUMP_DATA) {
try {
Set<MavenProject> visited = new HashSet<>();
modelWriter.write(new File(project.getBasedir(), "pom-model.xml"), Map.of(), model);
modelWriter.write(new File(project.getBasedir(), "pom-model.xml"), Map.of(),
project.getModel());
try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(new File(project.getBasedir(), "requirements.txt"))))) {
writer.write(project.getId() + ":\r\n");
Expand Down Expand Up @@ -223,13 +204,6 @@ private void dumpProjectRequirements(MavenProject project, BufferedWriter writer
}
}

private static String getKey(Dependency dependency) {

return dependency.getGroupId() + ":" + dependency.getArtifactId() + ":"
+ Objects.requireNonNullElse(dependency.getType(), "jar") + ":" + dependency.getVersion() + ":"
+ Objects.requireNonNullElse(dependency.getClassifier(), "");
}

@Override
public void afterSessionEnd(MavenSession session) throws MavenExecutionException {
buildListeners.notifyBuildEnd(session);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*******************************************************************************
* 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.extras.docbundle;

import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
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;

/**
* This mojo is only there
*/
@Mojo(name = "configure-document-bundle-plugin", defaultPhase = LifecyclePhase.INITIALIZE, requiresDependencyResolution = ResolutionScope.NONE, threadSafe = true)
public class ConfigureMojo extends AbstractMojo {

/**
* name of the parameter to inject javadoc source dependencies
*/
public static final String PARAM_INJECT_JAVADOC_DEPENDENCIES = "injectJavadocDependencies";
@Parameter(name = PARAM_INJECT_JAVADOC_DEPENDENCIES)
private boolean dummyBoolean;

@Override
public void execute() throws MojoExecutionException, MojoFailureException {
throw new MojoFailureException("This mojo is not intended to be ever called");
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/*******************************************************************************
* 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.extras.docbundle;

import java.io.File;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

import org.apache.maven.execution.MavenSession;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.component.annotations.Component;
import org.codehaus.plexus.component.annotations.Requirement;
import org.eclipse.tycho.build.BuildListener;
import org.eclipse.tycho.core.maven.MavenDependencyInjector;
import org.eclipse.tycho.helper.PluginConfigurationHelper;
import org.eclipse.tycho.helper.PluginConfigurationHelper.Configuration;
import org.eclipse.tycho.helper.ProjectHelper;

@Component(role = BuildListener.class, hint = "javadoc")
public class JavadocBuildListener implements BuildListener {

private static final String JAVADOC_GOAL = "javadoc";
private static final String ARTIFACT_ID = "maven-javadoc-plugin";
private static final String GROUP_ID = "org.apache.maven.plugins";

@Requirement
private ProjectHelper projectHelper;

@Requirement
private PluginConfigurationHelper configurationHelper;

@Override
public void buildStarted(MavenSession session) {
List<MavenProject> projects = session.getProjects();
for (MavenProject project : projects) {
if (isJavadocProject(project, session)) {
Configuration configuration = configurationHelper.getConfiguration(GROUP_ID, ARTIFACT_ID, JAVADOC_GOAL,
project, session);
List<MavenProject> additionalProjects = configuration.getString("sourcepath").stream()
.flatMap(sourcepath -> {
return Arrays.stream(sourcepath.split(";|:"));
}).map(s -> s.strip()).map(s -> new File(project.getBasedir(), s).toPath().normalize())
.map(sourcePath -> getProject(sourcePath, projects)).filter(Objects::nonNull).distinct()
.toList();
MavenDependencyInjector.injectMavenProjectDependencies(project, additionalProjects);
}
}

}

private MavenProject getProject(Path sourcePath, List<MavenProject> projects) {
MavenProject match = null;
int matchNameCount = -1;
for (MavenProject mavenProject : projects) {
Path basePath = mavenProject.getBasedir().toPath();
if (sourcePath.startsWith(basePath)) {
int nameCount = basePath.getNameCount();
if (match == null || nameCount > matchNameCount) {
match = mavenProject;
matchNameCount = nameCount;
}
}
}
return match;
}

private boolean isJavadocProject(MavenProject project, MavenSession mavenSession) {
if (projectHelper.hasPluginExecution(GROUP_ID, ARTIFACT_ID, JAVADOC_GOAL, project, mavenSession)) {
Configuration configuration = configurationHelper.getConfiguration(ConfigureMojo.class, project,
mavenSession);
return configuration.getBoolean(ConfigureMojo.PARAM_INJECT_JAVADOC_DEPENDENCIES).orElse(false);
}
return false;
}

@Override
public void buildEnded(MavenSession session) {
// nothing to do...
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,14 @@
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugin.LegacySupport;
import org.apache.maven.plugin.Mojo;
import org.apache.maven.plugin.MojoExecution;
import org.apache.maven.plugin.descriptor.MojoDescriptor;
import org.apache.maven.plugin.descriptor.PluginDescriptor;
import org.apache.maven.plugin.descriptor.PluginDescriptorBuilder;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.component.annotations.Component;
import org.codehaus.plexus.component.annotations.Requirement;
import org.codehaus.plexus.util.InterpolationFilterReader;
Expand Down Expand Up @@ -58,7 +60,26 @@ public Configuration getConfiguration(Xpp3Dom configuration) {
return new Configuration(configuration);
}

public Configuration getConfiguration(String pluginGroupId, String pluginArtifactId, String goal,
MavenProject project, MavenSession mavenSession) {
return new Configuration(
projectHelper.getPluginConfiguration(pluginGroupId, pluginArtifactId, goal, project, mavenSession));
}

public <M extends Mojo> Configuration getConfiguration(Class<M> mojo) {
MavenSession currentSession = legacySupport.getSession();
if (currentSession == null) {
return getConfiguration((Xpp3Dom) null);
}
MavenProject currentProject = currentSession.getCurrentProject();
if (currentProject == null) {
return getConfiguration((Xpp3Dom) null);
}
return getConfiguration(mojo, currentProject, currentSession);
}

public <M extends Mojo> Configuration getConfiguration(Class<M> mojo, MavenProject project,
MavenSession mavenSession) {
URL resource = mojo.getResource("/META-INF/maven/plugin.xml");
if (resource == null) {
throw new IllegalStateException("can't find plugin descriptor of mojo " + mojo.getName());
Expand All @@ -77,7 +98,7 @@ public <M extends Mojo> Configuration getConfiguration(Class<M> mojo) {
for (MojoDescriptor mojoDescriptor : pluginDescriptor.getMojos()) {
if (mojo.getName().equals(mojoDescriptor.getImplementation())) {
Xpp3Dom configuration = projectHelper.getPluginConfiguration(pluginDescriptor.getGroupId(),
pluginDescriptor.getArtifactId(), mojoDescriptor.getGoal());
pluginDescriptor.getArtifactId(), mojoDescriptor.getGoal(), project, mavenSession);
return getConfiguration(configuration);

}
Expand Down Expand Up @@ -132,6 +153,11 @@ public <E extends Enum<E>> Optional<E> getEnum(String name, Class<E> type) {
});
}

@Override
public String toString() {
return configuration == null ? "-empty configuration-" : String.valueOf(configuration);
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public List<Plugin> getPlugins(MavenProject project, MavenSession mavenSession)
* @param goal
* @param project
* @param mavenSession
* @return <code>true</code> if an execution was found or <code>false</code> otherwhise.
* @return <code>true</code> if an execution was found or <code>false</code> otherwise.
*/
public boolean hasPluginExecution(String pluginGroupId, String pluginArtifactId, String goal, MavenProject project,
MavenSession mavenSession) {
Expand Down Expand Up @@ -127,11 +127,14 @@ public Xpp3Dom getPluginConfiguration(String pluginGroupId, String pluginArtifac
if (goal == null) {
return getDom(plugin.getConfiguration());
}
//first check for goal specific configuration
for (PluginExecution execution : plugin.getExecutions()) {
if (execution.getGoals().contains(goal)) {
return getDom(execution.getConfiguration());
}
}
//get plugin config
return getDom(plugin.getConfiguration());
}
}
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
import org.eclipse.tycho.versions.pom.PomFile;
import org.osgi.framework.Version;

@Component(role = BuildListener.class)
@Component(role = BuildListener.class, hint = "version-bump")
public class VersionBumpBuildListener implements BuildListener {

@Requirement
Expand Down Expand Up @@ -79,10 +79,10 @@ public void buildEnded(MavenSession session) {
String newVersion = suggestedVersion.map(String::valueOf)
.orElseGet(() -> Versions.incrementVersion(currentVersion,
VersionBumpMojo.getIncrement(session, project, projectHelper)));
boolean isSnapshot = currentVersion.endsWith(TychoConstants.SUFFIX_SNAPSHOT);
if (isSnapshot) {
newVersion += TychoConstants.SUFFIX_SNAPSHOT;
}
boolean isSnapshot = currentVersion.endsWith(TychoConstants.SUFFIX_SNAPSHOT);
if (isSnapshot) {
newVersion += TychoConstants.SUFFIX_SNAPSHOT;
}
logger.info(project.getId() + " requires a version bump from " + currentVersion + " => "
+ newVersion);
engine.setProjects(metadataReader.getProjects());
Expand Down