MavenLocator.java
- package com.soebes.itf.jupiter.extension;
- /*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
- import java.nio.file.FileSystem;
- import java.nio.file.Files;
- import java.nio.file.Path;
- import java.util.Optional;
- import java.util.regex.Pattern;
- /**
- * It's the intention to find the {@code mvn} executable.
- * <p>
- * The {@code maven.home} is set during the execution of the
- * test by the user.
- * The {@code maven.home} has precedence over searching
- * of Maven via {@code PATH}. This gives the opportunity
- * to overload the given Maven version in cases where needed.
- *
- * @author Karl Heinz Marbaise
- * @implNote Currently {@code maven.home} is given to the maven-failsafe-plugin
- * configuration as a system property.
- * The parameter {@code isRunningOnWindows} is used instead
- * of using things like {@code org.junit.jupiter.api.condition.OS.WINDOWS.isCurrentOs()} because
- * they contain static initializers etc. which can't be tested.
- */
- class MavenLocator {
- /**
- * The name of the system property.
- */
- private static final String MAVEN_HOME = "maven.home";
- /**
- * The name of the system property to activate remote debugging.
- */
- private static final String ITF_DEBUG = "ITF_DEBUG";
- private final FileSystem fileSystem;
- private final Optional<String> pathEnvironment;
- private final boolean isRunningOnWindows;
- private final String mvnExecutable;
- /**
- * @param fileSystem The {@link FileSystem} which is used.
- * @param pathEnvironment The value of {@code PATH} if it exists otherwise {@link Optional#empty()}.
- * @param isRunningOnWindows {@code true} when running on Windows, false otherwise.
- */
- MavenLocator(FileSystem fileSystem, Optional<String> pathEnvironment, boolean isRunningOnWindows) {
- this.fileSystem = fileSystem;
- this.pathEnvironment = pathEnvironment;
- this.isRunningOnWindows = isRunningOnWindows;
- this.mvnExecutable = Boolean.getBoolean(ITF_DEBUG) ? "mvnDebug" : "mvn";
- }
- private Path intoPath(String s) {
- return this.fileSystem.getPath(s);
- }
- private Path intoBin(Path p) {
- return p.resolve("bin");
- }
- private Optional<String> mavenHomeFromSystemProperty() {
- return Optional.ofNullable(System.getProperty(MAVEN_HOME));
- }
- private Path toMvn(Path p) {
- return p.resolve(this.mvnExecutable);
- }
- private Path toBat(Path p) {
- return p.resolve(this.mvnExecutable + ".bat");
- }
- private Path toCmd(Path p) {
- return p.resolve(this.mvnExecutable + ".cmd");
- }
- private boolean isExecutable(Path s) {
- return Files.isRegularFile(s)
- && Files.isReadable(s)
- && Files.isExecutable(s);
- }
- private Optional<Path> executableNonWindows(Path s) {
- return Optional.of(toMvn(s))
- .filter(this::isExecutable);
- }
- private Optional<Path> executableWindows(Path s) {
- Path mvnBat = toBat(s);
- //Maven 3.0.5...3.2.5
- if (isExecutable(mvnBat)) {
- return Optional.of(mvnBat);
- }
- //Maven 3.3.1...
- Path mvnCmd = toCmd(s);
- if (isExecutable(mvnCmd)) {
- return Optional.of(mvnCmd);
- }
- return Optional.empty();
- }
- private Optional<Path> executable(Path p) {
- if (this.isRunningOnWindows) {
- return executableWindows(p);
- } else {
- return executableNonWindows(p);
- }
- }
- private Optional<Path> checkExecutableViaPathEnvironment() {
- if (!this.pathEnvironment.isPresent()) {
- return Optional.empty();
- }
- String pathSeparator = this.isRunningOnWindows ? ";" : ":";
- Pattern pathSeparatorPattern = Pattern.compile(Pattern.quote(pathSeparator));
- return pathSeparatorPattern.splitAsStream(pathEnvironment.get())
- .map(this::intoPath)
- .map(this::executable)
- .filter(Optional::isPresent)
- .findFirst()
- .orElse(Optional.empty());
- }
- Optional<Path> findMvn() {
- Optional<Path> path = mavenHomeFromSystemProperty()
- .map(this::intoPath)
- .map(this::intoBin)
- .flatMap(this::executable);
- if (path.isPresent()) {
- return path;
- }
- return checkExecutableViaPathEnvironment();
- }
- }