From 49d079b5b9bd40c34df3193dbb5e765a85ad7f77 Mon Sep 17 00:00:00 2001 From: Hannes Wellmann Date: Sun, 15 Oct 2023 10:45:02 +0200 Subject: [PATCH] Add support for Product Update-site names This a work-around to have https://github.com/eclipse-equinox/p2/pull/353 available now and can be reverted once the mentioned change in P2 is available in Tycho. --- .../publisher/PublishProductToolImpl.java | 120 +++++++++++++++++- 1 file changed, 118 insertions(+), 2 deletions(-) diff --git a/tycho-core/src/main/java/org/eclipse/tycho/p2/tools/publisher/PublishProductToolImpl.java b/tycho-core/src/main/java/org/eclipse/tycho/p2/tools/publisher/PublishProductToolImpl.java index 7ae086009b..733cf0fd71 100644 --- a/tycho-core/src/main/java/org/eclipse/tycho/p2/tools/publisher/PublishProductToolImpl.java +++ b/tycho-core/src/main/java/org/eclipse/tycho/p2/tools/publisher/PublishProductToolImpl.java @@ -16,21 +16,38 @@ import static org.eclipse.tycho.p2.tools.publisher.DependencySeedUtil.createSeed; import java.io.File; +import java.lang.reflect.Field; +import java.net.URI; +import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Collection; +import java.util.HashSet; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; import org.eclipse.core.runtime.AssertionFailedException; import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.URIUtil; +import org.eclipse.equinox.internal.p2.metadata.TouchpointInstruction; import org.eclipse.equinox.internal.p2.publisher.eclipse.IProductDescriptor; import org.eclipse.equinox.internal.p2.publisher.eclipse.ProductFile; import org.eclipse.equinox.p2.metadata.IInstallableUnit; import org.eclipse.equinox.p2.metadata.Version; import org.eclipse.equinox.p2.publisher.AdviceFileAdvice; +import org.eclipse.equinox.p2.publisher.IPublisherAction; import org.eclipse.equinox.p2.publisher.IPublisherAdvice; +import org.eclipse.equinox.p2.publisher.eclipse.ConfigCUsAction; +import org.eclipse.equinox.p2.publisher.eclipse.IConfigAdvice; import org.eclipse.equinox.p2.publisher.eclipse.ProductAction; +import org.eclipse.equinox.p2.publisher.eclipse.ProductFileAdvice; +import org.eclipse.equinox.p2.repository.IRepository; +import org.eclipse.equinox.p2.repository.IRepositoryReference; import org.eclipse.equinox.p2.repository.artifact.IArtifactRepository; import org.eclipse.equinox.p2.repository.metadata.IMetadataRepository; +import org.eclipse.equinox.p2.repository.spi.RepositoryReference; import org.eclipse.tycho.ArtifactKey; import org.eclipse.tycho.ArtifactType; import org.eclipse.tycho.BuildFailureException; @@ -41,6 +58,7 @@ import org.eclipse.tycho.p2.repository.PublishingRepository; import org.eclipse.tycho.p2.tools.publisher.facade.PublishProductTool; import org.eclipse.tycho.targetplatform.P2TargetPlatform; +import org.xml.sax.Attributes; /** * Tool for transforming product definition source files into p2 metadata and artifacts. Includes @@ -77,7 +95,58 @@ public List publishProduct(File productFile, File launcherBinari IPublisherAdvice[] advice = getProductSpecificAdviceFileAdvice(productFile, expandedProduct); - ProductAction action = new ProductAction(null, expandedProduct, flavor, launcherBinaries); + ProductAction action = new ProductAction(null, expandedProduct, flavor, launcherBinaries) { + //TODO: Remove this anonymous extension once https://github.com/eclipse-equinox/p2/pull/353 is available + @Override + protected IPublisherAction createConfigCUsAction() { + return new ConfigCUsAction(info, flavor, id, version) { + private static final Collection PROPERTIES_TO_SKIP = Set.of("osgi.frameworkClassPath", + "osgi.framework", "osgi.bundles", "eof", "eclipse.p2.profile", "eclipse.p2.data.area", + "org.eclipse.update.reconcile", "org.eclipse.equinox.simpleconfigurator.configUrl"); + + @Override + protected String[] getConfigurationStrings(Collection configAdvice) { + String configurationData = ""; //$NON-NLS-1$ + String unconfigurationData = ""; //$NON-NLS-1$ + Set properties = new HashSet<>(); + for (IConfigAdvice advice : configAdvice) { + for (Entry aProperty : advice.getProperties().entrySet()) { + String key = aProperty.getKey(); + if (PROPERTIES_TO_SKIP.contains(key) && !properties.contains(key)) { + properties.add(key); + Map parameters = new LinkedHashMap<>(); + parameters.put("propName", key); //$NON-NLS-1$ + parameters.put("propValue", aProperty.getValue()); //$NON-NLS-1$ + configurationData += TouchpointInstruction.encodeAction("setProgramProperty", //$NON-NLS-1$ + parameters); + parameters.put("propValue", ""); //$NON-NLS-1$//$NON-NLS-2$ + unconfigurationData += TouchpointInstruction.encodeAction("setProgramProperty", //$NON-NLS-1$ + parameters); + } + } + if (advice instanceof ProductFileAdvice) { + for (IRepositoryReference repo : ((ProductFileAdvice) advice).getUpdateRepositories()) { + Map parameters = new LinkedHashMap<>(); + parameters.put("type", Integer.toString(repo.getType())); //$NON-NLS-1$ + parameters.put("location", repo.getLocation().toString()); //$NON-NLS-1$ + if (repo.getNickname() != null) { + parameters.put("name", repo.getNickname()); //$NON-NLS-1$ + } + parameters.put("enabled", Boolean.toString( //$NON-NLS-1$ + (repo.getOptions() & IRepository.ENABLED) == IRepository.ENABLED)); + configurationData += TouchpointInstruction.encodeAction("addRepository", //$NON-NLS-1$ + parameters); + parameters.remove("enabled"); //$NON-NLS-1$ + unconfigurationData += TouchpointInstruction.encodeAction("removeRepository", //$NON-NLS-1$ + parameters); + } + } + } + return new String[] { configurationData, unconfigurationData }; + } + }; + } + }; IMetadataRepository metadataRepository = publishingRepository.getMetadataRepository(); IArtifactRepository artifactRepository = publishingRepository .getArtifactRepositoryForWriting(new ProductBinariesWriteSession(expandedProduct.getId())); @@ -126,7 +195,54 @@ private static void addRootFeatures(ExpandedProduct product, List repositories = getRepositoryEntries(); + URI uri = URIUtil.fromString(attributes.getValue("location")); + String name = attributes.getValue("name"); + boolean enabled = Boolean.parseBoolean(attributes.getValue("enabled")); + int options = enabled ? IRepository.ENABLED : IRepository.NONE; + // First add a metadata repository + repositories.add(new RepositoryReference(uri, name, IRepository.TYPE_METADATA, options)); + // Now a colocated artifact repository + repositories.add(new RepositoryReference(uri, name, IRepository.TYPE_ARTIFACT, options)); + } catch (URISyntaxException e) { + // ignore malformed URI's. These should have already been caught by the UI + } + } + }; } catch (Exception e) { throw new BuildFailureException( "Cannot parse product file " + productFile.getAbsolutePath() + ": " + e.getMessage(), e); //$NON-NLS-1$