package org.codehaus.mojo.solaris; /* * 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 org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; 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 java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintWriter; import java.util.Properties; /** * Creates a System V package from a source directory by running <code>pkgmk</code> and <code>pkgtrans</code>. * * @author <a href="mailto:trygvis@codehaus.org">Trygve Laugstøl</a> * @version $Id$ * @goal package */ public class PackagePkgMojo extends AbstractSolarisMojo { // ----------------------------------------------------------------------- // Parameters // ----------------------------------------------------------------------- /** * The base directory for all command line executions and relative paths. * * @parameter expression="${basedir}" * @required * @readonly */ private File basedir; /** * There directory where <code>pkgmk</code> and <code>pkgtrans</code> will be executed. All files that are to be * a part of the package has to be in this directory before the prototype file is generated. * * @parameter expression="${project.build.directory}/solaris/assembled-pkg" * @required */ private File packageRoot; /** * The directory where all temporary files are placed. * * @parameter expression="${project.build.directory}/solaris" * @required * @readonly */ private File solarisDir; /** * The resulting <code>pkg</code> file will be attached to this project as its primary artifact. * * @parameter expression="${project}" * @required * @readonly */ private MavenProject project; // ----------------------------------------------------------------------- // Mojo Implementation // ----------------------------------------------------------------------- public void execute() throws MojoExecutionException, MojoFailureException { File prototypeFile = new File( packageRoot, "prototype" ); File pkginfoFile = new File( packageRoot, "pkginfo" ); if ( !prototypeFile.canRead() ) { throw new MojoFailureException( "Could not read prototype file '" + prototypeFile.getAbsolutePath() + "'." ); } if ( !pkginfoFile.canRead() ) { throw new MojoFailureException( "Could not read pkginfo file '" + pkginfoFile.getAbsolutePath() + "'." ); } String packageName = getPkgName( pkginfoFile ); pkgmk( prototypeFile ); File pkgFile = pkgtrans( packageName ); project.getArtifact().setFile( pkgFile ); } // ----------------------------------------------------------------------- // Private // ----------------------------------------------------------------------- private String getPkgName( File pkginfoFile ) throws MojoExecutionException, MojoFailureException { FileInputStream inputStream = null; try { inputStream = new FileInputStream( pkginfoFile ); Properties properties = new Properties(); properties.load( inputStream ); String packageName = properties.getProperty( "PKG" ); if ( packageName == null ) { throw new MojoFailureException( "Could not read package name (PKG) from pkginfo file: '" + pkginfoFile.getAbsolutePath() + "'." ); } return packageName; } catch ( IOException e ) { throw new MojoExecutionException( "Error while reading pkginfo file." ); } finally { IOUtil.close( inputStream ); } } private void pkgmk( File prototypeFile ) throws MojoFailureException, MojoExecutionException { Commandline commandline = new Commandline(); commandline.setExecutable( "pkgmk" ); commandline.setWorkingDirectory( basedir.getAbsolutePath() ); // Overwrites the same instance; package instance will be overwritten if it already exists. commandline.createArgument().setValue( "-o" ); commandline.createArgument().setValue( "-d" ); // The additional slash is to make sure pkgmk writes to a directory and not a file commandline.createArgument().setValue( solarisDir.getAbsolutePath() ); commandline.createArgument().setValue( "-f" ); // I wonder why pkgmk need this reference -- trygve commandline.createArgument().setValue( prototypeFile.getAbsolutePath() ); commandline.createArgument().setValue( "-r" ); commandline.createArgument().setValue( packageRoot.getAbsolutePath() ); execute( commandline, "pkgmk" ); } private File pkgtrans( String packageName ) throws MojoFailureException, MojoExecutionException { File pkgFile = new File( solarisDir, packageName + ".pkg" ); Commandline commandline = new Commandline(); commandline.setExecutable( "pkgtrans" ); commandline.setWorkingDirectory( basedir.getAbsolutePath() ); commandline.createArgument().setValue( "-s" ); commandline.createArgument().setValue( "-o" ); commandline.createArgument().setValue( solarisDir.getAbsolutePath() ); commandline.createArgument().setValue( pkgFile.getAbsolutePath() ); commandline.createArgument().setValue( packageName ); execute( commandline, "pkgtrans" ); return pkgFile; } private void execute( Commandline commandline, String programName ) throws MojoFailureException, MojoExecutionException { PkgStreamConsumer streamConsumer = null; try { File outputFile = new File( solarisDir, programName + "-output.txt" ); FileOutputStream fos = new FileOutputStream( outputFile ); streamConsumer = new PkgStreamConsumer( fos ); int exitValue; getLog().debug( "Executing: " + programName ); getLog().debug( "Working directory: " + commandline.getWorkingDirectory() ); getLog().debug( commandline.toString() ); getLog().debug( "The output is in " + outputFile.getAbsolutePath() ); exitValue = CommandLineUtils.executeCommandLine( commandline, streamConsumer, streamConsumer ); if ( exitValue != 0 ) { throw new MojoFailureException( programName + " " + "returned a non-zero exit code. See the output file for output: " + outputFile.getAbsolutePath() ); } } catch ( CommandLineException e ) { throw new MojoExecutionException( "Error executing " + programName + " command.", e ); } catch ( FileNotFoundException e ) { throw new MojoExecutionException( "Error while opening file.", e ); } finally { IOUtil.close( streamConsumer ); } } private class PkgStreamConsumer extends PrintWriter implements StreamConsumer { public PkgStreamConsumer( FileOutputStream fos ) { super( fos ); } public synchronized void consumeLine( String line ) { println( line ); } } }