Merge remote-tracking branch 'origin/GP-0-dragonmacher-test-fixes-11-24-23'

This commit is contained in:
Ryan Kurtz 2023-11-24 14:14:21 -05:00
commit c225fac124
4 changed files with 81 additions and 81 deletions

View file

@ -96,12 +96,13 @@ public class ExtensionUtils {
} }
public static boolean install(ExtensionDetails extension, File file, TaskMonitor monitor) { public static boolean install(ExtensionDetails extension, File file, TaskMonitor monitor) {
boolean success = false;
try { try {
if (file.isFile()) { if (file.isFile()) {
return unzipToInstallationFolder(extension, file, monitor); success = unzipToInstallationFolder(extension, file, monitor);
} }
return copyToInstallationFolder(file, monitor); success = copyToInstallationFolder(extension, file, monitor);
} }
catch (CancelledException e) { catch (CancelledException e) {
log.info("Extension installation cancelled by user"); log.info("Extension installation cancelled by user");
@ -110,7 +111,12 @@ public class ExtensionUtils {
Msg.showError(ExtensionUtils.class, null, "Error Installing Extension", Msg.showError(ExtensionUtils.class, null, "Error Installing Extension",
"Unexpected error installing extension", e); "Unexpected error installing extension", e);
} }
return false;
if (success) {
extensions.add(extension);
}
return success;
} }
public static Set<ExtensionDetails> getActiveInstalledExtensions() { public static Set<ExtensionDetails> getActiveInstalledExtensions() {
@ -197,10 +203,17 @@ public class ExtensionUtils {
*/ */
public static void reload() { public static void reload() {
log.trace("Clearing extensions cache"); log.trace("Clearing extensions cache");
extensions = null; clearCache();
getAllInstalledExtensions(); getAllInstalledExtensions();
} }
/**
* Clears any cached extensions.
*/
public static void clearCache() {
extensions = null;
}
/** /**
* Returns all archive extensions. These are all the extensions found in * Returns all archive extensions. These are all the extensions found in
* {@link ApplicationLayout#getExtensionArchiveDir}. This are added to an installation as * {@link ApplicationLayout#getExtensionArchiveDir}. This are added to an installation as
@ -260,8 +273,7 @@ public class ExtensionUtils {
} }
} }
catch (IOException e) { catch (IOException e) {
log.error( log.error("Unable to read zip file to get extension properties: " + file, e);
"Unable to read zip file to get extension properties: " + file, e);
} }
return null; return null;
} }
@ -276,8 +288,7 @@ public class ExtensionUtils {
} }
if (results.contains(extension)) { if (results.contains(extension)) {
log.error( log.error("Skipping extension \"" + extension.getName() + "\" found at " +
"Skipping extension \"" + extension.getName() + "\" found at " +
extension.getInstallPath() + extension.getInstallPath() +
".\nArchived extension by that name already found."); ".\nArchived extension by that name already found.");
} }
@ -299,8 +310,7 @@ public class ExtensionUtils {
extension.setArchivePath(extDir.getAbsolutePath()); extension.setArchivePath(extDir.getAbsolutePath());
if (results.contains(extension)) { if (results.contains(extension)) {
log.error( log.error("Skipping duplicate extension \"" + extension.getName() + "\" found at " +
"Skipping duplicate extension \"" + extension.getName() + "\" found at " +
extension.getInstallPath()); extension.getInstallPath());
} }
results.add(extension); results.add(extension);
@ -368,8 +378,7 @@ public class ExtensionUtils {
Properties nextProperties = getProperties(zipFile, entry); Properties nextProperties = getProperties(zipFile, entry);
if (nextProperties != null) { if (nextProperties != null) {
if (props != null) { if (props != null) {
throw new IOException( throw new IOException("Zip file contains multiple extension properties files");
"Zip file contains multiple extension properties files");
} }
props = nextProperties; props = nextProperties;
} }
@ -484,27 +493,29 @@ public class ExtensionUtils {
* <p> * <p>
* Note: Any existing folder with the same name will be overwritten. * Note: Any existing folder with the same name will be overwritten.
* *
* @param extension the extension
* @param sourceFolder the extension folder * @param sourceFolder the extension folder
* @param monitor the task monitor * @param monitor the task monitor
* @return true if successful * @return true if successful
* @throws IOException if the delete or copy fails * @throws IOException if the delete or copy fails
* @throws CancelledException if the user cancels the copy * @throws CancelledException if the user cancels the copy
*/ */
private static boolean copyToInstallationFolder(File sourceFolder, TaskMonitor monitor) private static boolean copyToInstallationFolder(ExtensionDetails extension, File sourceFolder,
throws IOException, CancelledException { TaskMonitor monitor) throws IOException, CancelledException {
log.trace("Copying extension from " + sourceFolder); log.trace("Copying extension from " + sourceFolder);
ApplicationLayout layout = Application.getApplicationLayout(); ApplicationLayout layout = Application.getApplicationLayout();
ResourceFile installDir = layout.getExtensionInstallationDirs().get(0); ResourceFile installDir = layout.getExtensionInstallationDirs().get(0);
File installDirRoot = installDir.getFile(false); File installDirRoot = installDir.getFile(false);
File newDir = new File(installDirRoot, sourceFolder.getName()); File destinationFolder = new File(installDirRoot, sourceFolder.getName());
if (hasExistingExtension(newDir, monitor)) { if (hasExistingExtension(destinationFolder, monitor)) {
return false; return false;
} }
log.trace("Copying extension to " + newDir); log.trace("Copying extension to " + destinationFolder);
FileUtilities.copyDir(sourceFolder, newDir, monitor); FileUtilities.copyDir(sourceFolder, destinationFolder, monitor);
extension.setInstallDir(destinationFolder);
return true; return true;
} }
@ -524,8 +535,7 @@ public class ExtensionUtils {
* @throws IOException if error unzipping zip file * @throws IOException if error unzipping zip file
*/ */
private static boolean unzipToInstallationFolder(ExtensionDetails extension, File file, private static boolean unzipToInstallationFolder(ExtensionDetails extension, File file,
TaskMonitor monitor) TaskMonitor monitor) throws CancelledException, IOException {
throws CancelledException, IOException {
log.trace("Unzipping extension from " + file); log.trace("Unzipping extension from " + file);
@ -554,6 +564,8 @@ public class ExtensionUtils {
} }
} }
} }
extension.setInstallDir(destinationFolder);
return true; return true;
} }

View file

@ -43,7 +43,7 @@ public class Extensions {
* @return all matching extensions * @return all matching extensions
*/ */
public List<ExtensionDetails> getMatchingExtensions(ExtensionDetails e) { public List<ExtensionDetails> getMatchingExtensions(ExtensionDetails e) {
return extensionsByName.computeIfAbsent(e.getName(), name -> List.of()); return extensionsByName.computeIfAbsent(e.getName(), name -> new ArrayList<>());
} }
/** /**
@ -187,8 +187,7 @@ public class Extensions {
for (int i = 1; i < extensions.size(); i++) { for (int i = 1; i < extensions.size(); i++) {
ExtensionDetails duplicate = extensions.get(i); ExtensionDetails duplicate = extensions.get(i);
log.info("Duplicate extension found '" + name + "'. Keeping extension from " + log.info("Duplicate extension found '" + name + "'. Keeping extension from " +
loadedInstallDir + ". Skipping extension found at " + loadedInstallDir + ". Skipping extension found at " + duplicate.getInstallDir());
duplicate.getInstallDir());
} }
} }

View file

@ -121,8 +121,7 @@ public class ExtensionInstaller {
String archivePath = extension.getArchivePath(); String archivePath = extension.getArchivePath();
if (archivePath == null) { if (archivePath == null) {
log.error( log.error("Cannot install from archive; extension is missing archive path");
"Cannot install from archive; extension is missing archive path");
return false; return false;
} }
@ -161,9 +160,7 @@ public class ExtensionInstaller {
String message = "Extension version mismatch.\nName: " + extension.getName() + String message = "Extension version mismatch.\nName: " + extension.getName() +
"Extension version: " + extVersion + ".\nGhidra version: " + appVersion + "."; "Extension version: " + extVersion + ".\nGhidra version: " + appVersion + ".";
int choice = OptionDialog.showOptionDialogWithCancelAsDefaultButton(null, int choice = OptionDialog.showOptionDialogWithCancelAsDefaultButton(null,
"Extension Version Mismatch", "Extension Version Mismatch", message, "Install Anyway");
message,
"Install Anyway");
if (choice != OptionDialog.OPTION_ONE) { if (choice != OptionDialog.OPTION_ONE) {
log.info(removeNewlines(message + " Did not install")); log.info(removeNewlines(message + " Did not install"));
return false; return false;
@ -201,16 +198,12 @@ public class ExtensionInstaller {
"Installed extension version: " + installedExtension.getVersion() + ".\n\n" + "Installed extension version: " + installedExtension.getVersion() + ".\n\n" +
"To install, click 'Remove Existing', restart Ghidra, then install again."; "To install, click 'Remove Existing', restart Ghidra, then install again.";
int choice = OptionDialog.showOptionDialogWithCancelAsDefaultButton(null, int choice = OptionDialog.showOptionDialogWithCancelAsDefaultButton(null,
"Duplicate Extension", "Duplicate Extension", message, "Remove Existing");
message,
"Remove Existing");
String installPath = installedExtension.getInstallPath(); String installPath = installedExtension.getInstallPath();
if (choice != OptionDialog.OPTION_ONE) { if (choice != OptionDialog.OPTION_ONE) {
log.info( log.info(removeNewlines(message +
removeNewlines( " Skipping installation. Original extension still installed: " + installPath));
message + " Skipping installation. Original extension still installed: " +
installPath));
return true; return true;
} }
@ -218,8 +211,7 @@ public class ExtensionInstaller {
// At this point the user would like to replace the existing extension. We cannot delete // At this point the user would like to replace the existing extension. We cannot delete
// the existing extension, as it may be in use; mark it for removal. // the existing extension, as it may be in use; mark it for removal.
// //
log.info( log.info(removeNewlines(
removeNewlines(
message + " Installing new extension. Existing extension will be removed after " + message + " Installing new extension. Existing extension will be removed after " +
"restart: " + installPath)); "restart: " + installPath));
installedExtension.markForUninstall(); installedExtension.markForUninstall();

View file

@ -60,6 +60,9 @@ public class ExtensionInstallerTest extends AbstractDockingTest {
setErrorGUIEnabled(false); setErrorGUIEnabled(false);
// clear static caching of extensions
ExtensionUtils.clearCache();
appLayout = Application.getApplicationLayout(); appLayout = Application.getApplicationLayout();
FileUtilities.deleteDir(appLayout.getExtensionArchiveDir().getFile(false)); FileUtilities.deleteDir(appLayout.getExtensionArchiveDir().getFile(false));
@ -317,8 +320,7 @@ public class ExtensionInstallerTest extends AbstractDockingTest {
didInstall.set(ExtensionInstaller.install(extensionFolder2)); didInstall.set(ExtensionInstaller.install(extensionFolder2));
}); });
DialogComponentProvider confirmDialog = DialogComponentProvider confirmDialog = waitForDialogComponent("Duplicate Extension");
waitForDialogComponent("Duplicate Extension");
pressButtonByText(confirmDialog, "Remove Existing"); pressButtonByText(confirmDialog, "Remove Existing");
waitForSwing(); waitForSwing();
@ -363,8 +365,7 @@ public class ExtensionInstallerTest extends AbstractDockingTest {
didInstall.set(ExtensionInstaller.install(extensionFolder2)); didInstall.set(ExtensionInstaller.install(extensionFolder2));
}); });
DialogComponentProvider confirmDialog = DialogComponentProvider confirmDialog = waitForDialogComponent("Duplicate Extension");
waitForDialogComponent("Duplicate Extension");
pressButtonByText(confirmDialog, "Cancel"); pressButtonByText(confirmDialog, "Cancel");
waitForSwing(); waitForSwing();
@ -397,8 +398,7 @@ public class ExtensionInstallerTest extends AbstractDockingTest {
didInstall.set(ExtensionInstaller.install(extensionFolder2)); didInstall.set(ExtensionInstaller.install(extensionFolder2));
}); });
DialogComponentProvider confirmDialog = DialogComponentProvider confirmDialog = waitForDialogComponent("Duplicate Extension");
waitForDialogComponent("Duplicate Extension");
pressButtonByText(confirmDialog, "Remove Existing"); pressButtonByText(confirmDialog, "Remove Existing");
waitForSwing(); waitForSwing();
@ -493,8 +493,7 @@ public class ExtensionInstallerTest extends AbstractDockingTest {
private void assertExtensionNotInstalled(String name, String version) { private void assertExtensionNotInstalled(String name, String version) {
Set<ExtensionDetails> extensions = ExtensionUtils.getInstalledExtensions(); Set<ExtensionDetails> extensions = ExtensionUtils.getInstalledExtensions();
Optional<ExtensionDetails> match = Optional<ExtensionDetails> match = extensions.stream()
extensions.stream()
.filter(e -> e.getName().equals(name) && e.getVersion().equals(version)) .filter(e -> e.getName().equals(name) && e.getVersion().equals(version))
.findFirst(); .findFirst();
assertFalse("Extension should not be installed: '" + name + "'", match.isPresent()); assertFalse("Extension should not be installed: '" + name + "'", match.isPresent());
@ -594,8 +593,7 @@ public class ExtensionInstallerTest extends AbstractDockingTest {
} }
private File doCreateExternalExtensionInFolder(File externalFolder, String extensionName, private File doCreateExternalExtensionInFolder(File externalFolder, String extensionName,
String version) String version) throws Exception {
throws Exception {
return doCreateExternalExtensionInFolder(externalFolder, extensionName, extensionName, return doCreateExternalExtensionInFolder(externalFolder, extensionName, extensionName,
version); version);
} }
@ -609,9 +607,8 @@ public class ExtensionInstallerTest extends AbstractDockingTest {
version); version);
} }
private File doCreateExternalExtensionInFolder(File externalFolder, private File doCreateExternalExtensionInFolder(File externalFolder, String extensionName,
String extensionName, String nameProperty, String version) String nameProperty, String version) throws Exception {
throws Exception {
ResourceFile root = new ResourceFile(new ResourceFile(externalFolder), extensionName); ResourceFile root = new ResourceFile(new ResourceFile(externalFolder), extensionName);
root.mkdir(); root.mkdir();