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] Assemble repository for all environments in one pass #2860

Merged
merged 1 commit into from
Sep 27, 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 @@ -51,7 +51,6 @@
import org.eclipse.equinox.p2.repository.metadata.IMetadataRepository;
import org.eclipse.tycho.ArtifactType;
import org.eclipse.tycho.BuildDirectory;
import org.eclipse.tycho.TargetEnvironment;
import org.eclipse.tycho.core.resolver.shared.DependencySeed;
import org.eclipse.tycho.core.shared.StatusTool;
import org.eclipse.tycho.p2.repository.GAV;
Expand Down Expand Up @@ -164,28 +163,24 @@ public void mirrorReactor(RepositoryReferences sources, DestinationRepositoryDes
mirrorApp.setIncludeRequiredFeatures(includeRequiredFeatures);
mirrorApp.setIncludePacked(false); // no way, Tycho do no longer support packed artifacts anyways
mirrorApp.setFilterProvided(filterProvided);
// TODO the p2 mirror tool should support mirroring multiple environments at once
for (TargetEnvironment environment : context.getEnvironments()) {
SlicingOptions options = new SlicingOptions();
options.considerStrictDependencyOnly(!includeAllDependencies);
Map<String, String> filter = options.getFilter();
addFilterForFeatureJARs(filter);
if (filterProperties != null) {
filter.putAll(filterProperties);
}
filter.putAll(environment.toFilterProperties());
mirrorApp.setSlicingOptions(options);

try {
LogListener logListener = new LogListener(logger);
mirrorApp.setLog(logListener);

IStatus returnStatus = mirrorApp.run(null);
checkStatus(returnStatus, false);
logListener.showHelpForLoggedMessages();
} catch (ProvisionException e) {
throw new FacadeException(MIRROR_FAILURE_MESSAGE + ": " + StatusTool.collectProblems(e.getStatus()), e);
}
mirrorApp.setEnvironments(context.getEnvironments());
SlicingOptions options = new SlicingOptions();
options.considerStrictDependencyOnly(!includeAllDependencies);
Map<String, String> filter = options.getFilter();
addFilterForFeatureJARs(filter);
if (filterProperties != null) {
filter.putAll(filterProperties);
}
mirrorApp.setSlicingOptions(options);
try {
LogListener logListener = new LogListener(logger);
mirrorApp.setLog(logListener);

IStatus returnStatus = mirrorApp.run(null);
checkStatus(returnStatus, false);
logListener.showHelpForLoggedMessages();
} catch (ProvisionException e) {
throw new FacadeException(MIRROR_FAILURE_MESSAGE + ": " + StatusTool.collectProblems(e.getStatus()), e);
}
recreateArtifactRepository(destination);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
*
* Contributors:
* SAP SE - initial API and implementation
* Hannes Wellmann - Assemble repository for all environments in one pass
*******************************************************************************/
package org.eclipse.tycho.p2tools;

Expand All @@ -29,6 +30,8 @@
import org.eclipse.equinox.internal.p2.director.PermissiveSlicer;
import org.eclipse.equinox.internal.p2.director.Slicer;
import org.eclipse.equinox.internal.p2.metadata.IRequiredCapability;
import org.eclipse.equinox.internal.p2.metadata.InstallableUnit;
import org.eclipse.equinox.internal.p2.metadata.RequiredCapability;
import org.eclipse.equinox.p2.core.IProvisioningAgent;
import org.eclipse.equinox.p2.core.ProvisionException;
import org.eclipse.equinox.p2.internal.repository.tools.RepositoryDescriptor;
Expand Down Expand Up @@ -82,13 +85,16 @@ protected IArtifactRepository initializeDestination(RepositoryDescriptor toInit,

@Override
protected Slicer createSlicer(SlicingOptions options) {
Map<String, String> context = options.getFilter();
List<Map<String, String>> filters = getContextFilters();
List<IInstallableUnit> selectionContexts = filters.stream().map(InstallableUnit::contextIU).toList();
boolean includeOptionalDependencies = options.includeOptionalDependencies();
boolean onlyFilteredRequirements = options.followOnlyFilteredRequirements();
boolean considerFilter = context != null && context.size() > 1;
boolean considerFilter = filters.stream().anyMatch(f -> f.size() > 1);
boolean evalFilterTo = options.forceFilterTo();
IMetadataRepository repository = getCompositeMetadataRepository();
return new PermissiveSlicer(repository, context, includeOptionalDependencies, options.isEverythingGreedy(),
options.forceFilterTo(), options.considerStrictDependencyOnly(), onlyFilteredRequirements) {
boolean considerOnlyStrictDependency = options.considerStrictDependencyOnly();
return new PermissiveSlicer(repository, filters.get(0), includeOptionalDependencies,
options.isEverythingGreedy(), evalFilterTo, considerOnlyStrictDependency, onlyFilteredRequirements) {
@Override
protected boolean isApplicable(IInstallableUnit iu, IRequirement req) {
if ((includeRequiredBundles || includeRequiredFeatures) && QueryUtil.isGroup(iu)
Expand All @@ -103,15 +109,43 @@ protected boolean isApplicable(IInstallableUnit iu, IRequirement req) {
if (onlyFilteredRequirements && filter == null) {
return false;
}
return !considerFilter || filter == null || filter.isMatch(selectionContext);
return !considerFilter || filter == null || matchesSelectionContext(filter);
}
}
return super.isApplicable(req);
return isApplicable(req);
}

@Override
protected boolean isApplicable(IRequirement req) {
throw new UnsupportedOperationException("should never be called!");
//Every filter in this method needs to continue except when the filter does not pass
if (!includeOptionalDependencies && req.getMin() == 0) {
return false;
}
if (considerOnlyStrictDependency && !RequiredCapability.isStrictVersionRequirement(req.getMatches())) {
return false;
}
//deal with filters
IMatchExpression<IInstallableUnit> filter = req.getFilter();
if (considerFilter) {
if (onlyFilteredRequirements && filter == null) {
return false;
}
return filter == null || matchesSelectionContext(filter);
}
return filter == null ? !onlyFilteredRequirements : evalFilterTo;
}

@Override
protected boolean isApplicable(IInstallableUnit iu) {
if (considerFilter) {
IMatchExpression<IInstallableUnit> filter = iu.getFilter();
return filter == null || matchesSelectionContext(filter);
}
return iu.getFilter() == null || evalFilterTo;
}

private boolean matchesSelectionContext(IMatchExpression<IInstallableUnit> filter) {
return selectionContexts.stream().anyMatch(filter::isMatch);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -43,7 +44,6 @@
import org.eclipse.equinox.p2.metadata.VersionRange;
import org.eclipse.equinox.p2.planner.IPlanner;
import org.eclipse.equinox.p2.planner.IProfileChangeRequest;
import org.eclipse.equinox.p2.query.CompoundQueryable;
import org.eclipse.equinox.p2.query.IQuery;
import org.eclipse.equinox.p2.query.IQueryResult;
import org.eclipse.equinox.p2.query.IQueryable;
Expand All @@ -52,13 +52,15 @@
import org.eclipse.equinox.p2.repository.artifact.IArtifactRepository;
import org.eclipse.equinox.p2.repository.metadata.IMetadataRepository;
import org.eclipse.osgi.util.NLS;
import org.eclipse.tycho.TargetEnvironment;

public class MirrorApplication extends AbstractApplication implements IApplication, IExecutableExtension {
private static final String DEFAULT_COMPARATOR = ArtifactChecksumComparator.COMPARATOR_ID + ".sha-256"; //$NON-NLS-1$
private static final String LOG_ROOT = "p2.mirror"; //$NON-NLS-1$
private static final String MIRROR_MODE = "metadataOrArtifacts"; //$NON-NLS-1$

protected SlicingOptions slicingOptions = new SlicingOptions();
protected List<TargetEnvironment> environments = new ArrayList<>();

private URI baseline;
private String comparatorID;
Expand Down Expand Up @@ -397,22 +399,35 @@ private IArtifactMirrorLog getLog(File location, String root) {
}

private IQueryable<IInstallableUnit> performResolution(IProgressMonitor monitor) throws ProvisionException {
List<Map<String, String>> filters = getContextFilters();
IProfileRegistry registry = getProfileRegistry();
String profileId = "MirrorApplication-" + System.currentTimeMillis(); //$NON-NLS-1$
IProfile profile = registry.addProfile(profileId, slicingOptions.getFilter());
IPlanner planner = agent.getService(IPlanner.class);
if (planner == null)
throw new IllegalStateException();
IProfileChangeRequest pcr = planner.createChangeRequest(profile);
pcr.addAll(sourceIUs);
IProvisioningPlan plan = planner.getProvisioningPlan(pcr, null, monitor);
registry.removeProfile(profileId);
@SuppressWarnings("unchecked")
IQueryable<IInstallableUnit>[] arr = new IQueryable[plan.getInstallerPlan() == null ? 1 : 2];
arr[0] = plan.getAdditions();
if (plan.getInstallerPlan() != null)
arr[1] = plan.getInstallerPlan().getAdditions();
return new CompoundQueryable<>(arr);
List<IQueryable<IInstallableUnit>> queryables = new ArrayList<>();
for (Map<String, String> filter : filters) {
IProfile profile = registry.addProfile(profileId, filter);
IPlanner planner = agent.getService(IPlanner.class);
if (planner == null) {
throw new IllegalStateException();
}
IProfileChangeRequest pcr = planner.createChangeRequest(profile);
pcr.addAll(sourceIUs);
IProvisioningPlan plan = planner.getProvisioningPlan(pcr, null, monitor);
registry.removeProfile(profileId);
queryables.add(plan.getAdditions());
IProvisioningPlan installerPlan = plan.getInstallerPlan();
if (installerPlan != null) {
queryables.add(installerPlan.getAdditions());
}
}
return QueryUtil.compoundQueryable(queryables);
}

protected List<Map<String, String>> getContextFilters() {
return environments.isEmpty() ? List.of(slicingOptions.getFilter()) : environments.stream().map(environment -> {
Map<String, String> filter = new HashMap<>(slicingOptions.getFilter());
filter.putAll(environment.toFilterProperties());
return filter;
}).toList();
}

private IProfileRegistry getProfileRegistry() throws ProvisionException {
Expand Down Expand Up @@ -452,6 +467,10 @@ protected Slicer createSlicer(SlicingOptions options) {
return slicer;
}

public void setEnvironments(List<TargetEnvironment> environments) {
this.environments = environments;
}

public void setSlicingOptions(SlicingOptions options) {
slicingOptions = options;
}
Expand Down