Skip to content

Commit

Permalink
Align mvnd m39 with Maven 3.9.x re config interpolation
Browse files Browse the repository at this point in the history
Port Maven 3.9.7 config and new properties (session.root/top)
into Daemon m39.

The IT got this property as it triggers exception (failure)
if mvn39 could not "discover" top directory.

Fixes #910
  • Loading branch information
cstamas committed Apr 18, 2024
1 parent a1ac666 commit 6784b22
Show file tree
Hide file tree
Showing 2 changed files with 180 additions and 11 deletions.
190 changes: 179 additions & 11 deletions daemon-m39/src/main/java/org/apache/maven/cli/DaemonMavenCli.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.charset.Charset;
import java.nio.file.Files;
Expand All @@ -32,6 +33,7 @@
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.ListIterator;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
Expand All @@ -47,6 +49,7 @@
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.ParseException;
import org.apache.commons.cli.UnrecognizedOptionException;
import org.apache.maven.InternalErrorException;
import org.apache.maven.Maven;
import org.apache.maven.building.FileSource;
Expand Down Expand Up @@ -95,6 +98,9 @@
import org.codehaus.plexus.classworlds.ClassWorld;
import org.codehaus.plexus.classworlds.realm.ClassRealm;
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
import org.codehaus.plexus.interpolation.AbstractValueSource;
import org.codehaus.plexus.interpolation.InterpolationException;
import org.codehaus.plexus.interpolation.StringSearchInterpolator;
import org.eclipse.aether.transfer.TransferListener;
import org.mvndaemon.mvnd.cache.invalidating.InvalidatingExtensionRealmCache;
import org.mvndaemon.mvnd.cache.invalidating.InvalidatingPluginArtifactsCache;
Expand Down Expand Up @@ -145,9 +151,14 @@ public class DaemonMavenCli implements DaemonCli {

private static final String EXT_CLASS_PATH = "maven.ext.class.path";

private static final String EXTENSIONS_FILENAME = ".mvn/extensions.xml";
private static final String DOT_MVN = ".mvn";

private static final String MVN_MAVEN_CONFIG = ".mvn/maven.config";
private static final String UNABLE_TO_FIND_ROOT_PROJECT_MESSAGE = "Unable to find the root directory. Create a "
+ DOT_MVN + " directory in the project root directory to identify it.";

private static final String EXTENSIONS_FILENAME = DOT_MVN + "/extensions.xml";

private static final String MVN_MAVEN_CONFIG = DOT_MVN + "/maven.config";

public static final String STYLE_COLOR_PROPERTY = "style.color";

Expand Down Expand Up @@ -242,6 +253,9 @@ public int doMain(CliRequest cliRequest, Map<String, String> clientEnv) throws E
return execute(cliRequest);
} catch (ExitException e) {
return e.exitCode;
} catch (UnrecognizedOptionException e) {
// pure user error, suppress stack trace
return 1;
} finally {
eventSpyDispatcher.close();
System.setProperties(props);
Expand All @@ -257,10 +271,86 @@ void initialize(CliRequest cliRequest) throws ExitException {
}

if (cliRequest.multiModuleProjectDirectory == null) {
buildEventListener.log(String.format("-D%s system property is not set.", MULTIMODULE_PROJECT_DIRECTORY));
throw new ExitException(1);
String basedirProperty = System.getProperty(MULTIMODULE_PROJECT_DIRECTORY);
if (basedirProperty == null) {
System.err.format("-D%s system property is not set.", MULTIMODULE_PROJECT_DIRECTORY);
throw new ExitException(1);
}
File basedir = new File(basedirProperty);
try {
cliRequest.multiModuleProjectDirectory = basedir.getCanonicalFile();
} catch (IOException e) {
cliRequest.multiModuleProjectDirectory = basedir.getAbsoluteFile();
}
}

// We need to locate the top level project which may be pointed at using
// the -f/--file option. However, the command line isn't parsed yet, so
// we need to iterate through the args to find it and act upon it.
Path topDirectory = Paths.get(cliRequest.workingDirectory);
boolean isAltFile = false;
for (String arg : cliRequest.args) {
if (isAltFile) {
// this is the argument following -f/--file
Path path = topDirectory.resolve(arg);
if (Files.isDirectory(path)) {
topDirectory = path;
} else if (Files.isRegularFile(path)) {
topDirectory = path.getParent();
if (!Files.isDirectory(topDirectory)) {
System.err.println("Directory " + topDirectory
+ " extracted from the -f/--file command-line argument " + arg + " does not exist");
throw new ExitException(1);
}
} else {
System.err.println(
"POM file " + arg + " specified with the -f/--file command line argument does not exist");
throw new ExitException(1);
}
break;
} else {
// Check if this is the -f/--file option
isAltFile = arg.equals(String.valueOf(CLIManager.ALTERNATE_POM_FILE)) || arg.equals("file");
}
}
topDirectory = getCanonicalPath(topDirectory);
cliRequest.topDirectory = topDirectory;
// We're very early in the process and we don't have the container set up yet,
// so we on searchAcceptableRootDirectory method to find us acceptable directory.
// The method may return null if nothing acceptable found.
cliRequest.rootDirectory = searchAcceptableRootDirectory(topDirectory);

//
// Make sure the Maven home directory is an absolute path to save us from confusion with say drive-relative
// Windows paths.
//
String mavenHome = System.getProperty("maven.home");

if (mavenHome != null) {
System.setProperty("maven.home", new File(mavenHome).getAbsolutePath());
}
}

protected boolean isAcceptableRootDirectory(Path path) {
return path != null && Files.isDirectory(path.resolve(DOT_MVN));
}

protected Path searchAcceptableRootDirectory(Path path) {
if (path == null) {
return null;
}
if (isAcceptableRootDirectory(path)) {
return path;
}
return searchAcceptableRootDirectory(path.getParent());
}

private static Path getCanonicalPath(Path path) {
try {
return path.toRealPath();
} catch (IOException e) {
return getCanonicalPath(path.getParent()).resolve(path.getFileName());
}
System.setProperty("maven.multiModuleProjectDirectory", cliRequest.multiModuleProjectDirectory.toString());
}

void cli(CliRequest cliRequest) throws Exception {
Expand Down Expand Up @@ -465,8 +555,77 @@ private void commands(CliRequest cliRequest) {

// Needed to make this method package visible to make writing a unit test possible
// Maybe it's better to move some of those methods to separate class (SoC).
void properties(CliRequest cliRequest) {
populateProperties(cliRequest.commandLine, cliRequest.systemProperties, cliRequest.userProperties);
void properties(CliRequest cliRequest) throws ExitException {
try {
populateProperties(cliRequest, cliRequest.systemProperties, cliRequest.userProperties);

StringSearchInterpolator interpolator =
createInterpolator(cliRequest, cliRequest.systemProperties, cliRequest.userProperties);
CommandLine.Builder commandLineBuilder = new CommandLine.Builder();
for (Option option : cliRequest.commandLine.getOptions()) {
if (!String.valueOf(CLIManager.SET_USER_PROPERTY).equals(option.getOpt())) {
List<String> values = option.getValuesList();
for (ListIterator<String> it = values.listIterator(); it.hasNext(); ) {
it.set(interpolator.interpolate(it.next()));
}
}
commandLineBuilder.addOption(option);
}
for (String arg : cliRequest.commandLine.getArgList()) {
commandLineBuilder.addArg(interpolator.interpolate(arg));
}
cliRequest.commandLine = commandLineBuilder.build();
} catch (InterpolationException e) {
String message = "ERROR: Could not interpolate properties and/or arguments: " + e.getMessage();
System.err.println(message);
throw new ExitException(1); // user error
} catch (MavenCli.IllegalUseOfUndefinedProperty e) {
String message = "ERROR: Illegal use of undefined property: " + e.property;
System.err.println(message);
if (cliRequest.rootDirectory == null) {
System.err.println();
System.err.println(UNABLE_TO_FIND_ROOT_PROJECT_MESSAGE);
}
throw new ExitException(1); // user error
}
}

protected static StringSearchInterpolator createInterpolator(CliRequest cliRequest, Properties... properties) {
StringSearchInterpolator interpolator = new StringSearchInterpolator();
interpolator.addValueSource(new AbstractValueSource(false) {
@Override
public Object getValue(String expression) {
if ("session.topDirectory".equals(expression)) {
Path topDirectory = cliRequest.topDirectory;
if (topDirectory != null) {
return topDirectory.toString();
} else {
throw new MavenCli.IllegalUseOfUndefinedProperty(expression);
}
} else if ("session.rootDirectory".equals(expression)) {
Path rootDirectory = cliRequest.rootDirectory;
if (rootDirectory != null) {
return rootDirectory.toString();
} else {
throw new MavenCli.IllegalUseOfUndefinedProperty(expression);
}
}
return null;
}
});
interpolator.addValueSource(new AbstractValueSource(false) {
@Override
public Object getValue(String expression) {
for (Properties props : properties) {
Object val = props.getProperty(expression);
if (val != null) {
return val;
}
}
return null;
}
});
return interpolator;
}

void container(CliRequest cliRequest) {
Expand Down Expand Up @@ -1289,7 +1448,8 @@ static File resolveFile(File file, String workingDirectory) {
// System properties handling
// ----------------------------------------------------------------------

static void populateProperties(CommandLine commandLine, Properties systemProperties, Properties userProperties) {
static void populateProperties(CliRequest cliRequest, Properties systemProperties, Properties userProperties)
throws InterpolationException {
addEnvVars(systemProperties);

// ----------------------------------------------------------------------
Expand All @@ -1298,18 +1458,26 @@ static void populateProperties(CommandLine commandLine, Properties systemPropert
// are most dominant.
// ----------------------------------------------------------------------

if (commandLine.hasOption(CLIManager.SET_SYSTEM_PROPERTY)) {
String[] defStrs = commandLine.getOptionValues(CLIManager.SET_SYSTEM_PROPERTY);
Properties cliProperties = new Properties();
if (cliRequest.commandLine.hasOption(CLIManager.SET_SYSTEM_PROPERTY)) {
String[] defStrs = cliRequest.commandLine.getOptionValues(CLIManager.SET_SYSTEM_PROPERTY);

if (defStrs != null) {
for (String defStr : defStrs) {
setCliProperty(defStr, userProperties);
setCliProperty(defStr, cliProperties);
}
}
}

SystemProperties.addSystemProperties(systemProperties);

StringSearchInterpolator interpolator = createInterpolator(cliRequest, cliProperties, systemProperties);
for (Map.Entry<Object, Object> e : cliProperties.entrySet()) {
String name = (String) e.getKey();
String value = interpolator.interpolate((String) e.getValue());
userProperties.setProperty(name, value);
}

// ----------------------------------------------------------------------
// Properties containing info about the currently running version of Maven
// These override any corresponding properties set on the command line
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
-Dsomething=${session.rootDirectory}

0 comments on commit 6784b22

Please sign in to comment.