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

Add includeAllSources property to include all available source bundles #1120

Merged
merged 1 commit into from
Aug 24, 2022
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
5 changes: 5 additions & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ This page describes the noteworthy improvements provided by each release of Ecli

## 3.0.0 (under development)

### Support for inclusion of all source bundles in an update-site

The [tycho-p2-repository-plugin:2.7.0:assemble-repository](https://www.eclipse.org/tycho/sitedocs/tycho-p2/tycho-p2-repository-plugin/assemble-repository-mojo.html) now support a new property `includeAllSources` that,
when enabled, includes any available source bundle in the resulting repository.

### Support for Eclipse-Products with mixed Features and Plugins

Tycho now supports building _mixed_ Products. In mixed Products both the listed features and listed plug-ins are installed.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,15 @@
package org.eclipse.tycho.p2.tools.mirroring;

import java.net.URI;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.equinox.internal.p2.director.PermissiveSlicer;
import org.eclipse.equinox.internal.p2.director.Slicer;
import org.eclipse.equinox.internal.p2.metadata.IRequiredCapability;
Expand All @@ -26,8 +30,15 @@
import org.eclipse.equinox.p2.internal.repository.tools.RepositoryDescriptor;
import org.eclipse.equinox.p2.internal.repository.tools.SlicingOptions;
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.MetadataFactory;
import org.eclipse.equinox.p2.metadata.MetadataFactory.InstallableUnitDescription;
import org.eclipse.equinox.p2.metadata.Version;
import org.eclipse.equinox.p2.metadata.VersionRange;
import org.eclipse.equinox.p2.metadata.expression.IMatchExpression;
import org.eclipse.equinox.p2.query.CollectionResult;
import org.eclipse.equinox.p2.query.IQueryable;
import org.eclipse.equinox.p2.query.QueryUtil;
import org.eclipse.equinox.p2.repository.IRepository;
import org.eclipse.equinox.p2.repository.IRepositoryReference;
Expand All @@ -42,6 +53,7 @@ public class MirrorApplication extends org.eclipse.equinox.p2.internal.repositor

private final Map<String, String> extraArtifactRepositoryProperties;
private final List<RepositoryReference> repositoryReferences;
private boolean includeAllSource;

public MirrorApplication(IProvisioningAgent agent, Map<String, String> extraArtifactRepositoryProperties,
List<RepositoryReference> repositoryReferences) {
Expand Down Expand Up @@ -69,9 +81,10 @@ protected Slicer createSlicer(SlicingOptions options) {
boolean includeOptionalDependencies = options.includeOptionalDependencies();
boolean onlyFilteredRequirements = options.followOnlyFilteredRequirements();
boolean considerFilter = (context != null && context.size() > 1) ? true : false;
PermissiveSlicer slicer = new PermissiveSlicer(getCompositeMetadataRepository(), context,
includeOptionalDependencies, options.isEverythingGreedy(), options.forceFilterTo(),
options.considerStrictDependencyOnly(), onlyFilteredRequirements) {
IMetadataRepository repository = getCompositeMetadataRepository();
PermissiveSlicer slicer = new PermissiveSlicer(repository, context, includeOptionalDependencies,
options.isEverythingGreedy(), options.forceFilterTo(), options.considerStrictDependencyOnly(),
onlyFilteredRequirements) {
@Override
protected boolean isApplicable(IInstallableUnit iu, IRequirement req) {
if (QueryUtil.isGroup(iu)) {
Expand Down Expand Up @@ -99,10 +112,48 @@ protected boolean isApplicable(IInstallableUnit iu, IRequirement req) {
return super.isApplicable(iu, req);
}

@Override
public IQueryable<IInstallableUnit> slice(IInstallableUnit[] ius, IProgressMonitor monitor) {
IQueryable<IInstallableUnit> slice = super.slice(ius, monitor);
if (includeAllSource) {
Set<IInstallableUnit> units = slice.query(QueryUtil.ALL_UNITS, null).toSet();
IInstallableUnit sourceUnit = createSourceUnit(units);
IQueryable<IInstallableUnit> queryable = super.slice(new IInstallableUnit[] { sourceUnit },
monitor);
units.addAll(queryable.query(QueryUtil.ALL_UNITS, null).toSet());
units.remove(sourceUnit);
return new CollectionResult<>(units);
}
return slice;
}

};
return slicer;
}

private static final IInstallableUnit createSourceUnit(Collection<IInstallableUnit> units) {

final IRequirement bundleRequirement = MetadataFactory.createRequirement("org.eclipse.equinox.p2.eclipse.type",
"bundle", null, null, false, false, false);
InstallableUnitDescription sourceDescription = new MetadataFactory.InstallableUnitDescription();
String id = "Source-Bundles-" + UUID.randomUUID();
sourceDescription.setId(id);
final Version sourceIUVersion = Version.createOSGi(1, 0, 0);
sourceDescription.setVersion(sourceIUVersion);
sourceDescription.setCapabilities(new IProvidedCapability[] {
MetadataFactory.createProvidedCapability(IInstallableUnit.NAMESPACE_IU_ID, id, sourceIUVersion) });
sourceDescription.addRequirements(units.stream().filter(unit -> unit.satisfies(bundleRequirement))
.map(MirrorApplication::createSourceBundleRequirement).collect(Collectors.toList()));
return MetadataFactory.createInstallableUnit(sourceDescription);
}

private static IRequirement createSourceBundleRequirement(IInstallableUnit unit) {
IRequirement optionalGreedySourceBundleRequirement = MetadataFactory.createRequirement("osgi.bundle",
unit.getId() + ".source", new VersionRange(unit.getVersion(), true, unit.getVersion(), true), null,
true, false, true);
return optionalGreedySourceBundleRequirement;
}

@Override
protected IMetadataRepository initializeDestination(RepositoryDescriptor toInit, IMetadataRepositoryManager mgr)
throws ProvisionException {
Expand All @@ -125,4 +176,8 @@ private static org.eclipse.equinox.p2.repository.spi.RepositoryReference toSpiRe
type, rr.isEnable() ? IRepository.ENABLED : IRepository.NONE);
}

public void setIncludeSources(boolean includeAllSource) {
this.includeAllSource = includeAllSource;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -143,14 +143,15 @@ private static IQuery<IInstallableUnit> createQuery(IUDescription iu) {
@Override
public void mirrorReactor(RepositoryReferences sources, DestinationRepositoryDescriptor destination,
Collection<DependencySeed> projectSeeds, BuildContext context, boolean includeAllDependencies,
Map<String, String> filterProperties) throws FacadeException {
boolean includeAllSource, Map<String, String> filterProperties) throws FacadeException {
IProvisioningAgent agent = Activator.createProvisioningAgent(context.getTargetDirectory());
try {
final MirrorApplication mirrorApp = createMirrorApplication(sources, destination, agent);

// mirror scope: seed units...
mirrorApp.setSourceIUs(
toInstallableUnitList(projectSeeds, mirrorApp.getCompositeMetadataRepository(), sources));
mirrorApp.setIncludeSources(includeAllSource);

// TODO the p2 mirror tool should support mirroring multiple environments at once
for (TargetEnvironment environment : context.getEnvironments()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ public interface MirrorApplicationService {
* environment specific installable units
* @param includeAllDependencies
* Whether to include all transitive dependencies
* @param includeAllSource
* Whether to include all possible sources
* @param filterProperties
* additional filter properties to be set in the p2 slicing options. May be
* <code>null</code>
Expand All @@ -56,7 +58,7 @@ public interface MirrorApplicationService {
*/
public void mirrorReactor(RepositoryReferences sources, DestinationRepositoryDescriptor destination,
Collection<DependencySeed> seeds, BuildContext context, boolean includeAllDependencies,
Map<String, String> filterProperties) throws FacadeException;
boolean includeAllSource, Map<String, String> filterProperties) throws FacadeException;

/**
* recreates the metadata of an existing repository e.g. to account for changes in the contained
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,13 +97,13 @@ public void testMirrorNothing() throws Exception {
// make sure that this unsupported case is detected; the mirror application would just mirror everything
Collection<DependencySeed> noSeeds = Collections.emptyList();

subject.mirrorReactor(sourceRepos("patch", "e342"), destinationRepo, noSeeds, context, false, null);
subject.mirrorReactor(sourceRepos("patch", "e342"), destinationRepo, noSeeds, context, false, false, null);
}

@Test
public void testMirrorFeatureWithContent() throws Exception {
subject.mirrorReactor(sourceRepos("patch", "e342"), destinationRepo, seedFor(SIMPLE_FEATURE_IU), context, false,
null);
false, null);

logVerifier.expectNoWarnings();
assertTrue(repoFile(destinationRepo, "plugins/org.eclipse.core.runtime_3.4.0.v20080512.jar").exists());
Expand All @@ -119,7 +119,7 @@ public void testExtraArtifactRepositoryProperties() throws Exception {
destinationRepo = new DestinationRepositoryDescriptor(tempFolder.newFolder("dest2"), DEFAULT_NAME, false, false,
false, false, true, extraArtifactRepositoryProperties, Collections.emptyList());
subject.mirrorReactor(sourceRepos("patch", "e342"), destinationRepo, seedFor(SIMPLE_FEATURE_IU), context, false,
null);
false, null);

logVerifier.expectNoWarnings();
File artifactsXml = repoFile(destinationRepo, "artifacts.xml");
Expand All @@ -142,7 +142,7 @@ public void testExtraArtifactRepositoryProperties() throws Exception {
@Test
public void testMirrorPatch() throws Exception {
subject.mirrorReactor(sourceRepos("patch", "e352"), destinationRepo, seedFor(FEATURE_PATCH_IU), context, false,
null);
false, null);

//TODO why mirror tool emits a warning here? logVerifier.expectNoWarnings();
assertTrue(repoFile(destinationRepo, "plugins/org.eclipse.core.runtime_3.5.0.v20090525.jar").exists());
Expand All @@ -152,7 +152,7 @@ public void testMirrorPatch() throws Exception {
@Test
public void testMirrorFeatureAndPatch() throws Exception {
subject.mirrorReactor(sourceRepos("patch", "e352"), destinationRepo,
seedFor(SIMPLE_FEATURE_IU, FEATURE_PATCH_IU), context, false, null);
seedFor(SIMPLE_FEATURE_IU, FEATURE_PATCH_IU), context, false, false, null);

assertTrue(repoFile(destinationRepo, "plugins/org.eclipse.core.runtime_3.5.0.v20090525.jar").exists());
assertTrue(repoFile(destinationRepo, "features/" + SIMPLE_FEATURE + "_1.0.0.jar").exists());
Expand All @@ -170,7 +170,7 @@ public void testMirrorWithMissingMandatoryContent() throws Exception {
* since it is not easy to distinguish between patched and unpatched dependencies, only a
* warning is issued.
*/
subject.mirrorReactor(sourceRepos("patch"), destinationRepo, seedFor(SIMPLE_FEATURE_IU), context, false, null);
subject.mirrorReactor(sourceRepos("patch"), destinationRepo, seedFor(SIMPLE_FEATURE_IU), context, false, false, null);

logVerifier.expectWarning(not(is("")));
}
Expand All @@ -184,7 +184,7 @@ public void testMirrorForSeedWithNullIU() throws Exception {
List<DependencySeed> seeds = Collections
.singletonList(new DependencySeed(null, "org.eclipse.core.runtime", null));

subject.mirrorReactor(sourceRepos("e342"), destinationRepo, seeds, context, false, null);
subject.mirrorReactor(sourceRepos("e342"), destinationRepo, seeds, context, false, false, null);

assertTrue(repoFile(destinationRepo, "plugins/org.eclipse.core.runtime_3.4.0.v20080512.jar").exists());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,15 @@ public class AssembleRepositoryMojo extends AbstractRepositoryMojo {
@Parameter(defaultValue = "false")
private boolean includeAllDependencies;

/**
* <p>
* By default, only explicitly mentioned sources are included. Set this parameter to
* <code>true</code> to include all sources that are available and included in this repository.
* </p>
*/
@Parameter(defaultValue = "false")
private boolean includeAllSources;

/**
* <p>
* Compress the repository index files <tt>content.xml</tt> and <tt>artifacts.xml</tt>.
Expand Down Expand Up @@ -167,7 +176,7 @@ public void execute() throws MojoExecutionException, MojoFailureException {
destination, repositoryName, compress, xzCompress, keepNonXzIndexFiles,
!createArtifactRepository, true, extraArtifactRepositoryProperties, repositoryRefrences);
mirrorApp.mirrorReactor(sources, destinationRepoDescriptor, projectSeeds, getBuildContext(),
includeAllDependencies, profileProperties);
includeAllDependencies, includeAllSources, profileProperties);
} catch (FacadeException e) {
throw new MojoExecutionException("Could not assemble p2 repository", e);
}
Expand Down