*** src/main/java/org/codehaus/mojo/rpm/RPMMojo.java Mon Jan 5 15:04:33 2009 --- ../rpm-maven-plugin/src/main/java/org/codehaus/mojo/rpm/RPMMojo.java Mon Jan 5 14:19:21 2009 *************** *** 18,32 **** * specific language governing permissions and limitations * under the License. */ - import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.versioning.OverConstrainedVersionException; --- 18,34 ---- * specific language governing permissions and limitations * under the License. */ import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.PrintWriter; import java.util.ArrayList; + import java.util.HashMap; import java.util.Iterator; import java.util.List; + import java.util.Map; + import java.util.Set; import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.versioning.OverConstrainedVersionException; *************** *** 37,42 **** --- 39,45 ---- import org.apache.maven.project.MavenProject; import org.codehaus.plexus.archiver.dir.DirectoryArchiver; import org.codehaus.plexus.util.FileUtils; + import org.codehaus.plexus.util.StringUtils; import org.codehaus.plexus.util.cli.CommandLineException; import org.codehaus.plexus.util.cli.CommandLineUtils; import org.codehaus.plexus.util.cli.Commandline; *************** *** 44,49 **** --- 47,53 ---- /** * Construct the RPM file + * * @version $Id: RPMMojo.java 8528 2009-01-02 19:43:07Z carlos $ * @requiresDependencyResolution runtime * @goal rpm *************** *** 53,84 **** /** * The name portion of the output file name. * @parameter expression="${project.artifactId}" * @required */ private String name; - /** * The version portion of the RPM file name. * @parameter alias="version" expression="${project.version}" * @required */ private String projversion; - /** * The release portion of the RPM file name. * @parameter * @required */ private String release; - /** ! * Set to true if the package is dependent on the architecture ! * of the build machine. * @parameter */ private boolean needarch; - /** * Set to a key name to sign the package using GPG. Note that due * to RPM limitations, this always requires input from the --- 57,88 ---- /** * The name portion of the output file name. + * * @parameter expression="${project.artifactId}" * @required */ private String name; /** * The version portion of the RPM file name. + * * @parameter alias="version" expression="${project.version}" * @required */ private String projversion; /** * The release portion of the RPM file name. + * * @parameter * @required */ private String release; /** ! * Set to true if the package is dependent on the ! * architecture of the build machine. ! * * @parameter */ private boolean needarch; /** * Set to a key name to sign the package using GPG. Note that due * to RPM limitations, this always requires input from the *************** *** 89,323 **** /** * The long description of the package. * @parameter expression="${project.description}" */ private String description; - /** * The one-line description of the package. * @parameter expression="${project.name}" */ private String summary; - /** * The one-line copyright information. * @parameter */ private String copyright; ! /** * The distribution containing this package. * @parameter */ private String distribution; ! /** * An icon for the package. * @parameter */ private File icon; - /** * The vendor supplying the package. * @parameter expression="${project.organization.name}" */ private String vendor; - /** * A URL for the vendor. * @parameter expression="${project.organization.url}" */ private String url; - /** * The package group for the package. * @parameter * @required */ private String group; - /** * The name of the person or group creating the package. * @parameter expression="${project.organization.name}" */ private String packager; - /** * The list of virtual packages provided by this package. * @parameter */ private List provides; - /** * The list of requirements for this package. * @parameter */ private List requires; - /** * The list of conflicts for this package. * @parameter */ private List conflicts; - /** * The relocation prefix for this package. * @parameter */ private String prefix; - /** * The area for RPM to use for building the package. * @parameter expression="${project.build.directory}/rpm" */ private File workarea; - /** * The list of file mappings. * @parameter * @required */ private List mappings; - /** * The pre-installation script. * @parameter */ private String preinstall; - /** * The location of the pre-installation script. * @parameter */ private File preinstallScript; - /** * The post-installation script. * @parameter */ private String postinstall; - /** * The location of the post-installation script. * @parameter */ private File postinstallScript; - /** * The installation script. * @parameter */ private String install; - /** * The location of the installation script. * @parameter */ private File installScript; - /** * The pre-removal script. * @parameter */ private String preremove; - /** * The location of the pre-removal script. * @parameter */ private File preremoveScript; - /** * The post-removal script. * @parameter */ private String postremove; - /** * The location of the post-removal script. * @parameter */ private File postremoveScript; - /** * The verification script. * @parameter */ private String verify; - /** * The location of the verification script. * @parameter */ private File verifyScript; - /** * The clean script. * @parameter */ private String clean; - /** * The location of the clean script. * @parameter */ private File cleanScript; - /** * A Plexus component to copy files and directories. ! * @component role="org.codehaus.plexus.archiver.Archiver" ! * roleHint="dir" */ private DirectoryArchiver copier; - /** * The primary project artifact. * @parameter expression="${project.artifact}" * @required * @readonly */ private Artifact artifact; - /** * Auxillary project artifacts. * @parameter expression="${project.attachedArtifacts} * @required * @readonly */ private List attachedArtifacts; - /** * @parameter default-value="${project}" * @required * @readonly */ private MavenProject project; - /** * A list of %define arguments * @parameter */ private List defineStatements; - /** The root of the build area. */ private File buildroot; - /** The version string after parsing. */ private String version; // // // Consumers for rpmbuild output - /** ! * Consumer to receive lines sent to stdout. The lines are logged ! * as info. */ private class StdoutConsumer implements StreamConsumer { /** Logger to receive the lines. */ private Log logger; /** * Constructor. ! * @param log The logger to receive the lines */ public StdoutConsumer(Log log) { logger = log; --- 93,337 ---- /** * The long description of the package. + * * @parameter expression="${project.description}" */ private String description; /** * The one-line description of the package. + * * @parameter expression="${project.name}" */ private String summary; /** * The one-line copyright information. + * * @parameter */ private String copyright; ! /** ! * The one-line license information. ! * ! * @parameter ! */ ! private String license; /** * The distribution containing this package. + * * @parameter */ private String distribution; ! /** ! * The target architecture. This is overrides the needarch flag. ! * ! * @parameter ! */ ! private String targetArch; /** * An icon for the package. + * * @parameter */ private File icon; /** * The vendor supplying the package. + * * @parameter expression="${project.organization.name}" */ private String vendor; /** * A URL for the vendor. + * * @parameter expression="${project.organization.url}" */ private String url; /** * The package group for the package. + * * @parameter * @required */ private String group; /** * The name of the person or group creating the package. + * * @parameter expression="${project.organization.name}" */ private String packager; /** * The list of virtual packages provided by this package. + * * @parameter */ private List provides; /** * The list of requirements for this package. + * * @parameter */ private List requires; /** * The list of conflicts for this package. + * * @parameter */ private List conflicts; /** * The relocation prefix for this package. + * * @parameter */ private String prefix; /** * The area for RPM to use for building the package. + * * @parameter expression="${project.build.directory}/rpm" */ private File workarea; /** * The list of file mappings. + * * @parameter * @required */ private List mappings; /** * The pre-installation script. + * * @parameter */ private String preinstall; /** * The location of the pre-installation script. + * * @parameter */ private File preinstallScript; /** * The post-installation script. + * * @parameter */ private String postinstall; /** * The location of the post-installation script. + * * @parameter */ private File postinstallScript; /** * The installation script. + * * @parameter */ private String install; /** * The location of the installation script. + * * @parameter */ private File installScript; /** * The pre-removal script. + * * @parameter */ private String preremove; /** * The location of the pre-removal script. + * * @parameter */ private File preremoveScript; /** * The post-removal script. + * * @parameter */ private String postremove; /** * The location of the post-removal script. + * * @parameter */ private File postremoveScript; /** * The verification script. + * * @parameter */ private String verify; /** * The location of the verification script. + * * @parameter */ private File verifyScript; /** * The clean script. + * * @parameter */ private String clean; /** * The location of the clean script. + * * @parameter */ private File cleanScript; /** * A Plexus component to copy files and directories. ! * ! * @component role="org.codehaus.plexus.archiver.Archiver" roleHint="dir" */ private DirectoryArchiver copier; /** * The primary project artifact. + * * @parameter expression="${project.artifact}" * @required * @readonly */ private Artifact artifact; /** * Auxillary project artifacts. + * * @parameter expression="${project.attachedArtifacts} * @required * @readonly */ private List attachedArtifacts; /** * @parameter default-value="${project}" * @required * @readonly */ private MavenProject project; /** * A list of %define arguments + * * @parameter */ private List defineStatements; /** The root of the build area. */ private File buildroot; /** The version string after parsing. */ private String version; // // // Consumers for rpmbuild output /** ! * Consumer to receive lines sent to stdout. The lines are logged as info. */ private class StdoutConsumer implements StreamConsumer { + /** Logger to receive the lines. */ private Log logger; /** * Constructor. ! * ! * @param log ! * The logger to receive the lines */ public StdoutConsumer(Log log) { logger = log; *************** *** 325,331 **** /** * Consume a line. ! * @param string The line to consume */ public void consumeLine(String string) { logger.info(string); --- 339,347 ---- /** * Consume a line. ! * ! * @param string ! * The line to consume */ public void consumeLine(String string) { logger.info(string); *************** *** 333,348 **** } /** ! * Consumer to receive lines sent to stderr. The lines are logged ! * as warnings. */ private class StderrConsumer implements StreamConsumer { /** Logger to receive the lines. */ private Log logger; /** * Constructor. ! * @param log The logger to receive the lines */ public StderrConsumer(Log log) { logger = log; --- 349,367 ---- } /** ! * Consumer to receive lines sent to stderr. The lines are logged as ! * warnings. */ private class StderrConsumer implements StreamConsumer { + /** Logger to receive the lines. */ private Log logger; /** * Constructor. ! * ! * @param log ! * The logger to receive the lines */ public StderrConsumer(Log log) { logger = log; *************** *** 350,356 **** /** * Consume a line. ! * @param string The line to consume */ public void consumeLine(String string) { logger.warn(string); --- 369,377 ---- /** * Consume a line. ! * ! * @param string ! * The line to consume */ public void consumeLine(String string) { logger.warn(string); *************** *** 358,364 **** } // // // Mojo methods - /** {@inheritDoc} */ public void execute() throws MojoExecutionException, MojoFailureException { checkParams(); --- 379,384 ---- *************** *** 377,386 **** } // // // Internal methods - /** * Run the external command to build the package. ! * @throws MojoExecutionException if an error occurs */ private void buildPackage() throws MojoExecutionException { File f = new File(workarea, "SPECS"); --- 397,407 ---- } // // // Internal methods /** * Run the external command to build the package. ! * ! * @throws MojoExecutionException ! * if an error occurs */ private void buildPackage() throws MojoExecutionException { File f = new File(workarea, "SPECS"); *************** *** 393,401 **** cl.createArgument().setValue(buildroot.getAbsolutePath()); cl.createArgument().setValue("--define"); cl.createArgument().setValue("_topdir " + workarea.getAbsolutePath()); ! if (!needarch) { cl.createArgument().setValue("--target"); ! cl.createArgument().setValue("noarch"); } if (keyname != null) { cl.createArgument().setValue("--define"); --- 414,426 ---- cl.createArgument().setValue(buildroot.getAbsolutePath()); cl.createArgument().setValue("--define"); cl.createArgument().setValue("_topdir " + workarea.getAbsolutePath()); ! if (!needarch && StringUtils.isEmpty(targetArch)) { ! targetArch = "noarch"; ! } ! if (!StringUtils.isEmpty(targetArch)) { cl.createArgument().setValue("--target"); ! cl.createArgument().setValue(targetArch); ! getLog().info("Target arch is: [" + targetArch + "]"); } if (keyname != null) { cl.createArgument().setValue("--define"); *************** *** 423,429 **** /** * Build the structure of the work area. ! * @throws MojoFailureException if a directory cannot be built */ private void buildWorkArea() throws MojoFailureException { final String[] topdirs = { "BUILD", "RPMS", "SOURCES", "SPECS", "SRPMS" }; --- 448,456 ---- /** * Build the structure of the work area. ! * ! * @throws MojoFailureException ! * if a directory cannot be built */ private void buildWorkArea() throws MojoFailureException { final String[] topdirs = { "BUILD", "RPMS", "SOURCES", "SPECS", "SRPMS" }; *************** *** 459,474 **** /** * Check the parameters for validity. ! * @throws MojoFailureException if an invalid parameter is found ! * @throws MojoExecutionException if an error occurs reading a script */ private void checkParams() throws MojoExecutionException, MojoFailureException { // Check the version string if (projversion.indexOf("-") == -1) { version = projversion; } else { ! version = projversion.substring(0, projversion.indexOf("-")); ! getLog().warn("Version string truncated to " + version); } // Various checks in the mappings --- 486,504 ---- /** * Check the parameters for validity. ! * ! * @throws MojoFailureException ! * if an invalid parameter is found ! * @throws MojoExecutionException ! * if an error occurs reading a script */ private void checkParams() throws MojoExecutionException, MojoFailureException { // Check the version string if (projversion.indexOf("-") == -1) { version = projversion; } else { ! version = projversion.replaceAll("\\-", "_"); ! getLog().warn("Version string [" + projversion + "] modified to [" + version + "]"); } // Various checks in the mappings *************** *** 513,521 **** /** * Copy an artifact. ! * @param art The artifact to copy ! * @param dest The destination directory ! * @throws MojoExecutionException if a problem occurs */ private void copyArtifact(Artifact art, File dest) throws MojoExecutionException { if (art.getFile() == null) { --- 543,555 ---- /** * Copy an artifact. ! * ! * @param art ! * The artifact to copy ! * @param dest ! * The destination directory ! * @throws MojoExecutionException ! * if a problem occurs */ private void copyArtifact(Artifact art, File dest) throws MojoExecutionException { if (art.getFile() == null) { *************** *** 528,540 **** /** * Copy a set of files. ! * @param src The file or directory to start copying from ! * @param dest The destination directory ! * @param incl The list of inclusions ! * @param excl The list of exclusions ! * @throws MojoExecutionException if a problem occurs */ ! private void copySource(File src, File dest, List incl, List excl) throws MojoExecutionException { try { // Set the destination copier.setDestFile(dest); --- 562,582 ---- /** * Copy a set of files. ! * ! * @param src ! * The file or directory to start copying from ! * @param dest ! * The destination directory ! * @param incl ! * The list of inclusions ! * @param excl ! * The list of exclusions ! * @throws MojoExecutionException ! * if a problem occurs */ ! private Map copySource(File src, File dest, List incl, List excl) throws MojoExecutionException { ! ! Map resultMap = new HashMap(); try { // Set the destination copier.setDestFile(dest); *************** *** 559,575 **** // Perform the copy copier.createArchive(); // Clear the list for the next mapping copier.resetArchiver(); } catch (Throwable t) { throw new MojoExecutionException("Unable to copy files for packaging: " + t.getMessage(), t); } } /** * Determine if the dependency matches an include or exclude list. ! * @param dep The dependency to check ! * @param list The list to check against * @return true if the dependency was found on the list */ private boolean depMatcher(Artifact dep, List list) { --- 601,625 ---- // Perform the copy copier.createArchive(); + resultMap.putAll(copier.getFiles()); + resultMap.putAll(copier.getDirs()); + // Clear the list for the next mapping copier.resetArchiver(); } catch (Throwable t) { throw new MojoExecutionException("Unable to copy files for packaging: " + t.getMessage(), t); } + + return resultMap; } /** * Determine if the dependency matches an include or exclude list. ! * ! * @param dep ! * The dependency to check ! * @param list ! * The list to check against * @return true if the dependency was found on the list */ private boolean depMatcher(Artifact dep, List list) { *************** *** 585,591 **** getLog().debug("... Group matches"); if (item.getArtifactId().equals(dep.getArtifactId())) { getLog().debug("... Artifact matches"); ! //ArtifactVersion av = item.getVersionRange().matchVersion( dep.getAvailableVersions() ); try { if (item.getVersionRange().containsVersion(dep.getSelectedVersion())) { getLog().debug("... Version matches"); --- 635,642 ---- getLog().debug("... Group matches"); if (item.getArtifactId().equals(dep.getArtifactId())) { getLog().debug("... Artifact matches"); ! // ArtifactVersion av = item.getVersionRange().matchVersion( ! // dep.getAvailableVersions() ); try { if (item.getVersionRange().containsVersion(dep.getSelectedVersion())) { getLog().debug("... Version matches"); *************** *** 604,610 **** /** * Copy the files from the various mapping sources into the build root. ! * @throws MojoExecutionException if a problem occurs */ private void installFiles() throws MojoExecutionException { // Copy icon, if specified --- 655,663 ---- /** * Copy the files from the various mapping sources into the build root. ! * ! * @throws MojoExecutionException ! * if a problem occurs */ private void installFiles() throws MojoExecutionException { // Copy icon, if specified *************** *** 613,618 **** --- 666,673 ---- copySource(icon, icondest, null, null); } + List extraMappings = new ArrayList(); + // Process each mapping for (Iterator it = mappings.iterator(); it.hasNext();) { Mapping map = (Mapping) it.next(); *************** *** 631,636 **** --- 686,697 ---- if (srcs != null) { for (Iterator sit = srcs.iterator(); sit.hasNext();) { Source src = (Source) sit.next(); + //getLog().info("Filtering source #1: " + src.getLocation() + ", targetArch: [" + src.getTargetArch() + "]"); + // filter files not for the targeted arch + if (!StringUtils.isEmpty(src.getTargetArch()) && !src.getTargetArch().equals(targetArch)) { + //getLog().info("Filtered! - " + src.getLocation()); + continue; + } if (src.getLocation().exists()) { List elist = src.getExcludes(); if (!src.getNoDefaultExcludes()) { *************** *** 639,645 **** } elist.addAll(FileUtils.getDefaultExcludesAsList()); } ! copySource(src.getLocation(), dest, src.getIncludes(), elist); } else { throw new MojoExecutionException("Source location " + src.getLocation() + " does not exist"); } --- 700,723 ---- } elist.addAll(FileUtils.getDefaultExcludesAsList()); } ! Map resultMap = copySource(src.getLocation(), dest, src.getIncludes(), elist); ! // getLog().info("Copier handled the following: "); ! Set keys = resultMap.keySet(); ! /* ! * for (Iterator keysIt = keys.iterator(); ! * keysIt.hasNext();) { Object object = ! * keysIt.next(); ArchiveEntry archiveEntry = ! * (ArchiveEntry) resultMap.get(object); ! * ! * getLog().info("key: [" + object.toString() + "], ! * value: [" + archiveEntry.toString() + "]"); } ! * ! * getLog().info("Copied source, map include dir is: " + ! * map.isIncludeDirectory()); ! */ ! if (!map.isIncludeDirectory()) { ! fillExtraMappings(extraMappings, map, src.getLocation(), keys); ! } } else { throw new MojoExecutionException("Source location " + src.getLocation() + " does not exist"); } *************** *** 663,675 **** } } } } /** * Read a file into a string. ! * @param in The file to read * @return The file contents ! * @throws MojoExecutionException if an error occurs reading the file */ private String readFile(File in) throws MojoExecutionException { try { --- 741,810 ---- } } } + + // getLog().info("Extra mappings size is: " + extraMappings.size()); + mappings.addAll(extraMappings); + } + + private void fillExtraMappings(List extraMappings, Mapping map, File src, Set includes) { + // getLog().info("Filling extra mappings for: " + map.getDirectory()); + if (src.isDirectory()) { + for (Iterator it = includes.iterator(); it.hasNext();) { + String value = (String) it.next(); + if (value.length() > 0) { + extraMappings.add(createExtraMapping(map, map.getDirectory() + "/" + value)); + } + } + /* + * String[] srcFiles = src.list(); if (srcFiles != null) { for (int + * i = 0; i < srcFiles.length; i++) { if + * (includes.contains(srcFiles[i])) { + * extraMappings.add(createExtraMapping(map, map.getDirectory() + + * "/" + srcFiles[i])); } } } + */ + } else { + extraMappings.add(createExtraMapping(map, map.getDirectory() + "/" + src.getName())); + } + } + + private Mapping createExtraMapping(Mapping map, String filename) { + // getLog().info("Creating new mapping for: " + filename); + Mapping extraMap = new Mapping(); + extraMap.setDirectory(filename); + extraMap.setArtifact(map.getArtifact()); + extraMap.setConfiguration(map.isConfiguration()); + extraMap.setDependency(map.getDependency()); + extraMap.setDocumentation(map.isDocumentation()); + extraMap.setFilemode(map.getFilemode()); + extraMap.setGroupname(map.getGroupname()); + extraMap.setUsername(map.getUsername()); + List sources = map.getSources(); + List filteredSources = null; + if (sources != null) { + filteredSources = new ArrayList(); + for (Iterator sit = sources.iterator(); sit.hasNext();) { + Source src = (Source) sit.next(); + //getLog().info("Filtering source #2: " + src.getLocation() + ", targetArch: [" + src.getTargetArch() + "]"); + // filter files not for the targeted arch + if (!StringUtils.isEmpty(src.getTargetArch()) && !src.getTargetArch().equals(targetArch)) { + continue; + } + filteredSources.add(src); + } + } + extraMap.setSources(filteredSources); + extraMap.setIncludeDirectory(true); + return extraMap; } /** * Read a file into a string. ! * ! * @param in ! * The file to read * @return The file contents ! * @throws MojoExecutionException ! * if an error occurs reading the file */ private String readFile(File in) throws MojoExecutionException { try { *************** *** 688,694 **** /** * Make a list of the artifacts to package in this mapping. ! * @param am The artifact mapping information * @return The list of artifacts to package */ private List selectArtifacts(ArtifactMap am) { --- 823,831 ---- /** * Make a list of the artifacts to package in this mapping. ! * ! * @param am ! * The artifact mapping information * @return The list of artifacts to package */ private List selectArtifacts(ArtifactMap am) { *************** *** 715,721 **** /** * Make a list of the dependencies to package in this mapping. ! * @param d The artifact mapping information * @return The list of artifacts to package */ private List selectDependencies(Dependency d) { --- 852,860 ---- /** * Make a list of the dependencies to package in this mapping. ! * ! * @param d ! * The artifact mapping information * @return The list of artifacts to package */ private List selectDependencies(Dependency d) { *************** *** 745,751 **** /** * Write the SPEC file. ! * @throws MojoExecutionException if an error occurs writing the file */ private void writeSpecFile() throws MojoExecutionException { File f = new File(workarea, "SPECS"); --- 884,892 ---- /** * Write the SPEC file. ! * ! * @throws MojoExecutionException ! * if an error occurs writing the file */ private void writeSpecFile() throws MojoExecutionException { File f = new File(workarea, "SPECS"); *************** *** 768,773 **** --- 909,917 ---- if (summary != null) { spec.println("Summary: " + summary); } + if (license != null) { + copyright = license + ", Copyright " + copyright; + } /* copyright composition */ String copyrightText = copyright; *************** *** 832,862 **** spec.println(); spec.println("%files"); for (Iterator it = mappings.iterator(); it.hasNext();) { Mapping map = (Mapping) it.next(); ! ! boolean listFiles = false; ! ! if (map.getSources() != null) { ! // Check if all sources contains only files ! listFiles = true; ! for (Iterator sources = map.getSources().iterator(); sources.hasNext();) { ! Source source = (Source) sources.next(); ! if (source.getLocation().isDirectory()) { ! listFiles = false; ! break; ! } ! } ! } ! ! if (listFiles) { ! // Write a line in the spec file for each file ! for (Iterator sources = map.getSources().iterator(); sources.hasNext();) { ! Source source = (Source) sources.next(); ! spec.println(map.getAttrString() + " " + map.getDestination() + File.separator ! + source.getLocation().getName()); ! } ! } else { spec.println(map.getAttrString() + " " + map.getDestination()); } } --- 976,986 ---- spec.println(); spec.println("%files"); + getLog().info("Nr mappings to process: " + mappings.size()); for (Iterator it = mappings.iterator(); it.hasNext();) { Mapping map = (Mapping) it.next(); ! getLog().info("Writing spec file entry for: " + map.getDirectory()); ! if (map.isIncludeDirectory()) { spec.println(map.getAttrString() + " " + map.getDestination()); } }