check for plugin incompatibilities before update for a new version (IDEA-24014)

This commit is contained in:
Anna Kozlova
2014-05-22 15:13:37 +04:00
parent 1fc11e79ab
commit b553f5c960
6 changed files with 62 additions and 23 deletions
@@ -15,9 +15,6 @@
*/
package com.intellij.ide.plugins;
import com.intellij.icons.AllIcons;
import com.intellij.ide.IdeBundle;
import com.intellij.openapi.application.ApplicationNamesInfo;
import com.intellij.openapi.extensions.PluginId;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
@@ -30,15 +27,11 @@ import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.JDOMExternalizableStringList;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.FileStatus;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.ui.BooleanTableCellEditor;
import com.intellij.ui.BooleanTableCellRenderer;
import com.intellij.ui.JBColor;
import com.intellij.util.Function;
import com.intellij.util.containers.hash.HashSet;
import com.intellij.util.ui.ColumnInfo;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -159,7 +152,7 @@ public class InstalledPluginsTableModel extends PluginTableModel {
for (String host : pluginHosts) {
try {
final Map<PluginId, PluginDownloader> downloaded = new HashMap<PluginId, PluginDownloader>();
UpdateChecker.checkPluginsHost(host, downloaded, false, null, null);
UpdateChecker.checkPluginsHost(host, downloaded, false, null);
for (PluginId pluginId : downloaded.keySet()) {
myPlugin2host.put(pluginId.getIdString(), host);
}
@@ -189,7 +189,7 @@ public class PluginHostsConfigurable extends BaseConfigurable {
public void run() {
try {
result[0] =
UpdateChecker.checkPluginsHost(correctRepositoryRule(getTextField().getText()), new HashMap<PluginId, PluginDownloader>(), true, ProgressManager.getInstance().getProgressIndicator(), null);
UpdateChecker.checkPluginsHost(correctRepositoryRule(getTextField().getText()), new HashMap<PluginId, PluginDownloader>(), true, ProgressManager.getInstance().getProgressIndicator());
}
catch (Exception e1) {
ex[0] = e1;
@@ -319,7 +319,7 @@ public abstract class PluginManagerMain implements Disposable {
if (!acceptHost(host)) continue;
final Map<PluginId, PluginDownloader> downloaded = new HashMap<PluginId, PluginDownloader>();
try {
UpdateChecker.checkPluginsHost(host, downloaded, false, null, null);
UpdateChecker.checkPluginsHost(host, downloaded, false, null);
for (PluginDownloader downloader : downloaded.values()) {
final PluginNode pluginNode = PluginDownloader.createPluginNode(host, downloader);
if (pluginNode != null) {
@@ -145,12 +145,12 @@ public class PluginDownloader {
return false; //was not updated
}
setDescriptor(actualDescriptor);
if (PluginManagerCore.isIncompatible(actualDescriptor, forBuildNumber)) {
LOG.info("Plugin " + myPluginId + " is incompatible with current installation (since: " + actualDescriptor.getSinceBuild() + ", until: " + actualDescriptor.getUntilBuild()+ ")");
return false; //shouldn't happen
return false; //host outdated plugins, no compatible plugin for new version
}
setDescriptor(actualDescriptor);
}
return true;
}
@@ -173,12 +173,13 @@ public final class UpdateChecker {
buildNumber = latestBuild.getNumber();
}
}
final Collection<PluginDownloader> updatedPlugins = platformUpdate ? null : updatePlugins(manualCheck, hostsConfigurable, indicator, buildNumber);
final Collection<IdeaPluginDescriptor> incompatiblePlugins = buildNumber != null ? new HashSet<IdeaPluginDescriptor>() : null;
final Collection<PluginDownloader> updatedPlugins = platformUpdate ? null : updatePlugins(manualCheck, incompatiblePlugins, hostsConfigurable, indicator, buildNumber);
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
showUpdateResult(project, result, updatedPlugins, enableLink, manualCheck);
showUpdateResult(project, result, updatedPlugins, incompatiblePlugins, enableLink, manualCheck);
if (callback != null) {
callback.setDone();
}
@@ -187,6 +188,7 @@ public final class UpdateChecker {
}
public static Collection<PluginDownloader> updatePlugins(boolean manualCheck,
@Nullable Collection<IdeaPluginDescriptor> incompatiblePlugins,
@Nullable PluginHostsConfigurable hostsConfigurable,
@Nullable ProgressIndicator indicator,
@Nullable BuildNumber buildNumber) {
@@ -194,7 +196,7 @@ public final class UpdateChecker {
final Set<String> failed = new HashSet<String>();
for (String host : getPluginHosts(hostsConfigurable)) {
try {
checkPluginsHost(host, downloaded, true, indicator, buildNumber);
checkPluginsHost(host, downloaded, incompatiblePlugins, true, indicator, buildNumber);
}
catch (ProcessCanceledException e) {
return null;
@@ -240,7 +242,8 @@ public final class UpdateChecker {
final List<IdeaPluginDescriptor> process = RepositoryHelper.loadPluginsFromRepository(indicator);
final List<String> disabledPlugins = PluginManagerCore.getDisabledPlugins();
for (IdeaPluginDescriptor loadedPlugin : process) {
final String idString = loadedPlugin.getPluginId().getIdString();
final PluginId pluginId = loadedPlugin.getPluginId();
final String idString = pluginId.getIdString();
if (!toUpdate.containsKey(idString)) continue;
final IdeaPluginDescriptor installedPlugin = toUpdate.get(idString);
if (installedPlugin == null) {
@@ -253,6 +256,9 @@ public final class UpdateChecker {
prepareToInstall(downloaded, loadedPlugin, indicator, buildNumber);
}
}
if (!downloaded.containsKey(pluginId)) {
collectIncompatible(incompatiblePlugins, buildNumber, installedPlugin);
}
}
}
}
@@ -290,6 +296,14 @@ public final class UpdateChecker {
}
}
private static void collectIncompatible(Collection<IdeaPluginDescriptor> incompatiblePlugins,
BuildNumber buildNumber,
IdeaPluginDescriptor descriptor) {
if (incompatiblePlugins != null && descriptor != null && descriptor.isEnabled() && PluginManagerCore.isIncompatible(descriptor, buildNumber)) {
incompatiblePlugins.add(descriptor);
}
}
private static void showErrorMessage(boolean showDialog, final String message) {
if (showDialog) {
UIUtil.invokeLaterIfNeeded(new Runnable() {
@@ -321,7 +335,7 @@ public final class UpdateChecker {
public static boolean checkPluginsHost(final String host, final Map<PluginId, PluginDownloader> downloaded) throws Exception {
try {
return checkPluginsHost(host, downloaded, true, null, null);
return checkPluginsHost(host, downloaded, null, true, null, null);
}
catch (ProcessCanceledException e) {
return false;
@@ -330,9 +344,17 @@ public final class UpdateChecker {
public static boolean checkPluginsHost(final String host,
final Map<PluginId, PluginDownloader> downloaded,
final boolean collectToUpdate,
@Nullable ProgressIndicator indicator,
final BuildNumber buildNumber) throws Exception {
final boolean collectToUpdate,
@Nullable ProgressIndicator indicator) throws Exception {
return checkPluginsHost(host, downloaded, null, collectToUpdate, indicator, null);
}
private static boolean checkPluginsHost(final String host,
final Map<PluginId, PluginDownloader> downloaded,
final @Nullable Collection<IdeaPluginDescriptor> incompatiblePlugins,
final boolean collectToUpdate,
@Nullable ProgressIndicator indicator,
final BuildNumber buildNumber) throws Exception {
InputStream inputStream = loadVersionInfo(host);
if (inputStream == null) return false;
final Document document;
@@ -403,6 +425,9 @@ public final class UpdateChecker {
downloaded.put(PluginId.getId(pluginId), downloader);
}
}
if (loadedPlugin != null && !downloaded.containsKey(loadedPlugin.getPluginId())) {
collectIncompatible(incompatiblePlugins, buildNumber, loadedPlugin);
}
}
catch (IOException e) {
LOG.info(e);
@@ -476,6 +501,7 @@ public final class UpdateChecker {
private static void showUpdateResult(@Nullable final Project project,
final CheckForUpdateResult checkForUpdateResult,
final Collection<PluginDownloader> updatedPlugins,
final Collection<IdeaPluginDescriptor> incompatiblePlugins,
final boolean enableLink,
final boolean alwaysShowResults) {
final UpdateChannel channelToPropose = checkForUpdateResult.getChannelToPropose();
@@ -500,7 +526,7 @@ public final class UpdateChecker {
Runnable runnable = new Runnable() {
@Override
public void run() {
new UpdateInfoDialog(updatedChannel, enableLink, updatedPlugins).show();
new UpdateInfoDialog(updatedChannel, enableLink, updatedPlugins, incompatiblePlugins).show();
}
};
@@ -17,13 +17,16 @@ package com.intellij.openapi.updateSettings.impl;
import com.intellij.ide.BrowserUtil;
import com.intellij.ide.IdeBundle;
import com.intellij.ide.plugins.IdeaPluginDescriptor;
import com.intellij.openapi.application.ApplicationInfo;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ApplicationNamesInfo;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.BrowserHyperlinkListener;
import com.intellij.ui.JBColor;
import com.intellij.ui.components.JBLabel;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
@@ -43,7 +46,10 @@ class UpdateInfoDialog extends AbstractUpdateDialog {
private final PatchInfo myPatch;
private final boolean myWriteProtected;
protected UpdateInfoDialog(@NotNull UpdateChannel channel, boolean enableLink, Collection<PluginDownloader> updatedPlugins) {
protected UpdateInfoDialog(@NotNull UpdateChannel channel,
boolean enableLink,
Collection<PluginDownloader> updatedPlugins,
Collection<IdeaPluginDescriptor> incompatiblePlugins) {
super(enableLink);
myUpdatedChannel = channel;
myUpdatedPlugins = updatedPlugins;
@@ -52,6 +58,20 @@ class UpdateInfoDialog extends AbstractUpdateDialog {
myWriteProtected = myPatch != null && !new File(PathManager.getHomePath()).canWrite();
getCancelAction().putValue(DEFAULT_ACTION, Boolean.TRUE);
init();
if (incompatiblePlugins != null && !incompatiblePlugins.isEmpty()) {
final boolean onePluginFound = incompatiblePlugins.size() == 1;
String incompatibilityError = "Incompatible with new version plugin";
incompatibilityError += (onePluginFound ? " is" : "s are") + " detected: ";
incompatibilityError += onePluginFound ? "" : "<br>";
incompatibilityError += StringUtil.join(incompatiblePlugins, new Function<IdeaPluginDescriptor, String>() {
@Override
public String fun(IdeaPluginDescriptor downloader) {
return downloader.getName();
}
}, "<br/>");
setErrorText(incompatibilityError);
}
}
@Override