All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.sourceforge.javadpkg.plugin.DebianPackageMojo Maven / Gradle / Ivy

The newest version!
/*
 * dpkg - Debian Package library and the Debian Package Maven plugin
 * (c) Copyright 2016 Gerrit Hohl
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
package net.sourceforge.javadpkg.plugin;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;

import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecution;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugin.descriptor.PluginDescriptor;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.apache.maven.settings.Settings;

import net.sourceforge.javadpkg.BuildException;
import net.sourceforge.javadpkg.ChangeLog;
import net.sourceforge.javadpkg.Context;
import net.sourceforge.javadpkg.Copyright;
import net.sourceforge.javadpkg.DebianPackageBuilder;
import net.sourceforge.javadpkg.DebianPackageBuilderFactory;
import net.sourceforge.javadpkg.GlobalConstants;
import net.sourceforge.javadpkg.ParseException;
import net.sourceforge.javadpkg.Script;
import net.sourceforge.javadpkg.ScriptParser;
import net.sourceforge.javadpkg.ScriptVariableReplacer;
import net.sourceforge.javadpkg.Warning;
import net.sourceforge.javadpkg.control.BinaryControl;
import net.sourceforge.javadpkg.control.Size;
import net.sourceforge.javadpkg.impl.ContextImpl;
import net.sourceforge.javadpkg.impl.DebianPackageBuilderFactoryImpl;
import net.sourceforge.javadpkg.impl.ScriptParserImpl;
import net.sourceforge.javadpkg.impl.ScriptVariableReplacerImpl;
import net.sourceforge.javadpkg.io.DataSource;
import net.sourceforge.javadpkg.io.DataTarget;
import net.sourceforge.javadpkg.io.impl.DataFileSource;
import net.sourceforge.javadpkg.io.impl.DataFileTarget;
import net.sourceforge.javadpkg.io.impl.DataStreamSource;
import net.sourceforge.javadpkg.plugin.cfg.ChangeLogConfiguration;
import net.sourceforge.javadpkg.plugin.cfg.ControlConfiguration;
import net.sourceforge.javadpkg.plugin.cfg.CopyrightConfiguration;
import net.sourceforge.javadpkg.plugin.cfg.DataConfiguration;
import net.sourceforge.javadpkg.plugin.cfg.ScriptConfiguration;
import net.sourceforge.javadpkg.plugin.cfg.ScriptType;
import net.sourceforge.javadpkg.plugin.impl.BinaryControlBuilderImpl;
import net.sourceforge.javadpkg.plugin.impl.ChangeLogConfigurationParserImpl;
import net.sourceforge.javadpkg.plugin.impl.CopyrightConfigurationParserImpl;
import net.sourceforge.javadpkg.plugin.impl.DataConfigurationParserImpl;
import net.sourceforge.javadpkg.plugin.impl.TargetFileBuilderImpl;
import net.sourceforge.javadpkg.replace.ReplacementException;
import net.sourceforge.javadpkg.replace.Replacements;

/**
 * 

* Creates a Debian package. *

* * @author Gerrit Hohl ([email protected]) * @version 1.0, 03.05.2016 by Gerrit Hohl */ @Mojo(name = "dpkg", defaultPhase = LifecyclePhase.PACKAGE) public class DebianPackageMojo extends AbstractMojo implements GlobalConstants { /** The number format for the metrics in the log. */ private static final DecimalFormat FORMAT = new DecimalFormat("###,###,###,##0"); /** The session. */ @Parameter(defaultValue = "${session}", readonly = true) private MavenSession session; /** The project. */ @Parameter(defaultValue = "${project}", readonly = true) private MavenProject project; /** The MOJO. */ @Parameter(defaultValue = "${mojoExecution}", readonly = true) private MojoExecution mojo; /** The plug-in (only available in Maven 3). */ @Parameter(defaultValue = "${plugin}", readonly = true) private PluginDescriptor plugin; /** The settings. */ @Parameter(defaultValue = "${settings}", readonly = true) private Settings settings; /** The base directory. */ @Parameter(defaultValue = "${project.basedir}", readonly = true) private File basedir; /** The target directory. */ @Parameter(defaultValue = "${project.build.directory}", readonly = true) private File target; /** The encoding from the project. */ @Parameter(defaultValue = "${project.build.sourceEncoding}", readonly = true) private String sourceEncoding; /** The flag if the plug-in should fail if a warning is reported. */ @Parameter(name = "failOnWarning", defaultValue = "true") private boolean failOnWarning; /** The flag if the plug-in should be skipped. */ @Parameter(name = "skip", defaultValue = "false") private boolean skip; /** The output directory. */ @Parameter(name = "outputDirectory", defaultValue = "${project.build.directory}") private File outputDirectory; /** The control configuration. */ @Parameter(name = "control", required = true) private ControlConfiguration control; /** The script configurations. */ @Parameter(name = "scripts") private List scripts; /** The copyright configuration. */ @Parameter(name = "copyright", required = true) private CopyrightConfiguration copyright; /** The change log configuration. */ @Parameter(name = "changeLog", required = true) private ChangeLogConfiguration changeLog; /** The data configuration. */ @Parameter(name = "data", required = true) private DataConfiguration data; /** The properties. */ @Parameter(name = "properties") private Properties properties; /** The parser for the script. */ private ScriptParser scriptParser; /** The variable replacer for the script. */ private ScriptVariableReplacer scriptVariableReplacer; /** The parser for the copyright configuration. */ private CopyrightConfigurationParser copyrightConfigurationParser; /** The parser for the change log configuration. */ private ChangeLogConfigurationParser changeLogConfigurationParser; /** *

* Creates the POJO. *

*/ public DebianPackageMojo() { super(); this.scriptParser = new ScriptParserImpl(); this.scriptVariableReplacer = new ScriptVariableReplacerImpl(); this.copyrightConfigurationParser = new CopyrightConfigurationParserImpl(); this.changeLogConfigurationParser = new ChangeLogConfigurationParserImpl(); } @Override public void execute() throws MojoExecutionException, MojoFailureException { Log log; Charset defaultEncoding; DebianPackageBuilderFactory builderFactory; DebianPackageBuilder builder; DataConfigurationParser dataConfigurationParser; File targetDirectory; Properties pluginProperties; Replacements replacements; Size installedSize; Context context, dataContext; BinaryControlBuilder binaryControlBuilder; BinaryControl control; Copyright copyright; ChangeLog changeLog; TargetFileBuilder targetFileBuilder; // --- Start logging --- log = this.getLog(); if (log.isInfoEnabled()) { log.info("dpkg-maven-plugin"); if (log.isDebugEnabled()) { log.debug("Session : " + this.session); log.debug("Project : " + this.project); log.debug("Mojo : " + this.mojo); log.debug("Plugin : " + this.plugin); log.debug("Settings : " + this.settings); log.debug("Basedir : " + this.basedir); try { log.debug("Target : " + (this.target == null ? "null" : this.target.getCanonicalPath())); } catch (IOException e) { throw new MojoExecutionException("Couldn't create canonical path (removing '..'): " + e.getMessage(), e); } try { log.debug("Output Directory : " + (this.outputDirectory == null ? "null" : this.outputDirectory.getCanonicalPath())); } catch (IOException e) { throw new MojoExecutionException("Couldn't create canonical path (removing '..'): " + e.getMessage(), e); } if ((this.properties == null) || this.properties.isEmpty()) { log.debug("Properties : No properties defined."); } else { log.debug("Properties :"); for (Entry entry : this.properties.entrySet()) { log.debug(String.format(" %-16s : %s", entry.getKey().toString(), (entry.getValue() == null ? "null" : entry.getValue().toString()))); } } } } // --- The default encoding --- defaultEncoding = this.getDefaultEncoding(); if (log.isDebugEnabled()) { log.debug("Default Encoding : " + defaultEncoding); } if (this.skip) { if (log.isInfoEnabled()) { log.info("Skip."); } return; } // --- Check configuration --- if (this.control == null) throw new MojoExecutionException("Control configuration of the plugin is not set."); if (this.copyright == null) throw new MojoExecutionException("Copyright configuration of the plugin is not set."); if (this.changeLog == null) throw new MojoExecutionException("Change log configuration of the plugin is not set."); // --- Get the target directory --- try { if (this.outputDirectory != null) { targetDirectory = this.outputDirectory.getCanonicalFile(); } else { targetDirectory = this.target.getCanonicalFile(); } } catch (IOException e) { throw new MojoExecutionException( "Couldn't create canonical path for target directory |" + (this.outputDirectory == null ? this.target.getAbsolutePath() : this.outputDirectory.getAbsolutePath()) + "|: " + e.getMessage(), e); } // --- Create replacements --- if (this.properties == null) { pluginProperties = new Properties(); } else { pluginProperties = this.properties; } replacements = new ReplacementsMaven(pluginProperties, this.project, this.settings, System.getenv(), System.getProperties()); // --- Create builder --- try { builderFactory = new DebianPackageBuilderFactoryImpl(); } catch (IOException | ParseException e) { throw new MojoExecutionException("Couldn't create builder factory: " + e.getMessage(), e); } builder = builderFactory.createDebianPackageBuilder(); // --- Add data --- dataContext = new ContextImpl(); dataConfigurationParser = new DataConfigurationParserImpl(defaultEncoding, replacements); try { installedSize = dataConfigurationParser.parseDataConfiguration(log, this.data, builder, dataContext); } catch (IOException e) { throw new MojoExecutionException("An error occured while adding the directories and files: " + e.getMessage(), e); } catch (ParseException e) { throw new MojoFailureException("An error occured while adding the directories and files: " + e.getMessage(), e); } this.logWarnings(log, dataContext); // --- Create control --- // ROADMAP Get control from file and replace variables. binaryControlBuilder = new BinaryControlBuilderImpl(); context = new ContextImpl(); control = binaryControlBuilder.buildBinaryControl(log, this.control, installedSize, context); builder.setControl(control); this.logWarnings(log, context); // --- Add installation scripts --- context = new ContextImpl(); this.addInstallScripts(log, builder, replacements, context); this.logWarnings(log, context); // --- Set copyright --- context = new ContextImpl(); try { copyright = this.copyrightConfigurationParser.parseCopyrightConfiguration(log, this.copyright, context); } catch (IOException | ParseException e) { throw new MojoExecutionException("Couldn't parse copyright configuration: " + e.getMessage(), e); } builder.setCopyright(copyright); this.logWarnings(log, context); // --- Set change log --- context = new ContextImpl(); try { changeLog = this.changeLogConfigurationParser.parseChangeLogConfiguration(log, this.changeLog, context); } catch (IOException | ParseException e) { throw new MojoExecutionException("Couldn't parse change log configuration: " + e.getMessage(), e); } builder.setChangeLog(changeLog); this.logWarnings(log, context); // --- Build and write Debian package file --- targetFileBuilder = new TargetFileBuilderImpl(); context = new ContextImpl(); this.buildDebianPackage(log, builder, targetDirectory, control, targetFileBuilder, context); this.logWarnings(log, context); // --- Now we maybe also have some of the warnings from the file processing --- this.logWarnings(log, dataContext); } /** *

* Returns the default encoding. *

* * @return The default encoding. * @throws MojoExecutionException * If the encoding defined in the Maven model is not supported * by the JVM. */ private Charset getDefaultEncoding() throws MojoExecutionException { Charset charset; if (this.sourceEncoding != null) { try { charset = Charset.forName(this.sourceEncoding); } catch (IllegalArgumentException e) { throw new MojoExecutionException("The encoding |" + this.sourceEncoding + "| defined in the pom.xml is not supported by this JVM: " + e.getMessage(), e); } } else { charset = Charset.defaultCharset(); } return charset; } /** *

* Adds the installation scripts to the builder. *

* * @param log * The logging. * @param builder * The builder. * @param replacements * The replacements. * @param context * The context. * @throws MojoExecutionException * If a build error occurs. */ private void addInstallScripts(Log log, DebianPackageBuilder builder, Replacements replacements, Context context) throws MojoExecutionException { Map confs; Map scripts; Script script; if ((this.scripts == null) || this.scripts.isEmpty()) return; // --- Make sure we don't have any duplicates --- confs = new HashMap<>(); for (ScriptConfiguration conf : this.scripts) { if (confs.put(conf.getType(), conf) != null) throw new MojoExecutionException( "The installation script configuration for type |" + conf.getType() + "| exists more than once."); } // --- Process the scripts --- scripts = new HashMap<>(); for (ScriptConfiguration conf : confs.values()) { // --- Parse the script --- if (conf.getFile() != null) { if (log.isInfoEnabled()) { log.info("Read installation script for type |" + conf.getType() + "| from file |" + conf.getFile().getAbsolutePath() + "|."); } try { try (DataSource source = new DataFileSource(conf.getFile())) { script = this.scriptParser.parseScript(source, context); } } catch (IOException | ParseException e) { throw new MojoExecutionException("Couldn't parse the installation script configuration for type |" + conf.getType() + "| from file |" + conf.getFile().getAbsolutePath() + "|: " + e.getMessage(), e); } } else if (conf.getContent() != null) { if (log.isInfoEnabled()) { log.info("Read installation script for type |" + conf.getType() + "| from configuration."); } try { try (DataSource source = new DataStreamSource( new ByteArrayInputStream(conf.getContent().getBytes(UTF_8_CHARSET)), conf.getType().toString(), true)) { script = this.scriptParser.parseScript(source, context); } } catch (IOException | ParseException e) { throw new MojoExecutionException("Couldn't parse the installation script configuration for type |" + conf.getType() + "| from the element: " + e.getMessage(), e); } } else throw new MojoExecutionException("The installation script configuration for type |" + conf.getType() + "| is empty: No and no element is set."); // --- Replace the variables --- try { script = this.scriptVariableReplacer.replaceScriptVariables(script, replacements, context); } catch (ReplacementException e) { throw new MojoExecutionException( "Couldn't replace the variables in the installation script configuration for type |" + conf.getType() + "|: " + e.getMessage(), e); } scripts.put(conf.getType(), script); } // --- Set the scripts --- script = scripts.get(ScriptType.PREINST); if (script != null) { builder.setPreInstall(script); } script = scripts.get(ScriptType.POSTINST); if (script != null) { builder.setPostInstall(script); } script = scripts.get(ScriptType.PRERM); if (script != null) { builder.setPreRemove(script); } script = scripts.get(ScriptType.POSTRM); if (script != null) { builder.setPostRemove(script); } } /** *

* Builds the Debian package using the specified builder. *

* * @param log * The logging. * @param builder * The builder. * @param targetDirectory * The target directory. * @param control * The binary control. * @param targetFileBuilder * The builder for the name and path of the target file. * @param context * The context. * @throws MojoExecutionException * If a build error occurs. * @throws MojoFailureException * If an error occurs which fails the build. */ private void buildDebianPackage(Log log, DebianPackageBuilder builder, File targetDirectory, BinaryControl control, TargetFileBuilder targetFileBuilder, Context context) throws MojoExecutionException, MojoFailureException { File targetFile; targetFile = targetFileBuilder.createTargetFile(targetDirectory, control); if (!targetDirectory.exists()) { if (log.isDebugEnabled()) { log.debug("Create directory: " + targetDirectory.getAbsolutePath()); } if (!targetDirectory.mkdirs()) throw new MojoExecutionException("Couldn't create directory |" + targetDirectory.getAbsolutePath() + "|."); } if (log.isInfoEnabled()) { log.info("Write Debian package: " + targetFile.getAbsolutePath()); } try { try (DataTarget target = new DataFileTarget(targetFile)) { builder.buildDebianPackage(target, context); } } catch (IOException e) { if (log.isErrorEnabled()) { log.error("Couldn't write Debian package |" + targetFile.getAbsolutePath() + "|: " + e.getMessage(), e); } throw new MojoFailureException( "Couldn't build write package |" + targetFile.getAbsolutePath() + "|: " + e.getMessage(), e); } catch (BuildException e) { if (log.isErrorEnabled()) { log.error("Couldn't build Debian package |" + targetFile.getAbsolutePath() + "|: " + e.getMessage(), e); } throw new MojoFailureException( "Couldn't build Debian package |" + targetFile.getAbsolutePath() + "|: " + e.getMessage(), e); } if (log.isInfoEnabled()) { log.info("Size of Debian package: " + FORMAT.format(targetFile.length()) + " byte(s)"); } } /** *

* Logs the warnings of the context. *

* * @param log * The logging. * @param context * The context. * @throws MojoFailureException * If {@link #failOnWarning} is set and a warning is available. */ private void logWarnings(Log log, Context context) throws MojoFailureException { List warnings; warnings = context.getWarnings(); if (!warnings.isEmpty()) { if (log.isWarnEnabled()) { for (Warning warning : warnings) { log.warn(warning.getText()); } } if (this.failOnWarning) throw new MojoFailureException( "Found " + warnings.size() + " warning(s). First warning: " + warnings.get(0).getText()); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy