diff --git a/target-platform-configuration/src/main/java/org/eclipse/tycho/target/MirrorTargetPlatformMojo.java b/target-platform-configuration/src/main/java/org/eclipse/tycho/target/MirrorTargetPlatformMojo.java index bc7c9c61e3..0818a39ae5 100644 --- a/target-platform-configuration/src/main/java/org/eclipse/tycho/target/MirrorTargetPlatformMojo.java +++ b/target-platform-configuration/src/main/java/org/eclipse/tycho/target/MirrorTargetPlatformMojo.java @@ -13,7 +13,11 @@ package org.eclipse.tycho.target; import java.io.File; +import java.net.URI; import java.util.List; +import java.util.Set; +import java.util.UUID; +import java.util.stream.Collectors; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; @@ -24,9 +28,18 @@ import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.plugins.annotations.ResolutionScope; import org.apache.maven.project.MavenProject; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.equinox.internal.p2.updatesite.SiteCategory; +import org.eclipse.equinox.internal.p2.updatesite.SiteXMLAction; import org.eclipse.equinox.p2.core.IProvisioningAgent; +import org.eclipse.equinox.p2.metadata.IInstallableUnit; +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; import org.eclipse.equinox.p2.repository.artifact.IArtifactRepository; import org.eclipse.equinox.p2.repository.metadata.IMetadataRepository; +import org.eclipse.tycho.PackagingType; import org.eclipse.tycho.ReactorProject; import org.eclipse.tycho.TargetPlatform; import org.eclipse.tycho.TargetPlatformService; @@ -35,6 +48,7 @@ import org.eclipse.tycho.p2.repository.PublishingRepository; import org.eclipse.tycho.p2.tools.FacadeException; import org.eclipse.tycho.p2.tools.mirroring.facade.MirrorApplicationService; +import org.eclipse.tycho.p2maven.InstallableUnitSlicer; import org.eclipse.tycho.p2maven.ListCompositeArtifactRepository; import org.eclipse.tycho.repository.registry.facade.ReactorRepositoryManager; @@ -43,9 +57,11 @@ * what PDE offers with its export deployable feature / plug-in and assembles an update site that * contains everything this particular project depends on. */ -@Mojo(name = "mirror-target-platform", threadSafe = true, requiresDependencyResolution = ResolutionScope.COMPILE, defaultPhase = LifecyclePhase.PREPARE_PACKAGE) +@Mojo(name = "mirror-target-platform", threadSafe = true, requiresDependencyResolution = ResolutionScope.COMPILE, defaultPhase = LifecyclePhase.PACKAGE) public class MirrorTargetPlatformMojo extends AbstractMojo { + private static final SiteXMLAction CATEGORY_FACTORY = new SiteXMLAction((URI) null, (String) null); + @Parameter(property = "project", readonly = true) private MavenProject project; @@ -55,6 +71,9 @@ public class MirrorTargetPlatformMojo extends AbstractMojo { @Parameter(defaultValue = "${project.id}") private String name; + @Parameter(defaultValue = "true") + private boolean includeCategories = true; + @Component private TargetPlatformService platformService; @@ -67,6 +86,9 @@ public class MirrorTargetPlatformMojo extends AbstractMojo { @Component private IProvisioningAgent agent; + @Component + private InstallableUnitSlicer installableUnitSlicer; + @Override public void execute() throws MojoExecutionException, MojoFailureException { ReactorProject reactorProject = DefaultReactorProject.adapt(project); @@ -78,16 +100,54 @@ public void execute() throws MojoExecutionException, MojoFailureException { IArtifactRepository sourceArtifactRepository = targetPlatform.getArtifactRepository(); IMetadataRepository sourceMetadataRepository = targetPlatform.getMetadataRepository(); PublishingRepository publishingRepository = repositoryManager.getPublishingRepository(reactorProject); - getLog().info("Mirroring target platform, this can take a while ..."); try { + IMetadataRepository projectRepository = publishingRepository.getMetadataRepository(); IArtifactRepository artifactRepository = new ListCompositeArtifactRepository( List.of(sourceArtifactRepository, publishingRepository.getArtifactRepository()), agent); IMetadataRepository metadataRepository = new ListCompositeMetadataRepository( - List.of(sourceMetadataRepository, publishingRepository.getMetadataRepository()), agent); - mirrorService.mirrorDirect(artifactRepository, metadataRepository, destination, name); + List.of(sourceMetadataRepository, projectRepository), agent); + IQueryable mirrorUnits; + if (PackagingType.TYPE_ECLIPSE_TARGET_DEFINITION.equals(project.getPackaging())) { + //for a target platform we like to mirror everything... + mirrorUnits = metadataRepository; + } else { + //for everything else we want to mirror only items that are required by the project + try { + IQueryResult query = projectRepository.query(QueryUtil.ALL_UNITS, null); + Set rootIus = query.toSet(); + String label; + String projectName = project.getName(); + if (projectName != null && !projectName.isBlank()) { + label = projectName; + } else { + label = project.getId(); + } + rootIus.add(createCategory(label, query)); + mirrorUnits = installableUnitSlicer.computeDependencies(rootIus, metadataRepository); + } catch (CoreException e) { + throw new MojoFailureException("Failed to compute dependencies to mirror", e); + } + } + Set toMirror = mirrorUnits.query(QueryUtil.ALL_UNITS, null).toSet(); + if (!includeCategories) { + //remove any categories from the result + toMirror.removeIf(QueryUtil::isCategory); + } + getLog().info( + "Mirroring " + toMirror.size() + " unit(s) from the target platform, this can take a while ..."); + mirrorService.mirrorDirect(artifactRepository, new CollectionResult(toMirror), + destination, name); } catch (FacadeException e) { throw new MojoFailureException(e.getMessage(), e.getCause()); } } + private static IInstallableUnit createCategory(String label, IQueryResult result) { + SiteCategory category = new SiteCategory(); + category.setLabel(label); + category.setName("generated.project.category." + UUID.randomUUID()); + return CATEGORY_FACTORY.createCategoryIU(category, + result.stream().filter(iu -> !iu.getId().endsWith(".feature.jar")).collect(Collectors.toSet())); + } + } diff --git a/tycho-core/src/main/java/org/eclipse/tycho/p2/tools/mirroring/facade/MirrorApplicationService.java b/tycho-core/src/main/java/org/eclipse/tycho/p2/tools/mirroring/facade/MirrorApplicationService.java index 2cd396d248..6c9f772622 100644 --- a/tycho-core/src/main/java/org/eclipse/tycho/p2/tools/mirroring/facade/MirrorApplicationService.java +++ b/tycho-core/src/main/java/org/eclipse/tycho/p2/tools/mirroring/facade/MirrorApplicationService.java @@ -17,8 +17,9 @@ import java.util.Collection; import java.util.Map; +import org.eclipse.equinox.p2.metadata.IInstallableUnit; +import org.eclipse.equinox.p2.query.IQueryable; import org.eclipse.equinox.p2.repository.artifact.IArtifactRepository; -import org.eclipse.equinox.p2.repository.metadata.IMetadataRepository; import org.eclipse.tycho.BuildDirectory; import org.eclipse.tycho.DependencySeed; import org.eclipse.tycho.p2.tools.BuildContext; @@ -121,9 +122,11 @@ void mirrorStandalone(RepositoryReferences sources, DestinationRepositoryDescrip * the destination * @param repositoryName * the name of the new repository + * @throws FacadeException */ - void mirrorDirect(IArtifactRepository sourceArtifactRepository, IMetadataRepository sourceMetadataRepository, - File repositoryDestination, String repositoryName) throws FacadeException; + void mirrorDirect(IArtifactRepository sourceArtifactRepository, + IQueryable sourceMetadataRepository, File repositoryDestination, String repositoryName) + throws FacadeException; /** * Modifies the artifact repository to add mapping rules to download Maven released artifacts diff --git a/tycho-core/src/main/java/org/eclipse/tycho/p2tools/MirrorApplicationServiceImpl.java b/tycho-core/src/main/java/org/eclipse/tycho/p2tools/MirrorApplicationServiceImpl.java index 3225af8565..4709107cdb 100644 --- a/tycho-core/src/main/java/org/eclipse/tycho/p2tools/MirrorApplicationServiceImpl.java +++ b/tycho-core/src/main/java/org/eclipse/tycho/p2tools/MirrorApplicationServiceImpl.java @@ -62,6 +62,7 @@ import org.eclipse.equinox.p2.metadata.Version; import org.eclipse.equinox.p2.query.IQuery; import org.eclipse.equinox.p2.query.IQueryResult; +import org.eclipse.equinox.p2.query.IQueryable; import org.eclipse.equinox.p2.query.QueryUtil; import org.eclipse.equinox.p2.repository.IRepositoryManager; import org.eclipse.equinox.p2.repository.artifact.IArtifactDescriptor; @@ -459,8 +460,9 @@ public void addMavenMappingRules(File repository, URI[] mavenRepositories) throw } @Override - public void mirrorDirect(IArtifactRepository sourceArtifactRepository, IMetadataRepository sourceMetadataRepository, - File repositoryDestination, String repositoryName) throws FacadeException { + public void mirrorDirect(IArtifactRepository sourceArtifactRepository, + IQueryable sourceMetadataRepository, File repositoryDestination, String repositoryName) + throws FacadeException { if (repositoryDestination.exists()) { FileUtils.deleteQuietly(repositoryDestination); } diff --git a/tycho-its/projects/TYCHO0383dotQualifierMatching/featureDotQualifier/pom.xml b/tycho-its/projects/TYCHO0383dotQualifierMatching/featureDotQualifier/pom.xml index cbe79ed013..c62a0f93c7 100644 --- a/tycho-its/projects/TYCHO0383dotQualifierMatching/featureDotQualifier/pom.xml +++ b/tycho-its/projects/TYCHO0383dotQualifierMatching/featureDotQualifier/pom.xml @@ -32,11 +32,20 @@ org.eclipse.tycho - tycho-packaging-plugin + target-platform-configuration ${tycho-version} - - true - + + + inject + + mirror-target-platform + + + + + ${project.build.directory}/site + false + diff --git a/tycho-its/projects/TYCHO0439repositoryCategories/pom.xml b/tycho-its/projects/TYCHO0439repositoryCategories/pom.xml index 033073b31c..6a1f543414 100644 --- a/tycho-its/projects/TYCHO0439repositoryCategories/pom.xml +++ b/tycho-its/projects/TYCHO0439repositoryCategories/pom.xml @@ -31,11 +31,20 @@ org.eclipse.tycho - tycho-packaging-plugin + target-platform-configuration ${tycho-version} - - true - + + + inject + + mirror-target-platform + + + + + ${project.build.directory}/site + false + org.eclipse.tycho diff --git a/tycho-its/projects/brokenp2data/pom.xml b/tycho-its/projects/brokenp2data/pom.xml index 41de980146..384f934f90 100644 --- a/tycho-its/projects/brokenp2data/pom.xml +++ b/tycho-its/projects/brokenp2data/pom.xml @@ -25,9 +25,6 @@ org.eclipse.tycho tycho-packaging-plugin ${tycho-version} - - true - diff --git a/tycho-its/projects/custom-bundle-plugin/custom-bundle-parent/custom.bundle.feature/pom.xml b/tycho-its/projects/custom-bundle-plugin/custom-bundle-parent/custom.bundle.feature/pom.xml index 4401d0e80e..3c6ebbeb4f 100644 --- a/tycho-its/projects/custom-bundle-plugin/custom-bundle-parent/custom.bundle.feature/pom.xml +++ b/tycho-its/projects/custom-bundle-plugin/custom-bundle-parent/custom.bundle.feature/pom.xml @@ -15,11 +15,20 @@ org.eclipse.tycho - tycho-packaging-plugin + target-platform-configuration ${tycho-version} - - true - + + + inject + + mirror-target-platform + + + + + ${project.build.directory}/site + false + diff --git a/tycho-packaging-plugin/src/main/java/org/eclipse/tycho/packaging/PackageFeatureMojo.java b/tycho-packaging-plugin/src/main/java/org/eclipse/tycho/packaging/PackageFeatureMojo.java index c4c393f64c..74319d9c3d 100644 --- a/tycho-packaging-plugin/src/main/java/org/eclipse/tycho/packaging/PackageFeatureMojo.java +++ b/tycho-packaging-plugin/src/main/java/org/eclipse/tycho/packaging/PackageFeatureMojo.java @@ -103,10 +103,13 @@ public class PackageFeatureMojo extends AbstractTychoPackagingMojo { private String finalName; /** - * If set to true, standard eclipse update site directory with feature content will - * be created under target folder. - */ + * If set to true, standard eclipse update site directory with + * feature content will be created under target folder. + * + * @deprecated use the new mirror-target-platform instead. + */ @Parameter(defaultValue = "false") + @Deprecated private boolean deployableFeature = false; @Parameter(defaultValue = "${project.build.directory}/site")