Skip to content

Commit

Permalink
Support repository references in IU target locations
Browse files Browse the repository at this point in the history
Currently Tycho ignores repository references when resolving IU
locations.

This now adds support for referenced repositories so Tycho can resolve
from there as well.
  • Loading branch information
laeubi committed Jul 31, 2023
1 parent 0ffb59a commit 6f583b8
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -57,8 +58,8 @@ public class ListCompositeArtifactRepository extends AbstractArtifactRepository

public final List<IArtifactRepository> artifactRepositories;

public ListCompositeArtifactRepository(IProvisioningAgent agent,
List<? extends IArtifactRepository> artifactRepositories) {
public ListCompositeArtifactRepository(List<? extends IArtifactRepository> artifactRepositories,
IProvisioningAgent agent) {
super(agent, null, IArtifactRepositoryManager.TYPE_COMPOSITE_REPOSITORY, null, null, null, null, null);
try {
setLocation(new URI("list:" + UUID.randomUUID()));
Expand All @@ -74,12 +75,7 @@ public IQueryResult<IArtifactKey> query(IQuery<IArtifactKey> query, IProgressMon
if (size == 1) {
return artifactRepositories.get(0).query(query, monitor);
}
Collector<IArtifactKey> 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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ public IArtifactRepository getCompositeArtifactRepository(Collection<Repository>
for (Repository repository : repositories) {
childs.add(getArtifactRepository(repository));
}
return new ListCompositeArtifactRepository(agent, childs);
return new ListCompositeArtifactRepository(childs, agent);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -61,12 +61,7 @@ public IQueryResult<IInstallableUnit> query(IQuery<IInstallableUnit> query, IPro
if (size == 1) {
return metadataRepositories.get(0).query(query, monitor);
}
Collector<IInstallableUnit> 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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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
Expand All @@ -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<URI, IMetadataRepository> metadataRepositoriesMap = new LinkedHashMap<>();
Map<URI, IArtifactRepository> artifactRepositoriesMap = new LinkedHashMap<>();
loadMetadataRepositories(location, id, metadataRepositoriesMap, artifactRepositoriesMap, agent, monitor);
loadArtifactRepositories(location, artifactRepositoriesMap, agent);
Collection<IMetadataRepository> metadataRepositories = metadataRepositoriesMap.values();
if (metadataRepositories.size() == 1) {
metadataRepository = metadataRepositories.iterator().next();
} else {
metadataRepository = new ListCompositeMetadataRepository(List.copyOf(metadataRepositories), agent);
}
Collection<IArtifactRepository> 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<URI, IMetadataRepository> metadataRepositories,
Map<URI, IArtifactRepository> 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<IRepositoryReference> 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<URI, IArtifactRepository> 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;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down

0 comments on commit 6f583b8

Please sign in to comment.