allow non-programmers to test their updates.xml changes: apply patch

This commit is contained in:
Gregory.Shrago
2017-03-03 22:02:38 +03:00
parent 1a0869c3bb
commit e14f9cab63
3 changed files with 81 additions and 29 deletions
@@ -15,24 +15,39 @@
*/
package com.intellij.openapi.updateSettings.impl;
import com.intellij.ide.util.BrowseFilesListener;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
import com.intellij.openapi.fileChooser.FileChooserFactory;
import com.intellij.openapi.fileChooser.FileTextField;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.DialogBuilder;
import com.intellij.openapi.ui.LabeledComponent;
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.ScrollPaneFactory;
import com.intellij.ui.components.JBList;
import com.intellij.ui.components.JBTextField;
import com.intellij.util.JdomKt;
import com.intellij.util.ObjectUtils;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.UIUtil;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.util.Collections;
public class ShowUpdateInfoDialogAction extends AnAction {
@@ -40,38 +55,54 @@ public class ShowUpdateInfoDialogAction extends AnAction {
public ShowUpdateInfoDialogAction() {
}
@Override
public void update(AnActionEvent e) {
e.getPresentation().setEnabledAndVisible(e.getProject() != null);
}
@Override
public void actionPerformed(AnActionEvent e) {
Project project = ObjectUtils.notNull(e.getProject());
JComponent component = ObjectUtils.notNull((JComponent)e.getData(PlatformDataKeys.CONTEXT_COMPONENT));
Project project = e.getProject();
if (project == null) return;
String title = "Updates.xml <channel> Text";
JBList list = new JBList("Manual Text", "Default Text (short)", "Default Text (long)");
JBList list = new JBList("Manual Text", "Sample Text (short)", "Sample Text (long)");
JBPopupFactory.getInstance().createListPopupBuilder(list)
.setTitle(title)
.setFilteringEnabled(o -> (String)o)
.setItemChoosenCallback(() -> {
int index = list.getSelectedIndex();
showDialog(index == 0 ? getUserText(project, component, title) : getXML(index == 2));
Pair<String, VirtualFile> info = index == 0 ? getUserText(project, title) : Pair.create(getXML(index == 2), null);
showDialog(info.first, info.second);
})
.createPopup()
.showCenteredInCurrentWindow(project);
}
@Nullable
private static String getUserText(@NotNull Project project, @NotNull JComponent component, @NotNull String title) {
JBTextField field = new JBTextField();
field.setVisible(false);
component.getRootPane().add(field);
try {
Messages.showTextAreaDialog(field, title, null);
}
finally {
component.getRootPane().remove(field);
}
return field.getText();
@NotNull
private static Pair<String, VirtualFile> getUserText(@NotNull Project project, @NotNull String title) {
JTextArea textArea = new JTextArea(10, 50);
UIUtil.addUndoRedoActions(textArea);
textArea.setWrapStyleWord(true);
textArea.setLineWrap(true);
JPanel panel = new JPanel(new BorderLayout(0, 10));
panel.add(ScrollPaneFactory.createScrollPane(textArea), BorderLayout.CENTER);
Disposable disposable = Disposer.newDisposable();
FileTextField fileField = FileChooserFactory.getInstance().createFileTextField(BrowseFilesListener.SINGLE_FILE_DESCRIPTOR, disposable);
TextFieldWithBrowseButton fileCompo = new TextFieldWithBrowseButton(fileField.getField());
FileChooserDescriptor fileDescriptor = FileChooserDescriptorFactory.createSingleLocalFileDescriptor();
fileCompo.addBrowseFolderListener("Patch File", "Patch file", project, fileDescriptor);
panel.add(LabeledComponent.create(fileCompo, "Patch file:"), BorderLayout.SOUTH);
DialogBuilder builder = new DialogBuilder(project);
builder.addDisposable(disposable);
builder.setCenterPanel(panel);
builder.setPreferredFocusComponent(textArea);
builder.setTitle(title);
builder.addOkAction();
builder.addCancelAction();
return builder.showAndGet() ? Pair.create(textArea.getText(), fileField.getSelectedFile()) : Pair.empty();
}
protected void showDialog(@Nullable String text) {
protected void showDialog(@Nullable String text, @Nullable VirtualFile patchFile) {
String trim = StringUtil.trim(text);
if (StringUtil.isEmpty(trim)) return;
@@ -86,9 +117,19 @@ public class ShowUpdateInfoDialogAction extends AnAction {
}
UpdateChannel channel = new UpdateChannel(element);
BuildInfo newBuild = ContainerUtil.getFirstItem(channel.getBuilds());
if (newBuild == null) return;
PatchInfo patch = ContainerUtil.getFirstItem(newBuild.getPatches());
new UpdateInfoDialog(channel, newBuild, patch, true, UpdateSettings.getInstance().canUseSecureConnection(),
Collections.emptyList(), Collections.emptyList()).show();
UpdateInfoDialog dialog = new UpdateInfoDialog(channel, newBuild, patch, true, UpdateSettings.getInstance().canUseSecureConnection(),
Collections.emptyList(), Collections.emptyList()) {
@NotNull
@Override
File doDownloadPatch(@NotNull ProgressIndicator indicator) throws IOException {
File file = patchFile == null ? null : VfsUtilCore.virtualToIoFile(patchFile);
return file != null ? file : super.doDownloadPatch(indicator);
}
};
dialog.setTitle("[TEST] " + dialog.getTitle());
dialog.show();
}
@@ -56,6 +56,7 @@ import javax.swing.event.HyperlinkEvent;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.Collection;
@@ -191,7 +192,9 @@ class UpdateInfoDialog extends AbstractUpdateDialog {
public void run(@NotNull ProgressIndicator indicator) {
String[] command;
try {
command = UpdateInstaller.installPlatformUpdate(myPatch, myNewBuild.getNumber(), myForceHttps, indicator);
File file = doDownloadPatch(indicator);
indicator.setText(IdeBundle.message("update.preparing.patch.progress"));
command = UpdateInstaller.preparePatchCommand(file);
}
catch (ProcessCanceledException e) { throw e; }
catch (Exception e) {
@@ -224,6 +227,11 @@ class UpdateInfoDialog extends AbstractUpdateDialog {
}.queue();
}
@NotNull
File doDownloadPatch(@NotNull ProgressIndicator indicator) throws IOException {
return UpdateInstaller.downloadPatchFile(myPatch, myNewBuild.getNumber(), myForceHttps, indicator);
}
private void openDownloadPage() {
String url = myNewBuild.getDownloadUrl();
assert !StringUtil.isEmptyOrSpaces(url) : "channel:" + myUpdatedChannel.getId() + " build:" + myNewBuild.getNumber();
@@ -39,7 +39,10 @@ object UpdateInstaller {
@JvmStatic
@Throws(IOException::class)
fun installPlatformUpdate(patch: PatchInfo, toBuild: BuildNumber, forceHttps: Boolean, indicator: ProgressIndicator): Array<String> {
fun downloadPatchFile(patch: PatchInfo,
toBuild: BuildNumber,
forceHttps: Boolean,
indicator: ProgressIndicator): File {
indicator.text = IdeBundle.message("update.downloading.patch.progress")
val product = ApplicationInfo.getInstance().build.productCode
@@ -52,9 +55,7 @@ object UpdateInstaller {
val url = URL(URL(if (baseUrl.endsWith('/')) baseUrl else baseUrl + '/'), patchName)
val patchFile = File(getTempDir(), "patch.jar")
HttpRequests.request(url.toString()).gzip(false).forceHttps(forceHttps).saveToFile(patchFile, indicator)
indicator.text = IdeBundle.message("update.preparing.patch.progress")
return preparePatchCommand(patchFile)
return patchFile
}
@JvmStatic
@@ -105,7 +106,9 @@ object UpdateInstaller {
if (tempDir.exists()) FileUtil.delete(tempDir)
}
private fun preparePatchCommand(patchFile: File): Array<String> {
@JvmStatic
@Throws(IOException::class)
fun preparePatchCommand(patchFile: File): Array<String> {
val log4j = findLib("log4j.jar")
val jna = findLib("jna.jar")
val jnaUtils = findLib("jna-platform.jar")