package org.codehaus.mojo.shell; /* * 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. * */ import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.project.MavenProject; import org.codehaus.plexus.util.IOUtil; import org.codehaus.plexus.util.cli.CommandLineException; import org.codehaus.plexus.util.cli.CommandLineUtils; import org.codehaus.plexus.util.cli.Commandline; import org.codehaus.plexus.util.cli.StreamConsumer; import org.codehaus.plexus.util.cli.shell.BourneShell; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.Writer; import java.util.ArrayList; import java.util.List; /** * Mojo used to embed a shell script inside the POM. * This class handles construction of the command-line and monitoring of the check file, * if specified. It will also handle chmod'ing the given shell command, if required. * * @goal shell * @requiresDependencyResolution test */ public class ShellExecMojo extends AbstractMojo { /** * Whether to keep the script file generated by this invocation. * * @parameter default-value="false" expression="${shell.keepScriptFile}" */ private boolean keepScriptFile; /** * MavenProject instance used to resolve property expressions from within Ant. * * @parameter expression="${project}" * @required * @readonly */ private MavenProject project; /** * The temporary working directory where the project is actually built. By default, this is * within the '/target' directory. * * @parameter expression="${workDir}" default-value="${project.build.sourceDirectory}" * @required */ private File workDir; /** * The Ant messageLevel to use. * * @parameter expression="${chmod}" default-value="false" */ private boolean chmod; /** * The contents of the shell script. * * @parameter expression="${script}" * @required */ private String script; /** * Result of search for the configuration script, so we don't have to re-search. */ private File executable; /** * Whether to execute String.trim() on the script parameter before using it * to generate the script file. This can be important in environments like Bash, * where '#!/bin/sh' must be on the first line. * * @parameter expression="${trimScript}" default-value="true" */ private boolean trimScript; /** * The script-file extension. * * @parameter expression="${extension}" default-value=".sh" */ private String extension; /** * @parameter expression="${debug}" default-value="false" */ private boolean debug; /** * @parameter default-value="${project.remoteArtifactRepositories}" * @readonly * @required */ private List remoteRepositories; /** * @parameter default-value="${project.pluginArtifactRepositories}" * @required * @readonly */ private List remotePluginRepositories; /** * @parameter default-value="false" */ private boolean skipPomProjects; /** * 1. Create a temporary file containing the script. This is the executable. * * 3. If chmodUsed == true, then we'll set the executable bit on the executable file using chmod. * * 4. Construct the Ant Exec task using the supplied command, any command-line options, an optional * Make target, working directory, and overrides for failure conditions. * * 5. Next, execute the resulting Exec task. */ public void execute() throws MojoExecutionException { if ( skipPomProjects && "pom".equals( project.getPackaging() ) ) { getLog().info( "Skipping POM project, per configuration." ); return; } workDir.mkdirs(); try { createExecutable(); } catch ( IOException e ) { throw new MojoExecutionException( "Failed to create shell script. Reason: " + e.getMessage(), e ); } if ( chmod ) { // add the task to make the configure script executable chmod(); } Commandline exec = new Commandline(); exec.setShell( new BourneShell( true ) ); exec.setWorkingDirectory( workDir.getAbsolutePath() ); exec.setExecutable( executable.getAbsolutePath() ); try { StreamConsumer consumer = newInfoStreamConsumer(); int result = CommandLineUtils.executeCommandLine( exec, consumer, consumer ); if ( result != 0 ) { throw new MojoExecutionException( "Script failed to execute (exit value != 0). Please see output above for more information." ); } } catch ( CommandLineException e ) { throw new MojoExecutionException( "Failed to execute embedded shell script. Reason: " + e.getMessage(), e ); } } protected final void setChmodUsed( boolean chmodUsed ) { chmod = chmodUsed; } protected final void setProject( MavenProject project ) { this.project = project; } /** * Generate the script file (to a temp file). * @throws IOException * @throws MojoExecutionException */ private void createExecutable() throws IOException, MojoExecutionException { executable = File.createTempFile( "maven-shell-plugin-", extension ); if ( debug || getLog().isDebugEnabled() || keepScriptFile ) { getLog().info( "NOT deleting generated script file: " + executable.getAbsolutePath() ); } else { executable.deleteOnExit(); } Writer writer = null; String output = script; if ( trimScript ) { output = script.trim(); } try { writer = new FileWriter( executable ); List repositories = new ArrayList(); repositories.addAll( remoteRepositories ); repositories.addAll( remotePluginRepositories ); getLog().debug( "Resolving functions in script source." ); writer.write( output ); } finally { IOUtil.close( writer ); } } /** * Add the Ant task used to make the command executable. * @throws MojoExecutionException */ private void chmod() throws MojoExecutionException { Commandline chmod = new Commandline(); chmod.setExecutable( "chmod" ); chmod.createArg().setLine( "+x" ); chmod.createArg().setLine( executable.getAbsolutePath() ); StreamConsumer consumer = newDebugStreamConsumer(); try { int result = CommandLineUtils.executeCommandLine( chmod, consumer, consumer ); if ( result != 0 ) { throw new MojoExecutionException( "Failed to chmod script file (exit value != 0). Please see debug output for more information." ); } } catch ( CommandLineException e ) { throw new MojoExecutionException( "Failed to chmod +x: " + executable + ". Reason: " + e.getMessage(), e ); } } public StreamConsumer newDebugStreamConsumer() { return new StreamConsumer() { public void consumeLine( String line ) { if ( getLog().isDebugEnabled() ) { getLog().debug( line ); } } }; } public StreamConsumer newInfoStreamConsumer() { return new StreamConsumer() { public void consumeLine( String line ) { if ( getLog().isInfoEnabled() ) { getLog().info( line ); } } }; } }