From 6f583b8e0a39e15101bd7323642705e3c63fab93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20L=C3=A4ubrich?= Date: Mon, 31 Jul 2023 09:09:43 +0200 Subject: [PATCH] Support repository references in IU target locations Currently Tycho ignores repository references when resolving IU locations. This now adds support for referenced repositories so Tycho can resolve from there as well. --- .../ListCompositeArtifactRepository.java | 12 +-- .../repository/P2RepositoryManager.java | 2 +- .../ListCompositeMetadataRepository.java | 11 +-- .../resolver/URITargetDefinitionContent.java | 88 +++++++++++++++---- .../p2resolver/TargetDefinitionResolver.java | 2 +- 5 files changed, 82 insertions(+), 33 deletions(-) diff --git a/p2-maven-plugin/src/main/java/org/eclipse/tycho/p2maven/ListCompositeArtifactRepository.java b/p2-maven-plugin/src/main/java/org/eclipse/tycho/p2maven/ListCompositeArtifactRepository.java index 87a7490a1b..fc77efbc8a 100644 --- a/p2-maven-plugin/src/main/java/org/eclipse/tycho/p2maven/ListCompositeArtifactRepository.java +++ b/p2-maven-plugin/src/main/java/org/eclipse/tycho/p2maven/ListCompositeArtifactRepository.java @@ -37,6 +37,7 @@ 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.ICompositeRepository; import org.eclipse.equinox.p2.repository.artifact.IArtifactDescriptor; import org.eclipse.equinox.p2.repository.artifact.IArtifactRepository; @@ -57,8 +58,8 @@ public class ListCompositeArtifactRepository extends AbstractArtifactRepository public final List artifactRepositories; - public ListCompositeArtifactRepository(IProvisioningAgent agent, - List artifactRepositories) { + public ListCompositeArtifactRepository(List artifactRepositories, + IProvisioningAgent agent) { super(agent, null, IArtifactRepositoryManager.TYPE_COMPOSITE_REPOSITORY, null, null, null, null, null); try { setLocation(new URI("list:" + UUID.randomUUID())); @@ -74,12 +75,7 @@ public IQueryResult query(IQuery query, IProgressMon if (size == 1) { return artifactRepositories.get(0).query(query, monitor); } - Collector collector = new Collector<>(); - SubMonitor subMonitor = SubMonitor.convert(monitor, size); - for (IArtifactRepository repository : artifactRepositories) { - collector.addAll(repository.query(query, subMonitor.split(1))); - } - return collector; + return QueryUtil.compoundQueryable(artifactRepositories).query(query, IProgressMonitor.nullSafe(monitor)); } @Override diff --git a/p2-maven-plugin/src/main/java/org/eclipse/tycho/p2maven/repository/P2RepositoryManager.java b/p2-maven-plugin/src/main/java/org/eclipse/tycho/p2maven/repository/P2RepositoryManager.java index e34ebd32b0..95b7295d5a 100644 --- a/p2-maven-plugin/src/main/java/org/eclipse/tycho/p2maven/repository/P2RepositoryManager.java +++ b/p2-maven-plugin/src/main/java/org/eclipse/tycho/p2maven/repository/P2RepositoryManager.java @@ -93,7 +93,7 @@ public IArtifactRepository getCompositeArtifactRepository(Collection for (Repository repository : repositories) { childs.add(getArtifactRepository(repository)); } - return new ListCompositeArtifactRepository(agent, childs); + return new ListCompositeArtifactRepository(childs, agent); } /** diff --git a/tycho-core/src/main/java/org/eclipse/tycho/p2/repository/ListCompositeMetadataRepository.java b/tycho-core/src/main/java/org/eclipse/tycho/p2/repository/ListCompositeMetadataRepository.java index 30fa3e2043..90f55907a5 100644 --- a/tycho-core/src/main/java/org/eclipse/tycho/p2/repository/ListCompositeMetadataRepository.java +++ b/tycho-core/src/main/java/org/eclipse/tycho/p2/repository/ListCompositeMetadataRepository.java @@ -20,12 +20,12 @@ import java.util.UUID; import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.SubMonitor; import org.eclipse.equinox.p2.core.IProvisioningAgent; import org.eclipse.equinox.p2.metadata.IInstallableUnit; -import org.eclipse.equinox.p2.query.Collector; 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.ICompositeRepository; import org.eclipse.equinox.p2.repository.IRepositoryReference; import org.eclipse.equinox.p2.repository.artifact.IArtifactRepositoryManager; @@ -61,12 +61,7 @@ public IQueryResult query(IQuery query, IPro if (size == 1) { return metadataRepositories.get(0).query(query, monitor); } - Collector collector = new Collector<>(); - SubMonitor subMonitor = SubMonitor.convert(monitor, size); - for (IMetadataRepository repository : metadataRepositories) { - collector.addAll(repository.query(query, subMonitor.split(1))); - } - return collector; + return QueryUtil.compoundQueryable(metadataRepositories).query(query, IProgressMonitor.nullSafe(monitor)); } @Override diff --git a/tycho-core/src/main/java/org/eclipse/tycho/p2/resolver/URITargetDefinitionContent.java b/tycho-core/src/main/java/org/eclipse/tycho/p2/resolver/URITargetDefinitionContent.java index 9e37d989e5..0145af5faa 100644 --- a/tycho-core/src/main/java/org/eclipse/tycho/p2/resolver/URITargetDefinitionContent.java +++ b/tycho-core/src/main/java/org/eclipse/tycho/p2/resolver/URITargetDefinitionContent.java @@ -13,6 +13,10 @@ package org.eclipse.tycho.p2.resolver; import java.net.URI; +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.SubMonitor; @@ -21,18 +25,22 @@ import org.eclipse.equinox.p2.metadata.IInstallableUnit; import org.eclipse.equinox.p2.query.IQuery; import org.eclipse.equinox.p2.query.IQueryResult; +import org.eclipse.equinox.p2.repository.IRepository; +import org.eclipse.equinox.p2.repository.IRepositoryReference; import org.eclipse.equinox.p2.repository.artifact.IArtifactRepository; import org.eclipse.equinox.p2.repository.metadata.IMetadataRepository; import org.eclipse.equinox.p2.repository.metadata.IMetadataRepositoryManager; import org.eclipse.tycho.IRepositoryIdManager; import org.eclipse.tycho.p2.repository.LazyArtifactRepository; +import org.eclipse.tycho.p2.repository.ListCompositeMetadataRepository; import org.eclipse.tycho.p2.repository.RepositoryArtifactProvider; +import org.eclipse.tycho.p2maven.ListCompositeArtifactRepository; import org.eclipse.tycho.targetplatform.TargetDefinitionContent; import org.eclipse.tycho.targetplatform.TargetDefinitionResolutionException; public class URITargetDefinitionContent implements TargetDefinitionContent { - private final IArtifactRepository artifactRepository; + private IArtifactRepository artifactRepository; private IProvisioningAgent agent; private URI location; private String id; @@ -42,9 +50,6 @@ public URITargetDefinitionContent(IProvisioningAgent agent, URI location, String this.agent = agent; this.location = location; this.id = id; - //artifact repositories are resolved lazy here as loading them might not be always necessary (e.g only dependency resolution required) and could be expensive (net I/O) - artifactRepository = new LazyArtifactRepository(agent, location, RepositoryArtifactProvider::loadRepository); - } @Override @@ -61,28 +66,81 @@ public IMetadataRepository getMetadataRepository() { return metadataRepository; } - public synchronized void preload(IProgressMonitor monitor) { + private synchronized void preload(IProgressMonitor monitor) { if (metadataRepository == null) { - IMetadataRepositoryManager metadataManager = agent.getService(IMetadataRepositoryManager.class); - if (metadataManager == null) { - throw new TargetDefinitionResolutionException( - "IMetadataRepositoryManager is null in IProvisioningAgent"); + Map metadataRepositoriesMap = new LinkedHashMap<>(); + Map artifactRepositoriesMap = new LinkedHashMap<>(); + loadMetadataRepositories(location, id, metadataRepositoriesMap, artifactRepositoriesMap, agent, monitor); + loadArtifactRepositories(location, artifactRepositoriesMap, agent); + Collection metadataRepositories = metadataRepositoriesMap.values(); + if (metadataRepositories.size() == 1) { + metadataRepository = metadataRepositories.iterator().next(); + } else { + metadataRepository = new ListCompositeMetadataRepository(List.copyOf(metadataRepositories), agent); } + Collection artifactRepositories = artifactRepositoriesMap.values(); + if (artifactRepositories.size() == 1) { + artifactRepository = artifactRepositories.iterator().next(); + } else { + artifactRepository = new ListCompositeArtifactRepository(List.copyOf(artifactRepositories), agent); + } + } + } + + private static void loadMetadataRepositories(URI uri, String id, Map metadataRepositories, + Map artifactRepositories, IProvisioningAgent agent, IProgressMonitor monitor) { + URI key = uri.normalize(); + if (metadataRepositories.containsKey(key)) { + //already loaded... + return; + } + SubMonitor subMonitor = SubMonitor.convert(monitor, 100); + IMetadataRepositoryManager metadataManager = agent.getService(IMetadataRepositoryManager.class); + if (metadataManager == null) { + throw new TargetDefinitionResolutionException("IMetadataRepositoryManager is null in IProvisioningAgent"); + } + try { IRepositoryIdManager repositoryIdManager = agent.getService(IRepositoryIdManager.class); if (repositoryIdManager != null) { - repositoryIdManager.addMapping(id, location); + repositoryIdManager.addMapping(id, uri); } - try { - metadataRepository = metadataManager.loadRepository(location, monitor); - } catch (ProvisionException e) { - throw new TargetDefinitionResolutionException( - "Failed to load p2 metadata repository from location " + location, e); + IMetadataRepository repository = metadataManager.loadRepository(uri, subMonitor.split(50)); + metadataRepositories.put(key, repository); + Collection references = repository.getReferences(); + subMonitor.setWorkRemaining(references.size()); + for (IRepositoryReference reference : references) { + if ((reference.getOptions() | IRepository.ENABLED) != 0) { + if (reference.getType() == IRepository.TYPE_METADATA) { + loadMetadataRepositories(reference.getLocation(), reference.getNickname(), metadataRepositories, + artifactRepositories, agent, subMonitor.split(1)); + } else if (reference.getType() == IRepository.TYPE_ARTIFACT) { + loadArtifactRepositories(reference.getLocation(), artifactRepositories, agent); + subMonitor.worked(1); + } + } } + } catch (ProvisionException e) { + throw new TargetDefinitionResolutionException("Failed to load p2 metadata repository from location " + uri, + e); } + + } + + private static void loadArtifactRepositories(URI uri, Map artifactRepositories, + IProvisioningAgent agent) { + URI key = uri.normalize(); + if (artifactRepositories.containsKey(key)) { + //already loaded... + return; + } + //artifact repositories are resolved lazy here as loading them might not be always necessary (e.g only dependency resolution required) and could be expensive (net I/O) + artifactRepositories.put(key, + new LazyArtifactRepository(agent, uri, RepositoryArtifactProvider::loadRepository)); } @Override public IArtifactRepository getArtifactRepository() { + preload(null); return artifactRepository; } diff --git a/tycho-core/src/main/java/org/eclipse/tycho/p2resolver/TargetDefinitionResolver.java b/tycho-core/src/main/java/org/eclipse/tycho/p2resolver/TargetDefinitionResolver.java index 0b3d111fc0..fbd7c862e8 100644 --- a/tycho-core/src/main/java/org/eclipse/tycho/p2resolver/TargetDefinitionResolver.java +++ b/tycho-core/src/main/java/org/eclipse/tycho/p2resolver/TargetDefinitionResolver.java @@ -258,7 +258,7 @@ public IMetadataRepository getMetadataRepository() { @Override public IArtifactRepository getArtifactRepository() { if (artifactRepository == null) { - artifactRepository = new ListCompositeArtifactRepository(provisioningAgent, artifactRepositories); + artifactRepository = new ListCompositeArtifactRepository(artifactRepositories, provisioningAgent); } return artifactRepository; }