Package ch.rotscher.mavenext

Source Code of ch.rotscher.mavenext.VersionOverrideModelReader$RootPomData

package ch.rotscher.mavenext;

/**
* Copyright 2012 Roger Brechbühl
*
* 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 java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Map;

import org.apache.commons.io.IOUtils;
import org.apache.maven.MavenExecutionException;
import org.apache.maven.model.Dependency;
import org.apache.maven.model.Model;
import org.apache.maven.model.Parent;
import org.apache.maven.model.io.DefaultModelReader;
import org.apache.maven.model.io.ModelReader;
import org.codehaus.plexus.component.annotations.Component;
import org.codehaus.plexus.component.annotations.Requirement;
import org.codehaus.plexus.logging.Logger;
import org.codehaus.plexus.logging.console.ConsoleLogger;

/**
* <p>
* extension of {@link org.apache.maven.model.io.ModelReader} for overriding ${project.version} with the value given as a Java system property:
* </p>
* <p>
* <code>-Dversion.override=A-VERSION</code><br />
* <br />
* other options are:<br />
* <code>-Dversion.override.fail-on-error=[true | false]</code><br />
* <code>-Dversion.override.strict=[true | false]</code><br />
* <code>-Dversion.override.check-snapshot-dependency=[true | false]</code><br />
* </p>
* <p>
* This class helps releasing a project (from a maven point of view, that means not having "SNAPSHOT" in the version) without actually changing (and committing)
* the pom.xml
* </p>
* <p>
* Copyright by Roger Brechbühl, 2012
* </p>
*
* @author Roger Brechbühl
*
*/
@Component(role = ModelReader.class, hint = "custom-version-model-reader")
public class VersionOverrideModelReader extends DefaultModelReader implements ModelReader {

    static final String MAVENEXT_RELEASE_VERSION = "version.override";
    static final String MAVENEXT_BE_STRICT = "version.override.strict";
    static final String MAVENEXT_CHECK_SNAPSHOT_DEP_FAIL_ON_ERROR = "version.override.fail-on-error";
    static final String MAVENEXT_CHECK_SNAPSHOT_DEP = "version.override.check-snapshot-dependency";
    static final String MAVENEXT_BUILDNUMBER_FILE = ".buildnumber";

    private static RootPomData rootPomData = null;
   
    @Requirement
    private Logger logger = new ConsoleLogger();

    @Override
    public Model read(InputStream input, Map<String, ?> options) throws IOException {
        Model model = super.read(input, options);
        // this property is set from the command line with -Dversion.override
        String version = System.getProperty(MAVENEXT_RELEASE_VERSION);
        if (version == null) {
            return model;
        }
       
        String currentGroupId = getGroupId(model, logger);
        if (rootPomData == null) {
          rootPomData = new RootPomData(model, version, logger);
        }

        version = rootPomData.version;
       
        Boolean beStrict = Boolean.parseBoolean(System.getProperty(MAVENEXT_BE_STRICT));
       
        //either the groupId is equals or
        //e.g. the version is overridden here: ch.rotscher.app and ch.rotscher.app.domain
        // vs. not overridden in that case:    ch.rotscher.app and ch.rotscher.application
        if (currentGroupId.equals(rootPomData.groupId) || currentGroupId.startsWith(rootPomData.groupId + ".")) {
           
            if (beStrict && !model.getVersion().equals(rootPomData.originalVersion)) {
              if (logger.isDebugEnabled()) {
                logger.debug(String.format("version of %s (%s) not changed as it differ: %s", model, model.getVersion(), rootPomData.version));
              }
            } else {
              model.setVersion(version);
              if (logger.isDebugEnabled()) {
                    logger.debug(String.format("changing version of %s to %s", model, version));
               
              Parent parent = model.getParent();
              if (parent != null && (parent.getGroupId().equals(rootPomData.groupId) || parent.getGroupId().startsWith(rootPomData.groupId + "."))) {
                  logger.debug(String.format("changing version of parent  %s  to %s", parent, version));
                  parent.setVersion(version);
              }
            }
        }

        Boolean checkSnapshotDependencies = Boolean.parseBoolean(System.getProperty(MAVENEXT_CHECK_SNAPSHOT_DEP));
        Boolean failOnError = Boolean.parseBoolean(System.getProperty(MAVENEXT_CHECK_SNAPSHOT_DEP_FAIL_ON_ERROR));

        if (checkSnapshotDependencies == Boolean.TRUE) {
            for (Dependency dep : model.getDependencies()) {
                String depVersion = dep.getVersion();
                if (depVersion != null && depVersion.contains("SNAPSHOT")) {
                    File pomFile = model.getPomFile();
                    String pomFilePath = "[path not available]";
                    if (pomFile != null) {
                        pomFilePath = pomFile.getPath();
                    }
                    String errorMsg = String.format("there is a snapshot dependency (%s) in %s (%s)", dep, model, pomFilePath);
                    if (failOnError == Boolean.TRUE) {
                        logger.warn(errorMsg);
                        // wrap in a IOException as this one is thrown in the signature
                        throw new IOException(new MavenExecutionException(errorMsg, model.getPomFile()));
                    } else {
                        logger.warn(errorMsg);
                    }
                }
            }
        }

        return model;
    }

    /**
     * get the groupId of the given model. if not set then ask the parent
     *
     * @param model
     * @param logger
     * @return the groupId of the given module
     */
    static String getGroupId(Model model, Logger logger) {
        if (model.getGroupId() != null) {
            return model.getGroupId();
        }

        if (model.getParent() != null) {
            return model.getParent().getGroupId();
        }

        // TODO: return n/A if no groupId can be found!
        return "n/A";
    }

    /**
     * set by the unit test.
     *
     * @param logger
     *            the logger
     */
    void setLogger(Logger logger) {
        this.logger = logger;
    }
   
    static void reset() {
      rootPomData = null;
    }
   
    public static boolean isVersionOverridden() {
      String version = System.getProperty(VersionOverrideModelReader.MAVENEXT_RELEASE_VERSION);
      return version != null;
    }
   
    /**
     * helper class to store the very first groupId which is the base groupId for all following modules:
     *
     * the modules version is changed if the test <code>if module.groupId starts with GroupIdOfRootPom.groupId</code> is true
     *
     */
    static class RootPomData {

      private final String originalVersion;
        private final String groupId;
        private final String version;
        private final Logger logger;

        public RootPomData(Model model, String version, Logger logger) throws IOException {
            this.logger = logger;
            this.originalVersion = model.getVersion();
            this.groupId = VersionOverrideModelReader.getGroupId(model, logger);
            if (version.trim().length() < 1 || Boolean.valueOf(version)) {
              this.version = generateVersion(model);
              System.setProperty(MAVENEXT_RELEASE_VERSION, this.version);
            } else {
              this.version = version;
            }

            logger.info(String
                    .format("initialize groupId to '%s', the version of all modules and dependencies starting with this groupdId will be changed!",
                            groupId));
        }

        private String generateVersion(Model model) throws IOException {
         
              //generate a version based on the {project.version}
              String[] pomVersionTokens = model.getVersion().split("-");
              if (pomVersionTokens.length == 1) {
                return model.getVersion();
              }
             
              String buildNumber = "0";
             
              String jenkinsBuildNumber = System.getenv("BUILD_NUMBER");
              if (jenkinsBuildNumber != null) {
                buildNumber = jenkinsBuildNumber;
                logger.info(String
                            .format("using buildnumber from jenkins: %s",
                                buildNumber));
              } else {
                //read from buildnumber file
                File buildNumberFile = new File(MAVENEXT_BUILDNUMBER_FILE);
                if (buildNumberFile.exists()) {
                  List<String> lines = IOUtils.readLines(new FileInputStream(buildNumberFile));
       
                  for (String line : lines) {
                    //could extend this implementation to ignore any comments starting with # or any other chars
                    buildNumber = line;
                  }
                }
                int incrementedBuildNumber = Integer.parseInt(buildNumber) + 1;
                buildNumber = incrementedBuildNumber + "";
                  FileOutputStream fos = new FileOutputStream(buildNumberFile);
                IOUtils.write(incrementedBuildNumber + "", fos);
                IOUtils.closeQuietly(fos);
                logger.info(String
                            .format("using buildnumber from file .buildnumber: %s",
                                buildNumber));
              }
             
              String versionNumber = pomVersionTokens[0];
              String classifier = pomVersionTokens[1];
              if (classifier.equals("SNAPSHOT")) {
                //we shorten a little and avoid the literal 'SNAPSHOT'
                classifier = "S";
              }
             
            return String.format("%s-%s-%s", versionNumber, classifier, buildNumber);
            }
        }

}
TOP

Related Classes of ch.rotscher.mavenext.VersionOverrideModelReader$RootPomData

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.