mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-10 15:35:49 +01:00
Merge with default
This commit is contained in:
@@ -23,7 +23,7 @@
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<!--- root element of the plugin descriptor -->
|
<!--- root element of the plugin descriptor -->
|
||||||
<!ELEMENT plugin (scm-version|information|child-first-classloader|conditions|resources|dependencies|extension|extension-point|rest-resource|subscriber)*>
|
<!ELEMENT plugin (scm-version|information|child-first-classloader|conditions|resources|dependencies|optional-dependencies|extension|extension-point|rest-resource|subscriber)*>
|
||||||
|
|
||||||
<!--- major scm-manager version -->
|
<!--- major scm-manager version -->
|
||||||
<!ELEMENT scm-version (#PCDATA)>
|
<!ELEMENT scm-version (#PCDATA)>
|
||||||
@@ -79,13 +79,19 @@
|
|||||||
<!--- contains plugin dependencies -->
|
<!--- contains plugin dependencies -->
|
||||||
<!ELEMENT dependencies (dependency)*>
|
<!ELEMENT dependencies (dependency)*>
|
||||||
|
|
||||||
<!--- sing plugin dependency -->
|
<!--- contains optional plugin dependencies -->
|
||||||
|
<!ELEMENT optional-dependencies (dependency)*>
|
||||||
|
|
||||||
|
<!--- single plugin dependency -->
|
||||||
<!ELEMENT dependency (#PCDATA)>
|
<!ELEMENT dependency (#PCDATA)>
|
||||||
|
|
||||||
<!-- generated entries -->
|
<!-- generated entries -->
|
||||||
|
|
||||||
<!--- extension -->
|
<!--- extension -->
|
||||||
<!ELEMENT extension (description|class)*>
|
<!ELEMENT extension (description|class|requires)*>
|
||||||
|
|
||||||
|
<!--- requires value -->
|
||||||
|
<!ELEMENT requires (#PCDATA)>
|
||||||
|
|
||||||
<!--- class value -->
|
<!--- class value -->
|
||||||
<!ELEMENT class (#PCDATA)>
|
<!ELEMENT class (#PCDATA)>
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
},
|
},
|
||||||
"resolutions": {
|
"resolutions": {
|
||||||
"babel-core": "7.0.0-bridge.0",
|
"babel-core": "7.0.0-bridge.0",
|
||||||
"gitdiff-parser": "https://github.com/scm-manager/gitdiff-parser#6baa7278824ecd17a199d842ca720d0453f68982"
|
"gitdiff-parser": "https://github.com/scm-manager/gitdiff-parser#ed3fe7de73dbb0a06c3e6adbbdf22dbae6e66351"
|
||||||
},
|
},
|
||||||
"babel": {
|
"babel": {
|
||||||
"presets": [
|
"presets": [
|
||||||
|
|||||||
7
pom.xml
7
pom.xml
@@ -284,6 +284,12 @@
|
|||||||
<version>${jackson.version}</version>
|
<version>${jackson.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.hibernate</groupId>
|
||||||
|
<artifactId>hibernate-validator</artifactId>
|
||||||
|
<version>${hibernate-validator.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- JUnit 5 -->
|
<!-- JUnit 5 -->
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
@@ -843,6 +849,7 @@
|
|||||||
<jackson.version>2.10.0</jackson.version>
|
<jackson.version>2.10.0</jackson.version>
|
||||||
<guice.version>4.0</guice.version>
|
<guice.version>4.0</guice.version>
|
||||||
<jaxb.version>2.3.0</jaxb.version>
|
<jaxb.version>2.3.0</jaxb.version>
|
||||||
|
<hibernate-validator.version>6.1.0.Final</hibernate-validator.version>
|
||||||
|
|
||||||
<!-- event bus -->
|
<!-- event bus -->
|
||||||
<legman.version>1.6.1</legman.version>
|
<legman.version>1.6.1</legman.version>
|
||||||
|
|||||||
@@ -49,4 +49,15 @@ import java.lang.annotation.Target;
|
|||||||
@Target({ ElementType.TYPE })
|
@Target({ ElementType.TYPE })
|
||||||
@PluginAnnotation("extension")
|
@PluginAnnotation("extension")
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
public @interface Extension {}
|
public @interface Extension {
|
||||||
|
/**
|
||||||
|
* This extension is loaded only if all of the specified plugins are installed.
|
||||||
|
* The requires attribute can be used to implement optional extensions.
|
||||||
|
* A plugin author is able to implement an extension point of an optional plugin and the extension is only loaded if
|
||||||
|
* all of the specified plugins are installed.
|
||||||
|
*
|
||||||
|
* @since 2.0.0
|
||||||
|
* @return list of required plugins to load this extension
|
||||||
|
*/
|
||||||
|
String[] requires() default {};
|
||||||
|
}
|
||||||
|
|||||||
@@ -173,6 +173,13 @@
|
|||||||
<artifactId>activation</artifactId>
|
<artifactId>activation</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- validation -->
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.hibernate</groupId>
|
||||||
|
<artifactId>hibernate-validator</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- util -->
|
<!-- util -->
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
@@ -214,12 +221,6 @@
|
|||||||
<artifactId>shiro-unit</artifactId>
|
<artifactId>shiro-unit</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.hibernate</groupId>
|
|
||||||
<artifactId>hibernate-validator</artifactId>
|
|
||||||
<version>5.3.6.Final</version>
|
|
||||||
<scope>compile</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package sonia.scm.plugin;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.ToString;
|
||||||
|
|
||||||
|
import javax.xml.bind.annotation.XmlAccessType;
|
||||||
|
import javax.xml.bind.annotation.XmlAccessorType;
|
||||||
|
import javax.xml.bind.annotation.XmlElement;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@ToString
|
||||||
|
@NoArgsConstructor
|
||||||
|
@EqualsAndHashCode
|
||||||
|
@AllArgsConstructor
|
||||||
|
@XmlAccessorType(XmlAccessType.FIELD)
|
||||||
|
public class ExtensionElement {
|
||||||
|
@XmlElement(name = "class")
|
||||||
|
private String clazz;
|
||||||
|
private String description;
|
||||||
|
private Set<String> requires = new HashSet<>();
|
||||||
|
}
|
||||||
@@ -38,6 +38,7 @@ package sonia.scm.plugin;
|
|||||||
import com.google.common.base.MoreObjects;
|
import com.google.common.base.MoreObjects;
|
||||||
import com.google.common.base.Objects;
|
import com.google.common.base.Objects;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
|
|
||||||
import javax.xml.bind.annotation.XmlAccessType;
|
import javax.xml.bind.annotation.XmlAccessType;
|
||||||
import javax.xml.bind.annotation.XmlAccessorType;
|
import javax.xml.bind.annotation.XmlAccessorType;
|
||||||
@@ -76,7 +77,7 @@ public final class InstalledPluginDescriptor extends ScmModule implements Plugin
|
|||||||
*/
|
*/
|
||||||
public InstalledPluginDescriptor(int scmVersion, PluginInformation information,
|
public InstalledPluginDescriptor(int scmVersion, PluginInformation information,
|
||||||
PluginResources resources, PluginCondition condition,
|
PluginResources resources, PluginCondition condition,
|
||||||
boolean childFirstClassLoader, Set<String> dependencies)
|
boolean childFirstClassLoader, Set<String> dependencies, Set<String> optionalDependencies)
|
||||||
{
|
{
|
||||||
this.scmVersion = scmVersion;
|
this.scmVersion = scmVersion;
|
||||||
this.information = information;
|
this.information = information;
|
||||||
@@ -84,6 +85,7 @@ public final class InstalledPluginDescriptor extends ScmModule implements Plugin
|
|||||||
this.condition = condition;
|
this.condition = condition;
|
||||||
this.childFirstClassLoader = childFirstClassLoader;
|
this.childFirstClassLoader = childFirstClassLoader;
|
||||||
this.dependencies = dependencies;
|
this.dependencies = dependencies;
|
||||||
|
this.optionalDependencies = optionalDependencies;
|
||||||
}
|
}
|
||||||
|
|
||||||
//~--- methods --------------------------------------------------------------
|
//~--- methods --------------------------------------------------------------
|
||||||
@@ -116,7 +118,8 @@ public final class InstalledPluginDescriptor extends ScmModule implements Plugin
|
|||||||
&& Objects.equal(information, other.information)
|
&& Objects.equal(information, other.information)
|
||||||
&& Objects.equal(resources, other.resources)
|
&& Objects.equal(resources, other.resources)
|
||||||
&& Objects.equal(childFirstClassLoader, other.childFirstClassLoader)
|
&& Objects.equal(childFirstClassLoader, other.childFirstClassLoader)
|
||||||
&& Objects.equal(dependencies, other.dependencies);
|
&& Objects.equal(dependencies, other.dependencies)
|
||||||
|
&& Objects.equal(optionalDependencies, other.optionalDependencies);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -129,7 +132,7 @@ public final class InstalledPluginDescriptor extends ScmModule implements Plugin
|
|||||||
public int hashCode()
|
public int hashCode()
|
||||||
{
|
{
|
||||||
return Objects.hashCode(scmVersion, condition, information, resources,
|
return Objects.hashCode(scmVersion, condition, information, resources,
|
||||||
childFirstClassLoader, dependencies);
|
childFirstClassLoader, dependencies, optionalDependencies);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -149,6 +152,7 @@ public final class InstalledPluginDescriptor extends ScmModule implements Plugin
|
|||||||
.add("resources", resources)
|
.add("resources", resources)
|
||||||
.add("childFirstClassLoader", childFirstClassLoader)
|
.add("childFirstClassLoader", childFirstClassLoader)
|
||||||
.add("dependencies", dependencies)
|
.add("dependencies", dependencies)
|
||||||
|
.add("optionalDependencies", optionalDependencies)
|
||||||
.toString();
|
.toString();
|
||||||
//J+
|
//J+
|
||||||
}
|
}
|
||||||
@@ -186,6 +190,27 @@ public final class InstalledPluginDescriptor extends ScmModule implements Plugin
|
|||||||
return dependencies;
|
return dependencies;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method description
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*
|
||||||
|
* @since 2.0.0
|
||||||
|
*/
|
||||||
|
public Set<String> getOptionalDependencies() {
|
||||||
|
if (optionalDependencies == null)
|
||||||
|
{
|
||||||
|
optionalDependencies = ImmutableSet.of();
|
||||||
|
}
|
||||||
|
|
||||||
|
return optionalDependencies;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<String> getDependenciesInclusiveOptionals() {
|
||||||
|
return ImmutableSet.copyOf(Iterables.concat(getDependencies(), getOptionalDependencies()));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method description
|
* Method description
|
||||||
*
|
*
|
||||||
@@ -246,6 +271,11 @@ public final class InstalledPluginDescriptor extends ScmModule implements Plugin
|
|||||||
@XmlElementWrapper(name = "dependencies")
|
@XmlElementWrapper(name = "dependencies")
|
||||||
private Set<String> dependencies;
|
private Set<String> dependencies;
|
||||||
|
|
||||||
|
/** Field description */
|
||||||
|
@XmlElement(name = "dependency")
|
||||||
|
@XmlElementWrapper(name = "optional-dependencies")
|
||||||
|
private Set<String> optionalDependencies;
|
||||||
|
|
||||||
/** Field description */
|
/** Field description */
|
||||||
@XmlElement(name = "information")
|
@XmlElement(name = "information")
|
||||||
private PluginInformation information;
|
private PluginInformation information;
|
||||||
|
|||||||
@@ -89,9 +89,9 @@ public class ScmModule
|
|||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public Iterable<Class<?>> getExtensions()
|
public Iterable<ExtensionElement> getExtensions()
|
||||||
{
|
{
|
||||||
return unwrap(extensions);
|
return nonNull(extensions);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -223,7 +223,7 @@ public class ScmModule
|
|||||||
|
|
||||||
/** Field description */
|
/** Field description */
|
||||||
@XmlElement(name = "extension")
|
@XmlElement(name = "extension")
|
||||||
private Set<ClassElement> extensions;
|
private Set<ExtensionElement> extensions;
|
||||||
|
|
||||||
/** Field description */
|
/** Field description */
|
||||||
@XmlElement(name = "rest-provider")
|
@XmlElement(name = "rest-provider")
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ package sonia.scm.plugin;
|
|||||||
|
|
||||||
//~--- non-JDK imports --------------------------------------------------------
|
//~--- non-JDK imports --------------------------------------------------------
|
||||||
|
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.common.io.Resources;
|
import com.google.common.io.Resources;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@@ -69,10 +70,10 @@ public class ScmModuleTest
|
|||||||
|
|
||||||
//J-
|
//J-
|
||||||
assertThat(
|
assertThat(
|
||||||
module.getExtensions(),
|
Iterables.transform(module.getExtensions(), ExtensionElement::getClazz),
|
||||||
containsInAnyOrder(
|
containsInAnyOrder(
|
||||||
String.class,
|
String.class.getName(),
|
||||||
Integer.class
|
Integer.class.getName()
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
assertThat(
|
assertThat(
|
||||||
|
|||||||
@@ -47,10 +47,14 @@
|
|||||||
|
|
||||||
<extension>
|
<extension>
|
||||||
<class>java.lang.String</class>
|
<class>java.lang.String</class>
|
||||||
|
<requires>scm-mail-plugin</requires>
|
||||||
|
<requires>scm-review-plugin</requires>
|
||||||
|
<description>ext01</description>
|
||||||
</extension>
|
</extension>
|
||||||
|
|
||||||
<extension>
|
<extension>
|
||||||
<class>java.lang.Integer</class>
|
<class>java.lang.Integer</class>
|
||||||
|
<description>ext02</description>
|
||||||
</extension>
|
</extension>
|
||||||
|
|
||||||
<!-- rest providers -->
|
<!-- rest providers -->
|
||||||
|
|||||||
18
scm-ui/ui-components/src/__resources__/Diff.binary.ts
Normal file
18
scm-ui/ui-components/src/__resources__/Diff.binary.ts
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
export default `diff --git a/Main.java b/Main.java
|
||||||
|
index 9b5ca13..7ced845 100644
|
||||||
|
--- a/Main.java
|
||||||
|
+++ b/Main.java
|
||||||
|
@@ -1,5 +1,5 @@
|
||||||
|
class Main {
|
||||||
|
- public static void main(String[] args) {
|
||||||
|
+ public static void main(String[] arguments) {
|
||||||
|
System.out.println("Expect nothing more to happen.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
diff --git a/conflict.png b/conflict.png
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..7c77c7f
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/conflict.png
|
||||||
|
Binary files differ
|
||||||
|
`;
|
||||||
@@ -334,6 +334,305 @@ exports[`Storyshots DateFromNow Default 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`Storyshots Diff Binaries 1`] = `
|
||||||
|
Array [
|
||||||
|
<div
|
||||||
|
className="sc-iwsKbI czQDxz panel is-size-6"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="panel-heading"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="sc-gZMcBi hiXlnL level"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="sc-gqjmRU jMyrLy level-left is-flex has-cursor-pointer"
|
||||||
|
onClick={[Function]}
|
||||||
|
title="Main.java"
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
className="fas fa-angle-down has-text-inherit"
|
||||||
|
/>
|
||||||
|
<span
|
||||||
|
className="sc-VigVT kUVxiT is-ellipsis-overflow is-size-6"
|
||||||
|
>
|
||||||
|
Main.java
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
className="tag is-info is-outlined sc-jzJRlG fdoJSr is-rounded has-text-weight-normal"
|
||||||
|
>
|
||||||
|
modify
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="sc-jTzLTM ljPywG level-right is-flex"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="field is-grouped"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="control"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
className="button is-default is-reduced-mobile"
|
||||||
|
onClick={[Function]}
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
className="icon is-medium"
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
className="fas fa-columns has-text-inherit"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
<span>
|
||||||
|
diff.sideBySide
|
||||||
|
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="panel-block is-paddingless"
|
||||||
|
>
|
||||||
|
<table
|
||||||
|
className="diff diff-unified sc-cSHVUG cHkPoJ unified"
|
||||||
|
onMouseDown={[Function]}
|
||||||
|
>
|
||||||
|
<colgroup>
|
||||||
|
<col
|
||||||
|
className="diff-gutter-col"
|
||||||
|
/>
|
||||||
|
<col
|
||||||
|
className="diff-gutter-col"
|
||||||
|
/>
|
||||||
|
<col />
|
||||||
|
</colgroup>
|
||||||
|
<tbody
|
||||||
|
className="diff-decoration"
|
||||||
|
>
|
||||||
|
<tr>
|
||||||
|
<td
|
||||||
|
className="diff-decoration-content"
|
||||||
|
colSpan={3}
|
||||||
|
>
|
||||||
|
<span />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
<tbody
|
||||||
|
className="diff-hunk"
|
||||||
|
>
|
||||||
|
<tr
|
||||||
|
className="diff-line"
|
||||||
|
>
|
||||||
|
<td
|
||||||
|
className="diff-gutter diff-gutter-normal"
|
||||||
|
onMouseEnter={[Function]}
|
||||||
|
onMouseLeave={[Function]}
|
||||||
|
>
|
||||||
|
1
|
||||||
|
</td>
|
||||||
|
<td
|
||||||
|
className="diff-gutter diff-gutter-normal"
|
||||||
|
onMouseEnter={[Function]}
|
||||||
|
onMouseLeave={[Function]}
|
||||||
|
>
|
||||||
|
1
|
||||||
|
</td>
|
||||||
|
<td
|
||||||
|
className="diff-code diff-code-normal"
|
||||||
|
onMouseEnter={[Function]}
|
||||||
|
onMouseLeave={[Function]}
|
||||||
|
>
|
||||||
|
class Main {
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr
|
||||||
|
className="diff-line"
|
||||||
|
>
|
||||||
|
<td
|
||||||
|
className="diff-gutter diff-gutter-normal"
|
||||||
|
onMouseEnter={[Function]}
|
||||||
|
onMouseLeave={[Function]}
|
||||||
|
>
|
||||||
|
2
|
||||||
|
</td>
|
||||||
|
<td
|
||||||
|
className="diff-gutter diff-gutter-normal"
|
||||||
|
onMouseEnter={[Function]}
|
||||||
|
onMouseLeave={[Function]}
|
||||||
|
>
|
||||||
|
2
|
||||||
|
</td>
|
||||||
|
<td
|
||||||
|
className="diff-code diff-code-normal"
|
||||||
|
onMouseEnter={[Function]}
|
||||||
|
onMouseLeave={[Function]}
|
||||||
|
>
|
||||||
|
- public static void main(String[] args) {
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr
|
||||||
|
className="diff-line"
|
||||||
|
>
|
||||||
|
<td
|
||||||
|
className="diff-gutter diff-gutter-normal"
|
||||||
|
onMouseEnter={[Function]}
|
||||||
|
onMouseLeave={[Function]}
|
||||||
|
>
|
||||||
|
3
|
||||||
|
</td>
|
||||||
|
<td
|
||||||
|
className="diff-gutter diff-gutter-normal"
|
||||||
|
onMouseEnter={[Function]}
|
||||||
|
onMouseLeave={[Function]}
|
||||||
|
>
|
||||||
|
3
|
||||||
|
</td>
|
||||||
|
<td
|
||||||
|
className="diff-code diff-code-normal"
|
||||||
|
onMouseEnter={[Function]}
|
||||||
|
onMouseLeave={[Function]}
|
||||||
|
>
|
||||||
|
+ public static void main(String[] arguments) {
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr
|
||||||
|
className="diff-line"
|
||||||
|
>
|
||||||
|
<td
|
||||||
|
className="diff-gutter diff-gutter-normal"
|
||||||
|
onMouseEnter={[Function]}
|
||||||
|
onMouseLeave={[Function]}
|
||||||
|
>
|
||||||
|
4
|
||||||
|
</td>
|
||||||
|
<td
|
||||||
|
className="diff-gutter diff-gutter-normal"
|
||||||
|
onMouseEnter={[Function]}
|
||||||
|
onMouseLeave={[Function]}
|
||||||
|
>
|
||||||
|
4
|
||||||
|
</td>
|
||||||
|
<td
|
||||||
|
className="diff-code diff-code-normal"
|
||||||
|
onMouseEnter={[Function]}
|
||||||
|
onMouseLeave={[Function]}
|
||||||
|
>
|
||||||
|
System.out.println("Expect nothing more to happen.");
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr
|
||||||
|
className="diff-line"
|
||||||
|
>
|
||||||
|
<td
|
||||||
|
className="diff-gutter diff-gutter-normal"
|
||||||
|
onMouseEnter={[Function]}
|
||||||
|
onMouseLeave={[Function]}
|
||||||
|
>
|
||||||
|
5
|
||||||
|
</td>
|
||||||
|
<td
|
||||||
|
className="diff-gutter diff-gutter-normal"
|
||||||
|
onMouseEnter={[Function]}
|
||||||
|
onMouseLeave={[Function]}
|
||||||
|
>
|
||||||
|
5
|
||||||
|
</td>
|
||||||
|
<td
|
||||||
|
className="diff-code diff-code-normal"
|
||||||
|
onMouseEnter={[Function]}
|
||||||
|
onMouseLeave={[Function]}
|
||||||
|
>
|
||||||
|
}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>,
|
||||||
|
<div
|
||||||
|
className="sc-iwsKbI bGoZkF panel is-size-6"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="panel-heading"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="sc-gZMcBi hiXlnL level"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="sc-gqjmRU jMyrLy level-left is-flex has-cursor-pointer"
|
||||||
|
onClick={[Function]}
|
||||||
|
title="conflict.png"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
className="sc-VigVT kUVxiT is-ellipsis-overflow is-size-6"
|
||||||
|
>
|
||||||
|
conflict.png
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
className="tag is-info is-outlined sc-jzJRlG fdoJSr is-rounded has-text-weight-normal"
|
||||||
|
>
|
||||||
|
add
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="sc-jTzLTM ljPywG level-right is-flex"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="field is-grouped"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="control"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
className="button is-default is-reduced-mobile"
|
||||||
|
onClick={[Function]}
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
className="icon is-medium"
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
className="fas fa-columns has-text-inherit"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
<span>
|
||||||
|
diff.sideBySide
|
||||||
|
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="panel-block is-paddingless"
|
||||||
|
>
|
||||||
|
<table
|
||||||
|
className="diff diff-unified sc-cSHVUG cHkPoJ unified"
|
||||||
|
onMouseDown={[Function]}
|
||||||
|
>
|
||||||
|
<colgroup>
|
||||||
|
<col
|
||||||
|
className="diff-gutter-col"
|
||||||
|
/>
|
||||||
|
<col
|
||||||
|
className="diff-gutter-col"
|
||||||
|
/>
|
||||||
|
<col />
|
||||||
|
</colgroup>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>,
|
||||||
|
]
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`Storyshots Diff Collapsed 1`] = `
|
exports[`Storyshots Diff Collapsed 1`] = `
|
||||||
Array [
|
Array [
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import Diff from "./Diff";
|
|||||||
import parser from "gitdiff-parser";
|
import parser from "gitdiff-parser";
|
||||||
import simpleDiff from "../__resources__/Diff.simple";
|
import simpleDiff from "../__resources__/Diff.simple";
|
||||||
import hunksDiff from "../__resources__/Diff.hunks";
|
import hunksDiff from "../__resources__/Diff.hunks";
|
||||||
|
import binaryDiff from "../__resources__/Diff.binary";
|
||||||
import Button from "../buttons/Button";
|
import Button from "../buttons/Button";
|
||||||
import { DiffEventContext } from "./DiffTypes";
|
import { DiffEventContext } from "./DiffTypes";
|
||||||
import Toast from "../toast/Toast";
|
import Toast from "../toast/Toast";
|
||||||
@@ -52,4 +53,8 @@ storiesOf("Diff", module)
|
|||||||
.add("Hunks", () => {
|
.add("Hunks", () => {
|
||||||
const hunkDiffFiles = parser.parse(hunksDiff);
|
const hunkDiffFiles = parser.parse(hunksDiff);
|
||||||
return <Diff diff={hunkDiffFiles} />;
|
return <Diff diff={hunkDiffFiles} />;
|
||||||
|
})
|
||||||
|
.add("Binaries", () => {
|
||||||
|
const binaryDiffFiles = parser.parse(binaryDiff);
|
||||||
|
return <Diff diff={binaryDiffFiles} />;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ public class DefaultPluginLoader implements PluginLoader
|
|||||||
|
|
||||||
modules = getInstalled(parent, context, PATH_MODULECONFIG);
|
modules = getInstalled(parent, context, PATH_MODULECONFIG);
|
||||||
|
|
||||||
collector = new ExtensionCollector(Iterables.concat(modules, unwrap()));
|
collector = new ExtensionCollector(parent, modules, installedPlugins);
|
||||||
extensionProcessor = new DefaultExtensionProcessor(collector);
|
extensionProcessor = new DefaultExtensionProcessor(collector);
|
||||||
}
|
}
|
||||||
catch (IOException | JAXBException ex)
|
catch (IOException | JAXBException ex)
|
||||||
@@ -170,19 +170,6 @@ public class DefaultPluginLoader implements PluginLoader
|
|||||||
return uberWebResourceLoader;
|
return uberWebResourceLoader;
|
||||||
}
|
}
|
||||||
|
|
||||||
//~--- methods --------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
private Iterable<InstalledPluginDescriptor> unwrap()
|
|
||||||
{
|
|
||||||
return PluginsInternal.unwrap(installedPlugins);
|
|
||||||
}
|
|
||||||
|
|
||||||
//~--- get methods ----------------------------------------------------------
|
//~--- get methods ----------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -98,8 +98,8 @@ public final class ExplodedSmp implements Comparable<ExplodedSmp>
|
|||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
Set<String> depends = plugin.getDependencies();
|
Set<String> depends = plugin.getDependenciesInclusiveOptionals();
|
||||||
Set<String> odepends = o.plugin.getDependencies();
|
Set<String> odepends = o.plugin.getDependenciesInclusiveOptionals();
|
||||||
|
|
||||||
if (depends.isEmpty() && odepends.isEmpty())
|
if (depends.isEmpty() && odepends.isEmpty())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -55,63 +55,37 @@ import sonia.scm.util.Util;
|
|||||||
public final class ExtensionBinder
|
public final class ExtensionBinder
|
||||||
{
|
{
|
||||||
|
|
||||||
/** Field description */
|
|
||||||
private static final String TYPE_LOOSE_EXT = "loose extension";
|
private static final String TYPE_LOOSE_EXT = "loose extension";
|
||||||
|
|
||||||
/** Field description */
|
|
||||||
private static final String TYPE_REST_RESOURCE = "rest resource";
|
private static final String TYPE_REST_RESOURCE = "rest resource";
|
||||||
|
private static final String AS_EAGER_SINGLETON = " as eager singleton";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* the logger for ExtensionBinder
|
* the logger for ExtensionBinder
|
||||||
*/
|
*/
|
||||||
private static final Logger logger =
|
private static final Logger logger = LoggerFactory.getLogger(ExtensionBinder.class);
|
||||||
LoggerFactory.getLogger(ExtensionBinder.class);
|
|
||||||
|
|
||||||
//~--- constructors ---------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs ...
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param binder
|
|
||||||
*/
|
|
||||||
public ExtensionBinder(Binder binder)
|
public ExtensionBinder(Binder binder)
|
||||||
{
|
{
|
||||||
this.binder = binder;
|
this.binder = binder;
|
||||||
}
|
}
|
||||||
|
|
||||||
//~--- methods --------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param collector
|
|
||||||
*/
|
|
||||||
public void bind(ExtensionCollector collector)
|
public void bind(ExtensionCollector collector)
|
||||||
{
|
{
|
||||||
logger.info("bind extensions to extension points");
|
logger.debug("bind extensions to extension points");
|
||||||
|
|
||||||
for (ExtensionPointElement epe : collector.getExtensionPointElements())
|
for (ExtensionPointElement epe : collector.getExtensionPointElements())
|
||||||
{
|
{
|
||||||
bindExtensionPoint(collector, epe);
|
bindExtensionPoint(collector, epe);
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info("bind loose extensions");
|
logger.debug("bind loose extensions");
|
||||||
bindLooseExtensions(collector.getLooseExtensions());
|
bindLooseExtensions(collector.getLooseExtensions());
|
||||||
logger.info("bind rest providers");
|
logger.debug("bind rest providers");
|
||||||
bindRestProviders(collector.getRestProviders());
|
bindRestProviders(collector.getRestProviders());
|
||||||
logger.info("bind rest resources");
|
logger.debug("bind rest resources");
|
||||||
bindRestResource(collector.getRestResources());
|
bindRestResource(collector.getRestResources());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param collector
|
|
||||||
* @param epe
|
|
||||||
*/
|
|
||||||
private void bindExtensionPoint(ExtensionCollector collector,
|
private void bindExtensionPoint(ExtensionCollector collector,
|
||||||
ExtensionPointElement epe)
|
ExtensionPointElement epe)
|
||||||
{
|
{
|
||||||
@@ -142,12 +116,6 @@ public final class ExtensionBinder
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param extensions
|
|
||||||
*/
|
|
||||||
private void bindLooseExtensions(Iterable<Class> extensions)
|
private void bindLooseExtensions(Iterable<Class> extensions)
|
||||||
{
|
{
|
||||||
for (Class extension : extensions)
|
for (Class extension : extensions)
|
||||||
@@ -156,46 +124,27 @@ public final class ExtensionBinder
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private void bindMultiExtensionPoint(ExtensionPointElement extensionPoint, Iterable<Class> extensions)
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param found
|
|
||||||
*
|
|
||||||
* @param extensionPoint
|
|
||||||
*
|
|
||||||
* @param boundClasses
|
|
||||||
* @param extensionPointClass
|
|
||||||
* @param extensions
|
|
||||||
*/
|
|
||||||
private void bindMultiExtensionPoint(ExtensionPointElement extensionPoint,
|
|
||||||
Iterable<Class> extensions)
|
|
||||||
{
|
{
|
||||||
Class extensionPointClass = extensionPoint.getClazz();
|
Class extensionPointClass = extensionPoint.getClazz();
|
||||||
|
|
||||||
if (logger.isInfoEnabled())
|
logger.debug("create multibinder for {}", extensionPointClass.getName());
|
||||||
{
|
|
||||||
logger.info("create multibinder for {}", extensionPointClass.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
Multibinder multibinder = Multibinder.newSetBinder(binder,
|
|
||||||
extensionPointClass);
|
|
||||||
|
|
||||||
|
Multibinder multibinder = Multibinder.newSetBinder(binder, extensionPointClass);
|
||||||
for (Class extensionClass : extensions)
|
for (Class extensionClass : extensions)
|
||||||
{
|
{
|
||||||
boolean eagerSingleton = isEagerSingleton(extensionClass);
|
boolean eagerSingleton = isEagerSingleton(extensionClass);
|
||||||
|
|
||||||
if (logger.isInfoEnabled())
|
if (logger.isDebugEnabled())
|
||||||
{
|
{
|
||||||
String as = Util.EMPTY_STRING;
|
String as = Util.EMPTY_STRING;
|
||||||
|
|
||||||
if (eagerSingleton)
|
if (eagerSingleton)
|
||||||
{
|
{
|
||||||
as = " as eager singleton";
|
as = AS_EAGER_SINGLETON;
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info("bind {} to multibinder of {}{}", extensionClass.getName(),
|
logger.debug("bind {} to multibinder of {}{}", extensionClass.getName(),
|
||||||
extensionPointClass.getName(), as);
|
extensionPointClass.getName(), as);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -208,27 +157,15 @@ public final class ExtensionBinder
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param restProviders
|
|
||||||
*/
|
|
||||||
private void bindRestProviders(Iterable<Class> restProviders)
|
private void bindRestProviders(Iterable<Class> restProviders)
|
||||||
{
|
{
|
||||||
for (Class restProvider : restProviders)
|
for (Class restProvider : restProviders)
|
||||||
{
|
{
|
||||||
logger.info("bind rest provider {}", restProvider);
|
logger.debug("bind rest provider {}", restProvider);
|
||||||
binder.bind(restProvider).in(Singleton.class);
|
binder.bind(restProvider).in(Singleton.class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param restResources
|
|
||||||
*/
|
|
||||||
private void bindRestResource(Iterable<Class> restResources)
|
private void bindRestResource(Iterable<Class> restResources)
|
||||||
{
|
{
|
||||||
for (Class restResource : restResources)
|
for (Class restResource : restResources)
|
||||||
@@ -237,31 +174,22 @@ public final class ExtensionBinder
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param extensionPointClass
|
|
||||||
*
|
|
||||||
* @param extensionPoint
|
|
||||||
* @param extensionClass
|
|
||||||
*/
|
|
||||||
private void bindSingleInstance(ExtensionPointElement extensionPoint,
|
private void bindSingleInstance(ExtensionPointElement extensionPoint,
|
||||||
Class extensionClass)
|
Class extensionClass)
|
||||||
{
|
{
|
||||||
Class extensionPointClass = extensionPoint.getClazz();
|
Class extensionPointClass = extensionPoint.getClazz();
|
||||||
boolean eagerSingleton = isEagerSingleton(extensionClass);
|
boolean eagerSingleton = isEagerSingleton(extensionClass);
|
||||||
|
|
||||||
if (logger.isInfoEnabled())
|
if (logger.isDebugEnabled())
|
||||||
{
|
{
|
||||||
String as = Util.EMPTY_STRING;
|
String as = Util.EMPTY_STRING;
|
||||||
|
|
||||||
if (eagerSingleton)
|
if (eagerSingleton)
|
||||||
{
|
{
|
||||||
as = " as eager singleton";
|
as = AS_EAGER_SINGLETON;
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info("bind {} to {}{}", extensionClass.getName(),
|
logger.debug("bind {} to {}{}", extensionClass.getName(),
|
||||||
extensionPointClass.getName(), as);
|
extensionPointClass.getName(), as);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -274,13 +202,6 @@ public final class ExtensionBinder
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param type
|
|
||||||
* @param extension
|
|
||||||
*/
|
|
||||||
private void singleBind(String type, Class extension)
|
private void singleBind(String type, Class extension)
|
||||||
{
|
{
|
||||||
StringBuilder log = new StringBuilder();
|
StringBuilder log = new StringBuilder();
|
||||||
@@ -291,30 +212,19 @@ public final class ExtensionBinder
|
|||||||
|
|
||||||
if (isEagerSingleton(extension))
|
if (isEagerSingleton(extension))
|
||||||
{
|
{
|
||||||
log.append(" as eager singleton");
|
log.append(AS_EAGER_SINGLETON);
|
||||||
abb.asEagerSingleton();
|
abb.asEagerSingleton();
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info(log.toString());
|
if (logger.isDebugEnabled()) {
|
||||||
|
logger.debug(log.toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//~--- get methods ----------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method description
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param extensionClass
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
private boolean isEagerSingleton(Class extensionClass)
|
private boolean isEagerSingleton(Class extensionClass)
|
||||||
{
|
{
|
||||||
return extensionClass.isAnnotationPresent(EagerSingleton.class);
|
return extensionClass.isAnnotationPresent(EagerSingleton.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
//~--- fields ---------------------------------------------------------------
|
|
||||||
|
|
||||||
/** Field description */
|
|
||||||
private final Binder binder;
|
private final Binder binder;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,6 +39,8 @@ import com.google.common.collect.Lists;
|
|||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
import com.google.common.collect.Multimap;
|
import com.google.common.collect.Multimap;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
//~--- JDK imports ------------------------------------------------------------
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
|
|
||||||
@@ -47,6 +49,7 @@ import java.util.Collections;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -56,23 +59,33 @@ import java.util.Set;
|
|||||||
public final class ExtensionCollector
|
public final class ExtensionCollector
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
private static final Logger LOG = LoggerFactory.getLogger(ExtensionCollector.class);
|
||||||
* Constructs ...
|
|
||||||
*
|
private final Set<String> pluginIndex;
|
||||||
*
|
|
||||||
* @param modules
|
public ExtensionCollector(ClassLoader moduleClassLoader, Set<ScmModule> modules, Set<InstalledPlugin> installedPlugins) {
|
||||||
*/
|
this.pluginIndex = createPluginIndex(installedPlugins);
|
||||||
ExtensionCollector(Iterable<ScmModule> modules)
|
|
||||||
{
|
for (ScmModule module : modules) {
|
||||||
for (ScmModule module : modules)
|
|
||||||
{
|
|
||||||
collectRootElements(module);
|
collectRootElements(module);
|
||||||
}
|
}
|
||||||
|
for (ScmModule plugin : PluginsInternal.unwrap(installedPlugins)) {
|
||||||
for (ScmModule module : modules)
|
collectRootElements(plugin);
|
||||||
{
|
|
||||||
collectExtensions(module);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (ScmModule module : modules) {
|
||||||
|
collectExtensions(moduleClassLoader, module);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (InstalledPlugin plugin : installedPlugins) {
|
||||||
|
collectExtensions(plugin.getClassLoader(), plugin.getDescriptor());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Set<String> createPluginIndex(Set<InstalledPlugin> installedPlugins) {
|
||||||
|
return installedPlugins.stream()
|
||||||
|
.map(p -> p.getDescriptor().getInformation().getName())
|
||||||
|
.collect(Collectors.toSet());
|
||||||
}
|
}
|
||||||
|
|
||||||
//~--- methods --------------------------------------------------------------
|
//~--- methods --------------------------------------------------------------
|
||||||
@@ -245,20 +258,35 @@ public final class ExtensionCollector
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private void collectExtensions(ClassLoader defaultClassLoader, ScmModule module) {
|
||||||
* Method description
|
for (ExtensionElement extension : module.getExtensions()) {
|
||||||
*
|
if (isRequirementFulfilled(extension)) {
|
||||||
*
|
Class<?> extensionClass = loadExtension(defaultClassLoader, extension);
|
||||||
* @param module
|
appendExtension(extensionClass);
|
||||||
*/
|
}
|
||||||
private void collectExtensions(ScmModule module)
|
|
||||||
{
|
|
||||||
for (Class extension : module.getExtensions())
|
|
||||||
{
|
|
||||||
appendExtension(extension);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Class<?> loadExtension(ClassLoader classLoader, ExtensionElement extension) {
|
||||||
|
try {
|
||||||
|
return classLoader.loadClass(extension.getClazz());
|
||||||
|
} catch (ClassNotFoundException ex) {
|
||||||
|
throw new PluginLoadException("failed to load clazz", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isRequirementFulfilled(ExtensionElement extension) {
|
||||||
|
if (extension.getRequires() != null) {
|
||||||
|
for (String requiredPlugin : extension.getRequires()) {
|
||||||
|
if (!pluginIndex.contains(requiredPlugin)) {
|
||||||
|
LOG.debug("skip loading of extension {}, because the required plugin {} is not installed", extension.getClazz(), requiredPlugin);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method description
|
* Method description
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -189,7 +189,7 @@ public final class PluginProcessor
|
|||||||
|
|
||||||
PluginTree pluginTree = new PluginTree(smps);
|
PluginTree pluginTree = new PluginTree(smps);
|
||||||
|
|
||||||
logger.trace("build plugin tree: {}", pluginTree);
|
logger.info("install plugin tree:\n{}", pluginTree);
|
||||||
|
|
||||||
List<PluginNode> rootNodes = pluginTree.getRootNodes();
|
List<PluginNode> rootNodes = pluginTree.getRootNodes();
|
||||||
|
|
||||||
|
|||||||
@@ -35,15 +35,13 @@ package sonia.scm.plugin;
|
|||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.collect.Ordering;
|
import com.google.common.collect.Ordering;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
//~--- JDK imports ------------------------------------------------------------
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
|
||||||
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -104,9 +102,7 @@ public final class PluginTree
|
|||||||
|
|
||||||
if ((condition == null) || condition.isSupported())
|
if ((condition == null) || condition.isSupported())
|
||||||
{
|
{
|
||||||
Set<String> dependencies = plugin.getDependencies();
|
if (plugin.getDependencies().isEmpty() && plugin.getOptionalDependencies().isEmpty())
|
||||||
|
|
||||||
if ((dependencies == null) || dependencies.isEmpty())
|
|
||||||
{
|
{
|
||||||
rootNodes.add(new PluginNode(smp));
|
rootNodes.add(new PluginNode(smp));
|
||||||
}
|
}
|
||||||
@@ -170,6 +166,20 @@ public final class PluginTree
|
|||||||
//J+
|
//J+
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean rootNode = smp.getPlugin().getDependencies().isEmpty();
|
||||||
|
for (String dependency : smp.getPlugin().getOptionalDependencies()) {
|
||||||
|
if (appendNode(rootNodes, child, dependency)) {
|
||||||
|
rootNode = false;
|
||||||
|
} else {
|
||||||
|
logger.info("optional dependency {} of {} is not installed", dependency, child.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rootNode) {
|
||||||
|
logger.info("could not find optional dependencies of {}, append it as root node", child.getId());
|
||||||
|
rootNodes.add(new PluginNode(smp));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -212,7 +222,18 @@ public final class PluginTree
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "plugin tree: " + rootNodes.toString();
|
StringBuilder buffer = new StringBuilder();
|
||||||
|
for (PluginNode node : rootNodes) {
|
||||||
|
append(buffer, "", node);
|
||||||
|
}
|
||||||
|
return buffer.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void append(StringBuilder buffer, String indent, PluginNode node) {
|
||||||
|
buffer.append(indent).append("+- ").append(node.getId()).append("\n");
|
||||||
|
for (PluginNode child : node.getChildren()) {
|
||||||
|
append(buffer, indent + " ", child);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//~--- fields ---------------------------------------------------------------
|
//~--- fields ---------------------------------------------------------------
|
||||||
|
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ public class ExplodedSmpTest
|
|||||||
info.setVersion(version);
|
info.setVersion(version);
|
||||||
|
|
||||||
InstalledPluginDescriptor plugin = new InstalledPluginDescriptor(2, info, null, null, false,
|
InstalledPluginDescriptor plugin = new InstalledPluginDescriptor(2, info, null, null, false,
|
||||||
Sets.newSet(dependencies));
|
Sets.newSet(dependencies), null);
|
||||||
|
|
||||||
return new ExplodedSmp(null, plugin);
|
return new ExplodedSmp(null, plugin);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ package sonia.scm.plugin;
|
|||||||
//~--- non-JDK imports --------------------------------------------------------
|
//~--- non-JDK imports --------------------------------------------------------
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
@@ -72,7 +73,7 @@ public class PluginTreeTest
|
|||||||
PluginCondition condition = new PluginCondition("999",
|
PluginCondition condition = new PluginCondition("999",
|
||||||
new ArrayList<String>(), "hit");
|
new ArrayList<String>(), "hit");
|
||||||
InstalledPluginDescriptor plugin = new InstalledPluginDescriptor(2, createInfo("a", "1"), null, condition,
|
InstalledPluginDescriptor plugin = new InstalledPluginDescriptor(2, createInfo("a", "1"), null, condition,
|
||||||
false, null);
|
false, null, null);
|
||||||
ExplodedSmp smp = createSmp(plugin);
|
ExplodedSmp smp = createSmp(plugin);
|
||||||
|
|
||||||
new PluginTree(smp).getRootNodes();
|
new PluginTree(smp).getRootNodes();
|
||||||
@@ -115,7 +116,7 @@ public class PluginTreeTest
|
|||||||
public void testScmVersion() throws IOException
|
public void testScmVersion() throws IOException
|
||||||
{
|
{
|
||||||
InstalledPluginDescriptor plugin = new InstalledPluginDescriptor(1, createInfo("a", "1"), null, null, false,
|
InstalledPluginDescriptor plugin = new InstalledPluginDescriptor(1, createInfo("a", "1"), null, null, false,
|
||||||
null);
|
null, null);
|
||||||
ExplodedSmp smp = createSmp(plugin);
|
ExplodedSmp smp = createSmp(plugin);
|
||||||
|
|
||||||
new PluginTree(smp).getRootNodes();
|
new PluginTree(smp).getRootNodes();
|
||||||
@@ -152,6 +153,61 @@ public class PluginTreeTest
|
|||||||
assertThat(unwrapIds(b.getChildren()), containsInAnyOrder("c"));
|
assertThat(unwrapIds(b.getChildren()), containsInAnyOrder("c"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testWithOptionalDependency() throws IOException {
|
||||||
|
ExplodedSmp[] smps = new ExplodedSmp[] {
|
||||||
|
createSmpWithDependency("a"),
|
||||||
|
createSmpWithDependency("b", null, ImmutableSet.of("a")),
|
||||||
|
createSmpWithDependency("c", null, ImmutableSet.of("a", "b"))
|
||||||
|
};
|
||||||
|
|
||||||
|
PluginTree tree = new PluginTree(smps);
|
||||||
|
List<PluginNode> rootNodes = tree.getRootNodes();
|
||||||
|
|
||||||
|
assertThat(unwrapIds(rootNodes), containsInAnyOrder("a"));
|
||||||
|
|
||||||
|
PluginNode a = rootNodes.get(0);
|
||||||
|
assertThat(unwrapIds(a.getChildren()), containsInAnyOrder("b", "c"));
|
||||||
|
|
||||||
|
PluginNode b = a.getChild("b");
|
||||||
|
assertThat(unwrapIds(b.getChildren()), containsInAnyOrder("c"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testWithDeepOptionalDependency() throws IOException {
|
||||||
|
ExplodedSmp[] smps = new ExplodedSmp[] {
|
||||||
|
createSmpWithDependency("a"),
|
||||||
|
createSmpWithDependency("b", "a"),
|
||||||
|
createSmpWithDependency("c", null, ImmutableSet.of("b"))
|
||||||
|
};
|
||||||
|
|
||||||
|
PluginTree tree = new PluginTree(smps);
|
||||||
|
|
||||||
|
System.out.println(tree);
|
||||||
|
|
||||||
|
List<PluginNode> rootNodes = tree.getRootNodes();
|
||||||
|
|
||||||
|
assertThat(unwrapIds(rootNodes), containsInAnyOrder("a"));
|
||||||
|
|
||||||
|
PluginNode a = rootNodes.get(0);
|
||||||
|
assertThat(unwrapIds(a.getChildren()), containsInAnyOrder("b"));
|
||||||
|
|
||||||
|
PluginNode b = a.getChild("b");
|
||||||
|
assertThat(unwrapIds(b.getChildren()), containsInAnyOrder("c"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testWithNonExistentOptionalDependency() throws IOException {
|
||||||
|
ExplodedSmp[] smps = new ExplodedSmp[] {
|
||||||
|
createSmpWithDependency("a", null, ImmutableSet.of("b"))
|
||||||
|
};
|
||||||
|
|
||||||
|
PluginTree tree = new PluginTree(smps);
|
||||||
|
List<PluginNode> rootNodes = tree.getRootNodes();
|
||||||
|
|
||||||
|
assertThat(unwrapIds(rootNodes), containsInAnyOrder("a"));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method description
|
* Method description
|
||||||
*
|
*
|
||||||
@@ -200,7 +256,7 @@ public class PluginTreeTest
|
|||||||
private ExplodedSmp createSmp(String name) throws IOException
|
private ExplodedSmp createSmp(String name) throws IOException
|
||||||
{
|
{
|
||||||
return createSmp(new InstalledPluginDescriptor(2, createInfo(name, "1.0.0"), null, null,
|
return createSmp(new InstalledPluginDescriptor(2, createInfo(name, "1.0.0"), null, null,
|
||||||
false, null));
|
false, null, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -224,10 +280,19 @@ public class PluginTreeTest
|
|||||||
{
|
{
|
||||||
dependencySet.add(d);
|
dependencySet.add(d);
|
||||||
}
|
}
|
||||||
|
return createSmpWithDependency(name, dependencySet, null);
|
||||||
|
}
|
||||||
|
|
||||||
InstalledPluginDescriptor plugin = new InstalledPluginDescriptor(2, createInfo(name, "1"), null, null,
|
private ExplodedSmp createSmpWithDependency(String name, Set<String> dependencies, Set<String> optionalDependencies) throws IOException {
|
||||||
false, dependencySet);
|
InstalledPluginDescriptor plugin = new InstalledPluginDescriptor(
|
||||||
|
2,
|
||||||
|
createInfo(name, "1"),
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
false,
|
||||||
|
dependencies,
|
||||||
|
optionalDependencies
|
||||||
|
);
|
||||||
return createSmp(plugin);
|
return createSmp(plugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7332,9 +7332,9 @@ gitconfiglocal@^1.0.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
ini "^1.3.2"
|
ini "^1.3.2"
|
||||||
|
|
||||||
gitdiff-parser@^0.1.2, "gitdiff-parser@https://github.com/scm-manager/gitdiff-parser#6baa7278824ecd17a199d842ca720d0453f68982":
|
gitdiff-parser@^0.1.2, "gitdiff-parser@https://github.com/scm-manager/gitdiff-parser#ed3fe7de73dbb0a06c3e6adbbdf22dbae6e66351":
|
||||||
version "0.1.2"
|
version "0.1.2"
|
||||||
resolved "https://github.com/scm-manager/gitdiff-parser#6baa7278824ecd17a199d842ca720d0453f68982"
|
resolved "https://github.com/scm-manager/gitdiff-parser#ed3fe7de73dbb0a06c3e6adbbdf22dbae6e66351"
|
||||||
|
|
||||||
glob-parent@^3.1.0:
|
glob-parent@^3.1.0:
|
||||||
version "3.1.0"
|
version "3.1.0"
|
||||||
|
|||||||
Reference in New Issue
Block a user