From f472406677cb38d742a58226acc6abdd70116db9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20L=C3=A4ubrich?= Date: Sun, 10 Jul 2022 11:31:54 +0200 Subject: [PATCH] Add includeAllSources property to include all available source bundles Fix https://github.com/eclipse/tycho/issues/926 --- RELEASE_NOTES.md | 5 ++ .../p2/tools/mirroring/MirrorApplication.java | 61 ++++++++++++++++++- .../MirrorApplicationServiceImpl.java | 3 +- .../facade/MirrorApplicationService.java | 4 +- .../MirrorApplicationServiceTest.java | 14 ++--- .../p2/repository/AssembleRepositoryMojo.java | 11 +++- 6 files changed, 85 insertions(+), 13 deletions(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 5f72db673d..47bbd80ac0 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -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. diff --git a/tycho-bundles/org.eclipse.tycho.p2.tools.impl/src/main/java/org/eclipse/tycho/p2/tools/mirroring/MirrorApplication.java b/tycho-bundles/org.eclipse.tycho.p2.tools.impl/src/main/java/org/eclipse/tycho/p2/tools/mirroring/MirrorApplication.java index 215764603d..92b17128df 100644 --- a/tycho-bundles/org.eclipse.tycho.p2.tools.impl/src/main/java/org/eclipse/tycho/p2/tools/mirroring/MirrorApplication.java +++ b/tycho-bundles/org.eclipse.tycho.p2.tools.impl/src/main/java/org/eclipse/tycho/p2/tools/mirroring/MirrorApplication.java @@ -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; @@ -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; @@ -42,6 +53,7 @@ public class MirrorApplication extends org.eclipse.equinox.p2.internal.repositor private final Map extraArtifactRepositoryProperties; private final List repositoryReferences; + private boolean includeAllSource; public MirrorApplication(IProvisioningAgent agent, Map extraArtifactRepositoryProperties, List repositoryReferences) { @@ -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)) { @@ -99,10 +112,48 @@ protected boolean isApplicable(IInstallableUnit iu, IRequirement req) { return super.isApplicable(iu, req); } + @Override + public IQueryable slice(IInstallableUnit[] ius, IProgressMonitor monitor) { + IQueryable slice = super.slice(ius, monitor); + if (includeAllSource) { + Set units = slice.query(QueryUtil.ALL_UNITS, null).toSet(); + IInstallableUnit sourceUnit = createSourceUnit(units); + IQueryable 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 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 { @@ -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; + } + } diff --git a/tycho-bundles/org.eclipse.tycho.p2.tools.impl/src/main/java/org/eclipse/tycho/p2/tools/mirroring/MirrorApplicationServiceImpl.java b/tycho-bundles/org.eclipse.tycho.p2.tools.impl/src/main/java/org/eclipse/tycho/p2/tools/mirroring/MirrorApplicationServiceImpl.java index aac0c428e7..04e715a01a 100644 --- a/tycho-bundles/org.eclipse.tycho.p2.tools.impl/src/main/java/org/eclipse/tycho/p2/tools/mirroring/MirrorApplicationServiceImpl.java +++ b/tycho-bundles/org.eclipse.tycho.p2.tools.impl/src/main/java/org/eclipse/tycho/p2/tools/mirroring/MirrorApplicationServiceImpl.java @@ -143,7 +143,7 @@ private static IQuery createQuery(IUDescription iu) { @Override public void mirrorReactor(RepositoryReferences sources, DestinationRepositoryDescriptor destination, Collection projectSeeds, BuildContext context, boolean includeAllDependencies, - Map filterProperties) throws FacadeException { + boolean includeAllSource, Map filterProperties) throws FacadeException { IProvisioningAgent agent = Activator.createProvisioningAgent(context.getTargetDirectory()); try { final MirrorApplication mirrorApp = createMirrorApplication(sources, destination, agent); @@ -151,6 +151,7 @@ public void mirrorReactor(RepositoryReferences sources, DestinationRepositoryDes // 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()) { diff --git a/tycho-bundles/org.eclipse.tycho.p2.tools.shared/src/main/java/org/eclipse/tycho/p2/tools/mirroring/facade/MirrorApplicationService.java b/tycho-bundles/org.eclipse.tycho.p2.tools.shared/src/main/java/org/eclipse/tycho/p2/tools/mirroring/facade/MirrorApplicationService.java index d81648681c..c2c7ae9ef9 100644 --- a/tycho-bundles/org.eclipse.tycho.p2.tools.shared/src/main/java/org/eclipse/tycho/p2/tools/mirroring/facade/MirrorApplicationService.java +++ b/tycho-bundles/org.eclipse.tycho.p2.tools.shared/src/main/java/org/eclipse/tycho/p2/tools/mirroring/facade/MirrorApplicationService.java @@ -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 * null @@ -56,7 +58,7 @@ public interface MirrorApplicationService { */ public void mirrorReactor(RepositoryReferences sources, DestinationRepositoryDescriptor destination, Collection seeds, BuildContext context, boolean includeAllDependencies, - Map filterProperties) throws FacadeException; + boolean includeAllSource, Map filterProperties) throws FacadeException; /** * recreates the metadata of an existing repository e.g. to account for changes in the contained diff --git a/tycho-bundles/org.eclipse.tycho.p2.tools.tests/src/test/java/org/eclipse/tycho/p2/tools/mirroring/MirrorApplicationServiceTest.java b/tycho-bundles/org.eclipse.tycho.p2.tools.tests/src/test/java/org/eclipse/tycho/p2/tools/mirroring/MirrorApplicationServiceTest.java index 4fee40a478..0c096bafcd 100644 --- a/tycho-bundles/org.eclipse.tycho.p2.tools.tests/src/test/java/org/eclipse/tycho/p2/tools/mirroring/MirrorApplicationServiceTest.java +++ b/tycho-bundles/org.eclipse.tycho.p2.tools.tests/src/test/java/org/eclipse/tycho/p2/tools/mirroring/MirrorApplicationServiceTest.java @@ -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 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()); @@ -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"); @@ -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()); @@ -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()); @@ -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(""))); } @@ -184,7 +184,7 @@ public void testMirrorForSeedWithNullIU() throws Exception { List 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()); } diff --git a/tycho-p2/tycho-p2-repository-plugin/src/main/java/org/eclipse/tycho/plugins/p2/repository/AssembleRepositoryMojo.java b/tycho-p2/tycho-p2-repository-plugin/src/main/java/org/eclipse/tycho/plugins/p2/repository/AssembleRepositoryMojo.java index 86e1b519a5..5108c43e08 100644 --- a/tycho-p2/tycho-p2-repository-plugin/src/main/java/org/eclipse/tycho/plugins/p2/repository/AssembleRepositoryMojo.java +++ b/tycho-p2/tycho-p2-repository-plugin/src/main/java/org/eclipse/tycho/plugins/p2/repository/AssembleRepositoryMojo.java @@ -84,6 +84,15 @@ public class AssembleRepositoryMojo extends AbstractRepositoryMojo { @Parameter(defaultValue = "false") private boolean includeAllDependencies; + /** + *

+ * By default, only explicitly mentioned sources are included. Set this parameter to + * true to include all sources that are available and included in this repository. + *

+ */ + @Parameter(defaultValue = "false") + private boolean includeAllSources; + /** *

* Compress the repository index files content.xml and artifacts.xml. @@ -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); }