diff options
author | Tobias Oberlies | 2015-02-11 17:32:16 +0000 |
---|---|---|
committer | Tobias Oberlies | 2015-02-16 08:29:36 +0000 |
commit | ac896028a4cc69551aa137135fce3c06642016d5 (patch) | |
tree | c771dc79b6fcbb89323e55b09a2a3fd8a65b4cf8 /bundles | |
parent | 82f2b6357622391f971295b0ebc8a8d0c2dd1ab6 (diff) | |
download | rt.equinox.p2-ac896028a4cc69551aa137135fce3c06642016d5.tar.gz rt.equinox.p2-ac896028a4cc69551aa137135fce3c06642016d5.tar.xz rt.equinox.p2-ac896028a4cc69551aa137135fce3c06642016d5.zip |
428889 Don't include installMode="root" features in the product IU
- Ignore features marked with installMode="root" when publishing
products. This attribute is currently only supported by Tycho (cf.
bug 427563 for adding p2 support for this) and entails that the
feature must *not* be referenced from the product IU. This is achieved
with the changed implementation of getFeatures().
- This change allows to get rid of separate product file pre-processing
steps in Tycho.
Bug: 428889
Change-Id: Ib7aa666c6746fbf417fa7437a7fa7b6a95ebd51f
Diffstat (limited to 'bundles')
8 files changed, 165 insertions, 6 deletions
diff --git a/bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/internal/p2/publisher/eclipse/FeatureInstallMode.java b/bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/internal/p2/publisher/eclipse/FeatureInstallMode.java new file mode 100644 index 000000000..e21b67456 --- /dev/null +++ b/bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/internal/p2/publisher/eclipse/FeatureInstallMode.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2015 SAP SE 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * SAP SE - initial API and implementation + *******************************************************************************/ +package org.eclipse.equinox.internal.p2.publisher.eclipse; + +import org.eclipse.osgi.util.NLS; + +enum FeatureInstallMode { + INCLUDE("include"), ROOT("root"); //$NON-NLS-1$ //$NON-NLS-2$ + + private final String attributeValue; + + private FeatureInstallMode(String attributeValue) { + this.attributeValue = attributeValue; + } + + public static FeatureInstallMode parse(String value) { + if (value == null) { + return INCLUDE; + } + for (FeatureInstallMode mode : FeatureInstallMode.values()) { + if (mode.attributeValue.equals(value)) + return mode; + } + throw new IllegalArgumentException(NLS.bind(Messages.exception_invalidFeatureInstallMode, value)); + } + +} diff --git a/bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/internal/p2/publisher/eclipse/IProductDescriptor.java b/bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/internal/p2/publisher/eclipse/IProductDescriptor.java index 8bdc4be46..87f7fd0a9 100644 --- a/bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/internal/p2/publisher/eclipse/IProductDescriptor.java +++ b/bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/internal/p2/publisher/eclipse/IProductDescriptor.java @@ -29,6 +29,15 @@ import org.eclipse.equinox.p2.repository.IRepositoryReference; public interface IProductDescriptor { /** + * Flag for {@link #getFeatures(int)} to obtain the features included in the product. + */ + int INCLUDED_FEATURES = 0x1; + /** + * Flag for {@link #getFeatures(int)} to obtain the features to be installed as separately updatable roots. + */ + int ROOT_FEATURES = 0x2; + + /** * Gets the name of the launcher. */ public String getLauncherName(); @@ -48,12 +57,21 @@ public interface IProductDescriptor { public List<IVersionedId> getFragments(); /** - * Returns the features listed in the product. Note: These features are only part of + * Returns the features listed in the product. Same as <code>getFeatures(INCLUDED_FEATURES)</code>. Note: These features are only part of * the product if {@link #useFeatures()} returns <code>true</code>. */ public List<IVersionedId> getFeatures(); /** + * Returns the features listed in the product. Note: These features are only part of + * the product if {@link #useFeatures()} returns <code>true</code>. + * @param options bitmask to indicate what kind of features to return. + * @see #INCLUDED_FEATURES + * @see #ROOT_FEATURES + */ + public List<IVersionedId> getFeatures(int options); + + /** * Returns the path to the config.ini file as specified in the .product file. */ public String getConfigIniPath(String os); diff --git a/bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/internal/p2/publisher/eclipse/Messages.java b/bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/internal/p2/publisher/eclipse/Messages.java index c914949a0..8c176ba2d 100644 --- a/bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/internal/p2/publisher/eclipse/Messages.java +++ b/bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/internal/p2/publisher/eclipse/Messages.java @@ -22,6 +22,7 @@ public class Messages extends NLS { public static String exception_featureParse; public static String exception_productParse; public static String exception_invalidProductContentType; + public static String exception_invalidFeatureInstallMode; // feature parsing public static String feature_parse_invalidIdOrVersion; diff --git a/bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/internal/p2/publisher/eclipse/ProductFile.java b/bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/internal/p2/publisher/eclipse/ProductFile.java index 73fd078dc..109837b64 100644 --- a/bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/internal/p2/publisher/eclipse/ProductFile.java +++ b/bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/internal/p2/publisher/eclipse/ProductFile.java @@ -61,6 +61,7 @@ public class ProductFile extends DefaultHandler implements IProductDescriptor { private static final String ATTRIBUTE_OS = "os"; //$NON-NLS-1$ private static final String ATTRIBUTE_ARCH = "arch"; //$NON-NLS-1$ private static final String ATTRIBUTE_ENABLED = "enabled"; //$NON-NLS-1$ + private static final String ATTRIBUTE_FEATURE_INSTALL_MODE = "installMode"; //$NON-NLS-1$ private static final String PROPERTY_ECLIPSE_APPLICATION = "eclipse.application"; //$NON-NLS-1$ private static final String PROPERTY_ECLIPSE_PRODUCT = "eclipse.product"; //$NON-NLS-1$ @@ -183,6 +184,7 @@ public class ProductFile extends DefaultHandler implements IProductDescriptor { protected List<FeatureEntry> plugins = new ArrayList<FeatureEntry>(); protected List<FeatureEntry> fragments = new ArrayList<FeatureEntry>(); private final List<FeatureEntry> features = new ArrayList<FeatureEntry>(); + private final List<FeatureEntry> rootFeatures = new ArrayList<FeatureEntry>(); private String splashLocation = null; private String productName = null; private String application = null; @@ -393,10 +395,21 @@ public class ProductFile extends DefaultHandler implements IProductDescriptor { * Returns a List<VersionedName> of features that constitute this product. */ public List<IVersionedId> getFeatures() { + return getFeatures(INCLUDED_FEATURES); + } + + public List<IVersionedId> getFeatures(int options) { List<IVersionedId> result = new LinkedList<IVersionedId>(); - for (FeatureEntry feature : features) { - result.add(new VersionedId(feature.getId(), feature.getVersion())); + if ((options & INCLUDED_FEATURES) != 0) { + for (FeatureEntry feature : features) { + result.add(new VersionedId(feature.getId(), feature.getVersion())); + } + } + if ((options & ROOT_FEATURES) != 0) { + for (FeatureEntry feature : rootFeatures) { + result.add(new VersionedId(feature.getId(), feature.getVersion())); + } } return result; @@ -1099,9 +1112,16 @@ public class ProductFile extends DefaultHandler implements IProductDescriptor { private void processFeature(Attributes attributes) { String featureId = attributes.getValue(ATTRIBUTE_ID); String featureVersion = attributes.getValue(ATTRIBUTE_VERSION); + FeatureInstallMode installMode = FeatureInstallMode.parse(attributes.getValue(ATTRIBUTE_FEATURE_INSTALL_MODE)); FeatureEntry featureEntry = new FeatureEntry(featureId, featureVersion != null ? featureVersion : GENERIC_VERSION_NUMBER, false); - features.add(featureEntry); + switch (installMode) { + case ROOT : + rootFeatures.add(featureEntry); + break; + default : + features.add(featureEntry); + } } private void processProduct(Attributes attributes) { diff --git a/bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/internal/p2/publisher/eclipse/messages.properties b/bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/internal/p2/publisher/eclipse/messages.properties index 4c63bca8c..99db74ae0 100644 --- a/bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/internal/p2/publisher/eclipse/messages.properties +++ b/bundles/org.eclipse.equinox.p2.publisher.eclipse/src/org/eclipse/equinox/internal/p2/publisher/eclipse/messages.properties @@ -16,6 +16,7 @@ exception_missingElement = Unable to find element: {0}. exception_featureParse = Problems parsing the feature {0}. exception_productParse = Problems parsing the product file {0}. exception_invalidProductContentType=Provided value \"{0}\" for product content type is not valid. Allowed values are {1} +exception_invalidFeatureInstallMode=Invalid value for attribute 'installMode': {0} ### feature parsing feature_parse_invalidIdOrVersion= Invalid ID \"{0}\" or version \"{1}\" encountered. diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/AdditionalCoreMatchers.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/AdditionalCoreMatchers.java new file mode 100644 index 000000000..1bd3c120e --- /dev/null +++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/AdditionalCoreMatchers.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2015 SAP SE 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * SAP SE - initial API and implementation + *******************************************************************************/ +package org.eclipse.equinox.p2.tests; + +import java.util.Collection; +import org.hamcrest.*; + +public class AdditionalCoreMatchers { + + /** + * Creates a matcher matching any collection with the given size. + * + * @see CoreMatchers#hasItem(Matcher) + */ + public static <T> Matcher<Collection<? extends T>> hasSize(final int size) { + return new TypeSafeMatcher<Collection<? extends T>>() { + + public void describeTo(Description description) { + description.appendText("a collection with size " + size); + } + + protected boolean matchesSafely(Collection<? extends T> item) { + return item.size() == size; + } + }; + } + +} diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/ProductFileTest.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/ProductFileTest.java index e62ca72bb..8ec7a5fb5 100644 --- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/ProductFileTest.java +++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/publisher/actions/ProductFileTest.java @@ -9,13 +9,18 @@ ******************************************************************************/ package org.eclipse.equinox.p2.tests.publisher.actions; +import static org.eclipse.equinox.p2.tests.AdditionalCoreMatchers.hasSize; +import static org.hamcrest.CoreMatchers.hasItem; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + import java.util.List; import java.util.Map; import junit.framework.TestCase; import org.eclipse.equinox.frameworkadmin.BundleInfo; +import org.eclipse.equinox.internal.p2.publisher.eclipse.IProductDescriptor; import org.eclipse.equinox.internal.p2.publisher.eclipse.ProductFile; -import org.eclipse.equinox.p2.metadata.IVersionedId; -import org.eclipse.equinox.p2.metadata.Version; +import org.eclipse.equinox.p2.metadata.*; import org.eclipse.equinox.p2.tests.TestData; /** @@ -28,6 +33,7 @@ public class ProductFileTest extends TestCase { ProductFile noLauncherFlag = null; ProductFile falseLauncherFlag = null; ProductFile trueLauncherFlag = null; + ProductFile rootFeaturesProduct; String configFile = "/org.eclipse.equinox.p2.tests/testData/ProductActionTest/productWithConfig/config.ini"; private String uidProductFileLocation; @@ -41,6 +47,7 @@ public class ProductFileTest extends TestCase { productFile = new ProductFile(productFileLocation); uidProductFileLocation = TestData.getFile("ProductActionTest/productWithConfig", "uidproduct.product").toString(); uidProductFile = new ProductFile(uidProductFileLocation); + rootFeaturesProduct = new ProductFile(TestData.getFile("ProductActionTest", "rootFeatures.product").toString()); } /** @@ -112,6 +119,24 @@ public class ProductFileTest extends TestCase { assertEquals("1.2", Version.create("3.5.0.v20081110-9C9tEvNEla71LZ2jFz-RFB-t"), ((IVersionedId) features.get(0)).getVersion()); } + public void testGetRootFeatures() { + List<IVersionedId> features = rootFeaturesProduct.getFeatures(IProductDescriptor.ROOT_FEATURES); + assertThat(features, hasItem(new VersionedId("org.eclipse.help", "2.0.102.v20140128"))); + assertThat(features, hasItem(new VersionedId("org.eclipse.egit", "0.0.0"))); + assertThat(features, hasSize(2)); + } + + public void testGetIncludedFeatures() { + List<IVersionedId> features = rootFeaturesProduct.getFeatures(IProductDescriptor.INCLUDED_FEATURES); + assertThat(features, hasItem(new VersionedId("org.eclipse.rcp", "4.4.0.v20140128"))); + assertThat(features, hasItem(new VersionedId("org.eclipse.e4.rcp", "0.0.0"))); + assertThat(features, hasSize(2)); + } + + public void testGetFeaturesOnlyReturnsIncludedFeatures() { + assertThat(rootFeaturesProduct.getFeatures(), is(rootFeaturesProduct.getFeatures(IProductDescriptor.INCLUDED_FEATURES))); + } + /** * Test method for {@link org.eclipse.equinox.internal.p2.publisher.eclipse.ProductFile#getIcons(java.lang.String)}. */ diff --git a/bundles/org.eclipse.equinox.p2.tests/testData/ProductActionTest/rootFeatures.product b/bundles/org.eclipse.equinox.p2.tests/testData/ProductActionTest/rootFeatures.product new file mode 100644 index 000000000..9bb6a22ae --- /dev/null +++ b/bundles/org.eclipse.equinox.p2.tests/testData/ProductActionTest/rootFeatures.product @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?> +<?pde version="3.5"?> + +<product uid="product.with.root.features" useFeatures="true" includeLaunchers="true"> + + <configIni use="default"> + </configIni> + + <launcherArgs> + <vmArgsMac>-XstartOnFirstThread -Dorg.eclipse.swt.internal.carbon.smallFonts</vmArgsMac> + </launcherArgs> + + <plugins> + </plugins> + + <features> + <feature id="org.eclipse.rcp" version="4.4.0.v20140128" installMode="include"/> + <feature id="org.eclipse.e4.rcp"/> <!-- "include" is the default --> + <feature id="org.eclipse.help" version="2.0.102.v20140128" installMode="root"/> + <feature id="org.eclipse.egit" installMode="root"/> + </features> + +</product> |