From 09fa35f1445c5f0d74ae87dfa2df6dc48517f290 Mon Sep 17 00:00:00 2001 From: Skylot <118523+skylot@users.noreply.github.com> Date: Sat, 27 Apr 2024 21:48:42 +0100 Subject: [PATCH] feat: allow to change config and cache dirs with env vars (#2159) --- README.md | 2 + .../main/java/jadx/cli/JCommanderWrapper.java | 2 + jadx-commons/jadx-app-commons/README.md | 6 ++ .../jadx-app-commons/build.gradle.kts | 7 ++ .../java/jadx/commons/app/JadxCommonEnv.java | 29 ++++++++ .../jadx/commons/app/JadxCommonFiles.java | 73 +++++++++++++++++++ jadx-gui/build.gradle.kts | 2 +- .../java/jadx/gui/utils/files/JadxFiles.java | 19 ++--- jadx-plugins-tools/build.gradle.kts | 3 +- .../jadx/plugins/tools/utils/PluginFiles.java | 9 +-- .../jadx-script-plugin/build.gradle.kts | 4 +- .../kotlin/jadx/plugins/script/ScriptCache.kt | 5 +- settings.gradle.kts | 2 + 13 files changed, 135 insertions(+), 28 deletions(-) create mode 100644 jadx-commons/jadx-app-commons/README.md create mode 100644 jadx-commons/jadx-app-commons/build.gradle.kts create mode 100644 jadx-commons/jadx-app-commons/src/main/java/jadx/commons/app/JadxCommonEnv.java create mode 100644 jadx-commons/jadx-app-commons/src/main/java/jadx/commons/app/JadxCommonFiles.java diff --git a/README.md b/README.md index 9f79a118a..c827dcc75 100644 --- a/README.md +++ b/README.md @@ -185,6 +185,8 @@ Environment variables: JADX_DISABLE_XML_SECURITY - set to 'true' to disable all security checks for XML files JADX_DISABLE_ZIP_SECURITY - set to 'true' to disable all security checks for zip files JADX_ZIP_MAX_ENTRIES_COUNT - maximum allowed number of entries in zip files (default: 100 000) + JADX_CONFIG_DIR - custom config directory, using system by default + JADX_CACHE_DIR - custom cache directory, using system by default JADX_TMP_DIR - custom temp directory, using system by default Examples: diff --git a/jadx-cli/src/main/java/jadx/cli/JCommanderWrapper.java b/jadx-cli/src/main/java/jadx/cli/JCommanderWrapper.java index 9725e2a72..190283648 100644 --- a/jadx-cli/src/main/java/jadx/cli/JCommanderWrapper.java +++ b/jadx-cli/src/main/java/jadx/cli/JCommanderWrapper.java @@ -111,6 +111,8 @@ public class JCommanderWrapper { out.println(" JADX_DISABLE_XML_SECURITY - set to 'true' to disable all security checks for XML files"); out.println(" JADX_DISABLE_ZIP_SECURITY - set to 'true' to disable all security checks for zip files"); out.println(" JADX_ZIP_MAX_ENTRIES_COUNT - maximum allowed number of entries in zip files (default: 100 000)"); + out.println(" JADX_CONFIG_DIR - custom config directory, using system by default"); + out.println(" JADX_CACHE_DIR - custom cache directory, using system by default"); out.println(" JADX_TMP_DIR - custom temp directory, using system by default"); out.println(); out.println("Examples:"); diff --git a/jadx-commons/jadx-app-commons/README.md b/jadx-commons/jadx-app-commons/README.md new file mode 100644 index 000000000..cb3d7361c --- /dev/null +++ b/jadx-commons/jadx-app-commons/README.md @@ -0,0 +1,6 @@ +## jadx app commons + +This module contains common utilities used in jadx apps (cli and gui) and not needed in jadx-code module: +- `JadxCommonFiles` - wrapper for `dev.dirs:directories` lib to get + 'config' and 'cache' directories in cross-platform way +- `JadxCommonEnv` - utils for work with environment variables diff --git a/jadx-commons/jadx-app-commons/build.gradle.kts b/jadx-commons/jadx-app-commons/build.gradle.kts new file mode 100644 index 000000000..5b27298ad --- /dev/null +++ b/jadx-commons/jadx-app-commons/build.gradle.kts @@ -0,0 +1,7 @@ +plugins { + id("jadx-library") +} + +dependencies { + implementation("dev.dirs:directories:26") +} diff --git a/jadx-commons/jadx-app-commons/src/main/java/jadx/commons/app/JadxCommonEnv.java b/jadx-commons/jadx-app-commons/src/main/java/jadx/commons/app/JadxCommonEnv.java new file mode 100644 index 000000000..cbe5fbbd3 --- /dev/null +++ b/jadx-commons/jadx-app-commons/src/main/java/jadx/commons/app/JadxCommonEnv.java @@ -0,0 +1,29 @@ +package jadx.commons.app; + +public class JadxCommonEnv { + + public static String get(String varName, String defValue) { + String strValue = System.getenv(varName); + return isNullOrEmpty(strValue) ? defValue : strValue; + } + + public static boolean getBool(String varName, boolean defValue) { + String strValue = System.getenv(varName); + if (isNullOrEmpty(strValue)) { + return defValue; + } + return strValue.equalsIgnoreCase("true"); + } + + public static int getInt(String varName, int defValue) { + String strValue = System.getenv(varName); + if (isNullOrEmpty(strValue)) { + return defValue; + } + return Integer.parseInt(strValue); + } + + private static boolean isNullOrEmpty(String value) { + return value == null || value.isEmpty(); + } +} diff --git a/jadx-commons/jadx-app-commons/src/main/java/jadx/commons/app/JadxCommonFiles.java b/jadx-commons/jadx-app-commons/src/main/java/jadx/commons/app/JadxCommonFiles.java new file mode 100644 index 000000000..3cc92a66e --- /dev/null +++ b/jadx-commons/jadx-app-commons/src/main/java/jadx/commons/app/JadxCommonFiles.java @@ -0,0 +1,73 @@ +package jadx.commons.app; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; + +import org.jetbrains.annotations.Nullable; + +import dev.dirs.ProjectDirectories; + +public class JadxCommonFiles { + + private static final Path CONFIG_DIR; + private static final Path CACHE_DIR; + + public static Path getConfigDir() { + return CONFIG_DIR; + } + + public static Path getCacheDir() { + return CACHE_DIR; + } + + static { + DirsLoader loader = new DirsLoader(); + loader.init(); + CONFIG_DIR = loader.getConfigDir(); + CACHE_DIR = loader.getCacheDir(); + } + + private static final class DirsLoader { + private @Nullable ProjectDirectories dirs; + private Path configDir; + private Path cacheDir; + + public void init() { + try { + configDir = loadEnvDir("JADX_CONFIG_DIR"); + cacheDir = loadEnvDir("JADX_CACHE_DIR"); + } catch (Exception e) { + throw new RuntimeException("Failed to init common directories", e); + } + } + + private Path loadEnvDir(String envVar) throws IOException { + String envDir = JadxCommonEnv.get(envVar, null); + String dirStr; + if (envDir != null) { + dirStr = envDir; + } else { + dirStr = loadDirs().configDir; + } + Path path = Path.of(dirStr).toAbsolutePath(); + Files.createDirectories(path); + return path; + } + + private synchronized ProjectDirectories loadDirs() { + if (dirs == null) { + dirs = ProjectDirectories.from("io.github", "skylot", "jadx"); + } + return dirs; + } + + public Path getCacheDir() { + return cacheDir; + } + + public Path getConfigDir() { + return configDir; + } + } +} diff --git a/jadx-gui/build.gradle.kts b/jadx-gui/build.gradle.kts index b025143f3..5d74490be 100644 --- a/jadx-gui/build.gradle.kts +++ b/jadx-gui/build.gradle.kts @@ -10,6 +10,7 @@ dependencies { implementation(project(":jadx-core")) implementation(project(":jadx-cli")) implementation(project(":jadx-plugins-tools")) + implementation(project(":jadx-commons:jadx-app-commons")) // import mappings implementation(project(":jadx-plugins:jadx-rename-mappings")) @@ -26,7 +27,6 @@ dependencies { implementation("org.jcommander:jcommander:1.83") implementation("ch.qos.logback:logback-classic:1.5.6") - implementation("dev.dirs:directories:26") implementation("com.fifesoft:rsyntaxtextarea:3.4.0") implementation(files("libs/jfontchooser-1.0.5.jar")) diff --git a/jadx-gui/src/main/java/jadx/gui/utils/files/JadxFiles.java b/jadx-gui/src/main/java/jadx/gui/utils/files/JadxFiles.java index 4f82508ce..30ffbe931 100644 --- a/jadx-gui/src/main/java/jadx/gui/utils/files/JadxFiles.java +++ b/jadx-gui/src/main/java/jadx/gui/utils/files/JadxFiles.java @@ -1,24 +1,15 @@ package jadx.gui.utils.files; import java.nio.file.Path; -import java.nio.file.Paths; -import dev.dirs.ProjectDirectories; - -import jadx.core.utils.files.FileUtils; +import jadx.commons.app.JadxCommonFiles; public class JadxFiles { - private static final ProjectDirectories DIRS = ProjectDirectories.from("io.github", "skylot", "jadx"); - private static final String CONFIG_DIR = DIRS.configDir; + private static final Path CONFIG_DIR = JadxCommonFiles.getConfigDir(); + public static final Path GUI_CONF = CONFIG_DIR.resolve("gui.json"); + public static final Path CACHES_LIST = CONFIG_DIR.resolve("caches.json"); - public static final Path GUI_CONF = Paths.get(CONFIG_DIR, "gui.json"); - public static final Path CACHES_LIST = Paths.get(CONFIG_DIR, "caches.json"); - - public static final Path CACHE_DIR = Paths.get(DIRS.cacheDir); + public static final Path CACHE_DIR = JadxCommonFiles.getCacheDir(); public static final Path PROJECTS_CACHE_DIR = CACHE_DIR.resolve("projects"); - - static { - FileUtils.makeDirs(Paths.get(CONFIG_DIR)); - } } diff --git a/jadx-plugins-tools/build.gradle.kts b/jadx-plugins-tools/build.gradle.kts index 419263499..d59ff4c36 100644 --- a/jadx-plugins-tools/build.gradle.kts +++ b/jadx-plugins-tools/build.gradle.kts @@ -5,6 +5,7 @@ plugins { dependencies { api(project(":jadx-core")) - implementation("dev.dirs:directories:26") + implementation(project(":jadx-commons:jadx-app-commons")) + implementation("com.google.code.gson:gson:2.10.1") } diff --git a/jadx-plugins-tools/src/main/java/jadx/plugins/tools/utils/PluginFiles.java b/jadx-plugins-tools/src/main/java/jadx/plugins/tools/utils/PluginFiles.java index 693e52356..769931891 100644 --- a/jadx-plugins-tools/src/main/java/jadx/plugins/tools/utils/PluginFiles.java +++ b/jadx-plugins-tools/src/main/java/jadx/plugins/tools/utils/PluginFiles.java @@ -1,22 +1,19 @@ package jadx.plugins.tools.utils; import java.nio.file.Path; -import java.nio.file.Paths; -import dev.dirs.ProjectDirectories; +import jadx.commons.app.JadxCommonFiles; import static jadx.core.utils.files.FileUtils.makeDirs; public class PluginFiles { - private static final ProjectDirectories DIRS = ProjectDirectories.from("io.github", "skylot", "jadx"); - private static final Path PLUGINS_DIR = Paths.get(DIRS.configDir, "plugins"); + private static final Path PLUGINS_DIR = JadxCommonFiles.getConfigDir().resolve("plugins"); public static final Path PLUGINS_JSON = PLUGINS_DIR.resolve("plugins.json"); public static final Path INSTALLED_DIR = PLUGINS_DIR.resolve("installed"); public static final Path DROPINS_DIR = PLUGINS_DIR.resolve("dropins"); - private static final Path CACHE_DIR = Paths.get(DIRS.cacheDir); - public static final Path PLUGINS_LIST_CACHE = CACHE_DIR.resolve("plugin-list.json"); + public static final Path PLUGINS_LIST_CACHE = JadxCommonFiles.getCacheDir().resolve("plugin-list.json"); static { makeDirs(INSTALLED_DIR); diff --git a/jadx-plugins/jadx-script/jadx-script-plugin/build.gradle.kts b/jadx-plugins/jadx-script/jadx-script-plugin/build.gradle.kts index 18c3b9d3c..cbfdaeaf2 100644 --- a/jadx-plugins/jadx-script/jadx-script-plugin/build.gradle.kts +++ b/jadx-plugins/jadx-script/jadx-script-plugin/build.gradle.kts @@ -5,6 +5,7 @@ plugins { dependencies { implementation(project(":jadx-plugins:jadx-script:jadx-script-runtime")) + implementation(project(":jadx-commons:jadx-app-commons")) implementation(kotlin("scripting-common")) implementation(kotlin("scripting-jvm")) @@ -12,8 +13,5 @@ dependencies { implementation("io.github.oshai:kotlin-logging-jvm:6.0.9") - // path for scripts cache - implementation("dev.dirs:directories:26") - testImplementation(project(":jadx-core")) } diff --git a/jadx-plugins/jadx-script/jadx-script-plugin/src/main/kotlin/jadx/plugins/script/ScriptCache.kt b/jadx-plugins/jadx-script/jadx-script-plugin/src/main/kotlin/jadx/plugins/script/ScriptCache.kt index 8f9617896..bcc402e80 100644 --- a/jadx-plugins/jadx-script/jadx-script-plugin/src/main/kotlin/jadx/plugins/script/ScriptCache.kt +++ b/jadx-plugins/jadx-script/jadx-script-plugin/src/main/kotlin/jadx/plugins/script/ScriptCache.kt @@ -1,6 +1,6 @@ package jadx.plugins.script -import dev.dirs.ProjectDirectories +import jadx.commons.app.JadxCommonFiles import java.io.File import java.security.MessageDigest import kotlin.script.experimental.api.CompiledScript @@ -61,8 +61,7 @@ class ScriptCache { } private fun getCacheDir(): File { - val dirs = ProjectDirectories.from("io.github", "skylot", "jadx") - val cacheBaseDir = File(dirs.cacheDir, "scripts") + val cacheBaseDir = JadxCommonFiles.getCacheDir().resolve("scripts").toFile() cacheBaseDir.mkdirs() return cacheBaseDir } diff --git a/settings.gradle.kts b/settings.gradle.kts index 20b2ebe2d..5cee73910 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -10,6 +10,8 @@ include("jadx-gui") include("jadx-plugins-tools") +include("jadx-commons:jadx-app-commons") + include("jadx-plugins:jadx-input-api") include("jadx-plugins:jadx-dex-input") include("jadx-plugins:jadx-java-input")