From 08be6ce25bad261d895d28e2de0080845efcb477 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20L=C3=A4ubrich?= Date: Sat, 20 Jan 2024 19:42:17 +0100 Subject: [PATCH] Fail on missing plugin product requirement Currently Tycho does not fail if a requirement of a product can't be found in the resolve phase but only if the product is materialized. Even then it fails with an obscure error that claims the products bundle is not found where actually the dependency can't be found. --- .../actions/ProductDependenciesAction.java | 2 +- .../TargetPlatformConfigurationMojo.java | 43 +++++++- .../maven/TychoProjectExecutionListener.java | 2 +- .../publisher/ProductDependenciesAction.java | 103 ------------------ .../AbstractSlicerResolutionStrategy.java | 2 +- .../tycho/p2resolver/P2GeneratorImpl.java | 2 +- .../tycho/p2resolver/P2ResolverImpl.java | 2 +- .../ProjectorResolutionStrategy.java | 35 +++++- .../tycho/p2resolver/ResolutionData.java | 12 ++ .../p2resolver/SlicerResolutionStrategy.java | 4 +- .../tycho/p2tools/copiedfromp2/Projector.java | 6 +- .../tycho/test/util/InstallableUnitUtil.java | 9 +- .../feature/build.properties | 11 ++ .../feature/feature.xml | 30 +++++ .../feature/pom.xml | 50 +++++++++ .../missing-requirements-feature/pom.xml | 29 +++++ .../product/feature.product | 10 ++ .../product/pom.xml | 49 +++++++++ .../plugin.product | 8 ++ .../missing-requirements-plugins/pom.xml | 49 +++++++++ .../plugin.product | 14 +++ .../product-with-native-fragments/pom.xml | 94 ++++++++++++++++ .../tycho/test/product/ProductBuildTest.java | 36 ++++++ 23 files changed, 478 insertions(+), 124 deletions(-) delete mode 100644 tycho-core/src/main/java/org/eclipse/tycho/p2/publisher/ProductDependenciesAction.java create mode 100644 tycho-its/projects/tycho-p2-director-plugin/missing-requirements-feature/feature/build.properties create mode 100644 tycho-its/projects/tycho-p2-director-plugin/missing-requirements-feature/feature/feature.xml create mode 100644 tycho-its/projects/tycho-p2-director-plugin/missing-requirements-feature/feature/pom.xml create mode 100644 tycho-its/projects/tycho-p2-director-plugin/missing-requirements-feature/pom.xml create mode 100644 tycho-its/projects/tycho-p2-director-plugin/missing-requirements-feature/product/feature.product create mode 100644 tycho-its/projects/tycho-p2-director-plugin/missing-requirements-feature/product/pom.xml create mode 100644 tycho-its/projects/tycho-p2-director-plugin/missing-requirements-plugins/plugin.product create mode 100644 tycho-its/projects/tycho-p2-director-plugin/missing-requirements-plugins/pom.xml create mode 100644 tycho-its/projects/tycho-p2-director-plugin/product-with-native-fragments/plugin.product create mode 100644 tycho-its/projects/tycho-p2-director-plugin/product-with-native-fragments/pom.xml diff --git a/p2-maven-plugin/src/main/java/org/eclipse/tycho/p2maven/actions/ProductDependenciesAction.java b/p2-maven-plugin/src/main/java/org/eclipse/tycho/p2maven/actions/ProductDependenciesAction.java index 3058dbc170..dbdf4e85eb 100644 --- a/p2-maven-plugin/src/main/java/org/eclipse/tycho/p2maven/actions/ProductDependenciesAction.java +++ b/p2-maven-plugin/src/main/java/org/eclipse/tycho/p2maven/actions/ProductDependenciesAction.java @@ -61,7 +61,7 @@ protected Set getRequiredCapabilities() { } if (type == ProductContentType.BUNDLES || type == ProductContentType.MIXED) { for (FeatureEntry plugin : ((ProductFile) product).getProductEntries()) { - addRequiredCapability(required, plugin.getId(), Version.parseVersion(plugin.getVersion()), null, true); + addRequiredCapability(required, plugin.getId(), Version.parseVersion(plugin.getVersion()), null, false); } } diff --git a/target-platform-configuration/src/main/java/org/eclipse/tycho/target/TargetPlatformConfigurationMojo.java b/target-platform-configuration/src/main/java/org/eclipse/tycho/target/TargetPlatformConfigurationMojo.java index 8f062b3d30..5b8a39a0f7 100644 --- a/target-platform-configuration/src/main/java/org/eclipse/tycho/target/TargetPlatformConfigurationMojo.java +++ b/target-platform-configuration/src/main/java/org/eclipse/tycho/target/TargetPlatformConfigurationMojo.java @@ -37,7 +37,45 @@ public class TargetPlatformConfigurationMojo extends AbstractMojo { /** + *

* Target environments (os/ws/arch) to consider. + *

+ * Example: + * + *
+     *<environments>
+    *  <environment>
+    *    <os>linux</os>
+    *    <ws>gtk</ws>
+    *    <arch>x86_64</arch>
+    *  </environment>
+    *  <environment>
+    *    <os>linux</os>
+    *    <ws>gtk</ws>
+    *    <arch>ppc64le</arch>
+    *  </environment>
+    *   <environment>
+    *    <os>linux</os>
+    *    <ws>gtk</ws>
+    *    <arch>aarch64</arch>
+    *  </environment>
+    *  <environment>
+    *    <os>win32</os>
+    *    <ws>win32</ws>
+    *    <arch>x86_64</arch>
+    *  </environment>
+    *  <environment>
+    *    <os>macosx</os>
+    *    <ws>cocoa</ws>
+    *    <arch>x86_64</arch>
+    *  </environment>
+    *  <environment>
+    *    <os>macosx</os>
+    *    <ws>cocoa</ws>
+    *    <arch>aarch64</arch>
+    *  </environment>
+    *</environments>
+     * 
*/ @Parameter(name = DefaultTargetPlatformConfigurationReader.ENVIRONMENTS) private TargetEnvironment[] environments; @@ -208,8 +246,9 @@ public class TargetPlatformConfigurationMojo extends AbstractMojo { private IncludeSourceMode targetDefinionIncludeSource; /** - * Configures if referenced repositories should be included when fetching repositories. - * The default is ignore. To specify to use referenced repositories, pass include. + * Configures if referenced repositories should be included when fetching repositories. The + * default is ignore. To specify to use referenced repositories, pass + * include. */ @Parameter(name = DefaultTargetPlatformConfigurationReader.REFERENCED_REPOSITORY_MODE) private ReferencedRepositoryMode referencedRepositoryMode; diff --git a/tycho-core/src/main/java/org/eclipse/tycho/core/maven/TychoProjectExecutionListener.java b/tycho-core/src/main/java/org/eclipse/tycho/core/maven/TychoProjectExecutionListener.java index bc0b33fbd2..48a3c39aed 100644 --- a/tycho-core/src/main/java/org/eclipse/tycho/core/maven/TychoProjectExecutionListener.java +++ b/tycho-core/src/main/java/org/eclipse/tycho/core/maven/TychoProjectExecutionListener.java @@ -120,7 +120,7 @@ public void beforeProjectLifecycleExecution(ProjectExecutionEvent event) throws + " with context " + resolverException.getSelectionContext() + System.lineSeparator() + resolverException.explanations() .map(exp -> " " + exp.toString()).collect(Collectors.joining("\n")), - null, mavenProject); + null, mavenProject, resolverException); } } TychoProject tychoProject = projectManager.getTychoProject(mavenProject).orElse(null); diff --git a/tycho-core/src/main/java/org/eclipse/tycho/p2/publisher/ProductDependenciesAction.java b/tycho-core/src/main/java/org/eclipse/tycho/p2/publisher/ProductDependenciesAction.java deleted file mode 100644 index 13ff9d43eb..0000000000 --- a/tycho-core/src/main/java/org/eclipse/tycho/p2/publisher/ProductDependenciesAction.java +++ /dev/null @@ -1,103 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2008, 2014 Sonatype Inc. 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: - * Sonatype Inc. - initial API and implementation - *******************************************************************************/ -package org.eclipse.tycho.p2.publisher; - -import java.io.File; -import java.util.LinkedHashSet; -import java.util.Set; - -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.Path; -import org.eclipse.equinox.internal.p2.publisher.eclipse.IProductDescriptor; -import org.eclipse.equinox.internal.p2.publisher.eclipse.ProductContentType; -import org.eclipse.equinox.internal.p2.publisher.eclipse.ProductFile; -import org.eclipse.equinox.p2.metadata.IRequirement; -import org.eclipse.equinox.p2.metadata.IVersionedId; -import org.eclipse.equinox.p2.metadata.MetadataFactory.InstallableUnitDescription; -import org.eclipse.equinox.p2.metadata.Version; -import org.eclipse.equinox.p2.publisher.AdviceFileAdvice; -import org.eclipse.equinox.p2.publisher.IPublisherInfo; -import org.eclipse.equinox.p2.publisher.eclipse.FeatureEntry; -import org.eclipse.tycho.p2maven.actions.AbstractDependenciesAction; - -public class ProductDependenciesAction extends AbstractDependenciesAction { - private final IProductDescriptor product; - - public ProductDependenciesAction(IProductDescriptor product) { - this.product = product; - } - - @Override - protected Version getVersion() { - return Version.create(product.getVersion()); - } - - @Override - protected String getId() { - return product.getId(); - } - - @Override - protected Set getRequiredCapabilities() { - Set required = new LinkedHashSet<>(); - - ProductContentType type = product.getProductContentType(); - if (type == ProductContentType.FEATURES || type == ProductContentType.MIXED) { - for (IVersionedId feature : product.getFeatures()) { - String id = feature.getId() + FEATURE_GROUP_IU_SUFFIX; - Version version = feature.getVersion(); - - addRequiredCapability(required, id, version, null, false); - } - } - if (type == ProductContentType.BUNDLES || type == ProductContentType.MIXED) { - for (FeatureEntry plugin : ((ProductFile) product).getProductEntries()) { - addRequiredCapability(required, plugin.getId(), Version.parseVersion(plugin.getVersion()), null, true); - } - } - - if (product.includeLaunchers()) { - addRequiredCapability(required, "org.eclipse.equinox.executable.feature.group", null, null, false); - } - return required; - } - - @Override - protected void addPublisherAdvice(IPublisherInfo publisherInfo) { - // see org.eclipse.equinox.p2.publisher.eclipse.ProductAction.createAdviceFileAdvice() - - File productFileLocation = product.getLocation(); - if (productFileLocation == null) { - return; - } - - String id = product.getId(); - Version parseVersion = Version.parseVersion(product.getVersion()); - IPath basePath = new Path(productFileLocation.getParent()); - - // must match org.eclipse.tycho.plugins.p2.publisher.PublishProductMojo.getSourceP2InfFile(File) - final String productFileName = productFileLocation.getName(); - final String p2infFilename = productFileName.substring(0, productFileName.length() - ".product".length()) - + ".p2.inf"; - - AdviceFileAdvice advice = new AdviceFileAdvice(id, parseVersion, basePath, new Path(p2infFilename)); - if (advice.containsAdvice()) { - publisherInfo.addAdvice(advice); - } - } - - @Override - protected void addProperties(InstallableUnitDescription iud) { - iud.setProperty(InstallableUnitDescription.PROP_TYPE_PRODUCT, Boolean.toString(true)); - } -} diff --git a/tycho-core/src/main/java/org/eclipse/tycho/p2resolver/AbstractSlicerResolutionStrategy.java b/tycho-core/src/main/java/org/eclipse/tycho/p2resolver/AbstractSlicerResolutionStrategy.java index 230b437b8b..f2d64c9a95 100644 --- a/tycho-core/src/main/java/org/eclipse/tycho/p2resolver/AbstractSlicerResolutionStrategy.java +++ b/tycho-core/src/main/java/org/eclipse/tycho/p2resolver/AbstractSlicerResolutionStrategy.java @@ -28,7 +28,6 @@ import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.MultiStatus; import org.eclipse.equinox.internal.p2.director.QueryableArray; -import org.eclipse.equinox.internal.p2.director.Slicer; import org.eclipse.equinox.internal.p2.metadata.IRequiredCapability; import org.eclipse.equinox.internal.p2.metadata.RequiredCapability; import org.eclipse.equinox.internal.p2.metadata.RequiredPropertiesMatch; @@ -48,6 +47,7 @@ import org.eclipse.tycho.core.shared.MavenLogger; import org.eclipse.tycho.core.shared.StatusTool; import org.eclipse.tycho.p2.resolver.ResolverException; +import org.eclipse.tycho.p2tools.copiedfromp2.Slicer; abstract class AbstractSlicerResolutionStrategy extends AbstractResolutionStrategy { diff --git a/tycho-core/src/main/java/org/eclipse/tycho/p2resolver/P2GeneratorImpl.java b/tycho-core/src/main/java/org/eclipse/tycho/p2resolver/P2GeneratorImpl.java index 87d919d8ca..4f834050b5 100644 --- a/tycho-core/src/main/java/org/eclipse/tycho/p2resolver/P2GeneratorImpl.java +++ b/tycho-core/src/main/java/org/eclipse/tycho/p2resolver/P2GeneratorImpl.java @@ -79,12 +79,12 @@ import org.eclipse.tycho.p2.publisher.DownloadStatsAdvice; import org.eclipse.tycho.p2.publisher.FeatureDependenciesAction; import org.eclipse.tycho.p2.publisher.P2Artifact; -import org.eclipse.tycho.p2.publisher.ProductDependenciesAction; import org.eclipse.tycho.p2.publisher.TransientArtifactRepository; import org.eclipse.tycho.p2.publisher.rootfiles.FeatureRootAdvice; import org.eclipse.tycho.p2.repository.ArtifactsIO; import org.eclipse.tycho.p2.repository.MetadataIO; import org.eclipse.tycho.p2maven.actions.CategoryDependenciesAction; +import org.eclipse.tycho.p2maven.actions.ProductDependenciesAction; import org.eclipse.tycho.p2maven.actions.ProductFile2; import org.osgi.framework.BundleException; diff --git a/tycho-core/src/main/java/org/eclipse/tycho/p2resolver/P2ResolverImpl.java b/tycho-core/src/main/java/org/eclipse/tycho/p2resolver/P2ResolverImpl.java index fa0715103a..e02bc5fbd3 100644 --- a/tycho-core/src/main/java/org/eclipse/tycho/p2resolver/P2ResolverImpl.java +++ b/tycho-core/src/main/java/org/eclipse/tycho/p2resolver/P2ResolverImpl.java @@ -35,7 +35,6 @@ import org.apache.felix.resolver.util.CopyOnWriteSet; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.equinox.internal.p2.director.QueryableArray; -import org.eclipse.equinox.internal.p2.director.Slicer; import org.eclipse.equinox.p2.metadata.IArtifactKey; import org.eclipse.equinox.p2.metadata.IInstallableUnit; import org.eclipse.equinox.p2.metadata.IProvidedCapability; @@ -76,6 +75,7 @@ import org.eclipse.tycho.p2.resolver.ResolverException; import org.eclipse.tycho.p2.target.facade.TargetPlatformConfigurationStub; import org.eclipse.tycho.p2.target.facade.TargetPlatformFactory; +import org.eclipse.tycho.p2tools.copiedfromp2.Slicer; import org.eclipse.tycho.targetplatform.P2TargetPlatform; public class P2ResolverImpl implements P2Resolver { diff --git a/tycho-core/src/main/java/org/eclipse/tycho/p2resolver/ProjectorResolutionStrategy.java b/tycho-core/src/main/java/org/eclipse/tycho/p2resolver/ProjectorResolutionStrategy.java index 6adf97db66..8bc48e5be9 100644 --- a/tycho-core/src/main/java/org/eclipse/tycho/p2resolver/ProjectorResolutionStrategy.java +++ b/tycho-core/src/main/java/org/eclipse/tycho/p2resolver/ProjectorResolutionStrategy.java @@ -21,23 +21,25 @@ import java.util.Map; import java.util.Set; import java.util.function.Predicate; -import java.util.stream.Collectors; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.MultiStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.equinox.internal.p2.director.Explanation; -import org.eclipse.equinox.internal.p2.director.Projector; import org.eclipse.equinox.internal.p2.director.QueryableArray; import org.eclipse.equinox.internal.p2.director.SimplePlanner; -import org.eclipse.equinox.internal.p2.director.Slicer; import org.eclipse.equinox.p2.metadata.IInstallableUnit; import org.eclipse.equinox.p2.metadata.IRequirement; +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.tycho.core.shared.MavenLogger; import org.eclipse.tycho.core.shared.StatusTool; import org.eclipse.tycho.p2.resolver.ResolverException; +import org.eclipse.tycho.p2tools.copiedfromp2.Projector; +import org.eclipse.tycho.p2tools.copiedfromp2.Slicer; public class ProjectorResolutionStrategy extends AbstractSlicerResolutionStrategy { @@ -79,9 +81,32 @@ public Collection resolve(Map properties, IPro // force profile UIs to be used during resolution seedUnits.addAll(data.getEEResolutionHints().getMandatoryUnits()); seedRequires.addAll(data.getEEResolutionHints().getMandatoryRequires()); - Projector projector = new Projector(slice(properties, generatedUnits, monitor), selectionContext, - new HashSet<>(), false); + new HashSet<>(), false) { + IQueryable units; + + @Override + protected Collection getRequiredCapabilities(IInstallableUnit iu) { + Collection requiredCapabilities = super.getRequiredCapabilities(iu); + if (QueryUtil.isProduct(iu)) { + if (units == null) { + units = data.units(); + } + return requiredCapabilities.stream().filter(requirement -> { + IQuery query = QueryUtil.createMatchQuery(requirement.getMatches()); + IQueryResult result = units.query(query, null); + if (result.isEmpty()) { + //this must fail the resolve so we need to include the requirement + return true; + } + //If none of the results are applicable this means they are filtered and need not to be considered + //this happens in plugin based products that include native fragments from different platforms + return result.stream().anyMatch(matchIu -> isApplicable(matchIu)); + }).toList(); + } + return requiredCapabilities; + } + }; projector.encode(createUnitRequiring("tycho", seedUnits, seedRequires), EMPTY_IU_ARRAY /* alreadyExistingRoots */, new QueryableArray(List.of()) /* installedIUs */, seedUnits /* newRoots */, monitor); diff --git a/tycho-core/src/main/java/org/eclipse/tycho/p2resolver/ResolutionData.java b/tycho-core/src/main/java/org/eclipse/tycho/p2resolver/ResolutionData.java index dfb308b19a..c08738713d 100644 --- a/tycho-core/src/main/java/org/eclipse/tycho/p2resolver/ResolutionData.java +++ b/tycho-core/src/main/java/org/eclipse/tycho/p2resolver/ResolutionData.java @@ -20,8 +20,10 @@ import org.eclipse.equinox.p2.metadata.IInstallableUnit; import org.eclipse.equinox.p2.metadata.IRequirement; +import org.eclipse.equinox.p2.query.CollectionResult; import org.eclipse.equinox.p2.query.IQueryable; import org.eclipse.tycho.ExecutionEnvironmentResolutionHints; +import org.eclipse.tycho.p2maven.ListQueryable; public interface ResolutionData { @@ -42,4 +44,14 @@ public interface ResolutionData { Predicate getIInstallableUnitAcceptor(); IQueryable getAdditionalUnitStore(); + + default IQueryable units() { + ListQueryable listQueryable = new ListQueryable<>(); + listQueryable.add(new CollectionResult<>(getAvailableIUs())); + IQueryable unitStore = getAdditionalUnitStore(); + if (unitStore != null) { + listQueryable.add(unitStore); + } + return listQueryable; + } } diff --git a/tycho-core/src/main/java/org/eclipse/tycho/p2resolver/SlicerResolutionStrategy.java b/tycho-core/src/main/java/org/eclipse/tycho/p2resolver/SlicerResolutionStrategy.java index bf8f85e9d8..b96f8b0bf9 100644 --- a/tycho-core/src/main/java/org/eclipse/tycho/p2resolver/SlicerResolutionStrategy.java +++ b/tycho-core/src/main/java/org/eclipse/tycho/p2resolver/SlicerResolutionStrategy.java @@ -22,14 +22,14 @@ import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.MultiStatus; -import org.eclipse.equinox.internal.p2.director.PermissiveSlicer; -import org.eclipse.equinox.internal.p2.director.Slicer; import org.eclipse.equinox.p2.metadata.IInstallableUnit; import org.eclipse.equinox.p2.query.IQueryable; import org.eclipse.equinox.p2.query.QueryUtil; import org.eclipse.tycho.TargetEnvironment; import org.eclipse.tycho.core.shared.MavenLogger; import org.eclipse.tycho.p2.resolver.ResolverException; +import org.eclipse.tycho.p2tools.copiedfromp2.PermissiveSlicer; +import org.eclipse.tycho.p2tools.copiedfromp2.Slicer; public class SlicerResolutionStrategy extends AbstractSlicerResolutionStrategy { diff --git a/tycho-core/src/main/java/org/eclipse/tycho/p2tools/copiedfromp2/Projector.java b/tycho-core/src/main/java/org/eclipse/tycho/p2tools/copiedfromp2/Projector.java index f87d606149..7a642c20a1 100644 --- a/tycho-core/src/main/java/org/eclipse/tycho/p2tools/copiedfromp2/Projector.java +++ b/tycho-core/src/main/java/org/eclipse/tycho/p2tools/copiedfromp2/Projector.java @@ -379,12 +379,12 @@ private void createNegation(IInstallableUnit iu, IRequirement req) throws Contra } // Check whether the requirement is applicable - private boolean isApplicable(IRequirement req) { + protected boolean isApplicable(IRequirement req) { IMatchExpression filter = req.getFilter(); return filter == null || filter.isMatch(selectionContext); } - private boolean isApplicable(IInstallableUnit iu) { + protected boolean isApplicable(IInstallableUnit iu) { IMatchExpression filter = iu.getFilter(); return filter == null || filter.isMatch(selectionContext); } @@ -536,7 +536,7 @@ public void processIU(IInstallableUnit iu, boolean isRootIU) throws Contradictio } } - private Collection getRequiredCapabilities(IInstallableUnit iu) { + protected Collection getRequiredCapabilities(IInstallableUnit iu) { boolean isFragment = iu instanceof IInstallableUnitFragment; //Short-circuit for the case of an IInstallableUnit if ((!isFragment) && iu.getMetaRequirements().size() == 0) diff --git a/tycho-core/src/test/java/org/eclipse/tycho/test/util/InstallableUnitUtil.java b/tycho-core/src/test/java/org/eclipse/tycho/test/util/InstallableUnitUtil.java index c20baadc87..9236e3837b 100644 --- a/tycho-core/src/test/java/org/eclipse/tycho/test/util/InstallableUnitUtil.java +++ b/tycho-core/src/test/java/org/eclipse/tycho/test/util/InstallableUnitUtil.java @@ -26,13 +26,14 @@ import org.eclipse.equinox.p2.metadata.MetadataFactory.InstallableUnitDescription; import org.eclipse.equinox.p2.metadata.Version; import org.eclipse.equinox.p2.metadata.VersionRange; +import org.eclipse.equinox.p2.publisher.eclipse.BundlesAction; public class InstallableUnitUtil { - static final String IU_CAPABILITY_NS = "org.eclipse.equinox.p2.iu"; // see IInstallableUnit.NAMESPACE_IU_ID; - static final String BUNDLE_CAPABILITY_NS = "osgi.bundle"; // see BundlesAction.CAPABILITY_NS_OSGI_BUNDLE - static final String PRODUCT_TYPE_PROPERTY = "org.eclipse.equinox.p2.type.product"; // see InstallableUnitDescription.PROP_TYPE_PRODUCT; - static final String FEATURE_TYPE_PROPERTY = "org.eclipse.equinox.p2.type.group"; // see InstallableUnitDescription.PROP_TYPE_GROUP; + static final String IU_CAPABILITY_NS = IInstallableUnit.NAMESPACE_IU_ID; + static final String BUNDLE_CAPABILITY_NS = BundlesAction.CAPABILITY_NS_OSGI_BUNDLE; + static final String PRODUCT_TYPE_PROPERTY = InstallableUnitDescription.PROP_TYPE_PRODUCT; + static final String FEATURE_TYPE_PROPERTY = InstallableUnitDescription.PROP_TYPE_GROUP; public static String DEFAULT_VERSION = "0.0.20"; diff --git a/tycho-its/projects/tycho-p2-director-plugin/missing-requirements-feature/feature/build.properties b/tycho-its/projects/tycho-p2-director-plugin/missing-requirements-feature/feature/build.properties new file mode 100644 index 0000000000..0b6dc2b511 --- /dev/null +++ b/tycho-its/projects/tycho-p2-director-plugin/missing-requirements-feature/feature/build.properties @@ -0,0 +1,11 @@ +############################################################################### +# Copyright (c) 2010, 2011 SAP AG and others. +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v1.0 +# which accompanies this distribution, and is available at +# https://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# SAP AG - initial API and implementation +############################################################################### +bin.includes = feature.xml diff --git a/tycho-its/projects/tycho-p2-director-plugin/missing-requirements-feature/feature/feature.xml b/tycho-its/projects/tycho-p2-director-plugin/missing-requirements-feature/feature/feature.xml new file mode 100644 index 0000000000..c124ac532d --- /dev/null +++ b/tycho-its/projects/tycho-p2-director-plugin/missing-requirements-feature/feature/feature.xml @@ -0,0 +1,30 @@ + + + + + A description of an example feature + + + + [Enter Copyright Description here.] + + + + [Enter License Description here.] + + + + + + + + + + diff --git a/tycho-its/projects/tycho-p2-director-plugin/missing-requirements-feature/feature/pom.xml b/tycho-its/projects/tycho-p2-director-plugin/missing-requirements-feature/feature/pom.xml new file mode 100644 index 0000000000..defb37f1b3 --- /dev/null +++ b/tycho-its/projects/tycho-p2-director-plugin/missing-requirements-feature/feature/pom.xml @@ -0,0 +1,50 @@ + + + 4.0.0 + + + tycho-its + missing.parent + 1.0.0-SNAPSHOT + + + org.osgi.service.jaxrs.feature + eclipse-feature + Example Feature + + + + org.osgi + org.osgi.service.jaxrs + 1.0.1 + provided + + + org.apache.aries.spec + org.apache.aries.javax.jax.rs-api + 1.0.4 + provided + + + javax.xml.bind + jaxb-api + 2.3.1 + provided + + + jakarta.activation + jakarta.activation-api + 1.2.2 + provided + + + org.eclipse.platform + org.eclipse.osgi + 3.18.600 + provided + + + + diff --git a/tycho-its/projects/tycho-p2-director-plugin/missing-requirements-feature/pom.xml b/tycho-its/projects/tycho-p2-director-plugin/missing-requirements-feature/pom.xml new file mode 100644 index 0000000000..e6378baee9 --- /dev/null +++ b/tycho-its/projects/tycho-p2-director-plugin/missing-requirements-feature/pom.xml @@ -0,0 +1,29 @@ + + 4.0.0 + + tycho-its + missing.parent + 1.0.0-SNAPSHOT + pom + + + UTF-8 + + + + feature + product + + + + + + org.eclipse.tycho + tycho-maven-plugin + ${tycho-version} + true + + + + diff --git a/tycho-its/projects/tycho-p2-director-plugin/missing-requirements-feature/product/feature.product b/tycho-its/projects/tycho-p2-director-plugin/missing-requirements-feature/product/feature.product new file mode 100644 index 0000000000..238246b4e9 --- /dev/null +++ b/tycho-its/projects/tycho-p2-director-plugin/missing-requirements-feature/product/feature.product @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/tycho-its/projects/tycho-p2-director-plugin/missing-requirements-feature/product/pom.xml b/tycho-its/projects/tycho-p2-director-plugin/missing-requirements-feature/product/pom.xml new file mode 100644 index 0000000000..d29c849d38 --- /dev/null +++ b/tycho-its/projects/tycho-p2-director-plugin/missing-requirements-feature/product/pom.xml @@ -0,0 +1,49 @@ + + + + + 4.0.0 + + tycho-its + missing.parent + 1.0.0-SNAPSHOT + + feature.product + eclipse-repository + + + + + org.eclipse.tycho + tycho-maven-plugin + ${tycho-version} + true + + + org.eclipse.tycho + tycho-p2-director-plugin + ${tycho-version} + + + materialize-products + + materialize-products + + + + + + + + + + org.osgi + org.osgi.service.jaxrs + 1.0.1 + + + + \ No newline at end of file diff --git a/tycho-its/projects/tycho-p2-director-plugin/missing-requirements-plugins/plugin.product b/tycho-its/projects/tycho-p2-director-plugin/missing-requirements-plugins/plugin.product new file mode 100644 index 0000000000..b0c1ef4d9b --- /dev/null +++ b/tycho-its/projects/tycho-p2-director-plugin/missing-requirements-plugins/plugin.product @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/tycho-its/projects/tycho-p2-director-plugin/missing-requirements-plugins/pom.xml b/tycho-its/projects/tycho-p2-director-plugin/missing-requirements-plugins/pom.xml new file mode 100644 index 0000000000..9c35ce9b0e --- /dev/null +++ b/tycho-its/projects/tycho-p2-director-plugin/missing-requirements-plugins/pom.xml @@ -0,0 +1,49 @@ + + + + 4.0.0 + tycho-its + plugin.product + 1.0.0-SNAPSHOT + eclipse-repository + + + UTF-8 + + + + + + org.eclipse.tycho + tycho-maven-plugin + ${tycho-version} + true + + + org.eclipse.tycho + tycho-p2-director-plugin + ${tycho-version} + + + materialize-products + + materialize-products + + + + + + + + + + org.osgi + org.osgi.service.jaxrs + 1.0.1 + + + + \ No newline at end of file diff --git a/tycho-its/projects/tycho-p2-director-plugin/product-with-native-fragments/plugin.product b/tycho-its/projects/tycho-p2-director-plugin/product-with-native-fragments/plugin.product new file mode 100644 index 0000000000..0bf4f2ece4 --- /dev/null +++ b/tycho-its/projects/tycho-p2-director-plugin/product-with-native-fragments/plugin.product @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/tycho-its/projects/tycho-p2-director-plugin/product-with-native-fragments/pom.xml b/tycho-its/projects/tycho-p2-director-plugin/product-with-native-fragments/pom.xml new file mode 100644 index 0000000000..2f166e6e25 --- /dev/null +++ b/tycho-its/projects/tycho-p2-director-plugin/product-with-native-fragments/pom.xml @@ -0,0 +1,94 @@ + + + + 4.0.0 + tycho-its + plugin.product + 1.0.0-SNAPSHOT + eclipse-repository + + + UTF-8 + + + + + + org.eclipse.tycho + tycho-maven-plugin + ${tycho-version} + true + + + org.eclipse.tycho + tycho-p2-director-plugin + ${tycho-version} + + + materialize-products + + materialize-products + + + + + + org.eclipse.tycho + target-platform-configuration + ${tycho-version} + + + + linux + gtk + x86_64 + + + win32 + win32 + x86_64 + + + macosx + cocoa + x86_64 + + + + + + + + + + org.eclipse.platform + org.eclipse.swt + 3.124.200 + + + * + * + + + + + org.eclipse.platform + org.eclipse.swt.gtk.linux.x86_64 + 3.124.200 + + + org.eclipse.platform + org.eclipse.swt.win32.win32.x86_64 + 3.124.200 + + + org.eclipse.platform + org.eclipse.swt.cocoa.macosx.x86_64 + 3.124.200 + + + + \ No newline at end of file diff --git a/tycho-its/src/test/java/org/eclipse/tycho/test/product/ProductBuildTest.java b/tycho-its/src/test/java/org/eclipse/tycho/test/product/ProductBuildTest.java index aad80f804c..fb58c40393 100644 --- a/tycho-its/src/test/java/org/eclipse/tycho/test/product/ProductBuildTest.java +++ b/tycho-its/src/test/java/org/eclipse/tycho/test/product/ProductBuildTest.java @@ -13,6 +13,7 @@ import static org.hamcrest.Matchers.hasItem; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertThrows; import java.io.File; import java.io.IOException; @@ -24,6 +25,7 @@ import java.util.Optional; import java.util.stream.Collectors; +import org.apache.maven.it.VerificationException; import org.apache.maven.it.Verifier; import org.eclipse.tycho.TargetEnvironment; import org.eclipse.tycho.TychoConstants; @@ -39,6 +41,40 @@ public class ProductBuildTest extends AbstractTychoIntegrationTest { private static final List REQUIRED_PGP_PROPERTIES = List.of(TychoConstants.PROP_PGP_SIGNATURES, TychoConstants.PROP_PGP_KEYS); + @Test + public void testPluginProjectFailsOnMissingDependencies() throws Exception { + Verifier verifier = getVerifier("tycho-p2-director-plugin/missing-requirements-plugins", false, true); + assertThrows(VerificationException.class, () -> verifier.executeGoals(Arrays.asList("clean", "package"))); + verifier.verifyTextInLog( + "Cannot resolve dependencies of project tycho-its:plugin.product:eclipse-repository:1.0.0-SNAPSHOT"); + } + + @Test + public void testFeatureProjectFailsOnMissingDependencies() throws Exception { + Verifier verifier = getVerifier("tycho-p2-director-plugin/missing-requirements-feature", false, true); + assertThrows(VerificationException.class, () -> verifier.executeGoals(Arrays.asList("clean", "package"))); + verifier.verifyTextInLog( + "Cannot resolve dependencies of project tycho-its:feature.product:eclipse-repository:1.0.0-SNAPSHOT"); + } + + @Test + public void testPluginProductWithDifferentNativesCanBuild() throws Exception { + Verifier verifier = getVerifier("tycho-p2-director-plugin/product-with-native-fragments", false, true); + verifier.executeGoals(Arrays.asList("clean", "package")); + // FIXME verifier.verifyErrorFreeLog(); + // See https://github.com/eclipse-platform/eclipse.platform.swt/issues/992 + verifyTextNotInLog(verifier, "BUILD FAILURE"); + File basedir = new File(verifier.getBasedir()); + assertFileExists(basedir, + "target/products/plugin.product/linux/gtk/x86_64/plugins/org.eclipse.swt.gtk.linux.x86_64_*.jar"); + assertFileExists(basedir, + "target/products/plugin.product/linux/gtk/x86_64/plugins/org.eclipse.swt.gtk.linux.x86_64_*.jar"); + assertFileExists(basedir, + "target/products/plugin.product/win32/win32/x86_64/plugins/org.eclipse.swt.win32.win32.x86_64_*.jar"); + assertFileExists(basedir, + "target/products/plugin.product/macosx/cocoa/x86_64/Eclipse.app/Contents/Eclipse/plugins/org.eclipse.swt.cocoa.macosx.x86_64_*.jar"); + } + @Test public void testMavenDepedencyInTarget() throws Exception { Verifier verifier = getVerifier("product.mavenLocation", false);