From 87ee55555a9d0ba8d7ab66800803cff5c1951c77 Mon Sep 17 00:00:00 2001 From: Ivan Chirkov Date: Thu, 14 Jan 2016 20:03:07 +0100 Subject: [PATCH] Per-project custom repositories through required plugins --- .../testSrc/DefaultProjectStoreTest.kt | 2 +- .../DependencyOnPlugin.java | 13 +++++++-- .../impl/CheckRequiredPluginsActivity.java | 29 +++++++++++++++++-- .../impl/DependencyOnPluginState.java | 3 ++ .../ExternalDependenciesConfigurable.java | 8 +++-- .../impl/ExternalDependenciesManagerImpl.java | 2 +- 6 files changed, 48 insertions(+), 9 deletions(-) diff --git a/platform/configuration-store-impl/testSrc/DefaultProjectStoreTest.kt b/platform/configuration-store-impl/testSrc/DefaultProjectStoreTest.kt index d259d5f1ac69..a073215dc5a7 100644 --- a/platform/configuration-store-impl/testSrc/DefaultProjectStoreTest.kt +++ b/platform/configuration-store-impl/testSrc/DefaultProjectStoreTest.kt @@ -40,7 +40,7 @@ internal class DefaultProjectStoreTest { private val tempDirManager = TemporaryDirectory() - private val requiredPlugins = listOf(DependencyOnPlugin("fake", "0", "1")) + private val requiredPlugins = listOf(DependencyOnPlugin("fake", "0", "1", "alpha")) private val ruleChain = RuleChain( tempDirManager, diff --git a/platform/platform-impl/src/com/intellij/externalDependencies/DependencyOnPlugin.java b/platform/platform-impl/src/com/intellij/externalDependencies/DependencyOnPlugin.java index 037e3477ed05..cf0d475510c5 100644 --- a/platform/platform-impl/src/com/intellij/externalDependencies/DependencyOnPlugin.java +++ b/platform/platform-impl/src/com/intellij/externalDependencies/DependencyOnPlugin.java @@ -31,11 +31,13 @@ public class DependencyOnPlugin implements ProjectExternalDependency, Comparable private final String myPluginId; private final String myMinVersion; private final String myMaxVersion; + private final String myChannel; - public DependencyOnPlugin(@NotNull String pluginId, @Nullable String minVersion, @Nullable String maxVersion) { + public DependencyOnPlugin(@NotNull String pluginId, @Nullable String minVersion, @Nullable String maxVersion, @Nullable String channel) { myPluginId = pluginId; myMinVersion = minVersion; myMaxVersion = maxVersion; + myChannel = channel; } public String getPluginId() { @@ -50,6 +52,10 @@ public class DependencyOnPlugin implements ProjectExternalDependency, Comparable return myMaxVersion; } + public String getChannel() { + return myChannel; + } + @Override public boolean equals(Object o) { @@ -60,12 +66,13 @@ public class DependencyOnPlugin implements ProjectExternalDependency, Comparable return myPluginId.equals(plugin.myPluginId) && Comparing.equal(myMinVersion, plugin.myMinVersion) - && Comparing.equal(myMaxVersion, plugin.myMaxVersion); + && Comparing.equal(myMaxVersion, plugin.myMaxVersion) + && Comparing.equal(myChannel, plugin.myChannel); } @Override public int hashCode() { - return 31 * (31 * myPluginId.hashCode() + Comparing.hashcode(myMinVersion)) + Comparing.hashcode(myMaxVersion); + return 31 * (31 * (31 * myPluginId.hashCode() + Comparing.hashcode(myMinVersion)) + Comparing.hashcode(myMaxVersion)) + Comparing.hashcode(myChannel); } @Override diff --git a/platform/platform-impl/src/com/intellij/externalDependencies/impl/CheckRequiredPluginsActivity.java b/platform/platform-impl/src/com/intellij/externalDependencies/impl/CheckRequiredPluginsActivity.java index 782ec7a2ebef..aa1723fdb94c 100644 --- a/platform/platform-impl/src/com/intellij/externalDependencies/impl/CheckRequiredPluginsActivity.java +++ b/platform/platform-impl/src/com/intellij/externalDependencies/impl/CheckRequiredPluginsActivity.java @@ -26,6 +26,7 @@ import com.intellij.openapi.extensions.PluginId; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; import com.intellij.openapi.startup.StartupActivity; +import com.intellij.openapi.updateSettings.impl.UpdateSettings; import com.intellij.openapi.updateSettings.impl.pluginsAdvertisement.PluginsAdvertiser; import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.text.VersionComparatorUtil; @@ -42,6 +43,7 @@ import java.util.Set; */ public class CheckRequiredPluginsActivity implements StartupActivity, DumbAware { private static final NotificationGroup NOTIFICATION_GROUP = new NotificationGroup("Required Plugins", NotificationDisplayType.BALLOON, true); + public static final String PLUGINS_HOST = "https://plugins.jetbrains.com"; @Override public void runActivity(@NotNull final Project project) { @@ -53,11 +55,20 @@ public class CheckRequiredPluginsActivity implements StartupActivity, DumbAware List dependencies = ExternalDependenciesManager.getInstance(project).getDependencies(DependencyOnPlugin.class); if (dependencies.isEmpty()) return; + List customRepositories = UpdateSettings.getInstance().getStoredPluginHosts(); + final List errorMessages = new ArrayList(); + final List missingCustomRepositories = new ArrayList(); final List disabled = new ArrayList(); final List notInstalled = new ArrayList(); for (DependencyOnPlugin dependency : dependencies) { PluginId pluginId = PluginId.getId(dependency.getPluginId()); + String channel = dependency.getChannel(); + String customRepository = getCustomRepository(pluginId, channel); + if (!StringUtil.isEmpty(channel) && customRepositoryNotSpecified(customRepositories, customRepository)) { + errorMessages.add("Custom repository '" + customRepository + "' required for '" + project.getName() + "' project isn't installed."); + missingCustomRepositories.add(customRepository); + } IdeaPluginDescriptor plugin = PluginManager.getPlugin(pluginId); if (plugin == null) { errorMessages.add("Plugin '" + dependency.getPluginId() + "' required for '" + project.getName() + "' project isn't installed."); @@ -80,7 +91,10 @@ public class CheckRequiredPluginsActivity implements StartupActivity, DumbAware } if (!errorMessages.isEmpty()) { - if (!disabled.isEmpty() && notInstalled.isEmpty()) { + if (!missingCustomRepositories.isEmpty()) { + errorMessages.add("Add custom repositories and install required plugins"); + } + else if (!disabled.isEmpty() && notInstalled.isEmpty()) { String plugins = disabled.size() == 1 ? disabled.get(0).getName() : "required plugins"; errorMessages.add("Enable " + plugins + ""); } @@ -94,6 +108,9 @@ public class CheckRequiredPluginsActivity implements StartupActivity, DumbAware public void hyperlinkUpdate(@NotNull final Notification notification, @NotNull HyperlinkEvent event) { if (event.getEventType() == HyperlinkEvent.EventType.ACTIVATED) { + if ("addRepositories".equals(event.getDescription())) { + UpdateSettings.getInstance().getStoredPluginHosts().addAll(missingCustomRepositories); + } if ("enable".equals(event.getDescription())) { notification.expire(); for (IdeaPluginDescriptor descriptor : disabled) { @@ -101,7 +118,7 @@ public class CheckRequiredPluginsActivity implements StartupActivity, DumbAware } PluginManagerMain.notifyPluginsUpdated(project); } - else { + else if ("install".equals(event.getDescription()) || "addRepositories".equals(event.getDescription())) { Set pluginIds = new HashSet(); for (IdeaPluginDescriptor descriptor : disabled) { pluginIds.add(descriptor.getPluginId().getIdString()); @@ -121,4 +138,12 @@ public class CheckRequiredPluginsActivity implements StartupActivity, DumbAware }).notify(project); } } + + private static boolean customRepositoryNotSpecified(List repositories, String customRepository) { + return !repositories.contains(customRepository); + } + + private static String getCustomRepository(PluginId id, String channel) { + return String.format(PLUGINS_HOST + "/plugins/%s/%s", channel, id); + } } diff --git a/platform/platform-impl/src/com/intellij/externalDependencies/impl/DependencyOnPluginState.java b/platform/platform-impl/src/com/intellij/externalDependencies/impl/DependencyOnPluginState.java index aa8b925f8f9e..e15223d6e425 100644 --- a/platform/platform-impl/src/com/intellij/externalDependencies/impl/DependencyOnPluginState.java +++ b/platform/platform-impl/src/com/intellij/externalDependencies/impl/DependencyOnPluginState.java @@ -31,6 +31,7 @@ class DependencyOnPluginState { myId = dependency.getPluginId(); myMinVersion = dependency.getMinVersion(); myMaxVersion = dependency.getMaxVersion(); + myChannel = dependency.getChannel(); } @Attribute("id") @@ -39,4 +40,6 @@ class DependencyOnPluginState { public String myMinVersion; @Attribute("max-version") public String myMaxVersion; + @Attribute("channel") + public String myChannel; } diff --git a/platform/platform-impl/src/com/intellij/externalDependencies/impl/ExternalDependenciesConfigurable.java b/platform/platform-impl/src/com/intellij/externalDependencies/impl/ExternalDependenciesConfigurable.java index f16e268a4f4f..64923f7ff141 100644 --- a/platform/platform-impl/src/com/intellij/externalDependencies/impl/ExternalDependenciesConfigurable.java +++ b/platform/platform-impl/src/com/intellij/externalDependencies/impl/ExternalDependenciesConfigurable.java @@ -117,7 +117,7 @@ public class ExternalDependenciesConfigurable implements SearchableConfigurable, .setAddAction(new AnActionButtonRunnable() { @Override public void run(AnActionButton button) { - replaceDependency(new DependencyOnPlugin("", null, null), dependenciesList); + replaceDependency(new DependencyOnPlugin("", null, null, null), dependenciesList); } }) .setEditAction(new AnActionButtonRunnable() { @@ -198,14 +198,17 @@ public class ExternalDependenciesConfigurable implements SearchableConfigurable, final JBTextField minVersionField = new JBTextField(StringUtil.notNullize(original.getMinVersion())); final JBTextField maxVersionField = new JBTextField(StringUtil.notNullize(original.getMaxVersion())); + final JBTextField channelField = new JBTextField(StringUtil.notNullize(original.getChannel())); minVersionField.getEmptyText().setText(""); minVersionField.setColumns(10); maxVersionField.getEmptyText().setText(""); maxVersionField.setColumns(10); + channelField.setColumns(10); JPanel panel = FormBuilder.createFormBuilder() .addLabeledComponent("Plugin:", pluginChooser) .addLabeledComponent("Minimum version:", minVersionField) .addLabeledComponent("Maximum version:", maxVersionField) + .addLabeledComponent("Channel:", channelField) .getPanel(); final DialogBuilder dialogBuilder = new DialogBuilder(parent).title("Required Plugin").centerPanel(panel); dialogBuilder.setPreferredFocusComponent(pluginChooser); @@ -218,7 +221,8 @@ public class ExternalDependenciesConfigurable implements SearchableConfigurable, if (dialogBuilder.show() == DialogWrapper.OK_EXIT_CODE) { return new DependencyOnPlugin(((String)pluginChooser.getSelectedItem()), StringUtil.nullize(minVersionField.getText().trim()), - StringUtil.nullize(maxVersionField.getText().trim())); + StringUtil.nullize(maxVersionField.getText().trim()), + StringUtil.nullize(channelField.getText().trim())); } return null; } diff --git a/platform/platform-impl/src/com/intellij/externalDependencies/impl/ExternalDependenciesManagerImpl.java b/platform/platform-impl/src/com/intellij/externalDependencies/impl/ExternalDependenciesManagerImpl.java index 38990458cf5c..442cea5fb52e 100644 --- a/platform/platform-impl/src/com/intellij/externalDependencies/impl/ExternalDependenciesManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/externalDependencies/impl/ExternalDependenciesManagerImpl.java @@ -96,7 +96,7 @@ public class ExternalDependenciesManagerImpl extends ExternalDependenciesManager ArrayList oldDependencies = new ArrayList(myDependencies); myDependencies.clear(); for (DependencyOnPluginState dependency : state.myDependencies) { - myDependencies.add(new DependencyOnPlugin(dependency.myId, dependency.myMinVersion, dependency.myMaxVersion)); + myDependencies.add(new DependencyOnPlugin(dependency.myId, dependency.myMinVersion, dependency.myMaxVersion, dependency.myChannel)); } if (!oldDependencies.equals(myDependencies) && !myDependencies.isEmpty()) { StartupManager.getInstance(myProject).runWhenProjectIsInitialized(new DumbAwareRunnable() {