How to list active sub-modules in a Maven project?

Viewed 31352

I have a complex project where there are many directories that have POM files, but only some of which are sub-modules (possibly transitively) of a particular parent project.

Obviously, Maven knows the list of relevant files because it parses all the <module> tags to find them. But, I only see a list of the <name>s in the [INFO] comments, not the paths to those modules.

Is there a way to have Maven output a list of all the POM files that provided references to projects that are part of the reactor build for a given project?

11 Answers

The following command prints artifactId's of all sub-modules:

mvn -Dexec.executable='echo' -Dexec.args='${project.artifactId}' exec:exec -q

Example output:

build-tools
aws-sdk-java-pom
core
annotations
utils
http-client-spi
http-client-tests
http-clients
apache-client
test-utils
sdk-core
...

Get exactly name. Not ID. Result is appropriate for mvn -pl.

mvn help:evaluate -Dexpression=project.modules -q -DforceStdout | tail -n +2 | head -n -1 | sed 's/\s*<.*>\(.*\)<.*>/\1/'

or with main pom.xml

cat pom.xml | grep "<module>" | sed 's/\s*<.*>\(.*\)<.*>/\1/'

An example to list all modules and the parent of each

export REPO_DIR=$(pwd)
export REPO_NAME=$(basename ${REPO_DIR})

echo "${REPO_DIR} ==> ${REPO_NAME}"

mvn exec:exec -q \
  -Dexec.executable='echo' \
  -Dexec.args='${basedir}:${project.parent.groupId}:${project.parent.artifactId}:${project.parent.version}:${project.groupId}:${project.artifactId}:${project.version}:${project.packaging}' \
  | perl -pe "s/^${REPO_DIR//\//\\\/}/${REPO_NAME}/g" \
  | perl -pe 's/:/\t/g;'

I prepared the script below as mvn exec:exec runs slow on gitlab. I couldn't find a free time to investigate it more but I'm suspicious about it tries to get a new runner as it needs a new Runtime. So, if you're working with quite limited runners, it affects the overall build time in an unpredictable way if you used mvn exec:exec to determine the modules.

The below snippet gives you the module name, packaging and path to the module

#!/bin/bash
set -e;
mvnOptions='--add-opens java.base/java.lang=ALL-UNNAMED';

string=$(MAVEN_OPTS="$mvnOptions" mvn help:active-profiles)
delimiter='Active Profiles for Project*';
modules=()
while read -r line; do
  if [[ $line == $delimiter ]]; then
      module=$(echo $line | sed -E "s/.*'(.*):(.*):(.*):(.*)'.*/\2/");
      packaging=$(echo $line | sed -E "s/.*'(.*):(.*):(.*):(.*)'.*/\3/");
      path=$(MAVEN_OPTS="$mvnOptions" mvn help:evaluate -Dexpression=project.basedir -pl "$module" -q -DforceStdout || true);
      if [[ $path == *" $module "* ]]; then
        path=$(pwd);
      fi
      modules+=("$module" "$packaging" "$path")
  fi;
done <<< "$string"

size="$(echo ${#modules[@]})";
moduleCount=$(( $size / 3 ));

# prints the found modules
if [ $moduleCount -gt 0 ]; then
  echo "$moduleCount module(s) found"
  for (( i=0; i<$moduleCount; ++i)); do
    line=$(($i + 1));
    moduleIndex=$(($i * 3));
    pathIndex=$(($i * 3+2));
    module=${modules[moduleIndex]};
    path=${modules[pathIndex]};
    echo "  $line. '$module' at '$path'";
  done;
fi;
Related