From 22a707bb761f2f79f3f318742e2c2680125c0052 Mon Sep 17 00:00:00 2001 From: Chao Wang Date: Thu, 18 Sep 2025 15:20:28 +0800 Subject: [PATCH 1/2] feat: accept customized Maven user settings file and local repository. Signed-off-by: Chao Wang --- .../exhort/providers/JavaMavenProvider.java | 70 ++++++++++++------- .../com/redhat/exhort/tools/Operations.java | 11 +++ 2 files changed, 54 insertions(+), 27 deletions(-) diff --git a/src/main/java/com/redhat/exhort/providers/JavaMavenProvider.java b/src/main/java/com/redhat/exhort/providers/JavaMavenProvider.java index d7c006c5..6f87111e 100644 --- a/src/main/java/com/redhat/exhort/providers/JavaMavenProvider.java +++ b/src/main/java/com/redhat/exhort/providers/JavaMavenProvider.java @@ -65,28 +65,23 @@ public JavaMavenProvider(Path manifest) { @Override public Content provideStack() throws IOException { - var mvnCleanCmd = - new String[] {mvnExecutable, "clean", "-f", manifest.toString(), "--batch-mode", "-q"}; + var mvnCleanCmd = buildMvnCommandArgs("clean", "-f", manifest.toString(), "--batch-mode", "-q"); var mvnEnvs = getMvnExecEnvs(); // execute the clean command - Operations.runProcess(manifest.getParent(), mvnCleanCmd, mvnEnvs); + Operations.runProcess(manifest.getParent(), mvnCleanCmd.toArray(String[]::new), mvnEnvs); // create a temp file for storing the dependency tree in var tmpFile = Files.createTempFile("exhort_dot_graph_", null); // the tree command will build the project and create the dependency tree in the temp file var mvnTreeCmd = - new ArrayList() { - { - add(mvnExecutable); - add("org.apache.maven.plugins:maven-dependency-plugin:3.6.0:tree"); - add("-Dverbose"); - add("-DoutputType=text"); - add(String.format("-DoutputFile=%s", tmpFile.toString())); - add("-f"); - add(manifest.toString()); - add("--batch-mode"); - add("-q"); - } - }; + buildMvnCommandArgs( + "org.apache.maven.plugins:maven-dependency-plugin:3.6.0:tree", + "-Dverbose", + "-DoutputType=text", + String.format("-DoutputFile=%s", tmpFile.toString()), + "-f", + manifest.toString(), + "--batch-mode", + "-q"); // if we have dependencies marked as ignored, exclude them from the tree command var ignored = getDependencies(manifest).stream() @@ -133,18 +128,17 @@ public Content provideComponent() throws IOException { private Content generateSbomFromEffectivePom() throws IOException { var tmpEffPom = Files.createTempFile("exhort_eff_pom_", ".xml"); var mvnEffPomCmd = - new String[] { - mvnExecutable, - "clean", - "help:effective-pom", - String.format("-Doutput=%s", tmpEffPom.toString()), - "-f", - manifest.toString(), - "--batch-mode", - "-q" - }; + buildMvnCommandArgs( + "clean", + "help:effective-pom", + String.format("-Doutput=%s", tmpEffPom.toString()), + "-f", + manifest.toString(), + "--batch-mode", + "-q"); // execute the effective pom command - Operations.runProcess(manifest.getParent(), mvnEffPomCmd, getMvnExecEnvs()); + Operations.runProcess( + manifest.getParent(), mvnEffPomCmd.toArray(String[]::new), getMvnExecEnvs()); if (debugLoggingIsNeeded()) { String CaEffectivePoM = Files.readString(tmpEffPom); log.info( @@ -345,6 +339,28 @@ Map getMvnExecEnvs() { return null; } + private List buildMvnCommandArgs(String... baseArgs) { + List args = new ArrayList<>(); + args.add(mvnExecutable); + + var userSettingsFile = Operations.getMavenConfig("USER_SETTINGS_FILE"); + if (userSettingsFile != null) { + args.add("-s"); + args.add(userSettingsFile); + } + + var localRepository = Operations.getMavenConfig("LOCAL_REPOSITORY"); + if (localRepository != null) { + args.add("-Dmaven.repo.local=" + localRepository); + } + + for (String arg : baseArgs) { + args.add(arg); + } + + return args; + } + // NOTE if we want to include "scope" tags in ignore, // add property here and a case in the start-element-switch in the getIgnored method diff --git a/src/main/java/com/redhat/exhort/tools/Operations.java b/src/main/java/com/redhat/exhort/tools/Operations.java index 21327f0d..58c5e0f1 100644 --- a/src/main/java/com/redhat/exhort/tools/Operations.java +++ b/src/main/java/com/redhat/exhort/tools/Operations.java @@ -316,6 +316,17 @@ public static boolean getWrapperPreference(String name) { return Environment.get("EXHORT_PREFER_" + name.toUpperCase() + "W") != null; } + /** + * Retrieves a Maven configuration value from an environment variable. + * + * @param configName the configuration name (e.g., "USER_SETTINGS_FILE", "LOCAL_REPOSITORY") + * @return the configuration value if set and not blank, null otherwise + */ + public static String getMavenConfig(String configName) { + String configValue = Environment.get("EXHORT_MVN_" + configName); + return (configValue != null && !configValue.isBlank()) ? configValue : null; + } + /** * Attempts to retrieve the root directory of a Git repository for the given working directory. * From dc20d2dc41f6f10a0b563a7eb9ec0851ddf181b3 Mon Sep 17 00:00:00 2001 From: Chao Wang Date: Tue, 21 Oct 2025 15:49:15 +0800 Subject: [PATCH 2/2] feat: update var names and add missing docs. Signed-off-by: Chao Wang --- README.md | 44 +++++++++++++++++++ .../exhort/providers/JavaMavenProvider.java | 4 +- .../com/redhat/exhort/tools/Operations.java | 2 +- 3 files changed, 47 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 21300cd5..4bae3ad2 100644 --- a/README.md +++ b/README.md @@ -328,6 +328,9 @@ System.setProperty("EXHORT_PYTHON_PATH", "/path/to/python"); System.setProperty("EXHORT_PIP_PATH", "/path/to/pip"); // Configure proxy for all requests System.setProperty("EXHORT_PROXY_URL", "http://proxy.example.com:8080"); +// Configure Maven settings and repository +System.setProperty("EXHORT_MVN_USER_SETTINGS", "/path/to/custom/settings.xml"); +System.setProperty("EXHORT_MVN_LOCAL_REPO", "/path/to/custom/local/repository"); ``` > Environment variables takes precedence. @@ -436,6 +439,47 @@ following keys for setting custom paths for the said executables. +#### Maven Configuration + +You can customize Maven behavior by setting additional environment variables or Java properties: + + + + + + + + + + + + + + + + + + + + +
ConfigurationEnvironment VariableDescriptionDefault
Maven User SettingsEXHORT_MVN_USER_SETTINGSPath to custom Maven settings.xml fileUses Maven's default settings
Maven Local RepositoryEXHORT_MVN_LOCAL_REPOPath to custom Maven local repository directoryUses Maven's default local repository
+ +**Examples:** + +Using environment variables: +```bash +export EXHORT_MVN_USER_SETTINGS=/home/user/.m2/custom-settings.xml +export EXHORT_MVN_LOCAL_REPO=/home/user/custom-maven-repo +``` + +Using Java properties: +```java +System.setProperty("EXHORT_MVN_USER_SETTINGS", "/home/user/.m2/custom-settings.xml"); +System.setProperty("EXHORT_MVN_LOCAL_REPO", "/home/user/custom-maven-repo"); +``` + +> Environment variables take precedence over Java properties. + #### Match Manifest Versions Feature ##### Background diff --git a/src/main/java/com/redhat/exhort/providers/JavaMavenProvider.java b/src/main/java/com/redhat/exhort/providers/JavaMavenProvider.java index 6f87111e..7de45fe7 100644 --- a/src/main/java/com/redhat/exhort/providers/JavaMavenProvider.java +++ b/src/main/java/com/redhat/exhort/providers/JavaMavenProvider.java @@ -343,13 +343,13 @@ private List buildMvnCommandArgs(String... baseArgs) { List args = new ArrayList<>(); args.add(mvnExecutable); - var userSettingsFile = Operations.getMavenConfig("USER_SETTINGS_FILE"); + var userSettingsFile = Operations.getMavenConfig("USER_SETTINGS"); if (userSettingsFile != null) { args.add("-s"); args.add(userSettingsFile); } - var localRepository = Operations.getMavenConfig("LOCAL_REPOSITORY"); + var localRepository = Operations.getMavenConfig("LOCAL_REPO"); if (localRepository != null) { args.add("-Dmaven.repo.local=" + localRepository); } diff --git a/src/main/java/com/redhat/exhort/tools/Operations.java b/src/main/java/com/redhat/exhort/tools/Operations.java index 58c5e0f1..8b3f9a10 100644 --- a/src/main/java/com/redhat/exhort/tools/Operations.java +++ b/src/main/java/com/redhat/exhort/tools/Operations.java @@ -319,7 +319,7 @@ public static boolean getWrapperPreference(String name) { /** * Retrieves a Maven configuration value from an environment variable. * - * @param configName the configuration name (e.g., "USER_SETTINGS_FILE", "LOCAL_REPOSITORY") + * @param configName the configuration name (e.g., "USER_SETTINGS", "LOCAL_REPO") * @return the configuration value if set and not blank, null otherwise */ public static String getMavenConfig(String configName) {