diff --git a/Ghidra/Framework/Generic/src/main/java/ghidra/framework/Application.java b/Ghidra/Framework/Generic/src/main/java/ghidra/framework/Application.java
index 09572b2b80..6648dadba9 100644
--- a/Ghidra/Framework/Generic/src/main/java/ghidra/framework/Application.java
+++ b/Ghidra/Framework/Generic/src/main/java/ghidra/framework/Application.java
@@ -711,12 +711,12 @@ public class Application {
}
/**
- * Returns the Release name for this build or null if unknown.
+ * Returns the release name for this build.
+ * @return the application release name.
*/
public static String getApplicationReleaseName() {
checkAppInitialized();
- return app.layout.getApplicationProperties().getProperty(
- ApplicationProperties.RELEASE_NAME_PROPERTY);
+ return app.layout.getApplicationProperties().getApplicationReleaseName();
}
/**
diff --git a/Ghidra/Framework/Generic/src/main/java/ghidra/framework/GenericRunInfo.java b/Ghidra/Framework/Generic/src/main/java/ghidra/framework/GenericRunInfo.java
index 43c48f1e59..e7d999a9f1 100644
--- a/Ghidra/Framework/Generic/src/main/java/ghidra/framework/GenericRunInfo.java
+++ b/Ghidra/Framework/Generic/src/main/java/ghidra/framework/GenericRunInfo.java
@@ -155,21 +155,32 @@ public class GenericRunInfo {
/**
* This is the same as {@link #getUserSettingsDirsByTime()} except that it doesn't include the
- * current installation.
+ * current installation or installations with different release names.
*/
public static List getPreviousApplicationSettingsDirsByTime() {
- List allApplicationDirs = getUserSettingsDirsByTime();
- if (allApplicationDirs.isEmpty()) {
- return allApplicationDirs;
- }
+ List applicationSettiingsDirs = new ArrayList<>();
- File file = allApplicationDirs.get(0);
- if (Application.getUserSettingsDirectory().getAbsolutePath().equals(
- file.getAbsolutePath())) {
- // remove the current application settings dir from the results
- return allApplicationDirs.subList(1, allApplicationDirs.size());
+ ApplicationIdentifier myIdentifier = new ApplicationIdentifier(
+ Application.getApplicationLayout().getApplicationProperties());
+
+ for (File dir : getUserSettingsDirsByTime()) {
+ String dirName = dir.getName();
+ if (dirName.startsWith(".")) {
+ dirName = dirName.substring(1);
+ }
+ try {
+ ApplicationIdentifier identifier = new ApplicationIdentifier(dirName);
+ if (!identifier.equals(myIdentifier) &&
+ identifier.getApplicationReleaseName().equalsIgnoreCase(
+ myIdentifier.getApplicationReleaseName())) {
+ applicationSettiingsDirs.add(dir);
+ }
+ }
+ catch (IllegalArgumentException e) {
+ // The directory name didn't contain a valid application identifier...skip it
+ }
}
- return allApplicationDirs;
+ return applicationSettiingsDirs;
}
/**
diff --git a/Ghidra/Framework/Generic/src/test/java/ghidra/framework/ApplicationIdentifierTest.java b/Ghidra/Framework/Generic/src/test/java/ghidra/framework/ApplicationIdentifierTest.java
new file mode 100644
index 0000000000..4a4099cd27
--- /dev/null
+++ b/Ghidra/Framework/Generic/src/test/java/ghidra/framework/ApplicationIdentifierTest.java
@@ -0,0 +1,74 @@
+/* ###
+ * IP: GHIDRA
+ *
+ * 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 ghidra.framework;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+import generic.test.AbstractGenericTest;
+
+public class ApplicationIdentifierTest extends AbstractGenericTest {
+
+ @Test
+ public void testApplicationPropertiesIdentifier() {
+ // We should be able to create an ApplicationIdentifier object from the application info
+ // defined in the application properties file without an exception being thrown.
+ new ApplicationIdentifier(Application.getApplicationLayout().getApplicationProperties());
+ }
+
+ @Test
+ public void testApplicationVersionParsing() {
+ ApplicationIdentifier id = new ApplicationIdentifier("Ghidra_9.0.1_public_05212019");
+ assertEquals(id.getApplicationName(), "ghidra");
+ assertEquals(id.getApplicationVersion(), new ApplicationVersion("9.0.1"));
+ assertEquals(id.getApplicationReleaseName(), "PUBLIC");
+ assertEquals(id.toString(), "ghidra_9.0.1_PUBLIC");
+
+ try {
+ new ApplicationIdentifier("ghidra");
+ fail(
+ "Should not be able to parse only a name...a version and release name are required.");
+ }
+ catch (IllegalArgumentException e) {
+ // Getting here indicates success
+ }
+
+ try {
+ new ApplicationIdentifier("ghidra_9.0.1");
+ fail(
+ "Should not be able to parse only a name and version...a release name is required.");
+ }
+ catch (IllegalArgumentException e) {
+ // Getting here indicates success
+ }
+ }
+
+ @Test
+ public void testApplicationIdentifierEquals() {
+ ApplicationIdentifier id1 = new ApplicationIdentifier("ghidra_9.0_public");
+ ApplicationIdentifier id2 = new ApplicationIdentifier("Ghidra_9.0.0_PUBLIC");
+ assertEquals(id1, id2);
+
+ id1 = new ApplicationIdentifier("ghidra_9.0_public");
+ id2 = new ApplicationIdentifier("Ghidra_9.0.1_PUBLIC");
+ assertNotEquals(id1, id2);
+
+ id1 = new ApplicationIdentifier("ghidra_9.0_DEV");
+ id2 = new ApplicationIdentifier("ghidra_9.0_PUBLIC");
+ assertNotEquals(id1, id2);
+ }
+}
diff --git a/Ghidra/Framework/Generic/src/test/java/ghidra/framework/ApplicationVersionTest.java b/Ghidra/Framework/Generic/src/test/java/ghidra/framework/ApplicationVersionTest.java
index f5666929aa..9d4dfe9788 100644
--- a/Ghidra/Framework/Generic/src/test/java/ghidra/framework/ApplicationVersionTest.java
+++ b/Ghidra/Framework/Generic/src/test/java/ghidra/framework/ApplicationVersionTest.java
@@ -35,11 +35,11 @@ public class ApplicationVersionTest extends AbstractGenericTest {
public void testApplicationVersionParsing() {
assertEquals(new ApplicationVersion("9.0").toString(), "9.0");
assertEquals(new ApplicationVersion("9.0.0").toString(), "9.0");
- assertEquals(new ApplicationVersion("9.0.0-DEV").toString(), "9.0");
+ assertEquals(new ApplicationVersion("9.0.0-BETA").toString(), "9.0-BETA");
assertEquals(new ApplicationVersion("9.1").toString(), "9.1");
assertEquals(new ApplicationVersion("9.1.1").toString(), "9.1.1");
- assertEquals(new ApplicationVersion("9.1.1-DEV").toString(), "9.1.1");
+ assertEquals(new ApplicationVersion("9.1.1-BETA").toString(), "9.1.1-BETA");
try {
new ApplicationVersion("9");
@@ -52,16 +52,35 @@ public class ApplicationVersionTest extends AbstractGenericTest {
@Test
public void testApplicationVersionGetters() {
- ApplicationVersion applicationVersion = new ApplicationVersion("9.0.1-DEV");
+ ApplicationVersion applicationVersion = new ApplicationVersion("9.0.1-BETA");
assertEquals(applicationVersion.getMajor(), 9);
assertEquals(applicationVersion.getMinor(), 0);
assertEquals(applicationVersion.getPatch(), 1);
}
+ @Test
+ public void testApplicationVersionEquals() {
+ ApplicationVersion applicationVersion1 = new ApplicationVersion("9.0");
+ ApplicationVersion applicationVersion2 = new ApplicationVersion("9.0.0");
+ assertTrue(applicationVersion1.equals(applicationVersion2));
+
+ applicationVersion1 = new ApplicationVersion("9.0");
+ applicationVersion2 = new ApplicationVersion("9.0.0-BETA");
+ assertFalse(applicationVersion1.equals(applicationVersion2));
+
+ applicationVersion1 = new ApplicationVersion("9.0.0");
+ applicationVersion2 = new ApplicationVersion("9.0.1");
+ assertFalse(applicationVersion1.equals(applicationVersion2));
+
+ applicationVersion1 = new ApplicationVersion("9.0");
+ applicationVersion2 = new ApplicationVersion("10.0");
+ assertNotEquals(applicationVersion1, applicationVersion2);
+ }
+
@Test
public void testApplicationVersionCompare() {
ApplicationVersion applicationVersion1 = new ApplicationVersion("9.0");
- ApplicationVersion applicationVersion2 = new ApplicationVersion("9.0.0-DEV");
+ ApplicationVersion applicationVersion2 = new ApplicationVersion("9.0.0-BETA");
assertTrue(applicationVersion1.compareTo(applicationVersion2) == 0);
applicationVersion1 = new ApplicationVersion("9.0");
diff --git a/Ghidra/Framework/Utility/src/main/java/ghidra/framework/ApplicationIdentifier.java b/Ghidra/Framework/Utility/src/main/java/ghidra/framework/ApplicationIdentifier.java
new file mode 100644
index 0000000000..5869ae6aa7
--- /dev/null
+++ b/Ghidra/Framework/Utility/src/main/java/ghidra/framework/ApplicationIdentifier.java
@@ -0,0 +1,157 @@
+/* ###
+ * IP: GHIDRA
+ *
+ * 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 ghidra.framework;
+
+/**
+ * Class to represent an application's unique identifier. An application identifier is made up
+ * of an application name, an application version, and an application release name.
+ *
+ * The identifier format is (\.+) - \d\.\d(\.\d)?(\-.+)? _ (\.+)
+ * name version release name
+ *
+ * Application names will be converted to all lowercase and application release names will be
+ * converted to all uppercase.
+ *
+ * Examples:
+ *
ghidra-7.4_DEV
+ */
+public class ApplicationIdentifier {
+
+ private String applicationName;
+ private ApplicationVersion applicationVersion;
+ private String applicationReleaseName;
+
+ /**
+ * Creates a new {@link ApplicationIdentifier} object from an {@link ApplicationProperties}.
+ *
+ * @param applicationProperties An {@link ApplicationProperties}.
+ * @throws IllegalArgumentException if required elements from the {@link ApplicationProperties}
+ * were missing or otherwise failed to parse. The exception's message has more detailed
+ * information about why it failed.
+ */
+ public ApplicationIdentifier(ApplicationProperties applicationProperties)
+ throws IllegalArgumentException {
+ applicationName = applicationProperties.getApplicationName().toLowerCase();
+ if (applicationName.isEmpty()) {
+ throw new IllegalArgumentException("Application name is undefined.");
+ }
+
+ applicationVersion = new ApplicationVersion(applicationProperties.getApplicationVersion());
+
+ applicationReleaseName = applicationProperties.getApplicationReleaseName().toUpperCase();
+ if (applicationReleaseName.isEmpty()) {
+ throw new IllegalArgumentException("Application release name is undefined.");
+ }
+ }
+
+ /**
+ * Creates a new {@link ApplicationIdentifier} object from the given string.
+ *
+ * @param identifier An identifier string.
+ * @throws IllegalArgumentException if the identifier string failed to parse. The
+ * exception's message has more detailed information about why it failed.
+ */
+ public ApplicationIdentifier(String identifier) throws IllegalArgumentException {
+ parse(identifier);
+ }
+
+ /**
+ * Gets the application name.
+ *
+ * @return The application name.
+ */
+ public String getApplicationName() {
+ return applicationName;
+ }
+
+ /**
+ * Gets the {@link ApplicationVersion application version}.
+ *
+ * @return The {@link ApplicationVersion application version}.
+ */
+ public ApplicationVersion getApplicationVersion() {
+ return applicationVersion;
+ }
+
+ /**
+ * Gets the application release name.
+ *
+ * @return The application release name.
+ */
+ public String getApplicationReleaseName() {
+ return applicationReleaseName;
+ }
+
+ @Override
+ public String toString() {
+ return applicationName + "_" + applicationVersion + "_" + applicationReleaseName;
+ }
+
+ @Override
+ public int hashCode() {
+ return (applicationName + applicationReleaseName).hashCode() *
+ applicationVersion.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ ApplicationIdentifier other = (ApplicationIdentifier) obj;
+ if (!applicationName.equals(other.applicationName)) {
+ return false;
+ }
+ if (!applicationReleaseName.equals(other.applicationReleaseName)) {
+ return false;
+ }
+ if (!applicationVersion.equals(other.applicationVersion)) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Parses application identifier components out of the given version string.
+ *
+ * @param identifier An identifier string.
+ * @throws IllegalArgumentException if the identifier string failed to parse. The
+ * exception's message has more detailed information about why it failed.
+ */
+ private void parse(String identifier) throws IllegalArgumentException {
+ if (identifier == null) {
+ throw new IllegalArgumentException("Identifier is null");
+ }
+
+ String[] identifierParts = identifier.split("_");
+ if (identifierParts.length >= 3) {
+ applicationName = identifierParts[0].toLowerCase();
+ applicationVersion = new ApplicationVersion(identifierParts[1]);
+ applicationReleaseName = identifierParts[2].toUpperCase();
+ // Ignore any parts after the release name...they are not part of the identifier
+ }
+ else {
+ throw new IllegalArgumentException(
+ "Identifier has " + identifierParts.length + " parts but 3 are required");
+ }
+ }
+}
diff --git a/Ghidra/Framework/Utility/src/main/java/ghidra/framework/ApplicationProperties.java b/Ghidra/Framework/Utility/src/main/java/ghidra/framework/ApplicationProperties.java
index 24e27cf4b0..bdcfcd9592 100644
--- a/Ghidra/Framework/Utility/src/main/java/ghidra/framework/ApplicationProperties.java
+++ b/Ghidra/Framework/Utility/src/main/java/ghidra/framework/ApplicationProperties.java
@@ -105,16 +105,6 @@ public class ApplicationProperties extends Properties {
public static final String TEST_RELEASE_PROPERTY = "application.test.release";
public static final String RELEASE_SOURCE_PROPERTY = "application.release.source";
- /**
- * The default application name to use if {@link #APPLICATION_NAME_PROPERTY} is undefined.
- */
- private static final String DEFAULT_APPLICATION_NAME = "NO_APP_NAME_DEFINED";
-
- /**
- * The default version to use if {@link #APPLICATION_VERSION_PROPERTY} is undefined.
- */
- private static final String DEFAULT_APPLICATION_VERSION = "0.1";
-
/**
* Attempts to create an instance of this class by looking for the a properties file
* with the give name in the current working directory.
@@ -233,12 +223,12 @@ public class ApplicationProperties extends Properties {
/**
* Gets the application's name.
*
- * @return The application's name.
+ * @return The application's name (empty string if undefined).
*/
public String getApplicationName() {
String appName = getProperty(ApplicationProperties.APPLICATION_NAME_PROPERTY);
- if (appName == null) {
- return DEFAULT_APPLICATION_NAME;
+ if (appName == null || appName.trim().isEmpty()) {
+ return "";
}
return appName;
}
@@ -246,15 +236,28 @@ public class ApplicationProperties extends Properties {
/**
* Gets the application's version.
*
- * @return The application's version.
+ * @return The application's version (empty string if undefined).
*/
public String getApplicationVersion() {
String appVersion = getProperty(ApplicationProperties.APPLICATION_VERSION_PROPERTY);
- if (appVersion == null) {
- return DEFAULT_APPLICATION_VERSION;
+ if (appVersion == null || appVersion.trim().isEmpty()) {
+ return "";
}
return appVersion;
}
+
+ /**
+ * Gets the application's release name.
+ *
+ * @return The application's release name (empty string if undefined).
+ */
+ public String getApplicationReleaseName() {
+ String appReleaseName = getProperty(ApplicationProperties.RELEASE_NAME_PROPERTY);
+ if (appReleaseName == null || appReleaseName.trim().isEmpty()) {
+ return "";
+ }
+ return appReleaseName;
+ }
/**
* Gets the application's build date.
@@ -263,8 +266,8 @@ public class ApplicationProperties extends Properties {
*/
public String getApplicationBuildDate() {
String appBuildDate = getProperty(ApplicationProperties.BUILD_DATE_PROPERTY);
- if (appBuildDate == null) {
- // Use today if property is not found
+ if (appBuildDate == null || appBuildDate.trim().isEmpty()) {
+ // Use today if property is not defined
appBuildDate = new SimpleDateFormat("yyyy-MMM-dd").format(new Date());
}
return appBuildDate;
diff --git a/Ghidra/Framework/Utility/src/main/java/ghidra/framework/ApplicationVersion.java b/Ghidra/Framework/Utility/src/main/java/ghidra/framework/ApplicationVersion.java
index e6cda9eb80..8de22c4234 100644
--- a/Ghidra/Framework/Utility/src/main/java/ghidra/framework/ApplicationVersion.java
+++ b/Ghidra/Framework/Utility/src/main/java/ghidra/framework/ApplicationVersion.java
@@ -20,16 +20,20 @@ package ghidra.framework;
*
* The version format is \d\.\d(\.\d)?(\-.+)?
*
+ * Note: this class has a natural ordering that is inconsistent with equals (the tag
+ * part of the version is disregarded in the {@link #compareTo(ApplicationVersion)} method).
+ *
* Examples:
*
7.4
* 7.4.1
- * 7.4.1-DEV
+ * 7.4.1-BETA
*/
public class ApplicationVersion implements Comparable {
private int major;
private int minor;
private int patch;
+ private String tag;
/**
* Creates a new {@link ApplicationVersion} object from the given version string.
@@ -69,12 +73,30 @@ public class ApplicationVersion implements Comparable {
return patch;
}
+ /**
+ * Gets the tag.
+ *
+ * @return The tag. Could be the empty string.
+ */
+ public String getTag() {
+ return tag;
+ }
+
@Override
public String toString() {
- if (patch == 0) {
- return String.format("%d.%d", major, minor);
+ StringBuilder builder = new StringBuilder();
+ builder.append(major);
+ builder.append(".");
+ builder.append(minor);
+ if (patch > 0) {
+ builder.append(".");
+ builder.append(patch);
}
- return String.format("%d.%d.%d", major, minor, patch);
+ if (!tag.isEmpty()) {
+ builder.append("-");
+ builder.append(tag);
+ }
+ return builder.toString();
}
@Override
@@ -107,6 +129,7 @@ public class ApplicationVersion implements Comparable {
result = prime * result + major;
result = prime * result + minor;
result = prime * result + patch;
+ result += tag.hashCode();
return result;
}
@@ -131,11 +154,14 @@ public class ApplicationVersion implements Comparable {
if (patch != other.patch) {
return false;
}
+ if (!tag.equals(other.tag)) {
+ return false;
+ }
return true;
}
/**
- * Parses the major, minor, and optional patch integers out of the given version string.
+ * Parses the major, minor, patch, and tag components out of the given version string.
*
* @param version A version string.
* @throws IllegalArgumentException if the version string failed to parse. The
@@ -146,8 +172,12 @@ public class ApplicationVersion implements Comparable {
throw new IllegalArgumentException("Version is null");
}
+ tag = "";
int dashIndex = version.indexOf('-');
if (dashIndex != -1) {
+ if (dashIndex + 1 < version.length()) {
+ tag = version.substring(dashIndex + 1);
+ }
version = version.substring(0, dashIndex);
}
diff --git a/Ghidra/Framework/Utility/src/main/java/utility/application/ApplicationUtilities.java b/Ghidra/Framework/Utility/src/main/java/utility/application/ApplicationUtilities.java
index 9b247bb211..7e0c19de89 100644
--- a/Ghidra/Framework/Utility/src/main/java/utility/application/ApplicationUtilities.java
+++ b/Ghidra/Framework/Utility/src/main/java/utility/application/ApplicationUtilities.java
@@ -20,8 +20,7 @@ import java.util.ArrayList;
import java.util.Collection;
import generic.jar.ResourceFile;
-import ghidra.framework.ApplicationProperties;
-import ghidra.framework.OperatingSystem;
+import ghidra.framework.*;
import ghidra.util.Msg;
import ghidra.util.SystemUtilities;
@@ -68,8 +67,7 @@ public class ApplicationUtilities {
}
}
catch (IOException e) {
- Msg.error(ApplicationUtilities.class, "Invalid class path entry: " + pathEntry,
- e);
+ Msg.error(ApplicationUtilities.class, "Invalid class path entry: " + pathEntry, e);
}
}
return null;
@@ -181,23 +179,25 @@ public class ApplicationUtilities {
public static File getDefaultUserSettingsDir(ApplicationProperties applicationProperties,
ResourceFile installationDirectory) throws FileNotFoundException {
- String userSettingsDir = System.getProperty("user.home");
- if (userSettingsDir == null || userSettingsDir.isEmpty()) {
+ String homedir = System.getProperty("user.home");
+ if (homedir == null || homedir.isEmpty()) {
throw new FileNotFoundException("System property \"user.home\" is not set!");
}
- String prefix =
- "." + applicationProperties.getApplicationName().replaceAll("\\s", "").toLowerCase();
+ ApplicationIdentifier applicationIdentifier =
+ new ApplicationIdentifier(applicationProperties);
- File applicationParentDir = new File(userSettingsDir, prefix);
- String suffix = applicationProperties.getApplicationVersion();
+ File userSettingsParentDir =
+ new File(homedir, "." + applicationIdentifier.getApplicationName());
+
+ String userSettingsDirName = "." + applicationIdentifier;
if (SystemUtilities.isInDevelopmentMode()) {
- // Add the appication's installation directory name to this variable, so that each
+ // Add the application's installation directory name to this variable, so that each
// branch's project user directory is unique.
- suffix += "_location_" + installationDirectory.getName();
+ userSettingsDirName += "_location_" + installationDirectory.getName();
}
- return new File(applicationParentDir, prefix + "-" + suffix);
+ return new File(userSettingsParentDir, userSettingsDirName);
}
}
diff --git a/Ghidra/application.properties b/Ghidra/application.properties
index f85257a265..8748fe6d11 100644
--- a/Ghidra/application.properties
+++ b/Ghidra/application.properties
@@ -1,6 +1,6 @@
application.name=Ghidra
-application.version=9.1-DEV
-application.release.name=PUBLIC
+application.version=9.1
+application.release.name=DEV
application.layout.version=1
application.gradle.version=5.0
application.java.min=11
diff --git a/GhidraBuild/EclipsePlugins/GhidraDev/GhidraDevFeature/category.xml b/GhidraBuild/EclipsePlugins/GhidraDev/GhidraDevFeature/category.xml
index fc7d85210e..c04702a7a4 100644
--- a/GhidraBuild/EclipsePlugins/GhidraDev/GhidraDevFeature/category.xml
+++ b/GhidraBuild/EclipsePlugins/GhidraDev/GhidraDevFeature/category.xml
@@ -1,6 +1,6 @@
-
+
diff --git a/GhidraBuild/EclipsePlugins/GhidraDev/GhidraDevFeature/feature.xml b/GhidraBuild/EclipsePlugins/GhidraDev/GhidraDevFeature/feature.xml
index cedf88deb6..a12a0a45be 100644
--- a/GhidraBuild/EclipsePlugins/GhidraDev/GhidraDevFeature/feature.xml
+++ b/GhidraBuild/EclipsePlugins/GhidraDev/GhidraDevFeature/feature.xml
@@ -2,7 +2,7 @@
diff --git a/GhidraBuild/EclipsePlugins/GhidraDev/GhidraDevPlugin/GhidraDev_README.html b/GhidraBuild/EclipsePlugins/GhidraDev/GhidraDevPlugin/GhidraDev_README.html
index 687df593d6..10cb20eafa 100644
--- a/GhidraBuild/EclipsePlugins/GhidraDev/GhidraDevPlugin/GhidraDev_README.html
+++ b/GhidraBuild/EclipsePlugins/GhidraDev/GhidraDevPlugin/GhidraDev_README.html
@@ -19,7 +19,7 @@
GhidraDev README
GhidraDev provides support for developing and debugging Ghidra scripts and modules in Eclipse.
-The information provided in this document is effective as of GhidraDev 2.0.1 and is subject to
+
The information provided in this document is effective as of GhidraDev 2.1.0 and is subject to
change with future releases.
@@ -53,6 +53,8 @@ change with future releases.
Change History
+2.1.0: Added support for Ghidra 9.1. GhidraDev 2.1.0 will be unable to create
+new Eclipse projects for versions of Ghidra earlier than 9.1.
2.0.1: Fixed exception that occurred when performing certain actions on a Ghidra
project that was imported from a previously exported Archive File.
2.0.0:
diff --git a/GhidraBuild/EclipsePlugins/GhidraDev/GhidraDevPlugin/META-INF/MANIFEST.MF b/GhidraBuild/EclipsePlugins/GhidraDev/GhidraDevPlugin/META-INF/MANIFEST.MF
index 3a6bb4521a..17899d784d 100644
--- a/GhidraBuild/EclipsePlugins/GhidraDev/GhidraDevPlugin/META-INF/MANIFEST.MF
+++ b/GhidraBuild/EclipsePlugins/GhidraDev/GhidraDevPlugin/META-INF/MANIFEST.MF
@@ -3,7 +3,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: GhidraDev
Bundle-SymbolicName: ghidra.ghidradev;singleton:=true
-Bundle-Version: 2.0.1.qualifier
+Bundle-Version: 2.1.0.qualifier
Bundle-Activator: ghidradev.Activator
Require-Bundle: org.eclipse.ant.core;bundle-version="3.5.200",
org.eclipse.buildship.core;bundle-version="3.0.0",
diff --git a/GhidraBuild/EclipsePlugins/GhidraDev/GhidraDevPlugin/src/main/java/ghidradev/ghidraprojectcreator/preferences/GhidraProjectCreatorPreferencePage.java b/GhidraBuild/EclipsePlugins/GhidraDev/GhidraDevPlugin/src/main/java/ghidradev/ghidraprojectcreator/preferences/GhidraProjectCreatorPreferencePage.java
index bef66b124e..d01131a3d6 100644
--- a/GhidraBuild/EclipsePlugins/GhidraDev/GhidraDevPlugin/src/main/java/ghidradev/ghidraprojectcreator/preferences/GhidraProjectCreatorPreferencePage.java
+++ b/GhidraBuild/EclipsePlugins/GhidraDev/GhidraDevPlugin/src/main/java/ghidradev/ghidraprojectcreator/preferences/GhidraProjectCreatorPreferencePage.java
@@ -43,7 +43,7 @@ import utility.application.ApplicationLayout;
public class GhidraProjectCreatorPreferencePage extends PreferencePage
implements IWorkbenchPreferencePage {
- private static ApplicationVersion MIN_GHIDRA_VERSION = new ApplicationVersion("9.0");
+ private static ApplicationVersion MIN_GHIDRA_VERSION = new ApplicationVersion("9.1");
private Table table;
private Button addButton;
diff --git a/GhidraBuild/LaunchSupport/src/main/java/ghidra/launch/JavaConfig.java b/GhidraBuild/LaunchSupport/src/main/java/ghidra/launch/JavaConfig.java
index fe5730b974..dd1b8e0a3f 100644
--- a/GhidraBuild/LaunchSupport/src/main/java/ghidra/launch/JavaConfig.java
+++ b/GhidraBuild/LaunchSupport/src/main/java/ghidra/launch/JavaConfig.java
@@ -33,8 +33,9 @@ public class JavaConfig {
private LaunchProperties launchProperties;
private File javaHomeSaveFile;
- private String applicationName;
- private String applicationVersion;
+ private String applicationName; // example: Ghidra
+ private String applicationVersion; // example: 9.0.1
+ private String applicationReleaseName; // example: PUBLIC, DEV, etc
private int minSupportedJava;
private int maxSupportedJava;
private String compilerComplianceLevel;
@@ -277,6 +278,8 @@ public class JavaConfig {
// Required properties
applicationName = getDefinedProperty(applicationProperties, "application.name");
applicationVersion = getDefinedProperty(applicationProperties, "application.version");
+ applicationReleaseName =
+ getDefinedProperty(applicationProperties, "application.release.name");
compilerComplianceLevel =
getDefinedProperty(applicationProperties, "application.java.compiler");
try {
@@ -349,13 +352,16 @@ public class JavaConfig {
}
// Get the java home save file from user home directory (it might not exist yet).
- String prefix = "." + applicationName.replaceAll("\\s", "").toLowerCase();
- String suffix = applicationVersion;
+ File userSettingsParentDir = new File(userHomeDir, "." + applicationName.toLowerCase());
+
+ String userSettingsDirName = userSettingsParentDir.getName() + "_" + applicationVersion +
+ "_" + applicationReleaseName.toUpperCase();
+
if (isDev) {
- suffix += "_location_" + installDir.getParentFile().getName();
+ userSettingsDirName += "_location_" + installDir.getParentFile().getName();
}
- File userSettingsDir =
- new File(userHomeDir, prefix + File.separator + prefix + "-" + suffix);
+
+ File userSettingsDir = new File(userSettingsParentDir, userSettingsDirName);
javaHomeSaveFile = new File(userSettingsDir, JAVA_HOME_SAVE_NAME);
}
diff --git a/gradle/root/distribution.gradle b/gradle/root/distribution.gradle
index 66d84cc005..5d324c13da 100644
--- a/gradle/root/distribution.gradle
+++ b/gradle/root/distribution.gradle
@@ -15,8 +15,8 @@ import org.apache.tools.ant.filters.*
def currentPlatform = getCurrentPlatformName()
def PROJECT_DIR = file (rootProject.projectDir.absolutePath)
ext.DISTRIBUTION_DIR = file("$buildDir/dist")
-ext.ZIP_NAME_PREFIX = "${rootProject.DISTRO_PREFIX}_${rootProject.RELEASE_NAME}_${rootProject.BUILD_DATE_SHORT}"
-ext.ZIP_DIR_PREFIX = rootProject.DISTRO_PREFIX
+ext.ZIP_NAME_PREFIX = "${rootProject.DISTRO_PREFIX}_${rootProject.BUILD_DATE_SHORT}"
+ext.ZIP_DIR_PREFIX = "${rootProject.DISTRO_PREFIX}"
FileTree javadocFiles = fileTree (rootProject.projectDir.toString()) {
diff --git a/gradle/support/loadApplicationProperties.gradle b/gradle/support/loadApplicationProperties.gradle
index 29212ae03d..bd6abc89bc 100644
--- a/gradle/support/loadApplicationProperties.gradle
+++ b/gradle/support/loadApplicationProperties.gradle
@@ -11,8 +11,8 @@ file("Ghidra/application.properties").withReader { reader ->
version = ghidraProps.getProperty('application.version')
project.ext.RELEASE_VERSION = version
project.ext.RELEASE_NAME = ghidraProps.getProperty('application.release.name')
- project.ext.DISTRO_PREFIX = "ghidra_${version}"
project.ext.JAVA_COMPILER = ghidraProps.getProperty('application.java.compiler')
+ project.ext.DISTRO_PREFIX = "ghidra_${version}_${RELEASE_NAME}"
// Build dates may or may not be already present in the application.properties file.
// If they are not present, we will set the dates so Gradle can use them, and we will