From c984844f25a814530d46a81eabfc97e5384bff72 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Wed, 5 Aug 2020 08:02:58 +0200 Subject: [PATCH] adds versions to dependencies of the InstalledPluginDescriptor --- .../scm/plugin/InstalledPluginDescriptor.java | 59 ++++++++--- .../java/sonia/scm/plugin/NameAndVersion.java | 97 +++++++++++++++++++ .../plugin/InstalledPluginDescriptorTest.java | 63 ++++++++++++ .../sonia/scm/plugin/review-plugin.xml | 74 ++++++++++++++ 4 files changed, 280 insertions(+), 13 deletions(-) create mode 100644 scm-core/src/main/java/sonia/scm/plugin/NameAndVersion.java create mode 100644 scm-core/src/test/java/sonia/scm/plugin/InstalledPluginDescriptorTest.java create mode 100644 scm-core/src/test/resources/sonia/scm/plugin/review-plugin.xml diff --git a/scm-core/src/main/java/sonia/scm/plugin/InstalledPluginDescriptor.java b/scm-core/src/main/java/sonia/scm/plugin/InstalledPluginDescriptor.java index faedb2a6f5..785994bb54 100644 --- a/scm-core/src/main/java/sonia/scm/plugin/InstalledPluginDescriptor.java +++ b/scm-core/src/main/java/sonia/scm/plugin/InstalledPluginDescriptor.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ - + package sonia.scm.plugin; //~--- non-JDK imports -------------------------------------------------------- @@ -37,6 +37,7 @@ import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlElementWrapper; import javax.xml.bind.annotation.XmlRootElement; import java.util.Set; +import java.util.stream.Collectors; //~--- JDK imports ------------------------------------------------------------ @@ -67,7 +68,11 @@ public final class InstalledPluginDescriptor extends ScmModule implements Plugin * @param condition * @param childFirstClassLoader * @param dependencies + * + * @deprecated this constructor uses dependencies with plain strings, + * this is deprecated because the version information is missing. */ + @Deprecated public InstalledPluginDescriptor(int scmVersion, PluginInformation information, PluginResources resources, PluginCondition condition, boolean childFirstClassLoader, Set dependencies, Set optionalDependencies) @@ -77,8 +82,17 @@ public final class InstalledPluginDescriptor extends ScmModule implements Plugin this.resources = resources; this.condition = condition; this.childFirstClassLoader = childFirstClassLoader; - this.dependencies = dependencies; - this.optionalDependencies = optionalDependencies; + this.dependencies = mapToNameAndVersionSet(dependencies); + this.optionalDependencies = mapToNameAndVersionSet(optionalDependencies); + } + + private static Set mapToNameAndVersionSet(Set dependencies) { + if (dependencies == null){ + return ImmutableSet.of(); + } + return dependencies.stream() + .map(d -> new NameAndVersion(d, null)) + .collect(Collectors.toSet()); } //~--- methods -------------------------------------------------------------- @@ -173,13 +187,19 @@ public final class InstalledPluginDescriptor extends ScmModule implements Plugin * @since 2.0.0 */ @Override - public Set getDependencies() - { - if (dependencies == null) - { + public Set getDependencies() { + return mapToStringSet(getDependenciesWithVersion()); + } + + /** + * Returns name and versions of the plugins which are this plugin depends on. + * @return dependencies with their versions + * @since 2.4.0 + */ + public Set getDependenciesWithVersion() { + if (dependencies == null) { dependencies = ImmutableSet.of(); } - return dependencies; } @@ -193,11 +213,18 @@ public final class InstalledPluginDescriptor extends ScmModule implements Plugin */ @Override public Set getOptionalDependencies() { - if (optionalDependencies == null) - { + return mapToStringSet(getOptionalDependenciesWithVersion()); + } + + /** + * Returns name and versions of the plugins which are this plugin optional depends on. + * @return optional dependencies with their versions + * @since 2.4.0 + */ + public Set getOptionalDependenciesWithVersion() { + if (optionalDependencies == null) { optionalDependencies = ImmutableSet.of(); } - return optionalDependencies; } @@ -205,6 +232,12 @@ public final class InstalledPluginDescriptor extends ScmModule implements Plugin return ImmutableSet.copyOf(Iterables.concat(getDependencies(), getOptionalDependencies())); } + private Set mapToStringSet(Set dependencies) { + return dependencies.stream() + .map(NameAndVersion::getName) + .collect(Collectors.toSet()); + } + /** * Method description * @@ -263,12 +296,12 @@ public final class InstalledPluginDescriptor extends ScmModule implements Plugin /** Field description */ @XmlElement(name = "dependency") @XmlElementWrapper(name = "dependencies") - private Set dependencies; + private Set dependencies; /** Field description */ @XmlElement(name = "dependency") @XmlElementWrapper(name = "optional-dependencies") - private Set optionalDependencies; + private Set optionalDependencies; /** Field description */ @XmlElement(name = "information") diff --git a/scm-core/src/main/java/sonia/scm/plugin/NameAndVersion.java b/scm-core/src/main/java/sonia/scm/plugin/NameAndVersion.java new file mode 100644 index 0000000000..f867c14c17 --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/plugin/NameAndVersion.java @@ -0,0 +1,97 @@ +/* + * MIT License + * + * Copyright (c) 2020-present Cloudogu GmbH and Contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package sonia.scm.plugin; + +import com.google.common.base.Strings; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import sonia.scm.version.Version; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlValue; +import javax.xml.bind.annotation.adapters.XmlAdapter; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; +import java.util.Optional; + +/** + * @since 2.4.0 + */ +@Getter +@EqualsAndHashCode +@XmlAccessorType(XmlAccessType.FIELD) +public class NameAndVersion { + + @XmlValue + private String name; + + @XmlAttribute(name = "version") + @XmlJavaTypeAdapter(VersionXmlAdapter.class) + private Version version; + + NameAndVersion() { + // required for jaxb + } + + public NameAndVersion(String name) { + this(name, null); + } + + public NameAndVersion(String name, String version) { + this.name = name; + if (!Strings.isNullOrEmpty(version)) { + this.version = Version.parse(version); + } + } + + public Optional getVersion() { + return Optional.ofNullable(version); + } + + @Override + public String toString() { + return name + (version != null ? ":" + version.getParsedVersion() : ""); + } + + static class VersionXmlAdapter extends XmlAdapter { + + @Override + public Version unmarshal(String v) { + if (Strings.isNullOrEmpty(v)) { + return null; + } + return Version.parse(v); + } + + @Override + public String marshal(Version v) { + if (v != null) { + return v.getUnparsedVersion(); + } + return null; + } + } +} diff --git a/scm-core/src/test/java/sonia/scm/plugin/InstalledPluginDescriptorTest.java b/scm-core/src/test/java/sonia/scm/plugin/InstalledPluginDescriptorTest.java new file mode 100644 index 0000000000..ce78d659a5 --- /dev/null +++ b/scm-core/src/test/java/sonia/scm/plugin/InstalledPluginDescriptorTest.java @@ -0,0 +1,63 @@ +/* + * MIT License + * + * Copyright (c) 2020-present Cloudogu GmbH and Contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package sonia.scm.plugin; + +import com.google.common.io.Resources; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import javax.xml.bind.JAXB; +import java.net.URL; + +import static org.assertj.core.api.Assertions.assertThat; + +class InstalledPluginDescriptorTest { + + private static InstalledPluginDescriptor descriptor; + + @BeforeAll + @SuppressWarnings("UnstableApiUsage") + static void unmarshal() { + URL resource = Resources.getResource("sonia/scm/plugin/review-plugin.xml"); + descriptor = JAXB.unmarshal(resource, InstalledPluginDescriptor.class); + } + + @Test + void shouldUnmarshallDependencies() { + assertThat(descriptor.getDependencies()).containsOnly("scm-mail-plugin"); + assertThat(descriptor.getOptionalDependencies()).containsOnly("scm-editor-plugin", "scm-landingpage-plugin"); + assertThat(descriptor.getDependenciesInclusiveOptionals()).containsOnly("scm-mail-plugin", "scm-editor-plugin", "scm-landingpage-plugin"); + } + + @Test + void shouldUnmarshallDependenciesWithVersion() { + assertThat(descriptor.getDependenciesWithVersion()).containsOnly(new NameAndVersion("scm-mail-plugin", "2.1.0")); + assertThat(descriptor.getOptionalDependenciesWithVersion()).containsOnly( + new NameAndVersion("scm-landingpage-plugin", "1.0.0"), + new NameAndVersion("scm-editor-plugin") + ); + } + +} diff --git a/scm-core/src/test/resources/sonia/scm/plugin/review-plugin.xml b/scm-core/src/test/resources/sonia/scm/plugin/review-plugin.xml new file mode 100644 index 0000000000..dccadb5b12 --- /dev/null +++ b/scm-core/src/test/resources/sonia/scm/plugin/review-plugin.xml @@ -0,0 +1,74 @@ + + + + 2 + + Review + Cloudogu GmbH + Workflow + scm-review-plugin + 2.3.0-SNAPSHOT + Depict a review process with pull requests + + + 2.4.0-SNAPSHOT + + + + + + com.cloudogu.scm.review.emailnotification.EmailNotificationHook + com.cloudogu.scm.review.pullrequest.service.PullRequestRejectedEvent + + + Each {@link Rule} class implementation defines a type of workflow rule.<br> + <br> + Rules applied to your repositories are represented by {@link AppliedRule}s<br> + to support multiple {@link Rule}s of the same type with distinct configuration. + + true + true + com.cloudogu.scm.review.workflow.Rule + + + v2/pull-requests + com.cloudogu.scm.review.config.api.RepositoryConfigResource + + + com.cloudogu.scm.review.pullrequest.service.PullRequestEvent + + + com.cloudogu.scm.review.ProcessChangedFilesHook + + + scm-mail-plugin + + + scm-editor-plugin + scm-landingpage-plugin + +