Skip to content

Commit

Permalink
Add support for resolving target platform projects
Browse files Browse the repository at this point in the history
Currently target-platform projects do not have any resolved
dependencies, this has a few disadvantages:

- if one want to see the dependency tree it is empty
- if one wants to mirror a target platform this can't be performed

This adds support for target platform projects to resolve and have their
dependencies injected to support such advanced use-cases.
  • Loading branch information
laeubi committed Dec 17, 2023
1 parent 77acf50 commit 62523f1
Show file tree
Hide file tree
Showing 2 changed files with 142 additions and 25 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/*******************************************************************************
* Copyright (c) 2023 Christoph Läubrich and others.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Christoph Läubrich - initial API and implementation
*******************************************************************************/
package org.eclipse.tycho.core.osgitools;

import java.io.File;
import java.util.List;
import java.util.Set;

import org.apache.maven.execution.MavenSession;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.component.annotations.Component;
import org.eclipse.equinox.p2.metadata.IArtifactKey;
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
import org.eclipse.tycho.ArtifactKey;
import org.eclipse.tycho.DefaultArtifactKey;
import org.eclipse.tycho.DependencyArtifacts;
import org.eclipse.tycho.PackagingType;
import org.eclipse.tycho.ReactorProject;
import org.eclipse.tycho.TargetPlatform;
import org.eclipse.tycho.TychoConstants;
import org.eclipse.tycho.core.ArtifactDependencyVisitor;
import org.eclipse.tycho.core.ArtifactDependencyWalker;
import org.eclipse.tycho.core.TychoProject;
import org.eclipse.tycho.core.osgitools.targetplatform.DefaultDependencyArtifacts;
import org.eclipse.tycho.core.resolver.target.ArtifactTypeHelper;
import org.eclipse.tycho.model.Feature;
import org.eclipse.tycho.model.ProductConfiguration;
import org.eclipse.tycho.model.UpdateSite;
import org.eclipse.tycho.targetplatform.P2TargetPlatform;

@Component(role = TychoProject.class, hint = PackagingType.TYPE_ECLIPSE_TARGET_DEFINITION)
public class TargetPlatformProject extends AbstractTychoProject {

@Override
public ArtifactDependencyWalker getDependencyWalker(ReactorProject project) {
return new ArtifactDependencyWalker() {

@Override
public void walk(ArtifactDependencyVisitor visitor) {

}

@Override
public void traverseUpdateSite(UpdateSite site, ArtifactDependencyVisitor visitor) {

}

@Override
public void traverseProduct(ProductConfiguration productConfiguration, ArtifactDependencyVisitor visitor) {

}

@Override
public void traverseFeature(File location, Feature feature, ArtifactDependencyVisitor visitor) {

}
};
}

@Override
public ArtifactKey getArtifactKey(ReactorProject project) {
return new DefaultArtifactKey("target", project.getArtifactId(), project.getVersion());
}

@Override
public DependencyArtifacts getDependencyArtifacts(ReactorProject reactorProject) {
return reactorProject.computeContextValue(TychoConstants.CTX_DEPENDENCY_ARTIFACTS, () -> {
DefaultDependencyArtifacts artifacts = new DefaultDependencyArtifacts(reactorProject);
MavenSession mavenSession = getMavenSession(reactorProject);
MavenProject mavenProject = getMavenProject(reactorProject);
TargetPlatform targetPlatform = dependencyResolver.computePreliminaryTargetPlatform(mavenSession,
mavenProject);
if (targetPlatform instanceof P2TargetPlatform p2) {
Set<IInstallableUnit> installableUnits = p2.getInstallableUnits();
for (IInstallableUnit iu : installableUnits) {
for (IArtifactKey key : iu.getArtifacts()) {
ArtifactKey artifactKey = ArtifactTypeHelper.toTychoArtifactKey(iu, key);
artifacts.addArtifactFile(artifactKey, () -> targetPlatform.getArtifactLocation(artifactKey),
List.of(iu));
}
}
}
return artifacts;
});
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
import org.eclipse.tycho.MavenDependencyDescriptor;
import org.eclipse.tycho.MavenRepositoryLocation;
import org.eclipse.tycho.OptionalResolutionAction;
import org.eclipse.tycho.PackagingType;
import org.eclipse.tycho.ReactorProject;
import org.eclipse.tycho.TargetEnvironment;
import org.eclipse.tycho.TargetPlatform;
Expand All @@ -83,6 +84,7 @@
import org.eclipse.tycho.core.resolver.P2ResolutionResult;
import org.eclipse.tycho.core.resolver.P2Resolver;
import org.eclipse.tycho.core.resolver.P2ResolverFactory;
import org.eclipse.tycho.core.resolver.shared.IncludeSourceMode;
import org.eclipse.tycho.core.resolver.shared.PomDependencies;
import org.eclipse.tycho.helper.PluginRealmHelper;
import org.eclipse.tycho.p2.metadata.DependencyMetadataGenerator;
Expand All @@ -95,6 +97,8 @@
import org.eclipse.tycho.repository.registry.facade.ReactorRepositoryManager;
import org.eclipse.tycho.resolver.P2MetadataProvider;
import org.eclipse.tycho.targetplatform.TargetDefinitionFile;
import org.eclipse.tycho.targetplatform.TargetPlatformArtifactResolver;
import org.eclipse.tycho.targetplatform.TargetResolveException;

@Component(role = DependencyResolver.class, hint = P2DependencyResolver.ROLE_HINT, instantiationStrategy = "per-lookup")
public class P2DependencyResolver implements DependencyResolver, Initializable {
Expand Down Expand Up @@ -149,22 +153,26 @@ public class P2DependencyResolver implements DependencyResolver, Initializable {
@Override
public void setupProjects(final MavenSession session, final MavenProject project,
final ReactorProject reactorProject) {
TargetPlatformConfiguration configuration = projectManager.getTargetPlatformConfiguration(project);
List<TargetEnvironment> environments = configuration.getEnvironments();
Collection<IDependencyMetadata> metadataMap = getDependencyMetadata(session, project, environments,
OptionalResolutionAction.OPTIONAL);
Map<DependencyMetadataType, Set<IInstallableUnit>> typeMap = new TreeMap<>();
for (DependencyMetadataType type : DependencyMetadataType.values()) {
typeMap.put(type, new LinkedHashSet<>());
}
for (IDependencyMetadata metadata : metadataMap) {
typeMap.forEach((key, value) -> value.addAll(metadata.getDependencyMetadata(key)));
}
Set<IInstallableUnit> initial = new HashSet<>();
typeMap.forEach((key, value) -> {
reactorProject.setDependencyMetadata(key, value);
initial.addAll(value);
});
if (PackagingType.TYPE_ECLIPSE_TARGET_DEFINITION.equals(project.getPackaging())) {
//Target projects do not have any (initial) dependency metadata
} else {
TargetPlatformConfiguration configuration = projectManager.getTargetPlatformConfiguration(project);
List<TargetEnvironment> environments = configuration.getEnvironments();
Collection<IDependencyMetadata> metadataMap = getDependencyMetadata(session, project, environments,
OptionalResolutionAction.OPTIONAL);
Map<DependencyMetadataType, Set<IInstallableUnit>> typeMap = new TreeMap<>();
for (DependencyMetadataType type : DependencyMetadataType.values()) {
typeMap.put(type, new LinkedHashSet<>());
}
for (IDependencyMetadata metadata : metadataMap) {
typeMap.forEach((key, value) -> value.addAll(metadata.getDependencyMetadata(key)));
}
typeMap.forEach((key, value) -> {
reactorProject.setDependencyMetadata(key, value);
initial.addAll(value);
});
}
reactorProject.setDependencyMetadata(DependencyMetadataType.INITIAL, initial);
}

Expand Down Expand Up @@ -202,23 +210,35 @@ public TargetPlatform computePreliminaryTargetPlatform(MavenSession mavenSession
logger.debug("Computing preliminary target platform for " + mavenProject);
List<ReactorProject> reactorProjects = DefaultReactorProject.adapt(mavenSession);
TargetPlatformConfiguration configuration = projectManager.getTargetPlatformConfiguration(mavenProject);
ExecutionEnvironmentConfiguration ee = projectManager.getExecutionEnvironmentConfiguration(mavenProject);

TargetPlatformConfigurationStub tpConfiguration = new TargetPlatformConfigurationStub();
ExecutionEnvironmentConfiguration ee = projectManager.getExecutionEnvironmentConfiguration(mavenProject);
for (ArtifactRepository repository : mavenProject.getRemoteArtifactRepositories()) {
addEntireP2RepositoryToTargetPlatform(repository, tpConfiguration);
}

tpConfiguration.setEnvironments(configuration.getEnvironments());
for (TargetDefinitionFile target : configuration.getTargets()) {
tpConfiguration.addTargetDefinition(target);
}

tpConfiguration.addFilters(configuration.getFilters());
tpConfiguration.setIncludeSourceMode(configuration.getTargetDefinitionIncludeSourceMode());
tpConfiguration
.setIgnoreLocalArtifacts(configuration.getIgnoreLocalArtifacts() == LocalArtifactHandling.ignore);
tpConfiguration.setReferencedRepositoryMode(configuration.getReferencedRepositoryMode());
if (PackagingType.TYPE_ECLIPSE_TARGET_DEFINITION.equals(mavenProject.getPackaging())) {
//for target definition project itself we only want the main target to be considered
try {
File targetFile = TargetPlatformArtifactResolver.getMainTargetFile(mavenProject);
TargetDefinitionFile targetDefinitionFile = TargetDefinitionFile.read(targetFile);
tpConfiguration.addTargetDefinition(targetDefinitionFile);
} catch (TargetResolveException e) {
logger.warn("Can't read main target definition file from project " + mavenProject.getId(), e);
}
//also we always want to ignore sources
tpConfiguration.setIncludeSourceMode(IncludeSourceMode.ignore);
//and local artifacts
tpConfiguration.setIgnoreLocalArtifacts(true);
} else {
for (TargetDefinitionFile target : configuration.getTargets()) {
tpConfiguration.addTargetDefinition(target);
}
tpConfiguration.setIncludeSourceMode(configuration.getTargetDefinitionIncludeSourceMode());
tpConfiguration.setIgnoreLocalArtifacts(
configuration.getIgnoreLocalArtifacts() == LocalArtifactHandling.ignore);
}
return tpFactory.createTargetPlatform(tpConfiguration, ee, reactorProjects, reactorProject);
});
}
Expand Down

0 comments on commit 62523f1

Please sign in to comment.