From 2b50b86bf547ff7b2b4c37e7886d1ce552901981 Mon Sep 17 00:00:00 2001 From: Slawomir Jaranowski Date: Wed, 2 Feb 2022 18:00:41 +0100 Subject: [PATCH] [MSHARED-1009] Allow providing Maven executable from workspace --- pom.xml | 5 ++ .../invoker/MavenCommandLineBuilder.java | 82 +++++++++++-------- .../shared/invoker/DefaultInvokerTest.java | 37 +++++++++ .../test-maven-wrapper-in-project/mvnw | 21 +++++ .../test-maven-wrapper-in-project/mvnw.cmd | 21 +++++ 5 files changed, 133 insertions(+), 33 deletions(-) create mode 100755 src/test/resources/test-maven-wrapper-in-project/mvnw create mode 100644 src/test/resources/test-maven-wrapper-in-project/mvnw.cmd diff --git a/pom.xml b/pom.xml index 081b86d..dca694b 100644 --- a/pom.xml +++ b/pom.xml @@ -106,6 +106,11 @@ under the License. false + + org.apache.maven.plugins + maven-resources-plugin + 3.2.0 + maven-site-plugin 3.10.0 diff --git a/src/main/java/org/apache/maven/shared/invoker/MavenCommandLineBuilder.java b/src/main/java/org/apache/maven/shared/invoker/MavenCommandLineBuilder.java index 7376df8..69e4b13 100644 --- a/src/main/java/org/apache/maven/shared/invoker/MavenCommandLineBuilder.java +++ b/src/main/java/org/apache/maven/shared/invoker/MavenCommandLineBuilder.java @@ -62,20 +62,17 @@ public Commandline build( InvocationRequest request ) throws CommandLineConfigurationException { + Commandline cli = new Commandline(); + setupMavenHome( request ); - checkRequiredState(); - try - { - setupMavenExecutable( request ); - } - catch ( IOException e ) - { - throw new CommandLineConfigurationException( e.getMessage(), e ); - } + // discover value for working directory + setupBaseDirectory( request ); + cli.setWorkingDirectory( baseDirectory ); - Commandline cli = new Commandline(); + checkRequiredState(); + setupMavenExecutable( request ); cli.setExecutable( mavenExecutable.getAbsolutePath() ); // handling for OS-level envars @@ -89,11 +86,6 @@ public Commandline build( InvocationRequest request ) // includes/excludes, etc. setReactorBehavior( request, cli ); - // discover value for working directory - setupBaseDirectory( request ); - - cli.setWorkingDirectory( baseDirectory ); - // local repository location setLocalRepository( request, cli ); @@ -591,10 +583,9 @@ else if ( System.getProperty( "maven.home" ) != null ) * * @param request a Invoker request * @throws org.apache.maven.shared.invoker.CommandLineConfigurationException if any. - * @throws java.io.IOException if any. */ protected void setupMavenExecutable( InvocationRequest request ) - throws CommandLineConfigurationException, IOException + throws CommandLineConfigurationException { if ( request.getMavenExecutable() != null ) { @@ -608,38 +599,63 @@ protected void setupMavenExecutable( InvocationRequest request ) { executable = mavenExecutable.getPath(); } - else if ( Os.isFamily( "windows" ) ) + else + { + executable = "mvn"; + } + + // firs look in project directory + mavenExecutable = detectMavenExecutablePerOs( baseDirectory, executable ); + if ( mavenExecutable == null ) { - if ( new File( mavenHome, "/bin/mvn.cmd" ).exists() ) + // next maven home + mavenExecutable = detectMavenExecutablePerOs( mavenHome, "/bin/" + executable ); + } + + if ( mavenExecutable != null ) + { + try { - executable = "mvn.cmd"; + mavenExecutable = mavenExecutable.getCanonicalFile(); } - else + catch ( IOException e ) { - executable = "mvn.bat"; + logger.debug( "Failed to canonicalize maven executable: '" + mavenExecutable + + "'. Using as-is.", e ); } } else { - executable = "mvn"; + throw new CommandLineConfigurationException( + "Maven executable: '" + executable + "'" + + " not found at project dir: '" + baseDirectory + "' nor maven home: '" + mavenHome + "'" ); } + } + } - mavenExecutable = new File( mavenHome, "/bin/" + executable ); - - try - { - mavenExecutable = mavenExecutable.getCanonicalFile(); - } - catch ( IOException e ) + private File detectMavenExecutablePerOs( File baseDirectory, String executable ) + { + if ( Os.isFamily( Os.FAMILY_WINDOWS ) ) + { + File executableFile = new File( baseDirectory, executable + ".cmd" ); + if ( executableFile.isFile() ) { - logger.debug( "Failed to canonicalize maven executable: " + mavenExecutable + ". Using as-is.", e ); + return executableFile; } - if ( !mavenExecutable.isFile() ) + executableFile = new File( baseDirectory, executable + ".bat" ); + if ( executableFile.isFile() ) { - throw new CommandLineConfigurationException( "Maven executable not found at: " + mavenExecutable ); + return executableFile; } } + + File executableFile = new File( baseDirectory, executable ); + if ( executableFile.isFile() ) + { + return executableFile; + } + return null; } /** diff --git a/src/test/java/org/apache/maven/shared/invoker/DefaultInvokerTest.java b/src/test/java/org/apache/maven/shared/invoker/DefaultInvokerTest.java index f6ce7c9..8f59e2a 100644 --- a/src/test/java/org/apache/maven/shared/invoker/DefaultInvokerTest.java +++ b/src/test/java/org/apache/maven/shared/invoker/DefaultInvokerTest.java @@ -28,6 +28,7 @@ import java.util.Collections; import java.util.Properties; +import org.apache.maven.shared.utils.Os; import org.apache.maven.shared.utils.StringUtils; import org.junit.Test; @@ -239,6 +240,42 @@ public void testPomOutsideProject() throws Exception assertEquals( 0, result.getExitCode() ); } + @Test + public void testMavenWrapperInProject() throws Exception + { + File basedir = getBasedirForBuild(); + + Invoker invoker = newInvoker(); + + InvocationRequest request = new DefaultInvocationRequest(); + request.setBaseDirectory( basedir ); + request.setGoals( Collections.singletonList( "test-wrapper-goal" ) ); + request.setMavenExecutable( new File( "./mvnw" ) ); + + final StringBuilder outlines = new StringBuilder(); + request.setOutputHandler( new InvocationOutputHandler() + { + @Override + public void consumeLine( String line ) + { + outlines.append( line ); + } + } ); + + + InvocationResult result = invoker.execute( request ); + + assertEquals( 0, result.getExitCode() ); + if ( Os.isFamily( Os.FAMILY_WINDOWS ) ) + { + assertEquals( "Windows Wrapper executed", outlines.toString() ); + } + else + { + assertEquals( "Unix Wrapper executed", outlines.toString() ); + } + } + private Invoker newInvoker() { Invoker invoker = new DefaultInvoker(); diff --git a/src/test/resources/test-maven-wrapper-in-project/mvnw b/src/test/resources/test-maven-wrapper-in-project/mvnw new file mode 100755 index 0000000..90c90eb --- /dev/null +++ b/src/test/resources/test-maven-wrapper-in-project/mvnw @@ -0,0 +1,21 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# 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. +# ---------------------------------------------------------------------------- + +echo "Unix Wrapper executed" diff --git a/src/test/resources/test-maven-wrapper-in-project/mvnw.cmd b/src/test/resources/test-maven-wrapper-in-project/mvnw.cmd new file mode 100644 index 0000000..7159bd5 --- /dev/null +++ b/src/test/resources/test-maven-wrapper-in-project/mvnw.cmd @@ -0,0 +1,21 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- +@ECHO off + +echo Windows Wrapper executed