Skip to content

Commit

Permalink
Add support for specify test requirements of a bundle
Browse files Browse the repository at this point in the history
Currently there is only limited support for "test only" dependencies of
a bundle, the usual way is to add an (optional) import/require bundle to
the test but this is not very suitable when one wants to have tests in
the bundle itself, also some requirements can't be expressed as a
package/bundle without binding to a particular implementation and even
if, these are still added as regular dependencies and not with test
scope.

This ads a way to specify a list of 'test.requirements' in the
build.properties to account for this.
  • Loading branch information
laeubi committed Nov 13, 2023
1 parent af86173 commit 43df917
Show file tree
Hide file tree
Showing 9 changed files with 215 additions and 91 deletions.
7 changes: 5 additions & 2 deletions ui/org.eclipse.pde.core/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %name
Bundle-SymbolicName: org.eclipse.pde.core; singleton:=true
Bundle-Version: 3.17.200.qualifier
Bundle-Version: 3.18.0.qualifier
Bundle-Activator: org.eclipse.pde.internal.core.PDECore
Bundle-Vendor: %provider-name
Bundle-Localization: plugin
Expand Down Expand Up @@ -89,11 +89,14 @@ Import-Package: aQute.bnd.build;version="[4.4.0,5.0.0)",
aQute.bnd.service;version="[4.7.0,5.0.0)",
aQute.bnd.version;version="[2.2.0,3.0.0)",
aQute.service.reporter;version="[1.2.0,2.0.0)",
biz.aQute.resolve;version="[9.0.0,10.0.0)",
org.eclipse.equinox.internal.p2.publisher.eclipse,
org.eclipse.equinox.p2.publisher,
org.eclipse.equinox.p2.publisher.eclipse,
org.osgi.service.repository;version="[1.1.0,2.0.0)",
org.osgi.util.promise;version="[1.3.0,2.0.0)"
org.osgi.util.promise;version="[1.3.0,2.0.0)",
org.osgi.service.resolver,
org.osgi.resource
Require-Bundle:
org.eclipse.core.runtime;bundle-version="[3.29.0,4.0.0)",
org.eclipse.e4.core.contexts;bundle-version="[1.12.300,2.0.0)",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,39 +27,47 @@ public interface IBuildEntry extends IWritable {
/**
* A property name for changes to the 'name' field.
*/
public static final String P_NAME = "name"; //$NON-NLS-1$
String P_NAME = "name"; //$NON-NLS-1$
/**
* The prefix for any key denoting the source folders that
* should be compiled into a JAR. The suffix will
* be the name of the JAR.
*/
public static final String JAR_PREFIX = "source."; //$NON-NLS-1$
String JAR_PREFIX = "source."; //$NON-NLS-1$
/**
* The prefix for any key denoting output folders for a particular
* JAR. The suffix will be the name of the JAR.
*/
public static final String OUTPUT_PREFIX = "output."; //$NON-NLS-1$
String OUTPUT_PREFIX = "output."; //$NON-NLS-1$
/**
* The name of the key that lists all the folders and files
* to be included in the binary build.
*/
public static final String BIN_INCLUDES = "bin.includes"; //$NON-NLS-1$
String BIN_INCLUDES = "bin.includes"; //$NON-NLS-1$
/**
* The name of the key that lists all the folders and files
* to be included in the source build.
*/
public static final String SRC_INCLUDES = "src.includes"; //$NON-NLS-1$
String SRC_INCLUDES = "src.includes"; //$NON-NLS-1$
/**
* The name of the key that declares extra library entries to be added
* to the class path at build time only..
*/
public static final String JARS_EXTRA_CLASSPATH = "jars.extra.classpath"; //$NON-NLS-1$
String JARS_EXTRA_CLASSPATH = "jars.extra.classpath"; //$NON-NLS-1$
/**
* The name of the key that declares additional plug-in dependencies to augment development classpath
*
* @since 3.2
*/
public static final String SECONDARY_DEPENDENCIES = "additional.bundles"; //$NON-NLS-1$
String SECONDARY_DEPENDENCIES = "additional.bundles"; //$NON-NLS-1$

/**
* The name of the key that declares additional plug-in requirements for
* tests
*
* @since 3.18
*/
String TEST_REQUIREMENTS = "test.requirements"; //$NON-NLS-1$

/**
* Adds the token to the list of token for this entry.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,47 +49,54 @@ public String toString() {
private static final IAccessRule EXCLUDE_ALL_RULE = JavaCore.newAccessRule(IPath.fromOSString("**/*"), IAccessRule.K_NON_ACCESSIBLE | IAccessRule.IGNORE_IF_BETTER); //$NON-NLS-1$

protected void addProjectEntry(IProject project, List<Rule> rules, boolean exportsExternalAnnotations,
List<IClasspathEntry> entries) throws CoreException {
List<IClasspathEntry> entries, boolean test) throws CoreException {
if (project.hasNature(JavaCore.NATURE_ID)) {
IAccessRule[] accessRules = rules != null ? getAccessRules(rules) : null;
IClasspathAttribute[] extraAttribs = getClasspathAttributesForProject(project, exportsExternalAnnotations);
IClasspathAttribute[] extraAttribs = getClasspathAttributesForProject(project, exportsExternalAnnotations,
test);
IClasspathEntry entry = JavaCore.newProjectEntry(project.getFullPath(), accessRules, true, extraAttribs, false);
if (!entries.contains(entry)) {
entries.add(entry);
}
}
}

private IClasspathAttribute[] getClasspathAttributesForProject(IProject project, boolean exportsExternalAnnotations)
throws JavaModelException {
private IClasspathAttribute[] getClasspathAttributesForProject(IProject project, boolean exportsExternalAnnotations,
boolean test) throws JavaModelException {
List<IClasspathAttribute> attributes = new ArrayList<>();
if (test) {
attributes.add(newClasspathAttribute(IClasspathAttribute.TEST, "true")); //$NON-NLS-1$
}
if (exportsExternalAnnotations) {
String annotationPath = JavaCore.create(project).getOutputLocation().toString();
return new IClasspathAttribute[] {
JavaCore.newClasspathAttribute(IClasspathAttribute.EXTERNAL_ANNOTATION_PATH, annotationPath) };
attributes
.add(JavaCore.newClasspathAttribute(IClasspathAttribute.EXTERNAL_ANNOTATION_PATH, annotationPath));
}
return new IClasspathAttribute[0];
return attributes.toArray(IClasspathAttribute[]::new);
}

public static IClasspathEntry[] getExternalEntries(IPluginModelBase model) {
public static IClasspathEntry[] getExternalEntries(IPluginModelBase model, boolean test) {
List<IClasspathEntry> entries = new ArrayList<>();
addExternalPlugin(model, List.of(), entries);
addExternalPlugin(model, List.of(), entries, test);
return entries.toArray(new IClasspathEntry[entries.size()]);
}

protected static void addExternalPlugin(IPluginModelBase model, List<Rule> rules, List<IClasspathEntry> entries) {
protected static void addExternalPlugin(IPluginModelBase model, List<Rule> rules, List<IClasspathEntry> entries,
boolean test) {
boolean isJarShape = new File(model.getInstallLocation()).isFile();
if (isJarShape) {
IPath srcPath = ClasspathUtilCore.getSourceAnnotation(model, ".", isJarShape); //$NON-NLS-1$
if (srcPath == null) {
srcPath = IPath.fromOSString(model.getInstallLocation());
}
addLibraryEntry(IPath.fromOSString(model.getInstallLocation()), srcPath, rules, getClasspathAttributes(model), entries);
addLibraryEntry(IPath.fromOSString(model.getInstallLocation()), srcPath, rules,
getClasspathAttributes(model, test), entries);

// If the jarred plugin contains any jarred libraries they must be extracted as the compiler can't handle nested jar files
File[] extractedLibraries = PDECore.getDefault().getModelManager().getExternalModelManager().getExtractedLibraries(model);
for (File libraryFile : extractedLibraries) {
IPath path = IPath.fromOSString(libraryFile.getAbsolutePath());
addLibraryEntry(path, path, rules, getClasspathAttributes(model), entries);
addLibraryEntry(path, path, rules, getClasspathAttributes(model, test), entries);
}
} else {
IPluginLibrary[] libraries = model.getPluginBase().getLibraries();
Expand All @@ -99,7 +106,8 @@ protected static void addExternalPlugin(IPluginModelBase model, List<Rule> rules
if (srcPath == null) {
srcPath = IPath.fromOSString(model.getInstallLocation());
}
addLibraryEntry(IPath.fromOSString(model.getInstallLocation()), srcPath, rules, getClasspathAttributes(model), entries);
addLibraryEntry(IPath.fromOSString(model.getInstallLocation()), srcPath, rules,
getClasspathAttributes(model, test), entries);
} else {
for (IPluginLibrary library : libraries) {
if (IPluginLibrary.RESOURCE.equals(library.getType())) {
Expand All @@ -117,7 +125,7 @@ protected static void addExternalPlugin(IPluginModelBase model, List<Rule> rules
}
if (path != null) {
addLibraryEntry(path, ClasspathUtilCore.getSourceAnnotation(model, expandedName, isJarShape),
rules, getClasspathAttributes(model), entries);
rules, getClasspathAttributes(model, test), entries);
}
}
}
Expand Down Expand Up @@ -150,7 +158,7 @@ protected static IAccessRule[] getAccessRules(List<Rule> rules) {
return accessRules;
}

private static IClasspathAttribute[] getClasspathAttributes(IPluginModelBase model) {
private static IClasspathAttribute[] getClasspathAttributes(IPluginModelBase model, boolean test) {
List<IClasspathAttribute> attributes = new ArrayList<>();
JavadocLocationManager manager = PDECore.getDefault().getJavadocLocationManager();
String location = manager.getJavadocLocation(model);
Expand All @@ -161,6 +169,9 @@ private static IClasspathAttribute[] getClasspathAttributes(IPluginModelBase mod
String installLocation = model.getInstallLocation();
attributes.add(newClasspathAttribute(IClasspathAttribute.EXTERNAL_ANNOTATION_PATH, installLocation));
}
if (test) {
attributes.add(newClasspathAttribute(IClasspathAttribute.TEST, "true")); //$NON-NLS-1$
}
return attributes.toArray(IClasspathAttribute[]::new);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public class PDECoreMessages extends NLS {
public static String BaseExportTask_pdeExport;

public static String BuildErrorReporter_cannotFindBundle;
public static String BuildErrorReporter_cannotRequirement;

public static String BuildErrorReporter_cannotFindJar;

Expand Down
Loading

0 comments on commit 43df917

Please sign in to comment.