Skip to content

Commit

Permalink
exec mojo can run executableDependency instead of executable
Browse files Browse the repository at this point in the history
  • Loading branch information
mkarg committed May 27, 2016
1 parent 79ffade commit 7684096
Show file tree
Hide file tree
Showing 6 changed files with 170 additions and 45 deletions.
70 changes: 70 additions & 0 deletions src/main/java/org/codehaus/mojo/exec/AbstractExecMojo.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,16 @@
import java.util.List;

import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.factory.ArtifactFactory;
import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.resolver.ArtifactResolver;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.MavenProjectBuilder;
import org.codehaus.plexus.util.cli.CommandLineUtils;

/**
Expand All @@ -45,6 +51,40 @@ public abstract class AbstractExecMojo
@Parameter( defaultValue = "${project}", readonly = true )
protected MavenProject project;

@Component
private ArtifactResolver artifactResolver;

@Component
private ArtifactFactory artifactFactory;

@Component
private MavenProjectBuilder projectBuilder;

@Component
private ArtifactMetadataSource metadataSource;

@Parameter( readonly = true, required = true, defaultValue = "${localRepository}" )
private ArtifactRepository localRepository;

@Parameter( readonly = true, required = true, defaultValue = "${project.remoteArtifactRepositories}" )
private List<ArtifactRepository> remoteRepositories;

@Parameter( readonly = true, defaultValue = "${plugin.artifacts}" )
private List<Artifact> pluginDependencies;

/**
* If provided the ExecutableDependency identifies which of the plugin dependencies contains the executable class.
* This will have the affect of only including plugin dependencies required by the identified ExecutableDependency.
* <p/>
* If includeProjectDependencies is set to <code>true</code>, all of the project dependencies will be included on
* the executable's classpath. Whether a particular project dependency is a dependency of the identified
* ExecutableDependency will be irrelevant to its inclusion in the classpath.
*
* @since 1.1-beta-1
*/
@Parameter
protected ExecutableDependency executableDependency;

/**
* This folder is added to the list of those folders containing source to be compiled. Use this if your plugin
* generates source code.
Expand Down Expand Up @@ -185,4 +225,34 @@ protected boolean isSkip()
{
return skip;
}

/**
* Examine the plugin dependencies to find the executable artifact.
*
* @return an artifact which refers to the actual executable tool (not a POM)
* @throws MojoExecutionException if no executable artifact was found
*/
protected Artifact findExecutableArtifact()
throws MojoExecutionException
{
// ILimitedArtifactIdentifier execToolAssembly = this.getExecutableToolAssembly();

Artifact executableTool = null;
for ( Artifact pluginDep : this.pluginDependencies )
{
if ( this.executableDependency.matches( pluginDep ) )
{
executableTool = pluginDep;
break;
}
}

if ( executableTool == null )
{
throw new MojoExecutionException( "No dependency of the plugin matches the specified executableDependency."
+ " Specified executableToolAssembly is: " + executableDependency.toString() );
}

return executableTool;
}
}
43 changes: 0 additions & 43 deletions src/main/java/org/codehaus/mojo/exec/ExecJavaMojo.java
Original file line number Diff line number Diff line change
Expand Up @@ -150,19 +150,6 @@ public class ExecJavaMojo
@Parameter( property = "exec.includePluginsDependencies", defaultValue = "false" )
private boolean includePluginDependencies;

/**
* If provided the ExecutableDependency identifies which of the plugin dependencies contains the executable class.
* This will have the affect of only including plugin dependencies required by the identified ExecutableDependency.
* <p/>
* If includeProjectDependencies is set to <code>true</code>, all of the project dependencies will be included on
* the executable's classpath. Whether a particular project dependency is a dependency of the identified
* ExecutableDependency will be irrelevant to its inclusion in the classpath.
*
* @since 1.1-beta-1
*/
@Parameter
private ExecutableDependency executableDependency;

/**
* Whether to interrupt/join and possibly stop the daemon threads upon quitting. <br/>
* If this is <code>false</code>, maven does nothing about the daemon threads. When maven has no more work to do,
Expand Down Expand Up @@ -680,36 +667,6 @@ private Artifact getExecutablePomArtifact( Artifact executableArtifact )
executableArtifact.getVersion(), "pom" );
}

/**
* Examine the plugin dependencies to find the executable artifact.
*
* @return an artifact which refers to the actual executable tool (not a POM)
* @throws MojoExecutionException if no executable artifact was found
*/
private Artifact findExecutableArtifact()
throws MojoExecutionException
{
// ILimitedArtifactIdentifier execToolAssembly = this.getExecutableToolAssembly();

Artifact executableTool = null;
for ( Artifact pluginDep : this.pluginDependencies )
{
if ( this.executableDependency.matches( pluginDep ) )
{
executableTool = pluginDep;
break;
}
}

if ( executableTool == null )
{
throw new MojoExecutionException( "No dependency of the plugin matches the specified executableDependency."
+ " Specified executableToolAssembly is: " + executableDependency.toString() );
}

return executableTool;
}

/**
* Resolve the executable dependencies for the specified project
*
Expand Down
25 changes: 23 additions & 2 deletions src/main/java/org/codehaus/mojo/exec/ExecMojo.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
Expand All @@ -49,14 +50,23 @@
import org.apache.commons.exec.PumpStreamHandler;
import org.apache.commons.exec.ShutdownHookProcessDestroyer;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.factory.ArtifactFactory;
import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
import org.apache.maven.artifact.resolver.ArtifactResolver;
import org.apache.maven.artifact.resolver.filter.AndArtifactFilter;
import org.apache.maven.artifact.resolver.filter.IncludesArtifactFilter;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.model.Dependency;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.ResolutionScope;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.MavenProjectBuilder;
import org.apache.maven.project.artifact.MavenMetadataSource;
import org.apache.maven.toolchain.Toolchain;
import org.apache.maven.toolchain.ToolchainManager;
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
Expand All @@ -82,7 +92,7 @@ public class ExecMojo
/**
* <p>
* The executable. Can be a full path or the name of the executable. In the latter case, the executable must be in
* the PATH for the execution to work.
* the PATH for the execution to work. Omit when using <code>executableDependency</code>.
* </p>
* <p>
* The plugin will search for the executable in the following order:
Expand All @@ -97,7 +107,7 @@ public class ExecMojo
*
* @since 1.0
*/
@Parameter( property = "exec.executable", required = true )
@Parameter( property = "exec.executable" )
private String executable;

/**
Expand Down Expand Up @@ -212,6 +222,17 @@ public class ExecMojo
public void execute()
throws MojoExecutionException
{
if ( executable == null )
{
if (executableDependency == null)
{
throw new MojoExecutionException( "The parameter 'executable' is missing or invalid" );
}

executable = findExecutableArtifact().getFile().getAbsolutePath();
getLog().debug( "using executable dependency " + executable);
}

if ( isSkip() )
{
getLog().info( "skipping execute as per configuration" );
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
------
Using executable binary dependencies with the exec:exec goal
------
Markus KARG
------
2016-05-23
------

~~ Copyright 2016 The Codehaus
~~
~~ Licensed 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.

~~ NOTE: For help with the syntax of this file, see:
~~ http://maven.apache.org/doxia/references/apt-format.html


Using Executable Binary Dependencies Instead of Local Executables

Instead of invoking a locally installed binary executable (identified by <<<executable>>>), a dependency (identified by <<<executableDependency>>>) can directly get executed instead.
This particularly is useful when the dependency is an executable binary like <<<.exe>>> or <<<.bat>>> file produced by a different Maven project which got deployed into a repository.
The binary gets pulled to the local repository and is getting executed <<right there>> without the need to know its actual file name or location on disk: Just the GA coordinates (<<<groupId>>>, <<<artifactId>>>) are needed.
Hence the <<<executable>>> parameter has to be omitted in favor of the <<<executableDependency>>> parameter.

There are two ways of using executable binary dependencies: Project dependencies and plugin dependencies. Currently the <<<exec>>> goal only supports plugin dependencies.

* Plugin Dependencies

Plugin Dependencies are referenced from within the plugin configuration.

** pom.xml

-------------------
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>${project.version}</version>
...
<configuration>
<executableDependency>
<!-- REFERENCES plugin dependency, see declaration below -->
<groupId>your-group</groupId>
<artifactId>your-artifact</artifactId>
</executableDependency>
</configuration>
<dependencies>
<dependency>
<!-- DECLARES plugin dependency, see reference above -->
<groupId>your-group</groupId>
<artifactId>your-artifact</artifactId>
<type>exe</type>
<version>your-version</version>
</dependency>
</dependencies>
...
</plugin>
</plugins>
</build>
...
</project>
-------------------
2 changes: 2 additions & 0 deletions src/site/apt/index.apt
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,5 @@ Exec Maven Plugin
* {{{./examples/example-exec-using-plugin-dependencies.html} Using plugin dependencies with exec:exec}}

* {{{./examples/example-exec-using-toolchains.html} Using toolchains instead of explicit paths}}

* {{{./examples/example-exec-using-executabledependency.html} Using executable binary dependencies instead of local executables}}
1 change: 1 addition & 0 deletions src/site/site.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
<item name="Changing the classpath scope when running Java programs" href="examples/example-exec-or-java-change-classpath-scope.html"/>
<item name="Using plugin dependencies with exec:exec" href="examples/example-exec-using-plugin-dependencies.html"/>
<item name="Using toolchains with exec:exec" href="examples/example-exec-using-toolchains.html"/>
<item name="Using executable binary dependencies instead of local executables" href="examples/example-exec-using-executabledependency.html"/>
</menu>
</body>
</project>

0 comments on commit 7684096

Please sign in to comment.