Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Intellij plugin] Prompt user to update plugin when installed version is lower than minVersion #410

Open
wants to merge 13 commits into
base: develop
Choose a base branch
from
6 changes: 6 additions & 0 deletions changelog/@unreleased/pr-410.v2.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
type: improvement
improvement:
description: '[Intellij plugin] Prompt user to update plugin when installed version
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this is fine to try out in the this project for now; maybe eventually we can either make it a library each plugin uses (might be bad if they all try to open the update window at once though?) or a separate plugin that updates all the other plugins?

is lower than minVersion'
links:
- https://github.com/palantir/gradle-jdks/pull/410
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ public void onStart(@NotNull ExternalSystemTaskId id, String _workingDir) {
|| id.getType() == ExternalSystemTaskType.EXECUTE_TASK)) {
Project project = id.findProject();
if (project != null) {
project.getService(PluginUpdateCheckerService.class).checkPluginVersion();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess when projects are being refreshed is the place to do this as that's when the .idea/external-dependencies.xml is being changed.

project.getService(GradleJdksProjectService.class).maybeSetupGradleJdks();
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* (c) Copyright 2024 Palantir Technologies Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.palantir.gradle.jdks;

import com.intellij.externalDependencies.DependencyOnPlugin;
import com.intellij.externalDependencies.ExternalDependenciesManager;
import com.intellij.ide.plugins.IdeaPluginDescriptor;
import com.intellij.ide.plugins.PluginManagerCore;
import com.intellij.notification.Notification;
import com.intellij.notification.NotificationGroupManager;
import com.intellij.notification.NotificationType;
import com.intellij.openapi.components.Service;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.PluginId;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.updateSettings.impl.pluginsAdvertisement.PluginsAdvertiser;
import com.intellij.util.text.VersionComparatorUtil;
import java.util.Optional;
import java.util.Set;

@Service(Service.Level.PROJECT)
public final class PluginUpdateCheckerService {

private static final String PLUGIN_ID = "palantir-gradle-jdks";
private final Logger logger = Logger.getInstance(PluginUpdateCheckerService.class);
private final Project project;

public PluginUpdateCheckerService(Project project) {
this.project = project;
}

public void checkPluginVersion() {
PluginId pluginId = PluginId.getId(PLUGIN_ID);
IdeaPluginDescriptor pluginDescriptor = PluginManagerCore.getPlugin(pluginId);
if (pluginDescriptor == null) {
logger.info("Plugin " + pluginId + " not found");
return;
}
Optional<String> maybeMinVersion =
ExternalDependenciesManager.getInstance(project).getDependencies(DependencyOnPlugin.class).stream()
.filter(dependencyOnPlugin ->
dependencyOnPlugin.getPluginId().equals(pluginId.getIdString()))
.map(DependencyOnPlugin::getMinVersion)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just thought of a possible complication:

  1. We release a new version of a gradle + intellij plugin, set the min-version of intellij plugin to "force" people to upgrade.
  2. The Gradle plugin update immediately gets picked up by excavator, applied to people's repos
  3. Jetbrains takes two business days to approve our intellij plugin.
  4. Every single time Gradle is refreshed, people get the popup to update to the new IntelliJ version that is not available yet.

Copy link
Contributor Author

@crogoz crogoz Sep 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's a good point, I'll see if I can check that the version exists before opening the popup.
But that means we cannot really rely on the minVersion. Probably the best would be if the plugin will always maintain backwards compatibility with the intellij plugin and I can add a test for the logic here that we won't update the min-version of a plugin if that version doesn't already exist.

Copy link
Contributor Author

@crogoz crogoz Sep 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added a test that checks that the min-version intellij plugin: https://github.com/palantir/gradle-jdks/pull/410/files#diff-1d01bc54a43b33238be402e57110068b45d10d5b2c7f88104b1c1e67080c1a53R36. This should stop us from bumping the required min-version in externalDependencies.xml file.

I could add the check (probably cached + expiration) here in case we are going to "recall"(delete) a version, but I am not sure if we need it atm.

.filter(version -> Optional.ofNullable(version).isPresent())
.max(VersionComparatorUtil::compare);
boolean isPluginUpToDate = maybeMinVersion
.map(minVersion -> VersionComparatorUtil.compare(pluginDescriptor.getVersion(), minVersion) > 0)
.orElse(true);
if (isPluginUpToDate) {
return;
}
Notification notification = NotificationGroupManager.getInstance()
.getNotificationGroup("Update Palantir plugins")
.createNotification(
"Update palantir-gradle-jdks plugin",
String.format(
"Please update the plugin in the Settings window to a version higher than '%s'",
maybeMinVersion.get()),
NotificationType.ERROR);
notification.notify(project);
PluginsAdvertiser.installAndEnablePlugins(Set.of(PLUGIN_ID), notification::expire);
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we still get the other not so useful (see below) notification? Or is it suppressed somehow.

Screenshot 2024-09-06 at 16 44 27

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we still get it, we'd get both. I can remove my notification, but I thought it might be nice to actually tell you that the you need to use the pop-up window to update the plugin.

9 changes: 6 additions & 3 deletions idea-plugin/src/main/resources/META-INF/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@

<extensions defaultExtensionNs="com.intellij">
<externalSystemTaskNotificationListener implementation="com.palantir.gradle.jdks.GradleJdksExternalSystemTaskNotificationListener"/>
<notificationGroup id="Gradle JDK setup Notifications"
displayType="BALLOON"
key="notification.group.gradleJdkSetup"/>
<notificationGroup id="Update Palantir plugins"
displayType="BALLOON"
key="notification.group.gradleJdkSetup.plugins"/>
<notificationGroup id="Gradle JDK setup Notifications"
displayType="BALLOON"
key="notification.group.gradleJdkSetup"/>
</extensions>
</idea-plugin>