[JENKINS-33843] Permit disabling optional dependencies (#4001)

* Implied dependencies on detached plugins were not being marked optional despite being listed in optionalDependencies, confusing the calculation of optionalDependents in resolveDependentPlugins.

* Javadoc improvements based on code exploration.

* [JENKINS-33843] Do not consider optional dependencies for purposes of disabling plugins.

* PluginManagerInstalledGUITest updated to reflect new behavior.
This commit is contained in:
Jesse Glick authored and Oleg Nenashev committed 2019-06-15 11:21:20 +02:00
1 parent dcc395b814
commit 0f73231f77
6 files changed
+127 -54

No files matched your search

+55 -2
View File
@@ -255,6 +255,7 @@ public class PluginWrapper implements Comparable<PluginWrapper>, ModelObject {
/**
* Get the list of components that depend on this plugin.
* Note that the list will include elements of {@link #getOptionalDependents}.
* @return The list of components that depend on this plugin.
*/
public @Nonnull Set<String> getDependents() {
@@ -273,6 +274,16 @@ public class PluginWrapper implements Comparable<PluginWrapper>, ModelObject {
return getDependents();
}
/**
* Like {@link #getDependents} but excluding optional dependencies.
* @since TODO
*/
public @Nonnull Set<String> getMandatoryDependents() {
Set<String> s = new HashSet<>(dependents);
s.removeAll(optionalDependents);
return s;
}
/**
* @return The list of components that depend optionally on this plugin.
*/
@@ -290,6 +301,7 @@ public class PluginWrapper implements Comparable<PluginWrapper>, ModelObject {
/**
* Does this plugin have anything that depends on it.
* Note that optional dependents are included.
* @return {@code true} if something (Jenkins core, or another plugin) depends on this
* plugin, otherwise {@code false}.
*/
@@ -297,6 +309,17 @@ public class PluginWrapper implements Comparable<PluginWrapper>, ModelObject {
return (isBundled || !dependents.isEmpty());
}
/**
* Like {@link #hasDependents} but excluding optional dependencies.
* @since TODO
*/
public boolean hasMandatoryDependents() {
if (isBundled) {
return true;
}
return dependents.stream().anyMatch(d -> !optionalDependents.contains(d));
}
/**
* @deprecated Please use {@link hasDependents}.
*/
@@ -324,10 +347,19 @@ public class PluginWrapper implements Comparable<PluginWrapper>, ModelObject {
/**
* Does this plugin depend on any other plugins.
* Note that this include optional dependencies.
* @return {@code true} if this plugin depends on other plugins, otherwise {@code false}.
*/
public boolean hasDependencies() {
return (dependencies != null && !dependencies.isEmpty());
return !dependencies.isEmpty();
}
/**
* Like {@link #hasDependencies} but omitting optional dependencies.
* @since TODO
*/
public boolean hasMandatoryDependencies() {
return dependencies.stream().anyMatch(d -> !d.optional);
}
@ExportedBean
@@ -394,6 +426,9 @@ public class PluginWrapper implements Comparable<PluginWrapper>, ModelObject {
this.active = !disableFile.exists();
this.dependencies = dependencies;
this.optionalDependencies = optionalDependencies;
for (Dependency d : optionalDependencies) {
assert d.optional : d + " included among optionalDependencies of " + shortName + " but was not marked optional";
}
this.archive = archive;
}
@@ -438,11 +473,24 @@ public class PluginWrapper implements Comparable<PluginWrapper>, ModelObject {
return getBaseName(fileName);
}
/**
* Gets all dependencies of this plugin on other plugins.
* Note that the list will <em>usually</em> include the members of {@link #getOptionalDependencies}
* (missing optional dependencies will however be omitted).
*/
@Exported
public List<Dependency> getDependencies() {
return dependencies;
}
/**
* Like {@link #getDependencies} but omits optional dependencies.
* @since TODO
*/
public List<Dependency> getMandatoryDependencies() {
return dependencies.stream().filter(d -> !d.optional).collect(Collectors.toList());
}
public List<Dependency> getOptionalDependencies() {
return optionalDependencies;
}
@@ -753,7 +801,12 @@ public class PluginWrapper implements Comparable<PluginWrapper>, ModelObject {
public void setHasCycleDependency(boolean hasCycle){
hasCycleDependency = hasCycle;
}
/**
* Is this plugin bundled in the WAR?
* Normally false as noted in {@link PluginManager#loadBundledPlugins}:
* this does <em>not</em> apply to “detached” plugins.
*/
@Exported
public boolean isBundled() {
return isBundled;