Skip to content

Commit

Permalink
Move DependencyArtifacts computation into project types
Browse files Browse the repository at this point in the history
Currently DefaultTychoResolver computes the DependencyArtifacts on
behalf of the TychoProject and then set these into the project using a
context value, this has several drawbacks, e.g as it introduce ordering
problem and we need to handle some things special for custom types.

Instead the TychoProject itself should compute the dependencies on
demand as its concrete implementation knows best how to compute these
items and can simply do so on first request.
  • Loading branch information
laeubi committed Dec 8, 2023
1 parent 0d4fe15 commit 9367cc8
Show file tree
Hide file tree
Showing 17 changed files with 232 additions and 234 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ public interface TychoConstants {

// static final String CTX_TARGET_PLATFORM -> moved to TargetPlatform.FINAL_TARGET_PLATFORM_KEY;
static final String CTX_DEPENDENCY_ARTIFACTS = CTX_BASENAME + "/dependencyArtifacts";
static final String CTX_REPOSITORY_REFERENCE = CTX_BASENAME + "/repositoryReference";
static final String CTX_METADATA_ARTIFACT_LOCATION = CTX_BASENAME + "/metadataArtifactLocation";

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import org.eclipse.tycho.ReactorProject;
import org.eclipse.tycho.TargetEnvironment;
import org.eclipse.tycho.TargetPlatform;
import org.eclipse.tycho.core.osgitools.AbstractTychoProject;
import org.eclipse.tycho.p2.target.facade.PomDependencyCollector;

/**
Expand All @@ -46,6 +45,6 @@ public DependencyArtifacts resolveDependencies(MavenSession session, MavenProjec
TargetPlatform targetPlatform, List<ReactorProject> reactorProjects,
DependencyResolverConfiguration resolverConfiguration, List<TargetEnvironment> environments);

public void injectDependenciesIntoMavenModel(MavenProject project, AbstractTychoProject projectType,
public void injectDependenciesIntoMavenModel(MavenProject project, TychoProject projectType,
DependencyArtifacts resolvedDependencies, DependencyArtifacts testDepedencyArtifacts, Logger logger);
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ public interface TychoProject {
*/
public DependencyArtifacts getDependencyArtifacts(ReactorProject project);

/**
* Returns resolved project dependencies. For projects targeting multiple runtime environments,
* returned collection includes artifacts for all supported runtime environments.
*/
public DependencyArtifacts getTestDependencyArtifacts(ReactorProject project);

/**
* Returns resolved project dependencies resolved for specified runtime environment.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@
import org.eclipse.tycho.core.osgitools.OsgiManifest;
import org.eclipse.tycho.core.osgitools.OsgiManifestParserException;
import org.eclipse.tycho.core.resolver.DefaultTargetPlatformConfigurationReader;
import org.eclipse.tycho.core.utils.TychoProjectUtils;
import org.eclipse.tycho.helper.PluginRealmHelper;
import org.eclipse.tycho.model.project.EclipseProject;
import org.eclipse.tycho.targetplatform.TargetDefinition;
Expand Down Expand Up @@ -238,7 +237,7 @@ public Optional<Processor> getBndTychoProject(MavenProject project) {
public Collection<Path> getProjectDependencies(MavenProject project) throws Exception {
Set<Path> dependencySet = new HashSet<>();
TychoProject tychoProject = getTychoProject(project).get();
List<ArtifactDescriptor> dependencies = TychoProjectUtils
List<ArtifactDescriptor> dependencies = tychoProject
.getDependencyArtifacts(DefaultReactorProject.adapt(project)).getArtifacts();
for (ArtifactDescriptor descriptor : dependencies) {
File location = descriptor.fetchArtifact().get();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,11 @@
import org.eclipse.tycho.PackagingType;
import org.eclipse.tycho.ReactorProject;
import org.eclipse.tycho.TychoConstants;
import org.eclipse.tycho.core.TargetPlatformConfiguration;
import org.eclipse.tycho.core.osgitools.BundleReader;
import org.eclipse.tycho.core.osgitools.DefaultReactorProject;
import org.eclipse.tycho.core.osgitools.OsgiManifestParserException;
import org.eclipse.tycho.targetplatform.TargetDefinition.MavenGAVLocation;

public final class MavenDependencyInjector {

Expand Down Expand Up @@ -110,7 +112,8 @@ private static String getProjectKey(Dependency dependency) {
public static void injectMavenDependencies(MavenProject project, DependencyArtifacts dependencies,
DependencyArtifacts testDependencies, BundleReader bundleReader,
Function<ArtifactDescriptor, MavenDependencyDescriptor> descriptorMapping, Logger logger,
RepositorySystem repositorySystem, Settings settings, BuildPropertiesParser buildPropertiesParser) {
RepositorySystem repositorySystem, Settings settings, BuildPropertiesParser buildPropertiesParser,
TargetPlatformConfiguration configuration) {
MavenDependencyInjector generator = new MavenDependencyInjector(project, bundleReader, descriptorMapping,
logger);
for (ArtifactDescriptor artifact : dependencies.getArtifacts()) {
Expand Down Expand Up @@ -148,9 +151,10 @@ public static void injectMavenDependencies(MavenProject project, DependencyArtif
return dependency;
}).filter(Objects::nonNull).toList();
generator.addDependencyList(extraJars);
@SuppressWarnings("unchecked")
Collection<MavenArtifactRepositoryReference> repositoryReferences = (Collection<MavenArtifactRepositoryReference>) reactorProject
.getContextValue(TychoConstants.CTX_REPOSITORY_REFERENCE);
Collection<MavenArtifactRepositoryReference> repositoryReferences = configuration.getTargets().stream()
.flatMap(definition -> definition.getLocations().stream()).filter(MavenGAVLocation.class::isInstance)
.map(MavenGAVLocation.class::cast).flatMap(location -> location.getRepositoryReferences().stream())
.toList();
if (repositoryReferences != null && !repositoryReferences.isEmpty()) {
Map<String, ArtifactRepository> repositoryMap = project.getRemoteArtifactRepositories().stream()
.collect(Collectors.toMap(MavenDependencyInjector::getId, Function.identity(), (a, b) -> a,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,21 +29,24 @@
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.component.annotations.Requirement;
import org.codehaus.plexus.logging.AbstractLogEnabled;
import org.codehaus.plexus.logging.Logger;
import org.eclipse.aether.collection.DependencyCollectionException;
import org.eclipse.aether.resolution.DependencyResolutionException;
import org.eclipse.tycho.DependencyArtifacts;
import org.eclipse.tycho.ExecutionEnvironmentConfiguration;
import org.eclipse.tycho.IArtifactFacade;
import org.eclipse.tycho.ReactorProject;
import org.eclipse.tycho.TargetEnvironment;
import org.eclipse.tycho.TargetPlatform;
import org.eclipse.tycho.TychoConstants;
import org.eclipse.tycho.core.DependencyResolver;
import org.eclipse.tycho.core.DependencyResolverConfiguration;
import org.eclipse.tycho.core.TargetPlatformConfiguration;
import org.eclipse.tycho.core.TychoProject;
import org.eclipse.tycho.core.TychoProjectManager;
import org.eclipse.tycho.core.maven.MavenArtifactFacade;
import org.eclipse.tycho.core.maven.MavenDependenciesResolver;
import org.eclipse.tycho.core.osgitools.targetplatform.MultiEnvironmentDependencyArtifacts;
import org.eclipse.tycho.core.utils.TychoProjectUtils;
import org.eclipse.tycho.p2resolver.PomReactorProjectFacade;
import org.eclipse.tycho.targetplatform.TargetDefinition;
import org.osgi.framework.Filter;
Expand All @@ -56,16 +59,50 @@ public abstract class AbstractTychoProject extends AbstractLogEnabled implements
private static final String CTX_INITIAL_MAVEN_DEPENDENCIES = CTX_OSGI_BUNDLE_BASENAME + "/initialDependencies";

@Requirement
MavenDependenciesResolver projectDependenciesResolver;
protected MavenDependenciesResolver projectDependenciesResolver;
@Requirement
LegacySupport legacySupport;
protected LegacySupport legacySupport;

@Requirement
TychoProjectManager projectManager;
protected TychoProjectManager projectManager;

@Requirement
protected Logger logger;

@Requirement(hint = "p2")
protected DependencyResolver dependencyResolver;

@Override
public DependencyArtifacts getDependencyArtifacts(ReactorProject project) {
return TychoProjectUtils.getDependencyArtifacts(project);
public DependencyArtifacts getDependencyArtifacts(ReactorProject reactorProject) {
return reactorProject.computeContextValue(TychoConstants.CTX_DEPENDENCY_ARTIFACTS, () -> {
if (logger != null) {
logger.info("Resolving dependencies of " + reactorProject);
}
MavenSession mavenSession = getMavenSession(reactorProject);
MavenProject mavenProject = getMavenProject(reactorProject);
List<ReactorProject> reactorProjects = DefaultReactorProject.adapt(mavenSession);
TargetPlatform preliminaryTargetPlatform = dependencyResolver.computePreliminaryTargetPlatform(mavenSession,
mavenProject, reactorProjects);
TargetPlatformConfiguration configuration = projectManager.getTargetPlatformConfiguration(mavenProject);
DependencyResolverConfiguration resolverConfiguration = configuration.getDependencyResolverConfiguration();
DependencyArtifacts dependencyArtifacts = dependencyResolver.resolveDependencies(mavenSession, mavenProject,
preliminaryTargetPlatform, reactorProjects, resolverConfiguration, configuration.getEnvironments());
if (logger != null) {
if (logger.isDebugEnabled() && DebugUtils.isDebugEnabled(mavenSession, mavenProject)) {
StringBuilder sb = new StringBuilder();
sb.append("Resolved target platform for ").append(reactorProject).append("\n");
dependencyArtifacts.toDebugString(sb, " ");
logger.debug(sb.toString());
}
}
return dependencyArtifacts;
});

}

@Override
public DependencyArtifacts getTestDependencyArtifacts(ReactorProject project) {
return (DependencyArtifacts) project.getContextValue(TychoConstants.CTX_TEST_DEPENDENCY_ARTIFACTS);
}

@Override
Expand All @@ -83,16 +120,6 @@ public DependencyArtifacts getDependencyArtifacts(ReactorProject project, Target
return platform;
}

public void setDependencyArtifacts(MavenSession session, ReactorProject project,
DependencyArtifacts dependencyArtifacts) {
project.setContextValue(TychoConstants.CTX_DEPENDENCY_ARTIFACTS, dependencyArtifacts);
}

public void setTestDependencyArtifacts(MavenSession session, ReactorProject project,
DependencyArtifacts dependencyArtifacts) {
project.setContextValue(TychoConstants.CTX_TEST_DEPENDENCY_ARTIFACTS, dependencyArtifacts);
}

public void setupProject(MavenSession session, MavenProject project) {
ReactorProject reactorProject = DefaultReactorProject.adapt(project);
reactorProject.setContextValue(CTX_MAVEN_SESSION, session);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,15 +183,20 @@ public File getArtifact(String artifactClassifier) {
@Override
public Object getContextValue(String key) {
Object value = context.get(key);
if (value instanceof LazyValue<?> lazy) {
return lazy.get();
}
return (value != null) ? value : project.getContextValue(key);
}

@SuppressWarnings("unchecked")
@Override
public <T> T computeContextValue(String key, Supplier<T> initalValueSupplier) {
return (T) context.computeIfAbsent(key, nil -> {
return initalValueSupplier.get();
});
Object value = context.computeIfAbsent(key, nil -> new LazyValue<>(initalValueSupplier));
if (value instanceof LazyValue<?> lazy) {
return (T) lazy.get();
}
return (T) value;
}

@Override
Expand Down Expand Up @@ -284,4 +289,23 @@ public <T> T adapt(Class<T> target) {
return null;
}

private static final class LazyValue<T> implements Supplier<T> {

private Supplier<T> initalValueSupplier;
private T value;

LazyValue(Supplier<T> initalValueSupplier) {
this.initalValueSupplier = initalValueSupplier;
}

@Override
public synchronized T get() {
if (value == null) {
value = initalValueSupplier.get();
}
return value;
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import org.codehaus.plexus.component.annotations.Requirement;
import org.codehaus.plexus.logging.Logger;
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
import org.eclipse.equinox.p2.metadata.IRequirement;
import org.eclipse.osgi.container.namespaces.EclipsePlatformNamespace;
import org.eclipse.osgi.internal.framework.FilterImpl;
import org.eclipse.tycho.ArtifactDescriptor;
Expand All @@ -52,15 +53,18 @@
import org.eclipse.tycho.DefaultArtifactKey;
import org.eclipse.tycho.DependencyArtifacts;
import org.eclipse.tycho.ExecutionEnvironmentConfiguration;
import org.eclipse.tycho.OptionalResolutionAction;
import org.eclipse.tycho.PackagingType;
import org.eclipse.tycho.PlatformPropertiesUtils;
import org.eclipse.tycho.ReactorProject;
import org.eclipse.tycho.ResolvedArtifactKey;
import org.eclipse.tycho.TargetEnvironment;
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.BundleProject;
import org.eclipse.tycho.core.DependencyResolverConfiguration;
import org.eclipse.tycho.core.PluginDescription;
import org.eclipse.tycho.core.TargetPlatformConfiguration;
import org.eclipse.tycho.core.TychoProject;
Expand All @@ -71,8 +75,8 @@
import org.eclipse.tycho.core.osgitools.project.BuildOutputJar;
import org.eclipse.tycho.core.osgitools.project.EclipsePluginProject;
import org.eclipse.tycho.core.osgitools.project.EclipsePluginProjectImpl;
import org.eclipse.tycho.core.osgitools.targetplatform.DefaultDependencyArtifacts;
import org.eclipse.tycho.core.resolver.P2ResolverFactory;
import org.eclipse.tycho.core.utils.TychoProjectUtils;
import org.eclipse.tycho.model.Feature;
import org.eclipse.tycho.model.ProductConfiguration;
import org.eclipse.tycho.model.UpdateSite;
Expand Down Expand Up @@ -677,8 +681,42 @@ public List<ClasspathEntry> getTestClasspath(ReactorProject reactorProject, bool
}
}

public DependencyArtifacts getTestDependencyArtifacts(ReactorProject project) {
return TychoProjectUtils.getTestDependencyArtifacts(project);
@Override
public DependencyArtifacts getTestDependencyArtifacts(ReactorProject reactorProject) {
return reactorProject.computeContextValue(TychoConstants.CTX_TEST_DEPENDENCY_ARTIFACTS, () -> {
List<ArtifactKey> testDependencies = getExtraTestRequirements(reactorProject);
if (testDependencies.isEmpty()) {
return new DefaultDependencyArtifacts();
}
logger.info("Resolving test dependencies of " + reactorProject);
MavenSession mavenSession = getMavenSession(reactorProject);
MavenProject mavenProject = getMavenProject(reactorProject);
List<ReactorProject> reactorProjects = DefaultReactorProject.adapt(mavenSession);
TargetPlatformConfiguration configuration = projectManager.getTargetPlatformConfiguration(mavenProject);
DependencyResolverConfiguration resolverConfiguration = configuration.getDependencyResolverConfiguration();
DependencyResolverConfiguration testResolverConfiguration = new DependencyResolverConfiguration() {
@Override
public OptionalResolutionAction getOptionalResolutionAction() {
return resolverConfiguration.getOptionalResolutionAction();
}

@Override
public List<ArtifactKey> getAdditionalArtifacts() {
ArrayList<ArtifactKey> res = new ArrayList<>(resolverConfiguration.getAdditionalArtifacts());
res.addAll(testDependencies);
return res;
}

@Override
public Collection<IRequirement> getAdditionalRequirements() {
return resolverConfiguration.getAdditionalRequirements();
}
};
TargetPlatform preliminaryTargetPlatform = dependencyResolver.computePreliminaryTargetPlatform(mavenSession,
mavenProject, reactorProjects);
return dependencyResolver.resolveDependencies(mavenSession, mavenProject, preliminaryTargetPlatform,
reactorProjects, testResolverConfiguration, configuration.getEnvironments());
});
}

@Override
Expand Down
Loading

0 comments on commit 9367cc8

Please sign in to comment.