Skip to content

Commit

Permalink
Merge branch 'eclipse-tycho:tycho-4.0.x' into tycho-4.0.x
Browse files Browse the repository at this point in the history
  • Loading branch information
kevloral authored Dec 17, 2023
2 parents c56d094 + c4e5481 commit d116bc4
Show file tree
Hide file tree
Showing 136 changed files with 1,461 additions and 1,082 deletions.
10 changes: 5 additions & 5 deletions .github/workflows/maven.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ jobs:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
steps:
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- name: Set up Java
uses: actions/setup-java@5ffc13f4174014e2d4d4572b3d74c3fa61aeb2c2 # v3.11.0
uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 # v4.0.0
with:
java-version: |
8
Expand All @@ -34,7 +34,7 @@ jobs:
17
distribution: 'temurin'
- name: Cache local Maven repository
uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1
uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 # v3.3.2
with:
path: ~/.m2/repository
key: ${{ runner.os }}-tycho4m39-${{ matrix.os }}-${{ hashFiles('**/pom.xml', '**/*.target') }}
Expand All @@ -51,7 +51,7 @@ jobs:
cp .github/toolchains.xml ~/.m2/toolchains.xml
mvn -U -V -e -B -ntp clean install --file pom.xml -DtrimStackTrace=false -Pits -fae
- name: Upload Test Results
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
if: always()
with:
name: test-results-${{ matrix.os }}
Expand All @@ -63,7 +63,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Upload
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
with:
name: Event File
path: ${{ github.event_path }}
6 changes: 5 additions & 1 deletion RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ This page describes the noteworthy improvements provided by each release of Ecli

## 4.0.4

Various bugfixes and backports
Backports:
- Add schema-to-html mojo as a replacement for ant ConvertSchemaToHTML
- Only set download/install-size attributes in features if they exist
- Call the API tools directly without using ApiAnalysisApplication
- Make additional P2 units from p2.inf available to the target-platform

## 4.0.3

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@
*******************************************************************************/
package org.eclipse.tycho.p2maven;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.codehaus.plexus.component.annotations.Component;
import org.codehaus.plexus.component.annotations.Requirement;
Expand All @@ -27,7 +29,6 @@
import org.eclipse.equinox.internal.p2.metadata.InstallableUnit;
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
import org.eclipse.equinox.p2.metadata.IRequirement;
import org.eclipse.equinox.p2.query.CollectionResult;
import org.eclipse.equinox.p2.query.IQueryResult;
import org.eclipse.equinox.p2.query.IQueryable;
import org.eclipse.equinox.p2.query.QueryUtil;
Expand Down Expand Up @@ -76,32 +77,35 @@ public IQueryResult<IInstallableUnit> computeDependencies(Collection<IInstallabl
* @param rootIus the root {@link InstallableUnit}s to take into account
* @param avaiableIUs the {@link IQueryable} of all units that could be used for
* fulfilling a requirement
* @return the result of the slicing
* @param contextIUs context IUs that represent the the profile properties to
* consider during resolution, can be empty in which case a
* filter is always considered a match
* @return the result of the slicing, be aware that no maximum/minimum
* constraints or filters are applied as part of this computation
* @throws CoreException if there is any error
*/
public IQueryResult<IInstallableUnit> computeDirectDependencies(Collection<IInstallableUnit> rootIus,
public Map<IRequirement, Collection<IInstallableUnit>> computeDirectDependencies(
Collection<IInstallableUnit> rootIus,
IQueryable<IInstallableUnit> avaiableIUs) throws CoreException {
Collection<IInstallableUnit> result = new LinkedHashSet<>();
List<IRequirement> collect = rootIus.stream().flatMap(iu -> iu.getRequirements().stream()).filter(req -> {
for (IInstallableUnit unit : rootIus) {
if (unit.satisfies(req)) {
// self full filled requirement
return false;
}
}
return true;
}).toList();
List<IRequirement> collect = rootIus.stream().flatMap(iu -> iu.getRequirements().stream())
.filter(req -> {
for (IInstallableUnit unit : rootIus) {
if (unit.satisfies(req)) {
// self full filled requirement
return false;
}
}
return true;
}).toList();
Map<IRequirement, Collection<IInstallableUnit>> result = new LinkedHashMap<>(collect.size());
for (IInstallableUnit iu : avaiableIUs.query(QueryUtil.ALL_UNITS, new NullProgressMonitor()).toSet()) {
for (IRequirement requirement : collect) {
if (iu.satisfies(requirement)) {
result.add(iu);
// TODO remove the requirement from the set so we only collect exactly one
// provider for a requirement?
break;
result.computeIfAbsent(requirement, nil -> new ArrayList<>()).add(iu);
}
}
}
return new CollectionResult<>(result);
return result;
}

private final class TychoSlicer extends PermissiveSlicer {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,6 @@
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
Expand All @@ -29,6 +26,7 @@
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

Expand All @@ -44,6 +42,7 @@
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
import org.eclipse.equinox.p2.metadata.IProvidedCapability;
import org.eclipse.equinox.p2.metadata.IRequirement;
import org.eclipse.equinox.p2.metadata.expression.IMatchExpression;
import org.eclipse.equinox.p2.publisher.eclipse.BundlesAction;
import org.eclipse.equinox.p2.query.CollectionResult;
import org.eclipse.equinox.p2.query.IQueryable;
Expand All @@ -56,8 +55,7 @@
@Component(role = MavenProjectDependencyProcessor.class)
public class MavenProjectDependencyProcessor {

private static final ProjectDependencies EMPTY_DEPENDENCIES = new ProjectDependencies(Collections.emptyList(),
Collections.emptyList());
private static final ProjectDependencies EMPTY_DEPENDENCIES = new ProjectDependencies(Map.of(), Set.of());

private static final boolean DUMP_DATA = Boolean.getBoolean("tycho.p2.dump")
|| Boolean.getBoolean("tycho.p2.dump.dependencies");
Expand All @@ -72,13 +70,19 @@ public class MavenProjectDependencyProcessor {
* Computes the {@link ProjectDependencyClosure} of the given collection of
* projects.
*
* @param projects the projects to include in the closure
* @param session the maven session for this request
* @param projects the projects to include in the closure
* @param session the maven session for this request
* @param profilePropertiesSupplier supplier of context IUs for a project that
* represent the the profile properties to
* consider during resolution, can be empty in
* which case a filter is always considered a
* match
* @return the computed {@link ProjectDependencyClosure}
* @throws CoreException if computation failed
*/
public ProjectDependencyClosure computeProjectDependencyClosure(Collection<MavenProject> projects,
MavenSession session) throws CoreException {
MavenSession session)
throws CoreException {
Objects.requireNonNull(session);
Map<MavenProject, Collection<IInstallableUnit>> projectIUMap = generator.getInstallableUnits(projects, session);
Collection<IInstallableUnit> availableIUs = projectIUMap.values().stream().flatMap(Collection::stream)
Expand All @@ -105,9 +109,11 @@ public ProjectDependencies getProjectDependecies(MavenProject mavenProject) {
}

@Override
public Stream<Entry<MavenProject, Collection<IInstallableUnit>>> dependencies() {
public Stream<Entry<MavenProject, Collection<IInstallableUnit>>> dependencies(
Function<MavenProject, Collection<IInstallableUnit>> contextIuSupplier) {
return projectDependenciesMap.entrySet().stream()
.map(pd -> new SimpleEntry<>(pd.getKey(), pd.getValue().dependencies));
.map(pd -> new SimpleEntry<>(pd.getKey(),
pd.getValue().getDependencies(contextIuSupplier.apply(pd.getKey()))));
}

@Override
Expand Down Expand Up @@ -144,13 +150,15 @@ private Map<MavenProject, ProjectDependencies> computeProjectDependencies(Collec
Map<MavenProject, ProjectDependencies> result = new ConcurrentHashMap<>();
projects.parallelStream().unordered().takeWhile(nil -> errors.isEmpty()).forEach(project -> {
try {
ProjectDependencies projectDependencies = computeProjectDependencies(projectIUMap.get(project),
ProjectDependencies projectDependencies = computeProjectDependencies(
Set.copyOf(projectIUMap.get(project)),
avaiableIUs);
result.put(project, projectDependencies);
if (DUMP_DATA) {
File file = new File(project.getBasedir(), "project-dependencies.xml");
try {
new MetadataIO().writeXML(Collections.unmodifiableCollection(projectDependencies.dependencies),
new MetadataIO().writeXML(
Collections.unmodifiableCollection(projectDependencies.getDependencies(List.of())),
file);
} catch (IOException e) {
}
Expand Down Expand Up @@ -181,26 +189,15 @@ private Map<MavenProject, ProjectDependencies> computeProjectDependencies(Collec
* @return the collection of dependent {@link InstallableUnit}s
* @throws CoreException if computation failed
*/
private ProjectDependencies computeProjectDependencies(Collection<IInstallableUnit> projectUnits,
IQueryable<IInstallableUnit> avaiableIUs) throws CoreException {
private ProjectDependencies computeProjectDependencies(Set<IInstallableUnit> projectUnits,
IQueryable<IInstallableUnit> avaiableIUs)
throws CoreException {
if (projectUnits.isEmpty()) {
return EMPTY_DEPENDENCIES;
}
Set<IInstallableUnit> resolved = new LinkedHashSet<>(
slicer.computeDirectDependencies(projectUnits, avaiableIUs).toSet());
resolved.removeAll(projectUnits);
// now we need to filter all fragments that we are a host!
// for example SWT creates an explicit requirement to its fragments and we don't
// want them included directly
Set<IInstallableUnit> projectFragments = new HashSet<>();
for (Iterator<IInstallableUnit> iterator = resolved.iterator(); iterator.hasNext();) {
IInstallableUnit unit = iterator.next();
if (hasAnyHost(unit, projectUnits)) {
projectFragments.add(unit);
iterator.remove();
}
}
return new ProjectDependencies(resolved, projectFragments);
Map<IRequirement, Collection<IInstallableUnit>> dependencies = slicer.computeDirectDependencies(projectUnits,
avaiableIUs);
return new ProjectDependencies(dependencies, projectUnits);
}

private static boolean hasAnyHost(IInstallableUnit unit, Iterable<IInstallableUnit> collection) {
Expand Down Expand Up @@ -238,23 +235,32 @@ private static Stream<IRequirement> getFragmentHostRequirement(IInstallableUnit
}).filter(Objects::nonNull);
}

private static boolean isMatch(IRequirement requirement, Collection<IInstallableUnit> contextIUs) {
IMatchExpression<IInstallableUnit> filter = requirement.getFilter();
if (filter == null || contextIUs.isEmpty()) {
return true;
}
return contextIUs.stream().anyMatch(contextIU -> filter.isMatch(contextIU));
}

public static final class ProjectDependencies {

private final Collection<IInstallableUnit> dependencies;
private final Collection<IInstallableUnit> fragments;
private final Map<IRequirement, Collection<IInstallableUnit>> requirementsMap;
private final Set<IInstallableUnit> projectUnits;

private ProjectDependencies(Collection<IInstallableUnit> dependencies, Collection<IInstallableUnit> fragments) {
this.dependencies = dependencies;
this.fragments = fragments;
ProjectDependencies(Map<IRequirement, Collection<IInstallableUnit>> requirementsMap,
Set<IInstallableUnit> projectUnits) {
this.requirementsMap = requirementsMap;
this.projectUnits = projectUnits;
}

public Collection<IInstallableUnit> getDependencies() {
return dependencies;
public Collection<IInstallableUnit> getDependencies(Collection<IInstallableUnit> contextIUs) {
return requirementsMap.entrySet().stream().filter(entry -> isMatch(entry.getKey(), contextIUs))
.flatMap(entry -> entry.getValue().stream().filter(unit -> !projectUnits.contains(unit))
.limit(entry.getKey().getMax()))
.distinct().toList();
}

public Collection<IInstallableUnit> getFragments() {
return fragments;
}

}

Expand All @@ -279,31 +285,38 @@ public static interface ProjectDependencyClosure {
/**
* @return a stream of all contained maven projects with dependecies
*/
Stream<Entry<MavenProject, Collection<IInstallableUnit>>> dependencies();
Stream<Entry<MavenProject, Collection<IInstallableUnit>>> dependencies(
Function<MavenProject, Collection<IInstallableUnit>> contextIuSupplier);

/**
* Given a maven project returns all other maven projects this one (directly)
* depends on
*
* @param mavenProject
* @param mavenProject the maven project for which all direct dependent projects
* should be collected
* @param contextIUs the context IUs to filter dependencies
* @return the collection of projects this maven project depend on in this
* closure
*/
default Collection<MavenProject> getDependencyProjects(MavenProject mavenProject) {
default Collection<MavenProject> getDependencyProjects(MavenProject mavenProject,
Collection<IInstallableUnit> contextIUs) {
ProjectDependencies projectDependecies = getProjectDependecies(mavenProject);
List<MavenProject> list = projectDependecies.getDependencies().stream()
List<MavenProject> list = projectDependecies.getDependencies(contextIUs).stream()
.flatMap(dependency -> getProject(dependency).stream()).distinct().toList();
if (isFragment(mavenProject)) {
// for projects that are fragments don't do any special processing...
return list;
}
// for regular projects we must check if they have any fragment requirements
// that must be attached here, example is SWT that defines a requirement to its
// fragments and if build inside the same reactor with a consumer (e.g. JFace)
// has to be applied
return list.stream().flatMap(project -> {
ProjectDependencies dependecies = getProjectDependecies(project);
if (dependecies.getFragments().isEmpty()) {
return Stream.of(project);
}
return Stream.concat(Stream.of(project),
dependecies.getFragments().stream().flatMap(dependency -> getProject(dependency).stream()));
}).distinct().toList();
return Stream.concat(Stream.of(project), dependecies.getDependencies(contextIUs).stream()
.filter(dep -> hasAnyHost(dep, dependecies.projectUnits))
.flatMap(dependency -> getProject(dependency).stream()));
}).toList();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,11 @@ public IArtifactRequest createMirrorRequest(IArtifactKey key, IArtifactRepositor
@Override
public IArtifactRepository createRepository(URI location, String name, String type, Map<String, String> properties)
throws ProvisionException {
return delegate.createRepository(translate(location), name, type, properties);
synchronized (RemoteArtifactRepositoryManager.class) {
// TODO the sync is required unless
// https://github.com/eclipse-equinox/p2/pull/415 is fixed
return delegate.createRepository(translate(location), name, type, properties);
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public void setHeader(String key, String value) {
public Response<InputStream> get() throws IOException {
HttpURLConnection connection = createConnection();
connection.connect();
return new HttpResponse<InputStream>(connection) {
return new HttpResponse<>(connection) {

@Override
public void close() {
Expand Down Expand Up @@ -111,7 +111,7 @@ public Response<Void> head() throws IOException {
HttpURLConnection connection = createConnection();
connection.setRequestMethod("HEAD");
connection.connect();
return new HttpResponse<Void>(connection) {
return new HttpResponse<>(connection) {

@Override
public void close() {
Expand Down
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,14 @@
<commonsCompressVersion>1.25.0</commonsCompressVersion>
<plexusVersion>2.1.1</plexusVersion>
<plexusUtilsVersion>3.5.1</plexusUtilsVersion>
<plexusCompilerVersion>2.13.0</plexusCompilerVersion>
<plexusCompilerVersion>2.14.1</plexusCompilerVersion>
<cipherVersion>2.1.0</cipherVersion>
<pluginToolsVersion>3.10.2</pluginToolsVersion>
<jgit-version>6.8.0.202311291450-r</jgit-version>
<maven-version>3.9.6</maven-version>
<minimal-maven-version>3.9.0</minimal-maven-version>
<!-- When updating surefire version, double-check Import-Package statements generated by bnd-maven-plugin and possibly adapt instructions in various bnd.bnd files -->
<surefire-version>3.2.2</surefire-version>
<surefire-version>3.2.3</surefire-version>
<equinoxVersion>3.18.600</equinoxVersion>
<ecjVersion>3.36.0</ecjVersion>
<bnd.version>7.0.0</bnd.version>
Expand Down
Loading

0 comments on commit d116bc4

Please sign in to comment.