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

Backport api tools jar #3015

Merged
merged 2 commits into from
Nov 7, 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 @@ -16,12 +16,18 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.StandardCopyOption;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Properties;
import java.util.concurrent.Callable;
Expand Down Expand Up @@ -63,6 +69,11 @@
import org.eclipse.pde.api.tools.internal.provisional.model.IApiBaseline;
import org.eclipse.pde.api.tools.internal.provisional.model.IApiComponent;
import org.eclipse.pde.api.tools.internal.provisional.problems.IApiProblem;
import org.eclipse.pde.core.build.IBuild;
import org.eclipse.pde.core.build.IBuildEntry;
import org.eclipse.pde.core.build.IBuildModel;
import org.eclipse.pde.core.plugin.IPluginModelBase;
import org.eclipse.pde.core.plugin.PluginRegistry;
import org.eclipse.pde.core.target.ITargetDefinition;
import org.eclipse.pde.core.target.ITargetLocation;
import org.eclipse.pde.core.target.ITargetPlatformService;
Expand All @@ -74,6 +85,9 @@
import org.osgi.framework.Bundle;
import org.osgi.framework.FrameworkUtil;

/**
* Performs the API Analysis inside the embedded OSGi Frameworks
*/
public class ApiAnalysis implements Serializable, Callable<ApiAnalysisResult> {

private Collection<String> baselineBundles;
Expand All @@ -86,7 +100,7 @@ public class ApiAnalysis implements Serializable, Callable<ApiAnalysisResult> {
private String binaryArtifact;
private String outputDir;

public ApiAnalysis(Collection<Path> baselineBundles, Collection<Path> dependencyBundles, String baselineName,
ApiAnalysis(Collection<Path> baselineBundles, Collection<Path> dependencyBundles, String baselineName,
Path apiFilterFile, Path apiPreferences, Path projectDir, boolean debug, Path binaryArtifact,
Path outputDir) {
this.targetBundles = dependencyBundles.stream().map(ApiAnalysis::pathAsString).toList();
Expand Down Expand Up @@ -222,32 +236,126 @@ private BundleComponent importProject() throws CoreException, IOException {
}

private void createOutputFolder(IProject project, IPath projectPath) throws IOException, CoreException {
Map<String, String> outputJars = computeOutputJars(project);
IJavaProject javaProject = JavaCore.create(project);
if (javaProject != null) {
IPath fullPath = project.getFolder(outputDir).getFullPath();
IFolder outputFolder = project.getFolder(outputDir);
// FIXME see bug https://github.com/eclipse-pde/eclipse.pde/issues/801
// it can happen that project output location != maven compiled classes, usually
// eclipse uses output = bin/ while maven uses target/classes if not
// specifically configured to be even
javaProject.setOutputLocation(fullPath, null);
makeOutputFolder(javaProject.getOutputLocation(), projectPath);
IPath mainOutputLocation = javaProject.getOutputLocation();
IPath mainRealPath = getRealPath(mainOutputLocation, outputJars, outputFolder);
makeOutputFolder(mainOutputLocation, mainRealPath);
IClasspathEntry[] classpath = javaProject.getRawClasspath();
for (IClasspathEntry entry : classpath) {
// FIXME see bug https://github.com/eclipse-pde/eclipse.pde/issues/791
makeOutputFolder(entry.getOutputLocation(), projectPath);
IPath entryOutputLocation = entry.getOutputLocation();
if (entryOutputLocation != null) {
IPath realEntryPath = getRealPath(entryOutputLocation, outputJars, outputFolder);
makeOutputFolder(entryOutputLocation, realEntryPath);
}
}
}
}

private Map<String, String> computeOutputJars(IProject project) throws CoreException {
Map<String, String> outputJars = new HashMap<String, String>();
IPluginModelBase base = PluginRegistry.findModel(project);
if (base != null) {
IBuildModel model = PluginRegistry.createBuildModel(base);
if (model != null) {
IBuild ibuild = model.getBuild();
IBuildEntry[] entries = ibuild.getBuildEntries();
for (IBuildEntry entry : entries) {
String name = entry.getName();
if (name.startsWith(IBuildEntry.OUTPUT_PREFIX)) {
String key = name.substring(IBuildEntry.OUTPUT_PREFIX.length());
for (String token : entry.getTokens()) {
outputJars.put(token, key);
}
}
}
}
}
return outputJars;
}

private IPath getRealPath(IPath eclipseOutputLocation, Map<String, String> outputJars, IFolder mavenOutputFolder) {
if (eclipseOutputLocation == null) {
return null;
}
IFolder projectFolder = getProjectFolder(eclipseOutputLocation);
for (Entry<String, String> entry : outputJars.entrySet()) {
IFolder jarFolder = projectFolder.getProject().getFolder(entry.getKey());
if (jarFolder.equals(projectFolder)) {
String jarOutputPath = entry.getValue();
if (".".equals(jarOutputPath)) {
return mavenOutputFolder.getFullPath();
}
return mavenOutputFolder.getParent()
.getFolder(new org.eclipse.core.runtime.Path(jarOutputPath + "-classes")).getFullPath();
}
}
return eclipseOutputLocation;
}

private void makeOutputFolder(IPath outputLocation, IPath projectPath) throws CoreException, IOException {
if (outputLocation != null) {
private IFolder makeOutputFolder(IPath eclipseOutputLocation, IPath mavenOutputLocation)
throws CoreException, IOException {
if (eclipseOutputLocation != null) {
IWorkspace workspace = ResourcesPlugin.getWorkspace();
IFolder folder = workspace.getRoot().getFolder(outputLocation);
IFolder folder = workspace.getRoot().getFolder(eclipseOutputLocation);
if (!folder.exists()) {
folder.create(true, true, new NullProgressMonitor());
}
if (mavenOutputLocation != null && !eclipseOutputLocation.equals(mavenOutputLocation)) {
copy(getFile(mavenOutputLocation), getFile(eclipseOutputLocation));
}
folder.refreshLocal(IResource.DEPTH_INFINITE, new NullProgressMonitor());
return folder;
}
return null;
}

private File getFile(IPath path) {
if (path == null) {
return null;
}
IWorkspace workspace = ResourcesPlugin.getWorkspace();
IPath location = workspace.getRoot().getFolder(path).getLocation();
if (location == null) {
return null;
}
return location.toFile();
}

private void copy(File from, File to) throws IOException {
if (from == null || to == null || !from.isDirectory() || !to.isDirectory()) {
return;
}
final Path targetPath = to.toPath();
Files.walkFileTree(from.toPath(), new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(final Path dir, final BasicFileAttributes attrs)
throws IOException {
Files.createDirectories(targetPath.resolve(from.toPath().relativize(dir)));
return FileVisitResult.CONTINUE;
}

@Override
public FileVisitResult visitFile(final Path file, final BasicFileAttributes attrs) throws IOException {
Files.copy(file, targetPath.resolve(from.toPath().relativize(file)),
StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES);
return FileVisitResult.CONTINUE;
}
});
}

private IFolder getProjectFolder(IPath path) {
if (path != null) {
IWorkspace workspace = ResourcesPlugin.getWorkspace();
return workspace.getRoot().getFolder(path);
}
return null;
}

private void deleteAllProjects() throws CoreException {
Expand Down
61 changes: 61 additions & 0 deletions tycho-its/projects/api-tools/api-break/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?xml version="1.0" encoding="UTF-8"?>
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>org.eclipse.tycho.tycho-its</groupId>
<artifactId>apitools-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<!--module>api-repo</module-->
<!-- Used to build the baseline repo -->
<module>bundle1</module>
<module>bundle2</module>
</modules>
<properties>
<target-platform>https://download.eclipse.org/releases/2023-09/</target-platform>
</properties>
<repositories>
<repository>
<id>platform</id>
<url>${target-platform}</url>
<layout>p2</layout>
</repository>
</repositories>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-maven-plugin</artifactId>
<version>${tycho-version}</version>
<extensions>true</extensions>
</plugin>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-apitools-plugin</artifactId>
<version>${tycho-version}</version>
<configuration>
<baselines>
<repository>
<id>baseline</id>
<url>${baselineRepo}</url>
</repository>
</baselines>
</configuration>
<executions>
<execution>
<id>generate</id>
<goals>
<goal>generate</goal>
</goals>
</execution>
<execution>
<id>analyse</id>
<goals>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<extensions>
<extension>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-build</artifactId>
<version>${tycho-version}</version>
</extension>
</extensions>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
-Dtycho-version=5.0.0-SNAPSHOT
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-17"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" output="bin_ant" path="src_ant"/>
<classpathentry kind="output" path="bin"/>
</classpath>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
bin
lib
bin_ant
temp*
!/templates/
build.xml
!/scripts/build.xml
pdebuild.jar
org.eclipse.pde.build_*.zip
pdebuildsrc.zip
javaCompiler.pdebuild.jar.args
javaCompiler.lib_pdebuild-ant.jar.args
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>org.eclipse.pde.build</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ManifestBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.SchemaBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.ui.externaltools.ExternalToolBuilder</name>
<triggers>auto,full,incremental,</triggers>
<arguments>
<dictionary>
<key>LaunchConfigHandle</key>
<value>&lt;project&gt;/.externalToolBuilders/org.eclipse.pde.build localbuild.xml [Builder].launch</value>
</dictionary>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.api.tools.apiAnalysisBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.pde.api.tools.apiAnalysisNature</nature>
</natures>
</projectDescription>
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<component id="org.eclipse.pde.build" version="2">
<resource path="src/org/eclipse/pde/internal/build/AntLogAdapter.java" type="org.eclipse.pde.internal.build.AntLogAdapter">
<filter id="574619656">
<message_arguments>
<message_argument value="ILog"/>
<message_argument value="AntLogAdapter"/>
</message_arguments>
</filter>
</resource>
</component>
Loading
Loading