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] Add a category for mirrored feature / bundle project and filter IUs #3332

Merged
merged 1 commit into from
Jan 7, 2024
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 @@ -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;
Expand All @@ -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;
Expand All @@ -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;

Expand All @@ -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;

Expand All @@ -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;

Expand All @@ -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);
Expand All @@ -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<IInstallableUnit> 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<IInstallableUnit> query = projectRepository.query(QueryUtil.ALL_UNITS, null);
Set<IInstallableUnit> 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<IInstallableUnit> 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<IInstallableUnit>(toMirror),
destination, name);
} catch (FacadeException e) {
throw new MojoFailureException(e.getMessage(), e.getCause());
}
}

private static IInstallableUnit createCategory(String label, IQueryResult<IInstallableUnit> 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()));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<IInstallableUnit> sourceMetadataRepository, File repositoryDestination, String repositoryName)
throws FacadeException;

/**
* Modifies the artifact repository to add mapping rules to download Maven released artifacts
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<IInstallableUnit> sourceMetadataRepository, File repositoryDestination, String repositoryName)
throws FacadeException {
if (repositoryDestination.exists()) {
FileUtils.deleteQuietly(repositoryDestination);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,20 @@

<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-packaging-plugin</artifactId>
<artifactId>target-platform-configuration</artifactId>
<version>${tycho-version}</version>
<configuration>
<deployableFeature>true</deployableFeature>
</configuration>
<executions>
<execution>
<id>inject</id>
<goals>
<goal>mirror-target-platform</goal>
</goals>
</execution>
</executions>
<configuration>
<destination>${project.build.directory}/site</destination>
<includeCategories>false</includeCategories>
</configuration>
</plugin>

<plugin>
Expand Down
17 changes: 13 additions & 4 deletions tycho-its/projects/TYCHO0439repositoryCategories/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,20 @@
</plugin>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-packaging-plugin</artifactId>
<artifactId>target-platform-configuration</artifactId>
<version>${tycho-version}</version>
<configuration>
<deployableFeature>true</deployableFeature>
</configuration>
<executions>
<execution>
<id>inject</id>
<goals>
<goal>mirror-target-platform</goal>
</goals>
</execution>
</executions>
<configuration>
<destination>${project.build.directory}/site</destination>
<includeCategories>false</includeCategories>
</configuration>
</plugin>
<plugin>
<groupId>org.eclipse.tycho</groupId>
Expand Down
3 changes: 0 additions & 3 deletions tycho-its/projects/brokenp2data/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,6 @@
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-packaging-plugin</artifactId>
<version>${tycho-version}</version>
<configuration>
<deployableFeature>true</deployableFeature>
</configuration>
</plugin>
</plugins>
</build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,20 @@
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-packaging-plugin</artifactId>
<artifactId>target-platform-configuration</artifactId>
<version>${tycho-version}</version>
<configuration>
<deployableFeature>true</deployableFeature>
</configuration>
<executions>
<execution>
<id>inject</id>
<goals>
<goal>mirror-target-platform</goal>
</goals>
</execution>
</executions>
<configuration>
<destination>${project.build.directory}/site</destination>
<includeCategories>false</includeCategories>
</configuration>
</plugin>
</plugins>
</build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,41 +28,41 @@

public class RepositoryCategoriesTest extends AbstractTychoIntegrationTest {

@Test
public void testDeployableFeature() throws Exception {
Verifier v01 = getVerifier("TYCHO0439repositoryCategories");
v01.executeGoal("install");
v01.verifyErrorFreeLog();
@Test
public void testDeployableFeature() throws Exception {
Verifier v01 = getVerifier("TYCHO0439repositoryCategories");
v01.executeGoal("install");
v01.verifyErrorFreeLog();

File site = new File(v01.getBasedir(), "target/site");
Assert.assertTrue(site.isDirectory());
File site = new File(v01.getBasedir(), "target/site");
Assert.assertTrue(site.isDirectory());

File content = new File(site, "content.jar");
Assert.assertTrue(content.isFile());
File content = new File(site, "content.jar");
Assert.assertTrue(content.getAbsolutePath() + " is not a file!", content.isFile());

boolean found = false;
boolean found = false;

XMLParser parser = new XMLParser();
Document document = null;
ZipFile contentJar = new ZipFile(content);
try {
ZipEntry contentXmlEntry = contentJar.getEntry("content.xml");
document = parser.parse(new XMLIOSource(contentJar.getInputStream(contentXmlEntry)));
} finally {
contentJar.close();
}
Element repository = document.getRootElement();
all_units: for (Element unit : repository.getChild("units").getChildren("unit")) {
for (Element property : unit.getChild("properties").getChildren("property")) {
if ("org.eclipse.equinox.p2.type.category".equals(property.getAttributeValue("name"))
&& Boolean.parseBoolean(property.getAttributeValue("value"))) {
found = true;
break all_units;
}
}
}
XMLParser parser = new XMLParser();
Document document = null;
ZipFile contentJar = new ZipFile(content);
try {
ZipEntry contentXmlEntry = contentJar.getEntry("content.xml");
document = parser.parse(new XMLIOSource(contentJar.getInputStream(contentXmlEntry)));
} finally {
contentJar.close();
}
Element repository = document.getRootElement();
all_units: for (Element unit : repository.getChild("units").getChildren("unit")) {
for (Element property : unit.getChild("properties").getChildren("property")) {
if ("org.eclipse.equinox.p2.type.category".equals(property.getAttributeValue("name"))
&& Boolean.parseBoolean(property.getAttributeValue("value"))) {
found = true;
break all_units;
}
}
}

Assert.assertTrue("Custom category", found);
}
Assert.assertTrue("Custom category is missing: " + content.getAbsolutePath(), found);
}

}
Loading