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

Automatically discover dependencies from a published product #3499

Merged
merged 1 commit into from
Feb 10, 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 @@ -262,6 +262,10 @@ private List<IPublisherAction> getPublisherActions(String packaging, File basedi
return actions;
}

public Collection<IInstallableUnit> getInstallableUnits(IProductDescriptor productDescriptor) throws CoreException {
return publisher.publishMetadata(List.of(new ProductDependenciesAction(productDescriptor)));
}

public Collection<IInstallableUnit> getInstallableUnits(Manifest manifest) {
Attributes mainAttributes = manifest.getMainAttributes();
CaseInsensitiveDictionaryMap<String, String> headers = new CaseInsensitiveDictionaryMap<>(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
*******************************************************************************/
package org.eclipse.tycho.p2maven.actions;

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

import org.eclipse.equinox.internal.p2.publisher.eclipse.ProductFile;
Expand All @@ -26,7 +27,11 @@ public class ProductFile2 extends ProductFile {

protected static final String ATTRIBUTE_ARCH = "arch";

public ProductFile2(String location) throws Exception {
public ProductFile2(File location) throws Exception {
this(location.getAbsolutePath());
}

public ProductFile2(String location) throws Exception {
super(location);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,12 @@
public interface IDependencyMetadata {

enum DependencyMetadataType {
INITIAL, SEED, RESOLVE;
INITIAL, SEED, RESOLVE,
/**
* Additional metadata describing requirements like defined in the targets platform
* dependency resolution
*/
ADDITIONAL;
}

Set<IInstallableUnit> getDependencyMetadata(DependencyMetadataType type);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*******************************************************************************
* Copyright (c) 2024 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;

import java.util.Collection;
import java.util.Collections;
import java.util.Set;

import org.eclipse.equinox.p2.metadata.IInstallableUnit;

public class UnmodifiableDependencyMetadata implements IDependencyMetadata {

private Set<IInstallableUnit> units;
private DependencyMetadataType dependencyMetadataType;

public UnmodifiableDependencyMetadata(Set<IInstallableUnit> units, DependencyMetadataType type) {
this.dependencyMetadataType = type;
this.units = Collections.unmodifiableSet(units);
}

@Override
public Set<IInstallableUnit> getDependencyMetadata(DependencyMetadataType type) {
if (dependencyMetadataType == type) {
return getDependencyMetadata();
}
return Set.of();
}

@Override
public Set<IInstallableUnit> getDependencyMetadata() {
return units;
}

@Override
public void setDependencyMetadata(DependencyMetadataType type, Collection<IInstallableUnit> units) {
throw new UnsupportedOperationException();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
*******************************************************************************/
package org.eclipse.tycho.core.bnd;

import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
Expand All @@ -25,9 +24,11 @@
import org.eclipse.core.runtime.CoreException;
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
import org.eclipse.tycho.IDependencyMetadata;
import org.eclipse.tycho.IDependencyMetadata.DependencyMetadataType;
import org.eclipse.tycho.OptionalResolutionAction;
import org.eclipse.tycho.TargetEnvironment;
import org.eclipse.tycho.TychoConstants;
import org.eclipse.tycho.UnmodifiableDependencyMetadata;
import org.eclipse.tycho.resolver.InstallableUnitProvider;
import org.eclipse.tycho.resolver.P2MetadataProvider;

Expand All @@ -49,28 +50,8 @@ public Map<String, IDependencyMetadata> getDependencyMetadata(MavenSession sessi
if (units.isEmpty()) {
return Collections.emptyMap();
}
IDependencyMetadata metadata = new IDependencyMetadata() {

@Override
public Set<IInstallableUnit> getDependencyMetadata(DependencyMetadataType type) {
if (type == DependencyMetadataType.INITIAL) {
return getDependencyMetadata();
}
return Collections.emptySet();
}

@Override
public Set<IInstallableUnit> getDependencyMetadata() {
return units;
}

@Override
public void setDependencyMetadata(DependencyMetadataType type, Collection<IInstallableUnit> units) {
throw new UnsupportedOperationException();
}

};
return Map.of(TychoConstants.PDE_BND, metadata);
return Map.of(TychoConstants.PDE_BND,
new UnmodifiableDependencyMetadata(units, DependencyMetadataType.INITIAL));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ public List<Category> loadCategories(final File categoriesDirectory) {
* @param project
* @return
*/
protected List<ProductConfiguration> loadProducts(final ReactorProject project) {
public static List<ProductConfiguration> loadProducts(final ReactorProject project) {
List<ProductConfiguration> products = new ArrayList<>();
for (File file : getProductFiles(project)) {
try {
Expand Down Expand Up @@ -153,7 +153,7 @@ private List<File> getCategoryFiles(final File basedir) {
* the project containing the product files
* @return The list of product files to parse for an eclipse-repository project
*/
public List<File> getProductFiles(final ReactorProject project) {
public static List<File> getProductFiles(final ReactorProject project) {
final File projectLocation = project.getBasedir();
return getProductFiles(projectLocation);
}
Expand All @@ -165,7 +165,7 @@ public List<File> getProductFiles(final ReactorProject project) {
* the directory containing the product files
* @return The list of product files to parse for an eclipse-repository project
*/
public List<File> getProductFiles(final File basedir) {
public static List<File> getProductFiles(final File basedir) {
final List<File> files = new ArrayList<>();

// noinspection ConstantConditions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,13 @@ private DependencyArtifacts doResolveDependencies(MavenSession session, MavenPro
for (IRequirement requirement : resolverConfiguration.getAdditionalRequirements()) {
resolver.addRequirement(requirement);
}
Set<IInstallableUnit> additionalDependencyMetadata = DefaultReactorProject.adapt(project)
.getDependencyMetadata(DependencyMetadataType.ADDITIONAL);
for (IInstallableUnit unit : additionalDependencyMetadata) {
for (IRequirement requirement : unit.getRequirements()) {
resolver.addRequirement(requirement);
}
}
}

BuildProperties buildProperties = buildPropertiesParser.parse(DefaultReactorProject.adapt(project));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
<exportedPackage>org.eclipse.equinox.p2.repository.artifact</exportedPackage>
<exportedPackage>org.eclipse.equinox.p2.repository.metadata</exportedPackage>
<exportedPackage>org.eclipse.equinox.internal.p2.metadata</exportedPackage>
<exportedPackage>org.eclipse.equinox.internal.p2.publisher.eclipse</exportedPackage>
<!-- <exportedPackage>org.eclipse.core.runtime</exportedPackage>
<exportedPackage>org.eclipse.core.resources</exportedPackage> -->
<!-- other -->
Expand Down
17 changes: 17 additions & 0 deletions tycho-p2-publisher-plugin/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,21 @@
</dependency>
</dependencies>


<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-plugin-plugin</artifactId>
<!-- workaround for https://issues.apache.org/jira/browse/MPLUGIN-450 -->
<configuration>
<goalPrefix>tycho-p2-publisher</goalPrefix>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-component-metadata</artifactId>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*******************************************************************************
* Copyright (c) 2024 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.plugins.p2.publisher;

import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.maven.execution.MavenSession;
import org.apache.maven.model.Plugin;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.component.annotations.Component;
import org.codehaus.plexus.component.annotations.Requirement;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
import org.eclipse.equinox.p2.metadata.IRequirement;
import org.eclipse.tycho.PackagingType;
import org.eclipse.tycho.core.osgitools.EclipseRepositoryProject;
import org.eclipse.tycho.p2maven.InstallableUnitGenerator;
import org.eclipse.tycho.p2maven.actions.ProductFile2;
import org.eclipse.tycho.resolver.InstallableUnitProvider;

@Component(role = InstallableUnitProvider.class, hint = PublishProductInstallableUnitProvider.HINT)
public class PublishProductInstallableUnitProvider implements InstallableUnitProvider {

static final String HINT = "publish-products";

@Requirement
private InstallableUnitGenerator installableUnitGenerator;

@Override
public Collection<IInstallableUnit> getInstallableUnits(MavenProject project, MavenSession session)
throws CoreException {
return getProductUnits(installableUnitGenerator, project);
}

static Set<IInstallableUnit> getProductUnits(InstallableUnitGenerator installableUnitGenerator,
MavenProject project) {
if (PackagingType.TYPE_ECLIPSE_REPOSITORY.equals(project.getPackaging())) {
//This is already handled there...
//TODO can we merge the both ways to determine the requirements?
return Set.of();
}
Plugin plugin = project.getPlugin("org.eclipse.tycho:tycho-p2-publisher-plugin");
if (plugin == null || plugin.getExecutions().isEmpty()) {
return Set.of();
}
List<File> productFiles = EclipseRepositoryProject.getProductFiles(project.getBasedir());
if (productFiles.isEmpty()) {
return Set.of();
}
List<IRequirement> requirements = new ArrayList<>();
for (File file : productFiles) {
try {
Collection<IInstallableUnit> units = installableUnitGenerator
.getInstallableUnits(new ProductFile2(file));
for (IInstallableUnit unit : units) {
requirements.addAll(unit.getRequirements());
}
} catch (CoreException e) {
} catch (Exception e) {
}
}
if (requirements.isEmpty()) {
return Set.of();
}
return new HashSet<>(InstallableUnitProvider.createIU(requirements, HINT));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package org.eclipse.tycho.plugins.p2.publisher;

import java.util.List;
import java.util.Map;
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.codehaus.plexus.component.annotations.Requirement;
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
import org.eclipse.tycho.IDependencyMetadata;
import org.eclipse.tycho.IDependencyMetadata.DependencyMetadataType;
import org.eclipse.tycho.OptionalResolutionAction;
import org.eclipse.tycho.TargetEnvironment;
import org.eclipse.tycho.UnmodifiableDependencyMetadata;
import org.eclipse.tycho.p2maven.InstallableUnitGenerator;
import org.eclipse.tycho.resolver.P2MetadataProvider;

@Component(role = P2MetadataProvider.class, hint = PublishProductInstallableUnitProvider.HINT)
public class PublishProductMetadataProvider implements P2MetadataProvider {

@Requirement
private InstallableUnitGenerator installableUnitGenerator;

@Override
public Map<String, IDependencyMetadata> getDependencyMetadata(MavenSession session, MavenProject project,
List<TargetEnvironment> environments, OptionalResolutionAction optionalAction) {

Set<IInstallableUnit> productUnits = PublishProductInstallableUnitProvider
.getProductUnits(installableUnitGenerator, project);
if (productUnits.isEmpty()) {
return Map.of();
}
return Map.of(PublishProductInstallableUnitProvider.HINT,
new UnmodifiableDependencyMetadata(productUnits, DependencyMetadataType.ADDITIONAL));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@

/**
* <p>
* Publishes all product definitions files (<code>*.product</code>) that are present in the root of the
* project.
* Publishes all product definitions files (<code>*.product</code>) that are present in the root of
* the project.
* </p>
*
* @see https://wiki.eclipse.org/Equinox/p2/Publisher
Expand Down Expand Up @@ -113,7 +113,7 @@ protected Collection<DependencySeed> publishContent(PublisherServiceFactory publ

List<DependencySeed> seeds = new ArrayList<>();
boolean hasLaunchers = false;
for (final File productFile : eclipseRepositoryProject.getProductFiles(productsDirectory)) {
for (final File productFile : EclipseRepositoryProject.getProductFiles(productsDirectory)) {
try {
ProductConfiguration productConfiguration = ProductConfiguration.read(productFile);
if (productConfiguration.getId() == null || productConfiguration.getId().isEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ static Collection<IInstallableUnit> createIU(Stream<IRequirement> requirements,
return createIU(requirements.toList(), idPrefix);
}

static Collection<IInstallableUnit> createIU(List<IRequirement> requirements, String idPrefix) {
static Collection<IInstallableUnit> createIU(Collection<IRequirement> requirements, String idPrefix) {
if (requirements.isEmpty()) {
return Collections.emptyList();
}
Expand Down
Loading