Skip to content

Commit

Permalink
Fixes jenkinsci#316: When resolving dependencies using manifest, do n…
Browse files Browse the repository at this point in the history
…ot fail if an optional plugin cannot be retrieved
  • Loading branch information
PierreBtz committed Apr 7, 2021
1 parent 8926b6e commit 6407cf3
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@
import static java.util.Comparator.comparing;

public class PluginManager implements Closeable {
private static final VersionNumber LATEST = new VersionNumber("latest");
static final VersionNumber LATEST = new VersionNumber("latest");
private List<Plugin> failedPlugins;
/**
* Directory where the plugins will be downloaded
Expand Down Expand Up @@ -835,26 +835,43 @@ public JSONArray getPluginDependencyJsonArray(Plugin plugin, JSONObject ucJson)
* Retrieves the latest available version of a specified plugin.
*
* @param dependendantPlugin the plugin depending on the given plugin
* @param pluginName the name of the plugin
* @param plugin the plugin to resolve the latest version for
* @return latest version of the specified plugin
* @throws IllegalStateException Update Center JSON has not been retrieved yet
*/
public VersionNumber getLatestPluginVersion(Plugin dependendantPlugin, String pluginName) {
public VersionNumber getLatestPluginVersion(Plugin dependendantPlugin, Plugin plugin) {
if (latestPlugins == null) {
throw new IllegalStateException("List of plugins is not available. Likely Update Center data has not been downloaded yet");
}

if (!latestPlugins.has(pluginName)) {
throw new PluginNotFoundException(dependendantPlugin, String.format("unable to find dependant plugin %s in update center %s", pluginName,
if (!latestPlugins.has(plugin.getName())) {
if (plugin.getOptional()) {
// case where a plugin depends on an optional plugin that is not available in the same Update Center
// we don't care about the version as we won't be able to download the plugin anyway
return LATEST;
}
throw new PluginNotFoundException(dependendantPlugin, String.format("unable to find dependant plugin %s in update center %s", plugin.getName(),
jenkinsUcLatest));
}

JSONObject pluginInfo = (JSONObject) latestPlugins.get(pluginName);
JSONObject pluginInfo = (JSONObject) latestPlugins.get(plugin.getName());
String latestPluginVersion = pluginInfo.getString("version");

return new VersionNumber(latestPluginVersion);
}

/**
* @deprecated use {@link #getLatestPluginVersion(Plugin, Plugin)} instead
* @param dependendantPlugin the plugin depending on the given plugin
* @param pluginName the name of the plugin
* @return latest version of the specified plugin
* @throws IllegalStateException Update Center JSON has not been retrieved yet
*/
@Deprecated
public VersionNumber getLatestPluginVersion(Plugin dependendantPlugin, String pluginName) {
return getLatestPluginVersion(dependendantPlugin, new Plugin(pluginName,null, null, null));
}

/**
* Resolves direct dependencies from downloaded plugin manifest. Done for plugins in which dependencies can't be
* determined via easily via json, such as when a user downloads a plugin directly from url or incremental plugins,
Expand Down Expand Up @@ -907,19 +924,11 @@ public List<Plugin> resolveDependenciesFromManifest(Plugin plugin) {
String pluginVersion = pluginInfo[1];
Plugin dependentPlugin = new Plugin(pluginName, pluginVersion, null, null);
dependentPlugin.setOptional(dependency.contains("resolution:=optional"));

if (useLatestSpecified && plugin.isLatest() || useLatestAll) {
try {
VersionNumber latestPluginVersion = getLatestPluginVersion(plugin, pluginName);
dependentPlugin.setVersion(latestPluginVersion);
dependentPlugin.setLatest(true);
} catch(PluginNotFoundException e) {
if (!dependentPlugin.getOptional()) {
throw e;
}
}
VersionNumber latestPluginVersion = getLatestPluginVersion(plugin, dependentPlugin);
dependentPlugin.setVersion(latestPluginVersion);
dependentPlugin.setLatest(true);
}

dependentPlugins.add(dependentPlugin);
dependentPlugin.setParent(plugin);
}
Expand Down Expand Up @@ -966,7 +975,7 @@ public List<Plugin> resolveDependenciesFromJson(Plugin plugin, JSONObject plugin

try {
if (useLatestSpecified && plugin.isLatest() || useLatestAll) {
VersionNumber latestPluginVersion = getLatestPluginVersion(plugin, pluginName);
VersionNumber latestPluginVersion = getLatestPluginVersion(plugin, dependentPlugin);
dependentPlugin.setVersion(latestPluginVersion);
dependentPlugin.setLatest(true);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -711,20 +711,30 @@ public void getPluginVersionTest() {
public void getLatestPluginVersionExceptionTest() {
setTestUcJson();

assertThatThrownBy(() -> pm.getLatestPluginVersion(null, "git"))
assertThatThrownBy(() -> pm.getLatestPluginVersion(null, new Plugin("git", null, null, null)))
.isInstanceOf(PluginNotFoundException.class);
}

@Test
public void getLatestPluginTest() {
setTestUcJson();
VersionNumber antLatestVersion = pm.getLatestPluginVersion(null, "ant");
VersionNumber antLatestVersion = pm.getLatestPluginVersion(null, new Plugin("ant", null, null, null));
assertThat(antLatestVersion).hasToString("1.9");

VersionNumber amazonEcsLatestVersion = pm.getLatestPluginVersion(null, "amazon-ecs");
VersionNumber amazonEcsLatestVersion = pm.getLatestPluginVersion(null, new Plugin("amazon-ecs", null, null, null));
assertThat(amazonEcsLatestVersion).hasToString("1.20");
}

@Test
public void getLatestOptionalAbsentPluginTest() {
setTestUcJson();

Plugin absentPlugin = new Plugin("git", null, null, null);
absentPlugin.setOptional(true);
VersionNumber absentPluginVersion = pm.getLatestPluginVersion(null, absentPlugin);
assertThat(absentPluginVersion).isEqualByComparingTo(PluginManager.LATEST);
}

@Test
public void resolveDependenciesFromManifestLatestSpecified() {
Config config = Config.builder()
Expand All @@ -748,7 +758,7 @@ public void resolveDependenciesFromManifestLatestSpecified() {
.when(pluginManagerSpy).getAttributeFromManifest(any(File.class), any(String.class));

doReturn(new VersionNumber("2.4")).doReturn(new VersionNumber("2.20")).when(pluginManagerSpy).
getLatestPluginVersion(any(Plugin.class), any(String.class));
getLatestPluginVersion(any(Plugin.class), any(Plugin.class));

List<Plugin> actualPlugins = pluginManagerSpy.resolveDependenciesFromManifest(testPlugin);

Expand Down Expand Up @@ -777,7 +787,7 @@ public void resolveDependenciesFromManifestLatestAll() {
.when(pluginManagerSpy).getAttributeFromManifest(any(File.class), any(String.class));

doReturn(new VersionNumber("2.4")).doReturn(new VersionNumber("2.20")).when(pluginManagerSpy).
getLatestPluginVersion(any(Plugin.class), any(String.class));
getLatestPluginVersion(any(Plugin.class), any(Plugin.class));

List<Plugin> actualPlugins = pluginManagerSpy.resolveDependenciesFromManifest(testPlugin);

Expand Down Expand Up @@ -985,7 +995,7 @@ public void resolveDependenciesFromJsonLatestAll() {
doReturn(mavenInvokerDependencies).when(pluginManagerSpy).getPluginDependencyJsonArray(any(Plugin.class), any(JSONObject.class));
doReturn(new VersionNumber("2.44")).doReturn(new VersionNumber("2.30")).doReturn(new VersionNumber("1.18"))
.doReturn(new VersionNumber("2.0")).doReturn(new VersionNumber("1.8"))
.when(pluginManagerSpy).getLatestPluginVersion(any(Plugin.class), any(String.class));
.when(pluginManagerSpy).getLatestPluginVersion(any(Plugin.class), any(Plugin.class));

List<Plugin> actualPlugins = pluginManagerSpy.resolveDependenciesFromJson(mvnInvokerPlugin, pluginJson);

Expand Down

0 comments on commit 6407cf3

Please sign in to comment.