Java tutorial
package org.codehaus.mojo.rpm; /* * 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 java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import org.apache.maven.artifact.Artifact; import org.apache.maven.execution.MavenSession; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugin.logging.Log; import org.apache.maven.plugins.annotations.Component; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.project.MavenProject; import org.apache.maven.settings.Server; import org.apache.maven.settings.Settings; import org.apache.maven.shared.filtering.MavenFileFilter; import org.apache.maven.shared.filtering.MavenFilteringException; import org.apache.maven.shared.filtering.MavenResourcesExecution; import org.apache.maven.shared.utils.io.FileUtils.FilterWrapper; import org.codehaus.mojo.rpm.VersionHelper.RPMVersionableMojo; import org.codehaus.plexus.util.FileUtils; import org.codehaus.plexus.util.Os; import org.sonatype.plexus.components.sec.dispatcher.SecDispatcher; import org.sonatype.plexus.components.sec.dispatcher.SecDispatcherException; /** * Abstract base class for building RPMs. * * @author Carlos * @author Brett Okken, Cerner Corp. */ abstract class AbstractRPMMojo extends AbstractMojo implements RPMVersionableMojo { /** * The name portion of the output file name. */ @Parameter(required = true, property = "rpm.name", defaultValue = "${project.artifactId}") private String name; /** * The version portion of the RPM file name. */ @Parameter(required = true, alias = "version", property = "rpm.version", defaultValue = "${project.version}") private String projversion; /** * The release portion of the RPM file name. * <p> * Beginning with 2.0-beta-2, this is an optional parameter. By default, the release will be generated from the * modifier portion of the <a href="#projversion">project version</a> using the following rules: * <ul> * <li>If no modifier exists, the release will be <code>1</code>.</li> * <li>If the modifier ends with <i>SNAPSHOT</i>, the timestamp (in UTC) of the build will be appended to end.</li> * <li>All instances of <code>'-'</code> in the modifier will be replaced with <code>'_'</code>.</li> * <li>If a modifier exists and does not end with <i>SNAPSHOT</i>, <code>"_1"</code> will be appended to end.</li> * </ul> * </p> */ @Parameter(property = "rpm.release") private String release; /** * The stage to build. Default to '-bb' but let users specify for instance '-ba' if they want source rpms as well. */ @Parameter(alias = "rpmbuildStage", property = "rpm.rpmbuild.stage", defaultValue = "-bb") private String rpmbuildStage; /** * The target architecture for the rpm. The default value is <i>noarch</i>. * <p> * For passivity purposes, a value of <code>true</code> or <code>false</code> will indicate whether the <a * href="http://plexus.codehaus.org/plexus-utils/apidocs/org/codehaus/plexus/util/Os.html#OS_ARCH">architecture</a> * of the build machine will be used. Any other value (such as <tt>x86_64</tt>) will set the architecture of the rpm * to <tt>x86_64</tt>. * </p> * <p> * This can also be used in conjunction with <a href="source-params.html#targetArchitecture">Source * targetArchitecture</a> to flex the contents of the rpm based on the architecture. * </p> */ @Parameter private String needarch; /** * The actual targeted architecture. This will be based on evaluation of {@link #needarch}. */ private String targetArch; /** * The target os for building the RPM. By default, this will be populated to <a * href="http://plexus.codehaus.org/plexus-utils/apidocs/org/codehaus/plexus/util/Os.html#OS_NAME">Os.OS_NAME</a>. * <p> * This can be used in conjunction with <a href="source-params.html#targetOSName">Source targetOSName</a> to flex * the contents of the rpm based on operating system. * </p> * * @since 2.0-beta-3 */ @Parameter private String targetOS; /** * The target vendor for building the RPM. By default, this will be populated to the result of <i>rpm -E * %{_host_vendor}</i>. * * @since 2.0-beta-3 */ @Parameter private String targetVendor; /** * Set to a key name to sign the package using GPG. If <i>keyPassphrase</i> is not also provided, this will require * the input of the passphrase at the terminal. */ @Parameter(property = "gpg.keyname") private String keyname; /** * The directory from which gpg will load keyrings. If not specified, gpg will use the value configured for its * installation, e.g. <code>~/.gnupg</code> or <code>%APPDATA%/gnupg</code>. * @since 2.1.2 */ @Parameter(property = "gpg.homedir") private File keypath; /** * The passphrase for the <i>keyname</i> to sign the rpm. This utilizes <a href="http://expect.nist.gov/">expect</a> * and requires that {@code expect} be on the PATH. * <p> * Note that the data type used is <b>NOT</b> {@code String}. * * <pre> * <configuration> * ... * <keyPassphrase> * <passphrase><i>password</i></passphrase> * </keyPassphrase> * </configuration> * </pre> * * </p> * If not given, look up the value under Maven settings using server id at 'keyPassphraseServerId' configuration. * * @since 2.0-beta-4 */ @Parameter private Passphrase keyPassphrase; /** * Server id to lookup the gpg passphrase under Maven settings. The default value intentionally selected to match * with maven-gpg-plugin. * * @Since 2.1.2 */ @Parameter(property = "gpg.passphraseServerId", defaultValue = "gpg.passphrase") private String passphraseServerId; /** * The long description of the package. */ @Parameter(property = "rpm.description", defaultValue = "${project.description}") private String description; /** * The one-line description of the package. */ @Parameter(property = "rpm.summary", defaultValue = "${project.name}") private String summary; /** * The one-line license information. * * @since 2.1-alpha-4 */ @Parameter private String license; /** * The distribution containing this package. */ @Parameter private String distribution; /** * The epoch of this package. * As defined here: http://www.rpm.org/max-rpm-snapshot/s1-rpm-inside-tags.html */ @Parameter private String epoch; /** * An icon for the package. */ @Parameter private File icon; /** * The vendor supplying the package. */ @Parameter(property = "rpm.vendor", defaultValue = "${project.organization.name}") private String vendor; /** * A URL for the vendor. */ @Parameter(property = "rpm.url", defaultValue = "${project.organization.url}") private String url; /** * The package group for the package. */ @Parameter(required = true) private String group; /** * The name of the person or group creating the package. */ @Parameter(property = "rpm.packager", defaultValue = "${project.organization.name}") private String packager; /** * Automatically add provided shared libraries. * * @since 2.0-beta-4 */ @Parameter(defaultValue = "true") private boolean autoProvides; /** * Automatically add requirements deduced from included shared libraries. * * @since 2.0-beta-4 */ @Parameter(defaultValue = "true") private boolean autoRequires; /** * The list of virtual packages provided by this package. */ @Parameter private LinkedHashSet<String> provides; /** * The list of requirements for this package. */ @Parameter private LinkedHashSet<String> requires; /** * The list of requirements for running the pre-installation scriptlet. * @since 2.1.6 */ @Parameter private LinkedHashSet<String> requiresPre; /** * The list of requirements for running the post install scriptlet. * @since 2.1.6 */ @Parameter private LinkedHashSet<String> requiresPost; /** * The list of requirements for running the pre-removal scriptlet. * @since 2.1.6 */ @Parameter private LinkedHashSet<String> requiresPreun; /** * The list of prerequisites for this package. * * @since 2.0-beta-3 */ @Parameter private LinkedHashSet<String> prereqs; /** * The list of obsoletes for this package. * * @since 2.0-beta-3 */ @Parameter private LinkedHashSet<String> obsoletes; /** * The list of conflicts for this package. */ @Parameter private LinkedHashSet<String> conflicts; /** * The relocation prefix for this package. * */ @Parameter private String prefix; /** * Additional relocation prefixes if needed. * * @since 2.1-alpha-4 */ @Parameter private List<String> prefixes; /** * The area for RPM to use for building the package.<br/> * <b>NOTE:</b> The absolute path to the workarea <i>MUST NOT</i> have a space in any of the directory names. * <p> * Beginning with release 2.0-beta-3, sub-directories will be created within the workarea for each execution of the * plugin within a life cycle.<br/> * The pattern will be <code>workarea/<i>name[-classifier]</i></code>.<br/> * The classifier portion is only applicable for the <a href="attached-rpm-mojo.html">attached-rpm</a> goal. * </p> */ @Parameter(defaultValue = "${project.build.directory}/rpm") private File workarea; /** * The list of file <a href="map-params.html">mappings</a>. */ @Parameter private List<Mapping> mappings = Collections.emptyList(); /** * The prepare scriptlet; * * @since 2.0-beta-4 */ @Parameter private Scriptlet prepareScriptlet; /** * The pre-installation scriptlet. * * @since 2.0-beta-4 */ @Parameter private Scriptlet preinstallScriptlet; /** * The post install scriptlet. * * @since 2.0-beta-4 */ @Parameter private Scriptlet postinstallScriptlet; /** * The installation scriptlet. * * @since 2.0-beta-4 */ @Parameter private Scriptlet installScriptlet; /** * The pre-removal scriptlet. * * @since 2.0-beta-4 */ @Parameter private Scriptlet preremoveScriptlet; /** * The post-removal scriptlet. * * @since 2.0-beta-4 */ @Parameter private Scriptlet postremoveScriptlet; /** * The verify scriptlet. * * @since 2.0-beta-4 */ @Parameter private Scriptlet verifyScriptlet; /** * The clean scriptlet. * * @since 2.0-beta-4 */ @Parameter private Scriptlet cleanScriptlet; /** * The pretrans scriptlet. * * @since 2.0-beta-4 */ @Parameter private Scriptlet pretransScriptlet; /** * The posttrans script. * * @since 2.0-beta-4 */ @Parameter private Scriptlet posttransScriptlet; /** * The list of triggers to take place on installation of other packages. * * <pre> * <triggers> * <installTrigger> * <subpackage>optional</subpackage> * <program>program to execute (if not shell) optional</program> * <script>actual contents of script - optional</script> * <scriptFile>location of file containing script - optional</script> * <fileEncoding>character encoding for script file - recommended</fileEncoding> * <triggers> * <trigger>package/version to trigger on (i.e. jre > 1.5)</trigger> * ... * </triggers> * </installTrigger> * <removeTrigger> * ... * </removeTrigger> * <postRemoveTrigger> * ... * </postRemoveTrigger> * ... * </triggers> * </pre> * * @since 2.0-beta-4 * @see BaseTrigger */ @Parameter private List<BaseTrigger> triggers; /** * Filters (property files) to include during the interpolation of the pom.xml. * * @since 2.0 */ @Parameter private List<String> filters; /** * Expression preceded with the String won't be interpolated \${foo} will be replaced with ${foo} * * @since 2.0 */ @Parameter(property = "maven.rpm.escapeString") private String escapeString; /** * @since 2.0 */ @Parameter(defaultValue = "${session}", readonly = true, required = true) private MavenSession session; /** * @since 2.1-alpha-4 */ @Parameter(required = true, readonly = true, property = "project.build.sourceEncoding") private String sourceEncoding; /** * The primary project artifact. */ @Parameter(required = true, readonly = true, property = "project.artifact") private Artifact artifact; /** * Auxillary project artifacts. */ @Parameter(required = true, readonly = true, property = "project.attachedArtifacts") private List<Artifact> attachedArtifacts; @Parameter(defaultValue = "${project}", readonly = true, required = true) protected MavenProject project; /** * Should <i>brp-repack-jars</i> be used in the RPM build. Defaults to <code>false</code>. If it is * <code>false</code> <i>brp-repack-jars</i> will be disabled by:<br/> * <code>%define __jar_repack 0</code> This will have no effect on RHEL5 or earlier release. * * @since 2.1-alpha-4 */ @Parameter private boolean repackJars = false; /** * A list of <code>%define</code> arguments */ @Parameter private List<String> defineStatements; /** * The default file mode (octal string) to assign to files when installed. <br/> * Only applicable to a <a href="map-params.html">Mapping</a> if <a href="map-params.html#filemode">filemode</a>, <a * href="map-params.html#username">username</a>, AND <a href="map-params.html#groupname">groupname</a> are * <b>NOT</b> populated. * * @since 2.0-beta-2 */ @Parameter private String defaultFilemode; /** * The default directory mode (octal string) to assign to directories when installed.<br/> * Only applicable to a <a href="map-params.html">Mapping</a> if <a href="map-params.html#filemode">filemode</a>, <a * href="map-params.html#username">username</a>, AND <a href="map-params.html#groupname">groupname</a> are * <b>NOT</b> populated. * * @since 2.0-beta-2 */ @Parameter private String defaultDirmode; /** * The default user name for files when installed.<br/> * Only applicable to a <a href="map-params.html">Mapping</a> if <a href="map-params.html#filemode">filemode</a>, <a * href="map-params.html#username">username</a>, AND <a href="map-params.html#groupname">groupname</a> are * <b>NOT</b> populated. * * @since 2.0-beta-2 */ @Parameter private String defaultUsername; /** * The default group name for files when installed.<br/> * Only applicable to a <a href="map-params.html">Mapping</a> if <a href="map-params.html#filemode">filemode</a>, <a * href="map-params.html#username">username</a>, AND <a href="map-params.html#groupname">groupname</a> are * <b>NOT</b> populated. * * @since 2.0-beta-2 */ @Parameter private String defaultGroupname; /** * Indicates if the execution should be disabled. If <code>true</code>, nothing will occur during execution. * * @since 2.0 */ @Parameter(property = "rpm.disabled", defaultValue = "false") private boolean disabled; /** * The system property to read the calculated version from, normally set by the version mojo. * * @since 2.1-alpha-2 */ @Parameter(required = true, defaultValue = "rpm.version") private String versionProperty; /** * The system property to read the calculated release from, normally set by the version mojo. * * @since 2.1-alpha-2 */ @Parameter(required = true, defaultValue = "rpm.release") private String releaseProperty; /** * The changelog file. If the file does not exist, it is ignored. * * @since 2.0-beta-3 */ @Parameter private File changelogFile; /** * Option to copy the created RPM to another location * @since 2.1. */ @Parameter(property = "rpm.copyTo") private File copyTo; ////////////////////////////////////////////////////////////////////////// /** * @since 2.0 */ @Component(role = org.apache.maven.shared.filtering.MavenFileFilter.class, hint = "default") private MavenFileFilter mavenFileFilter; /** * Maven Security Dispatcher * * @since 2.1.2 */ @Component(hint = "mng-4384") private SecDispatcher securityDispatcher; /** * Current user system settings for use in Maven. * * @since 2.1.2 */ @Parameter(defaultValue = "${settings}", readonly = true) private Settings settings; /** * Indicates if the execution should be disabled for POM projects. If <code>true</code>, nothing will happen during * execution in projects with packaging "pom". * @since 2.1.6 */ @Parameter(defaultValue = "false") private boolean skipPOMs; ////////////////////////////////////////////////////////////////////////// /** * Maintains a mapping of macro keys to their values (either {@link RPMHelper#evaluateMacro(String) evaluated} or * set via {@link #defineStatements}. * * @since 2.1-alpha-1 */ private final Map<String, String> macroKeyToValue = new HashMap<String, String>(); /** * The key of the map is the directory where the files should be linked to. The value is the {@code List} of * {@link SoftlinkSource}s to be linked to. * * @since 2.0-beta-3 */ private final Map<String, List<SoftlinkSource>> linkTargetToSources = new LinkedHashMap<String, List<SoftlinkSource>>(); /** The root of the build area prior to calling rpmbuild. */ private File buildroot; /** The root of the build area as used by rpmbuild. */ private File rpmBuildroot; /** The changelog string. */ private String changelog; /** * This is not set until {@link #execute() is called}. * * @since 2.1-alpha-1 */ private RPMHelper helper; /** * The {@link FileUtils.FilterWrapper filter wrappers} to use for file filtering. * * @since 2.0 * @see #mavenFileFilter */ private List<FilterWrapper> defaultFilterWrappers; // // // Mojo methods///////////////////////////////////////////////////// /** {@inheritDoc} */ public final void execute() throws MojoExecutionException, MojoFailureException { if (skipPOMs && isPOM()) { getLog().info("skipping because artifact is a pom (skipPOMs)"); return; } if (disabled) { getLog().info("MOJO is disabled. Doing nothing."); // FIXME, is it a correct way getting install/deploy to ignore the original primary 'rpm' artifact? if ("rpm".equals(this.project.getPackaging())) { this.project.setPackaging("pom"); } return; } if (this.prefix != null) { if (this.prefixes == null) { this.prefixes = new ArrayList<String>(); } this.prefixes.add(prefix); } helper = new RPMHelper(this); checkParams(helper); final String classifier = getClassifier(); if (classifier != null) { workarea = new File(workarea, name + '-' + classifier); } else { workarea = new File(workarea, name); } buildWorkArea(); // set up the maven file filter and FilteringDirectoryArchiver setDefaultWrappers(); final FilteringDirectoryArchiver copier = new FilteringDirectoryArchiver(); copier.setMavenFileFilter(mavenFileFilter); new FileHelper(this, copier).installFiles(); writeSpecFile(); this.loadGpgPassphrase(); helper.buildPackage(); afterExecution(); if (this.copyTo != null) { makeSecondCopy(); } } /** * @return The Maven project used by this MOJO */ private MavenProject getProject() { if (project.getExecutionProject() != null) { return project.getExecutionProject(); } return project; } /** * @return Whether the artifact is a POM or not */ private boolean isPOM() { return "pom".equalsIgnoreCase(getProject().getArtifact().getType()); } private void makeSecondCopy() throws MojoFailureException { try { this.getLog().info("Copy " + this.getRPMFile() + " to " + copyTo); FileUtils.copyFile(this.getRPMFile(), copyTo); } catch (IOException e) { throw new MojoFailureException("Unable to copy file"); } } /** * Will be called on completion of {@link #execute()}. Provides subclasses an opportunity to perform any post * execution logic (such as attaching an artifact). * * @throws MojoExecutionException If an error occurs. * @throws MojoFailureException If failure occurs. */ protected void afterExecution() throws MojoExecutionException, MojoFailureException { } /** * Provides an opportunity for subclasses to provide an additional classifier for the rpm workarea.<br/> * By default this implementation returns {@code null}, which indicates that no additional classifier should be * used. * * @return An additional classifier to use for the rpm workarea or {@code null} if no additional classifier should * be used. */ String getClassifier() { return null; } /** * Returns the generated rpm {@link File}. * * @return The generated rpm <tt>File</tt>. */ protected File getRPMFile() { File rpms = new File(workarea, "RPMS"); File archDir = new File(rpms, targetArch); return new File(archDir, name + '-' + projversion + '-' + release + '.' + targetArch + ".rpm"); } /** * @throws MojoExecutionException */ private void setDefaultWrappers() throws MojoExecutionException { final MavenResourcesExecution mavenResourcesExecution = new MavenResourcesExecution(); mavenResourcesExecution.setEscapeString(escapeString); try { defaultFilterWrappers = mavenFileFilter.getDefaultFilterWrappers(project, filters, false, this.session, mavenResourcesExecution); } catch (MavenFilteringException e) { getLog().error("fail to build filering wrappers " + e.getMessage()); throw new MojoExecutionException(e.getMessage(), e); } } /** * Build the structure of the work area. * * @throws MojoFailureException if a directory cannot be built * @throws MojoExecutionException if buildroot cannot be cleared (if exists) */ private void buildWorkArea() throws MojoFailureException, MojoExecutionException { final String[] topdirs = { "BUILD", "RPMS", "SOURCES", "SPECS", "SRPMS", "tmp-buildroot", "buildroot" }; // Build the top directory if (!workarea.exists()) { getLog().info("Creating directory " + workarea.getAbsolutePath()); if (!workarea.mkdirs()) { throw new MojoFailureException("Unable to create directory " + workarea.getAbsolutePath()); } } validateWorkarea(); // Build each directory in the top directory for (String topdir : topdirs) { File dir = new File(workarea, topdir); if (dir.exists()) { getLog().info("Directory " + dir.getAbsolutePath() + " already exists. Deleting all contents."); try { FileUtils.cleanDirectory(dir); } catch (IOException e) { throw new MojoExecutionException("Unable to clear directory: " + dir.getName(), e); } } else { getLog().info("Creating directory " + dir.getAbsolutePath()); if (!dir.mkdir()) { throw new MojoFailureException("Unable to create directory " + dir.getAbsolutePath()); } } } // set build root variable buildroot = new File(workarea, "tmp-buildroot"); rpmBuildroot = new File(workarea, "buildroot"); } /** * 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(RPMHelper helper) throws MojoExecutionException, MojoFailureException { Log log = getLog(); // Retrieve any versions set by the VersionMojo if (versionProperty != null) { String projversion = this.project.getProperties().getProperty(versionProperty); if (projversion != null) { this.projversion = projversion; } } if (releaseProperty != null) { String release = this.project.getProperties().getProperty(releaseProperty); if (release != null) { this.release = release; } } // calculate versions if neccessary, check for existing maven modifier and split them accordingly if (this.projversion == null || this.release == null || this.projversion.contains("-")) { // including -SNAPSHOT and 1-34 final VersionHelper.Version version = new VersionHelper(this).calculateVersion(); this.projversion = version.version; this.release = version.release; } log.debug("project version = " + this.projversion); log.debug("project release = " + this.release); // evaluate needarch and populate targetArch if (needarch == null || needarch.length() == 0 || "false".equalsIgnoreCase(needarch)) { targetArch = "noarch"; } else if ("true".equalsIgnoreCase(needarch)) { targetArch = helper.getArch(); } else { targetArch = needarch; } log.debug("targetArch = " + targetArch); // provide default targetOS if value not given if (targetOS == null || targetOS.length() == 0) { targetOS = Os.OS_NAME; } log.debug("targetOS = " + targetOS); if (targetVendor == null || targetVendor.length() == 0) { targetVendor = helper.getHostVendor(); } log.debug("targetVendor = " + targetVendor); // Various checks in the mappings for (Mapping map : mappings) { if (map.getDirectory() == null) { throw new MojoFailureException("<mapping> element must contain the destination directory"); } if (map.getSources() != null) { for (Source src : map.getSources()) { if (src.getLocation() == null) { throw new MojoFailureException("<mapping><source> tag must contain the source directory"); } } } } if ((changelog == null) && (changelogFile != null)) { if (!changelogFile.exists()) { log.debug(changelogFile.getAbsolutePath() + " does not exist - ignoring"); } else { try { StringBuilder sb = new StringBuilder(); BufferedReader br = new BufferedReader(new FileReader(changelogFile)); while (br.ready()) { String line = br.readLine(); sb.append(line); sb.append('\n'); } br.close(); changelog = sb.toString(); } catch (Throwable t) { throw new MojoExecutionException("Unable to read " + changelogFile.getAbsolutePath(), t); } } } // generate license text if not set if (license == null) { license = generateDefaultCopyrightText(); } // if this package obsoletes any packages, make sure those packages are added to the provides list if (obsoletes != null && "true".equals(System.getProperty("disable.mrpm24"))) { //this block is incorrectly implemented, however we want to provide capability // to enable this if needed in the next few releases, after that remove it completely if (provides == null) { provides = obsoletes; } else { provides.addAll(obsoletes); } } if (!repackJars) { if (defineStatements == null) { defineStatements = new ArrayList<String>(); } defineStatements.add("__jar_repack 0"); } processDefineStatements(); } /** * Put all name/value pairs in {@link #defineStatements} in {@link #macroKeyToValue}. * * @since 2.1-alpha-1 */ private void processDefineStatements() { if (defineStatements == null) { return; } for (String define : defineStatements) { String[] parts = define.split(" "); if (parts.length == 2) { macroKeyToValue.put(parts[0], parts[1]); } } } /** * Validate that {@link #workarea} is a {@link File#isDirectory() directory} and that the * {@link File#getAbsolutePath()} does not contain any spaces. * * @throws MojoExecutionException */ private void validateWorkarea() throws MojoExecutionException { if (!workarea.isDirectory()) { throw new MojoExecutionException(workarea + " is not a directory"); } if (workarea.getAbsolutePath().trim().indexOf(" ") != -1) { throw new MojoExecutionException(workarea + " contains a space in path"); } } /** * Determines the actual value for the <i>macro</i>. Will check both {@link #defineStatements} and * {@link RPMHelper#evaluateMacro(String)}. * * @param macro The macro to evaluate. * @return The literal value or name of macro if it has no value. * @throws MojoExecutionException * @since 2.1-alpha-1 */ String evaluateMacro(String macro) throws MojoExecutionException { if (macroKeyToValue.containsKey(macro)) { return macroKeyToValue.get(macro); } final String value = helper.evaluateMacro(macro); macroKeyToValue.put(macro, value); return value; } /** * Write the SPEC file. * * @throws MojoExecutionException if an error occurs writing the file */ private void writeSpecFile() throws MojoExecutionException { File f = new File(workarea, "SPECS"); File specf = new File(f, name + ".spec"); try { getLog().info("Creating spec file " + specf.getAbsolutePath()); PrintWriter spec = new UnixPrintWriter(new FileWriter(specf)); try { new SpecWriter(this, spec).writeSpecFile(); } finally { spec.close(); } } catch (IOException e) { throw new MojoExecutionException("Unable to write " + specf.getAbsolutePath(), e); } } /** * Generates a default copyright text from {@link MavenProject#getOrganization()} and * {@link MavenProject#getInceptionYear()}. * * @return Generated copyright text from the organization name and inception year. */ private String generateDefaultCopyrightText() { String copyrightText; String year = project.getInceptionYear(); String organization = project.getOrganization() == null ? null : project.getOrganization().getName(); if ((year != null) && (organization != null)) { copyrightText = year + " " + organization; } else { copyrightText = year == null ? organization : year; } return "(c) " + copyrightText; } /** * @return Returns the {@link #linkTargetToSources}. */ final Map<String, List<SoftlinkSource>> getLinkTargetToSources() { return this.linkTargetToSources; } /** * @return Returns the {@link #name}. */ final String getName() { return this.name; } /** * @return Returns the {@link #release}. */ public final String getRelease() { return this.release; } public Date getBuildTimestamp() { return (session == null) ? new Date() : session.getStartTime(); } /** * @return Returns the {@link #description}. */ final String getDescription() { return this.description; } /** * @return Returns the {@link #summary}. */ final String getSummary() { return this.summary; } /** * @return Returns the {@link #license}. */ final String getLicense() { return this.license; } /** * @return Returns the {@link #epoch}. */ final String getEpoch() { return this.epoch; } /** * @return Returns the {@link #distribution}. */ final String getDistribution() { return this.distribution; } /** * @return Returns the {@link #icon}. */ final File getIcon() { return this.icon; } /** * @return Returns the {@link #vendor}. */ final String getVendor() { return this.vendor; } /** * @return Returns the {@link #url}. */ final String getUrl() { return this.url; } /** * @return Returns the {@link #group}. */ final String getGroup() { return this.group; } /** * @return Returns the {@link #packager}. */ final String getPackager() { return this.packager; } /** * @return Returns the {@link #autoProvides}. */ final boolean isAutoProvides() { return this.autoProvides; } /** * @return Returns the {@link #autoRequires}. */ final boolean isAutoRequires() { return this.autoRequires; } /** * @return Returns the {@link #provides}. */ final LinkedHashSet<String> getProvides() { return this.provides; } /** * @return Returns the {@link #requires}. */ final LinkedHashSet<String> getRequires() { return this.requires; } /** * @return Returns the {@link #requiresPre}. */ final LinkedHashSet<String> getRequiresPre() { return this.requiresPre; } /** * @return Returns the {@link #requiresPreun}. */ final LinkedHashSet<String> getRequiresPreun() { return this.requiresPreun; } /** * @return Returns the {@link #requiresPost}. */ final LinkedHashSet<String> getRequiresPost() { return this.requiresPost; } /** * @return Returns the {@link #prereqs}. */ final LinkedHashSet<String> getPrereqs() { return this.prereqs; } /** * @return Returns the {@link #obsoletes}. */ final LinkedHashSet<String> getObsoletes() { return this.obsoletes; } /** * @return Returns the {@link #conflicts}. */ final LinkedHashSet<String> getConflicts() { return this.conflicts; } final List<String> getPrefixes() { return prefixes; } /** * @return Returns the {@link #mappings}. */ final List<Mapping> getMappings() { return this.mappings; } /** * @return Returns the {@link #prepareScriptlet}. */ final Scriptlet getPrepareScriptlet() { return this.prepareScriptlet; } /** * @return Returns the {@link #preinstallScriptlet}. */ final Scriptlet getPreinstallScriptlet() { return this.preinstallScriptlet; } /** * @return Returns the {@link #postinstallScriptlet}. */ final Scriptlet getPostinstallScriptlet() { return this.postinstallScriptlet; } /** * @return Returns the {@link #installScriptlet}. */ final Scriptlet getInstallScriptlet() { return this.installScriptlet; } /** * @return Returns the {@link #preremoveScriptlet}. */ final Scriptlet getPreremoveScriptlet() { return this.preremoveScriptlet; } /** * @return Returns the {@link #postremoveScriptlet}. */ final Scriptlet getPostremoveScriptlet() { return this.postremoveScriptlet; } /** * @return Returns the {@link #verifyScriptlet}. */ final Scriptlet getVerifyScriptlet() { return this.verifyScriptlet; } /** * @return Returns the {@link #cleanScriptlet}. */ final Scriptlet getCleanScriptlet() { return this.cleanScriptlet; } /** * @return Returns the {@link #pretransScriptlet}. */ final Scriptlet getPretransScriptlet() { return this.pretransScriptlet; } /** * @return Returns the {@link #posttransScriptlet}. */ final Scriptlet getPosttransScriptlet() { return this.posttransScriptlet; } /** * @return Returns the {@link #triggers}. */ final List<BaseTrigger> getTriggers() { return this.triggers; } /** * @return Returns the {@link #defineStatements}. */ final List<String> getDefineStatements() { return this.defineStatements; } /** * @return Returns the {@link #defaultFilemode}. */ final String getDefaultFilemode() { return this.defaultFilemode; } /** * @return Returns the {@link #defaultDirmode}. */ final String getDefaultDirmode() { return this.defaultDirmode; } /** * @return Returns the {@link #defaultUsername}. */ final String getDefaultUsername() { return this.defaultUsername; } /** * @return Returns the {@link #defaultGroupname}. */ final String getDefaultGroupname() { return this.defaultGroupname; } /** * @return Returns the {@link #buildroot}. */ final File getBuildroot() { return this.buildroot; } /** * @return Returns the {@link #rpmBuildroot}. */ final File getRPMBuildroot() { return this.rpmBuildroot; } /** * @inheritDoc */ public final String getVersion() { return this.projversion; } /** * @return Returns the {@link #changelog}. */ final String getChangelog() { return this.changelog; } /** * @return Returns the {@link #targetArch}. */ final String getTargetArch() { return this.targetArch; } /** * @return Returns the {@link #targetOS}. */ final String getTargetOS() { return this.targetOS; } /** * @return Returns the {@link #targetVendor}. */ final String getTargetVendor() { return this.targetVendor; } /** * @return Returns the {@link #keypath}. */ final File getKeypath() { return this.keypath; } /** * @return Returns the {@link #keyname}. */ final String getKeyname() { return this.keyname; } /** * @return Returns the {@link #keyPassphrase}. */ final Passphrase getKeyPassphrase() { return this.keyPassphrase; } /** * @return Returns the {@link #workarea}. */ final File getWorkarea() { return this.workarea; } /** * @return Returns the {@link #artifact}. */ final Artifact getArtifact() { return this.artifact; } /** * @return Returns the {@link #attachedArtifacts}. */ final List<Artifact> getAttachedArtifacts() { return this.attachedArtifacts; } /** * Returns the {@link FileUtils.FilterWrapper wrappers} to use for filtering resources. * * @return Returns the {@code FilterWrapper}s to use for filtering resources. */ final List<FilterWrapper> getFilterWrappers() { return this.defaultFilterWrappers; } /** * @return the rpmbuildStage */ final public String getRpmbuildStage() { return rpmbuildStage; } /** * @param rpmRpmbuildStage the rpmRpmbuildStage to set */ final public void setRpmbuildStage(String rpmbuildStage) { this.rpmbuildStage = rpmbuildStage; } /** * Load and decrypt gpg passphrase from maven settings if not given from plugin configuration * * @throws MojoFailureException */ private void loadGpgPassphrase() throws MojoFailureException { if (this.keyPassphrase == null && passphraseServerId != null) { Server server = this.settings.getServer(passphraseServerId); if (server != null) { if (server.getPassphrase() != null) { try { this.keyPassphrase = new Passphrase(); this.keyPassphrase.setPassphrase(securityDispatcher.decrypt(server.getPassphrase())); } catch (SecDispatcherException e) { throw new MojoFailureException("Unable to decrypt gpg password", e); } } } } } }