Skip to content

Give consumers the pieces every migration from maven-invoker rewrites #51

Description

@slachiewicz

Four small consumers of maven-invoker moved to maven-executor 1.0.0 this week: apache/maven-gpg-plugin#344, apache/maven-archetype#1034, apache/maven-javadoc-plugin#1390, apache/maven-release#1504. Each one is a modest change (+80 to +220 lines), but the same glue appears in all four, and the one consumer left, maven-invoker-plugin, would rewrite it a fifth time on a larger scale. This is what the library could carry so that a consumer's migration is a few lines.

1. Typed Maven options next to the raw argument list

ExecutorRequest.arguments() is the right primitive, but every consumer keeps a table of the options it needs and re-derives the CLI syntax: -B, -X, -q, -e, -V, -o, -U, -f, -s, -gs, -t, -gt, -P, -T, -N, --fail-at-end, -Dkey=value, -Dmaven.repo.local=…. The invoker-plugin's invoker.properties maps exactly these (GOALS PROFILES MAVEN_OPTS FAILURE_BEHAVIOR NON_RECURSIVE OFFLINE DEBUG QUIET TIMEOUT_IN_SECONDS UPDATE_SNAPSHOTS SETTINGS_FILE PROJECT MAVEN_EXECUTABLE plus properties and environment) and today does it through InvocationRequest setters. A small builder that produces the argument list, say MavenArguments with goals(...), profiles(...), property(k, v), userSettings(Path), globalSettings(Path), toolchains(Path), localRepository(Path), pomFile(Path), batchMode(), debug(), quiet(), showErrors(), showVersion(), offline(), updateSnapshots(), nonRecursive(), threads(String), failureBehavior(...), and toArguments(), would remove the tables from the consumers and keep the 3.9/4 syntax differences (if any appear) in one place. It stays optional: arguments(List) remains for everything else.

2. Line-oriented output handlers

The consumers log the build's output line by line into a Maven Log, an SLF4J logger, or a file they keep writing to. Three of the four PRs contain the same OutputStream that buffers bytes and emits a line on \n. Builder.stdOutLines(Consumer<String>) and stdErrLines(Consumer<String>), with the split done in the executor's pump threads, would replace them.

3. Do not close caller-supplied streams (#45)

Both the archetype and the javadoc migrations had to wrap their stream in a FilterOutputStream whose close() only flushes, because the pump closes stdOut/stdErr when the build ends and the caller still needs the stream (a build.log the verify script prints to, System.out). The executor owns the streams it creates and should leave the caller's alone.

4. Kill the process tree on timeout (#48)

Every consumer with a timeout (invoker.timeoutInSeconds, the gpg tests' 60 s guard) expects the build and what it forked to be gone afterwards; today only the direct child is destroyed.

5. Installation and executable discovery

ExecutorRequest.discoverInstallationDirectory() reads maven.home only. Consumers add their own fallbacks: the invoker-plugin has mavenHome, mavenExecutable (relative mvnDebug, or an absolute path) and javaHome parameters; maven-verifier and the javadoc plugin looked at M2_HOME/MAVEN_HOME as well. The command() on the request already covers mvnDebug; an absolute executable and an env-variable fallback in discovery would cover the rest, and a JAVA_HOME setter would say what the environment variable does today by convention.

6. A one-line "run this and give me the exit code"

ExecutorHelper.forMavenInstallation(dir, mode) exists; what the small consumers wrote around it is a static helper of the shape MavenBuilds.run(request) (try-with-resources on a ForkedMavenExecutor built from discoverInstallationDirectory(), return the result). Worth shipping as ExecutorHelper.run(request) or similar.

With 1 to 4 in place the invoker-plugin migration becomes a mapping from invoker.properties to MavenArguments plus its existing FileLogger as a line consumer, and the four PRs above shrink to dependency swaps.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions