Skip to content

Commit

Permalink
Publish a product IU into the PDE launch profile
Browse files Browse the repository at this point in the history
Currently PDE published already root-feature what is already a great
win. But in a usual product install there is also one unit for the
product and because that is missing it can't be updated in a launched
product from the IDE.

This adds a very bare unit to the profile by just publish the product
id/version/name, but already allows that P2 pick up the unit when an
update is requested.
  • Loading branch information
laeubi committed Apr 24, 2024
1 parent 65942e1 commit 0261aa9
Show file tree
Hide file tree
Showing 7 changed files with 221 additions and 6 deletions.
3 changes: 2 additions & 1 deletion org.eclipse.pde.doc.user/forceQualifierUpdate.txt
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
Comparator Errors in 4.32 I-Build I20240304-0140
Comparator Errors in 4.32 I-Build I20240304-0140
Update to IPDELauncherConstants
3 changes: 2 additions & 1 deletion ui/org.eclipse.pde.core/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,8 @@ Require-Bundle:
org.eclipse.equinox.p2.garbagecollector;bundle-version="[1.3.100,2.0.0)",
org.eclipse.equinox.p2.touchpoint.eclipse;bundle-version="[2.4.100,3.0.0)",
org.eclipse.core.expressions;bundle-version="[3.9.200,4.0.0)",
org.eclipse.core.filesystem;bundle-version="[1.10.200,2.0.0)"
org.eclipse.core.filesystem;bundle-version="[1.10.200,2.0.0)",
org.eclipse.equinox.p2.publisher
Bundle-RequiredExecutionEnvironment: JavaSE-17
Bundle-ActivationPolicy: lazy
Automatic-Module-Name: org.eclipse.pde.core
Expand Down
168 changes: 166 additions & 2 deletions ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/P2Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@
import org.eclipse.core.runtime.URIUtil;
import org.eclipse.equinox.frameworkadmin.BundleInfo;
import org.eclipse.equinox.internal.p2.metadata.InstallableUnit;
import org.eclipse.equinox.internal.p2.publisher.eclipse.IProductDescriptor;
import org.eclipse.equinox.internal.p2.publisher.eclipse.ProductContentType;
import org.eclipse.equinox.p2.core.IProvisioningAgent;
import org.eclipse.equinox.p2.core.IProvisioningAgentProvider;
import org.eclipse.equinox.p2.engine.IEngine;
Expand All @@ -56,12 +58,18 @@
import org.eclipse.equinox.p2.metadata.IRequirement;
import org.eclipse.equinox.p2.metadata.ITouchpointType;
import org.eclipse.equinox.p2.metadata.IUpdateDescriptor;
import org.eclipse.equinox.p2.metadata.IVersionedId;
import org.eclipse.equinox.p2.metadata.MetadataFactory;
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.metadata.expression.IMatchExpression;
import org.eclipse.equinox.p2.planner.ProfileInclusionRules;
import org.eclipse.equinox.p2.publisher.PublisherInfo;
import org.eclipse.equinox.p2.publisher.PublisherResult;
import org.eclipse.equinox.p2.publisher.eclipse.ProductAction;
import org.eclipse.equinox.p2.query.QueryUtil;
import org.eclipse.equinox.p2.repository.IRepositoryReference;
import org.eclipse.equinox.simpleconfigurator.manipulator.SimpleConfiguratorManipulator;
import org.eclipse.osgi.service.resolver.BundleDescription;
import org.eclipse.osgi.service.resolver.BundleSpecification;
Expand Down Expand Up @@ -408,7 +416,7 @@ public static boolean profileExists(String profileID, File p2DataArea) throws Co
*/
public static void createProfile(String profileID, File p2DataArea, Collection<List<IPluginModelBase>> bundles)
throws CoreException {
createProfile(profileID, p2DataArea, bundles, null);
createProfile(profileID, p2DataArea, bundles, null, null);
}

/**
Expand Down Expand Up @@ -436,7 +444,7 @@ public static void createProfile(String profileID, File p2DataArea, Collection<L
* if the profile cannot be generated
*/
public static void createProfile(String profileID, File p2DataArea, Collection<List<IPluginModelBase>> bundles,
Map<IFeature, Boolean> featureMap) throws CoreException {
Map<IFeature, Boolean> featureMap, ProductInfo productInfo) throws CoreException {
// Acquire the required p2 services, creating an agent in the target p2 metadata area
IProvisioningAgentProvider provider = PDECore.getDefault().acquireService(IProvisioningAgentProvider.class);
if (provider == null) {
Expand Down Expand Up @@ -493,6 +501,158 @@ public static void createProfile(String profileID, File p2DataArea, Collection<L
createFeatureIUs(featureEntry.getKey(), featureEntry.getValue(), plan, plugins, features);
}
}
if (productInfo != null) {
ProductAction productAction = new ProductAction(null, new IProductDescriptor() {

@Override
public boolean useFeatures() {
return false;
}

@Override
public boolean includeLaunchers() {
return false;
}

@Override
public boolean hasFeatures() {
return false;
}

@Override
public boolean hasBundles() {
return false;
}

@Override
public String getVersion() {
return productInfo.version();
}

@Override
public String getVMArguments(String os, String arch) {
return null;
}

@Override
public String getVMArguments(String os) {
return null;
}

@Override
public String getVM(String os) {
return null;
}

@Override
public String getSplashLocation() {
return null;
}

@Override
public List<IRepositoryReference> getRepositoryEntries() {
return List.of();
}

@Override
public String getProgramArguments(String os, String arch) {
return null;
}

@Override
public String getProgramArguments(String os) {
return null;
}

@Override
public String getProductName() {
return productInfo.name();
}

@Override
public String getProductId() {
return null;
}

@Override
public ProductContentType getProductContentType() {
return ProductContentType.MIXED;
}

@Override
public File getLocation() {
return null;
}

@Override
public String getLicenseURL() {
return null;
}

@Override
public String getLicenseText() {
return null;
}

@Override
public String getLauncherName() {
return null;
}

@Override
public String getId() {
return productInfo.id();
}

@Override
public String[] getIcons(String os) {
return null;
}

@Override
public List<IVersionedId> getFeatures(int options) {
return List.of();
}

@Override
public List<IVersionedId> getFeatures() {
return List.of();
}

@Override
public Map<String, String> getConfigurationProperties(String os, String arch) {
return null;
}

@Override
public Map<String, String> getConfigurationProperties() {
return null;
}

@Override
public String getConfigIniPath(String os) {
return null;
}

@Override
public List<IVersionedId> getBundles() {
return List.of();
}

@Override
public List<BundleInfo> getBundleInfos() {
return List.of();
}

@Override
public String getApplication() {
return null;
}
}, P2_FLAVOR_DEFAULT, null);
PublisherResult results = new PublisherResult();
productAction.perform(new PublisherInfo(), results, null);
results.query(QueryUtil.ALL_UNITS, null).forEach(plan::addInstallableUnit);
}
IPhaseSet phaseSet = PhaseSetFactory.createDefaultPhaseSetExcluding(new String[] {PhaseSetFactory.PHASE_CHECK_TRUST, PhaseSetFactory.PHASE_COLLECT, PhaseSetFactory.PHASE_CONFIGURE, PhaseSetFactory.PHASE_UNCONFIGURE, PhaseSetFactory.PHASE_UNINSTALL});
IStatus status = engine.perform(plan, phaseSet, new NullProgressMonitor());

Expand Down Expand Up @@ -794,4 +954,8 @@ private static VersionRange fromOSGiVersionRange(org.eclipse.osgi.service.resolv
}
return new VersionRange(fromOSGiVersion(range.getMinimum()), range.getIncludeMinimum(), fromOSGiVersion(range.getRight()), range.getIncludeMaximum());
}

public static record ProductInfo(String id, String version, String name) {

}
}
2 changes: 1 addition & 1 deletion ui/org.eclipse.pde.launching/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %name
Bundle-SymbolicName: org.eclipse.pde.launching;singleton:=true
Bundle-Version: 3.12.100.qualifier
Bundle-Version: 3.13.0.qualifier
Bundle-RequiredExecutionEnvironment: JavaSE-17
Bundle-Vendor: %provider-name
Require-Bundle: org.eclipse.jdt.junit.core;bundle-version="[3.6.0,4.0.0)",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import org.eclipse.pde.core.plugin.TargetPlatform;
import org.eclipse.pde.internal.build.IPDEBuildConstants;
import org.eclipse.pde.internal.core.P2Utils;
import org.eclipse.pde.internal.core.P2Utils.ProductInfo;
import org.eclipse.pde.internal.core.PDECore;
import org.eclipse.pde.internal.core.TargetPlatformHelper;
import org.eclipse.pde.internal.core.ifeature.IFeature;
Expand Down Expand Up @@ -216,7 +217,16 @@ else if ((productID != null && !productID.equals(properties.get(PROP_PRODUCT)) |

// Unless we are restarting an existing profile, generate/overwrite the profile
if (!configuration.getAttribute(IPDEConstants.RESTART, false) || !P2Utils.profileExists(profileID, p2DataArea)) {
P2Utils.createProfile(profileID, p2DataArea, bundles.values(), features);
ProductInfo productInfo;
String productId = configuration.getAttribute(IPDELauncherConstants.PRODUCT_ID, ""); //$NON-NLS-1$
String productVersion = configuration.getAttribute(IPDELauncherConstants.PRODUCT_VERSION, "0.0.0"); //$NON-NLS-1$
String productName = configuration.getAttribute(IPDELauncherConstants.PRODUCT_NAME, ""); //$NON-NLS-1$
if (productId.isBlank()) {
productInfo = null;
} else {
productInfo = new ProductInfo(productId, productVersion, productName);
}
P2Utils.createProfile(profileID, p2DataArea, bundles.values(), features, productInfo);
}
properties.setProperty("eclipse.p2.profile", profileID); //$NON-NLS-1$
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,27 @@ public interface IPDELauncherConstants {
*/
String PRODUCT = "product"; //$NON-NLS-1$

/**
* Launch configuration attribute key. The value is a string specifying
* the product id to be published in the profile of the run if enabled.
* @since 3.13
*/
String PRODUCT_ID = "productId"; //$NON-NLS-1$

/**
* Launch configuration attribute key. The value is a string specifying
* the product version to be published in the profile of the run if enabled.
* @since 3.13
*/
String PRODUCT_VERSION = "productVersion"; //$NON-NLS-1$

/**
* Launch configuration attribute key. The value is a string specifying
* the product name to be published in the profile of the run if enabled.
* @since 3.13
*/
String PRODUCT_NAME = "productName"; //$NON-NLS-1$

/**
* Launch configuration attribute key. The value is a boolean specifying
* if the launch should appear in product-mode. If the value is <code>false</code>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,24 @@ public ILaunchConfiguration findLaunchConfiguration() throws CoreException {
private ILaunchConfigurationWorkingCopy refreshConfiguration(ILaunchConfigurationWorkingCopy wc) {
wc.setAttribute(IPDELauncherConstants.PRODUCT, fProduct.getProductId());
wc.setAttribute(IPDELauncherConstants.APPLICATION, fProduct.getApplication());
String productId = fProduct.getId();
if (productId == null || productId.isEmpty()) {
wc.removeAttribute(IPDELauncherConstants.PRODUCT_ID);
} else {
wc.setAttribute(IPDELauncherConstants.PRODUCT_ID, productId);
}
String productVersion = fProduct.getVersion();
if (productVersion == null || productVersion.isEmpty()) {
wc.removeAttribute(IPDELauncherConstants.PRODUCT_VERSION);
} else {
wc.setAttribute(IPDELauncherConstants.PRODUCT_VERSION, productVersion);
}
String productName = fProduct.getName();
if (productName == null || productName.isEmpty()) {
wc.removeAttribute(IPDELauncherConstants.PRODUCT_NAME);
} else {
wc.setAttribute(IPDELauncherConstants.PRODUCT_NAME, productName);
}

if (TargetPlatformHelper.usesNewApplicationModel()) {
wc.setAttribute(IPDEConstants.LAUNCHER_PDE_VERSION, "3.3"); //$NON-NLS-1$
Expand Down

0 comments on commit 0261aa9

Please sign in to comment.