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

com.itemis.maven.plugins.unleash.util.scm.ScmPomVersionsMergeClient Maven / Gradle / Ivy

Go to download

This plugin provides a generic alternative to the error-prone default release plugin provided by Maven. It is designed to require a minimal effort of work for releasing modules and being extensible to integrate in every project setup.

There is a newer version: 3.2.0
Show newest version
package com.itemis.maven.plugins.unleash.util.scm;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import org.apache.maven.model.Model;
import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
import org.w3c.dom.Document;

import com.google.common.base.Objects;
import com.google.common.base.Optional;
import com.google.common.io.ByteStreams;
import com.google.common.io.Closeables;
import com.itemis.maven.plugins.unleash.scm.ScmException;
import com.itemis.maven.plugins.unleash.scm.ScmOperation;
import com.itemis.maven.plugins.unleash.scm.merge.MergeClient;
import com.itemis.maven.plugins.unleash.util.MavenVersionUtil;
import com.itemis.maven.plugins.unleash.util.PomUtil;

/**
 * An implementation of the {@link MergeClient} used while committing changes during the release process.
* This merge client is only able to merge versions and parent versions if conflicting POM files. This is sufficient at * this point as in the release process other conflicts should not arise. * * @author Stanley Hillner * @since 1.0.0 */ public class ScmPomVersionsMergeClient implements MergeClient { @Override public void merge(InputStream local, InputStream remote, InputStream base, OutputStream result) throws ScmException { Optional localModel = loadModel(local); if (!localModel.isPresent()) { // TODO implement merge of other files! throw new ScmException(ScmOperation.MERGE, "Unable to merge non-POM changes."); } byte[] remoteData = null; try { remoteData = ByteStreams.toByteArray(remote); } catch (IOException e) { throw new ScmException(ScmOperation.MERGE, "Unable to read remote content!", e); } finally { Closeables.closeQuietly(remote); } Optional remoteModel = loadModel(new ByteArrayInputStream(remoteData)); Optional baseModel = loadModel(base); Model resultModel = loadModel(new ByteArrayInputStream(remoteData)).get(); mergeVersions(localModel.get(), remoteModel.get(), baseModel.get(), resultModel); mergeParentVersions(localModel.get(), remoteModel.get(), baseModel.get(), resultModel); try { Document document = PomUtil.parsePOM(new ByteArrayInputStream(remoteData)); PomUtil.setProjectVersion(resultModel, document, resultModel.getVersion()); if (resultModel.getParent() != null) { PomUtil.setParentVersion(resultModel, document, resultModel.getParent().getVersion()); } PomUtil.writePOM(document, result, false); } catch (Throwable t) { throw new ScmException(ScmOperation.MERGE, "Could not serialize merged POM!", t); } } private void mergeVersions(Model local, Model remote, Model base, Model result) throws ScmException { boolean remoteChange = !Objects.equal(remote.getVersion(), base.getVersion()); if (remoteChange) { if (!Objects.equal(local.getVersion(), remote.getVersion())) { if (MavenVersionUtil.isNewerVersion(local.getVersion(), remote.getVersion())) { result.setVersion(local.getVersion()); } else { result.setVersion(remote.getVersion()); // throw new ScmException(ScmOperation.MERGE, // "Could not merge POM version changes since the new remote version is higher than the local one!"); } } } else { result.setVersion(local.getVersion()); } } private void mergeParentVersions(Model local, Model remote, Model base, Model result) throws ScmException { String localParentVersion = local.getParent() != null ? local.getParent().getVersion() : null; String remoteParentVersion = remote.getParent() != null ? remote.getParent().getVersion() : null; String baseParentVersion = base.getParent() != null ? base.getParent().getVersion() : null; boolean remoteParentRemoved = remoteParentVersion == null && baseParentVersion != null; boolean remoteParentAdded = remoteParentVersion != null && baseParentVersion == null; boolean remoteParentVersionChanged = !Objects.equal(remoteParentVersion, baseParentVersion); boolean localParentRemoved = localParentVersion == null && baseParentVersion != null; boolean localParentAdded = localParentVersion != null && baseParentVersion == null; boolean localParentVersionChanged = !Objects.equal(localParentVersion, baseParentVersion); if (localParentAdded) { // if locally added the base had no parent (remote remove and change is not relevant) if (remoteParentAdded) { if (Objects.equal(local.getParent().getArtifactId(), remote.getParent().getArtifactId()) && Objects.equal(local.getParent().getGroupId(), remote.getParent().getGroupId())) { if (MavenVersionUtil.isNewerVersion(local.getParent().getVersion(), remote.getParent().getVersion())) { result.setParent(local.getParent()); } } else { throw new ScmException(ScmOperation.MERGE, "Could not merge local and remote POM parent changes since both versions added different parent artifacts."); } } else { result.setParent(local.getParent()); } } else if (localParentRemoved) { // if locally removed the base had a parent (remote add is not relevant and remote remove is ok) if (remoteParentVersionChanged) { throw new ScmException(ScmOperation.MERGE, "Could not merge POM parent version conflicts since in the local POM the parent had been removed and in the remote POM the parent had been changed."); } else { result.getParent().setVersion(localParentVersion); } } else if (localParentVersionChanged) { // if locally changed the base had a parent (remote add is not relevant) if (remoteParentVersionChanged) { if (Objects.equal(local.getParent().getArtifactId(), remote.getParent().getArtifactId()) && Objects.equal(local.getParent().getGroupId(), remote.getParent().getGroupId())) { if (MavenVersionUtil.isNewerVersion(local.getParent().getVersion(), remote.getParent().getVersion())) { result.setParent(local.getParent()); } } else { throw new ScmException(ScmOperation.MERGE, "Could not merge local and remote POM parent changes since both versions are referencing different parent artifacts."); } } else if (remoteParentRemoved) { throw new ScmException(ScmOperation.MERGE, "Could not merge POM parent version conflicts since in the local POM the parent had been updated while in the remote POM the parent had been removed."); } else { result.getParent().setVersion(localParentVersion); } } } private Optional loadModel(InputStream in) { MavenXpp3Reader reader = new MavenXpp3Reader(); try { Model model = reader.read(in); return Optional.of(model); } catch (Exception e) { return Optional.absent(); } finally { Closeables.closeQuietly(in); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy