GP-4176: GhidraDev can now handle both legacy user settings directories

as well as the new XDG layout
This commit is contained in:
Ryan Kurtz 2024-02-16 09:50:46 -05:00
parent fea1243894
commit 4fc9ccde28
7 changed files with 56 additions and 25 deletions

View File

@ -48,7 +48,13 @@ public class ApplicationProperties extends Properties {
* The application's layout version. The layout version should get incremented any time
* something changes about the application that could affect external tools that need to
* navigate the application in some way (such as the Eclipse GhidraDev plugin).
* For example, "1".
* <p>
* Current application versions are:
* <ul>
* <li>1: Layout used by Ghidra &lt; 11.1</li>
* <li>2: Introduced with Ghidra 11.1. Default user settings/cache/temp directories changed,
* and XDG environment variables are supported.
* </ul>
*/
public static final String APPLICATION_LAYOUT_VERSION_PROPERTY = "application.layout.version";

View File

@ -1,7 +1,7 @@
application.name=Ghidra
application.version=11.1
application.release.name=DEV
application.layout.version=1
application.layout.version=2
application.gradle.min=7.3
application.gradle.max=
application.java.min=17

View File

@ -2,7 +2,7 @@
<feature
id="ghidra.ghidradev"
label="GhidraDev"
version="3.0.2.qualifier"
version="3.1.0.qualifier"
provider-name="Ghidra">
<description>
@ -45,9 +45,6 @@ limitations under the License.
<plugin
id="ghidra.ghidradev"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
version="0.0.0"/>
</feature>

View File

@ -19,7 +19,7 @@
<h1>GhidraDev README</h1>
<p>GhidraDev provides support for developing and debugging Ghidra scripts and modules in Eclipse.
</p>
<p>The information provided in this document is effective as of GhidraDev 3.0.2 and is subject to
<p>The information provided in this document is effective as of GhidraDev 3.1.0 and is subject to
change with future releases.</p>
<ul>
@ -53,6 +53,13 @@ change with future releases.</p>
</ul>
<h2><a name="ChangeHistory"></a>Change History</h2>
<p><u><b>3.1.0</b>:</u>
<ul>
<li>
GhidraDev has been upgraded to be compatible with Ghidra 11.1 and later. Older versions of
GhidraDev will report an error when trying to link against Ghidra 11.1 or later.
</li>
</ul>
<p><u><b>3.0.2</b>:</u>
<ul>
<li>

View File

@ -3,7 +3,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: GhidraDev
Bundle-SymbolicName: ghidra.ghidradev;singleton:=true
Bundle-Version: 3.0.2.qualifier
Bundle-Version: 3.1.0.qualifier
Bundle-Activator: ghidradev.Activator
Require-Bundle: org.eclipse.ant.core;bundle-version="3.6.200",
org.eclipse.buildship.core;bundle-version="3.1.5",

View File

@ -229,12 +229,21 @@ implements IWorkbenchPreferencePage {
}
String layoutVersion = applicationProperties.getProperty(
ApplicationProperties.APPLICATION_LAYOUT_VERSION_PROPERTY);
if (layoutVersion == null || !layoutVersion.equals("1")) {
// We can be smarter about this check and what we support later, once the layout version
// actually changes.
boolean layoutVersionError = false;
try {
int ver = Integer.parseInt(layoutVersion);
if (ver < 1 || ver > 2) {
layoutVersionError = true;
}
}
catch (NumberFormatException e) {
layoutVersionError = true;
}
if (layoutVersionError) {
throw new IOException(
"Ghidra application layout is not supported. Please upgrade " +
Activator.PLUGIN_ID + " to use this version of Ghidra.");
"Ghidra application layout '%s' is not supported. Please upgrade %s to use this version of Ghidra."
.formatted(layoutVersion != null ? layoutVersion : "<null>",
Activator.PLUGIN_ID));
}
}
}

View File

@ -36,6 +36,7 @@ public class JavaConfig {
private String applicationName; // example: Ghidra
private String applicationVersion; // example: 9.0.1
private String applicationReleaseName; // example: PUBLIC, DEV, etc
private String applicationLayoutVersion; // example: 2
private int minSupportedJava;
private int maxSupportedJava;
private String compilerComplianceLevel;
@ -299,6 +300,8 @@ public class JavaConfig {
applicationVersion = getDefinedProperty(applicationProperties, "application.version");
applicationReleaseName =
getDefinedProperty(applicationProperties, "application.release.name");
applicationLayoutVersion =
getDefinedProperty(applicationProperties, "application.layout.version");
compilerComplianceLevel =
getDefinedProperty(applicationProperties, "application.java.compiler");
try {
@ -359,7 +362,7 @@ public class JavaConfig {
*/
private void initJavaHomeSaveFile(File installDir) throws FileNotFoundException {
boolean isDev = new File(installDir, "build.gradle").isFile();
String appName = applicationName.toLowerCase();
String appName = applicationName.replaceAll("\\s", "").toLowerCase();
String userSettingsDirName = appName + "_" + applicationVersion + "_" +
applicationReleaseName.replaceAll("\\s", "").toUpperCase();
@ -367,16 +370,6 @@ public class JavaConfig {
userSettingsDirName += "_location_" + installDir.getParentFile().getName();
}
File userSettingsDir = null;
// Look for XDG environment variable
String xdgConfigHomeDirStr = System.getenv("XDG_CONFIG_HOME");
if (xdgConfigHomeDirStr != null && !xdgConfigHomeDirStr.isEmpty()) {
userSettingsDir = new File(xdgConfigHomeDirStr, appName + "/" + userSettingsDirName);
javaHomeSaveFile = new File(userSettingsDir, JAVA_HOME_SAVE_NAME);
return;
}
// Ensure there is a user home directory (there definitely should be)
String userHomeDirPath = System.getProperty("user.home");
if (userHomeDirPath == null || userHomeDirPath.isEmpty()) {
@ -387,6 +380,24 @@ public class JavaConfig {
throw new FileNotFoundException("User home directory does not exist: " + userHomeDir);
}
File userSettingsDir = null;
// Handle legacy application layout
if (applicationLayoutVersion.equals("1")) {
userSettingsDir = new File(userHomeDir, "." + appName + "/." + userSettingsDirName);
javaHomeSaveFile = new File(userSettingsDir, JAVA_HOME_SAVE_NAME);
return;
}
// Look for XDG environment variable
String xdgConfigHomeDirStr = System.getenv("XDG_CONFIG_HOME");
if (xdgConfigHomeDirStr != null && !xdgConfigHomeDirStr.isEmpty()) {
userSettingsDir = new File(xdgConfigHomeDirStr, appName + "/" + userSettingsDirName);
javaHomeSaveFile = new File(userSettingsDir, JAVA_HOME_SAVE_NAME);
return;
}
// Look in current user settings directory
switch (JavaFinder.getCurrentPlatform()) {
case WINDOWS:
String localAppDataDirPath = System.getenv("APPDATA");
@ -408,6 +419,7 @@ public class JavaConfig {
throw new FileNotFoundException(
"Failed to find the user settings directory: Unsupported operating system.");
}
javaHomeSaveFile = new File(userSettingsDir, JAVA_HOME_SAVE_NAME);
}