diff --git a/CHANGES.md b/CHANGES.md index 72a0d432d..b434f7ed2 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,6 +1,8 @@ # Goomph releases ## [Unreleased] +### Added +- Added `CategoryPublisher` ([#124](https://github.com/diffplug/goomph/issues/124)) ## [3.23.0] - 2020-06-17 ### Added diff --git a/README.md b/README.md index 807816d74..fcafad55d 100644 --- a/README.md +++ b/README.md @@ -89,6 +89,7 @@ Below is an index of Goomph's capabilities, along with links to the javadoc wher * [`asmaven`](https://javadoc.io/static/com.diffplug.gradle/goomph/3.23.0/com/diffplug/gradle/p2/AsMavenPlugin.html) downloads dependencies from a p2 repository and makes them available in a local maven repository. * [`P2Model`](https://javadoc.io/static/com.diffplug.gradle/goomph/3.23.0/com/diffplug/gradle/p2/P2Model.html) models a set of p2 repositories and IUs, and provides convenience methods for running p2-director or the p2.mirror ant task against these. * [`P2AntRunner`](https://javadoc.io/static/com.diffplug.gradle/goomph/3.23.0/com/diffplug/gradle/p2/P2AntRunner.html) runs eclipse ant tasks. +* [`CategoryPublisher`](https://javadoc.io/static/com.diffplug.gradle/goomph/3.23.0/com/diffplug/gradle/p2/CategoryPublisher.html) models the CategoryPublisher eclipse application. * [`FeaturesAndBundlesPublisher`](https://javadoc.io/static/com.diffplug.gradle/goomph/3.23.0/com/diffplug/gradle/p2/FeaturesAndBundlesPublisher.html) models the FeaturesAndBundlesPublisher eclipse application. * [`Repo2Runnable`](https://javadoc.io/static/com.diffplug.gradle/goomph/3.23.0/com/diffplug/gradle/p2/Repo2Runnable.html) models the Repo2Runnable eclipse application. diff --git a/src/main/java/com/diffplug/gradle/p2/CategoryPublisher.java b/src/main/java/com/diffplug/gradle/p2/CategoryPublisher.java new file mode 100644 index 000000000..d7a268e73 --- /dev/null +++ b/src/main/java/com/diffplug/gradle/p2/CategoryPublisher.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2020 DiffPlug + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.diffplug.gradle.p2; + + +import com.diffplug.gradle.FileMisc; +import com.diffplug.gradle.eclipserunner.EclipseApp; +import com.diffplug.gradle.pde.EclipseRelease; +import com.diffplug.gradle.pde.PdeInstallation; +import java.io.File; + +/** + * Models the CategoryPublisher application ([eclipse docs](https://wiki.eclipse.org/Equinox/p2/Publisher#Category_Publisher). + */ +public class CategoryPublisher extends EclipseApp { + + private final EclipseRelease eclipseRelease; + + /** + * Creates a CategoryPublisher + * + * @param eclipseRelease The eclipse release to be used to run the public application + * */ + public CategoryPublisher(EclipseRelease eclipseRelease) { + super("org.eclipse.equinox.p2.publisher.CategoryPublisher"); + consolelog(); + this.eclipseRelease = eclipseRelease; + } + + /** Compress the output index */ + public void compress() { + addArg("compress"); + } + + /** Sets the given location to be the target for metadata. */ + public void metadataRepository(File file) { + addArg("metadataRepository", FileMisc.asUrl(file)); + } + + /** Sets the given location of context metadata. */ + public void contextMetadata(File file) { + addArg("contextMetadata", FileMisc.asUrl(file)); + } + + /** Sets the given location of the category definition. */ + public void categoryDefinition(File file) { + addArg("categoryDefinition", FileMisc.asUrl(file)); + } + + /** Sets the given category qualifier */ + public void categoryQualifier(String categoryQualifier) { + addArg("categoryQualifier", categoryQualifier); + } + + public void runUsingPdeInstallation() throws Exception { + runUsing(PdeInstallation.from(eclipseRelease)); + } +} diff --git a/src/test/java/com/diffplug/gradle/p2/CategoryPublisherTest.java b/src/test/java/com/diffplug/gradle/p2/CategoryPublisherTest.java new file mode 100644 index 000000000..66d8a7604 --- /dev/null +++ b/src/test/java/com/diffplug/gradle/p2/CategoryPublisherTest.java @@ -0,0 +1,160 @@ +/* + * Copyright (C) 2020 DiffPlug + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.diffplug.gradle.p2; + + +import com.diffplug.gradle.GradleIntegrationTest; +import java.io.File; +import java.io.IOException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import org.junit.Assert; +import org.junit.Test; + +public class CategoryPublisherTest extends GradleIntegrationTest { + + // Eclipse version used for application execution + private static String ECLIPSE_PDE_VERSION = "4.8.0"; + + private static String FEATURE_ID = "goomph.test.feature"; + private static String FEATURE_VERSION = "1.1.1"; + private static String FEATURE_JAR_NAME = FEATURE_ID + "_" + FEATURE_VERSION + ".jar"; + + private static String PLUGIN_NAME = "goomph.test.plugin"; + private static String PLUGIN_VERSION = "0.2.0"; + private static String PLUGIN_JAR_NAME = PLUGIN_NAME + "_" + PLUGIN_VERSION + ".jar"; + + // Directory used as target of the applications + private static String PROJECT_DIR_PATH = "project"; + private static String PLUGINS_DIR_PATH = PROJECT_DIR_PATH + "/plugins"; + private static String FEATURES_DIR_PATH = PROJECT_DIR_PATH + "/features"; + + private static String CATEGORY_FILE_PATH = "category/category.xml"; + private static String CATEGORY_NAME = "TestCategory"; + + private static String PUBLISH_CATEGORY_TASK_NAME = "publishCategory"; + private static String PUBLISH_FEATURES_AND_BUNDLES_TASK_NAME = "publishFeaturesAndBundles"; + + /** + * Tests the update site creation using the {@see FeaturesAndBundlesPublisher} + * and {@see CategoryPublisher} + **/ + @Test + public void testCreateUpdateSite() throws IOException { + + write( + "build.gradle", + "plugins {", + " id 'com.diffplug.p2.asmaven'", + "}", + "import com.diffplug.gradle.pde.EclipseRelease", + "import com.diffplug.gradle.p2.CategoryPublisher", + "import com.diffplug.gradle.p2.FeaturesAndBundlesPublisher", + "tasks.register('testProjectJar', Jar) {", + " archiveFileName = 'test.jar'", + " destinationDirectory = file('" + PLUGINS_DIR_PATH + "')", + " manifest{attributes('Bundle-SymbolicName': '" + PLUGIN_NAME + "', 'Bundle-Version': '" + PLUGIN_VERSION + "')}", + "}", + "tasks.register('" + PUBLISH_FEATURES_AND_BUNDLES_TASK_NAME + "') {", + " dependsOn('testProjectJar')", + " doLast {", + " new FeaturesAndBundlesPublisher().with {", + " source(file('" + PROJECT_DIR_PATH + "'))", + " inplace()", + " append()", + " publishArtifacts()", + " runUsingBootstrapper()", + " }", + " }", + "}", + "tasks.register('" + PUBLISH_CATEGORY_TASK_NAME + "') {", + " doLast {", + " new CategoryPublisher(EclipseRelease.official('" + ECLIPSE_PDE_VERSION + "')).with {", + " metadataRepository(file('" + PROJECT_DIR_PATH + "'))", + " categoryDefinition(file('" + CATEGORY_FILE_PATH + "'))", + " runUsingPdeInstallation()", + " }", + " }", + "}"); + + folder.newFolder(PLUGINS_DIR_PATH); + folder.newFolder(FEATURES_DIR_PATH); + + writeFeatureXml(); + writeCategoryDefinition(); + + /* Execute FeaturesAndBundlesPublisher using the file structure: + * project + * - features + * - feature.xml + * - plugins + * - test.jar // created by task 'testProjectJar' + */ + gradleRunner().forwardOutput().withArguments(PUBLISH_FEATURES_AND_BUNDLES_TASK_NAME).build(); + + // Verify result of FeaturesAndBundlesPublisher application execution + String artifactsXml = read(PROJECT_DIR_PATH + "/artifacts.xml"); + Assert.assertTrue("FeaturesAndBundles application does not found plugin specified in features.xml", + artifactsXml.contains("id='goomph.test.plugin'")); + Assert.assertTrue("FeaturesAndBundles application does not create a feature jar", + new File(folder.getRoot(), FEATURES_DIR_PATH + '/' + FEATURE_JAR_NAME).exists()); + Assert.assertTrue("FeaturesAndBundles application does not create a plugin jar", + new File(folder.getRoot(), PLUGINS_DIR_PATH + '/' + PLUGIN_JAR_NAME).exists()); + + Pattern categoryContextPattern = Pattern.compile("\\s*" + + ""); + + String contentXML = read(PROJECT_DIR_PATH + "/content.xml"); + Matcher m = categoryContextPattern.matcher(contentXML); + Assert.assertFalse("content.xml already contains category metadata", m.find()); + + // Execute CategoryPublisher + gradleRunner().forwardOutput().withArguments(PUBLISH_CATEGORY_TASK_NAME).build(); + + // Verify result of CategoryPublisher application execution + contentXML = read(PROJECT_DIR_PATH + "/content.xml"); + m = categoryContextPattern.matcher(contentXML); + Assert.assertTrue("CategoryPublisher application does not add the category metadata to content.xml", m.find()); + } + + private void writeFeatureXml() throws IOException { + write(FEATURES_DIR_PATH + "/feature.xml", + "", + "", + " ", + " ", + ""); + } + + private void writeCategoryDefinition() throws IOException { + write(CATEGORY_FILE_PATH, + "", + "", + " ", + " ", + " ", + " ", + " ", + ""); + } +}