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

com.github.danielflower.mavenplugins.release.Reactor Maven / Gradle / Ivy

package com.github.danielflower.mavenplugins.release;

import org.apache.maven.model.Dependency;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.project.MavenProject;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.lib.Repository;

import java.util.ArrayList;
import java.util.List;

public class Reactor {

    private final List modulesInBuildOrder;

    public Reactor(List modulesInBuildOrder) {
        this.modulesInBuildOrder = modulesInBuildOrder;
    }

    public List getModulesInBuildOrder() {
        return modulesInBuildOrder;
    }

    public static Reactor fromProjects(Log log, Git git, MavenProject rootProject, List projects, Long buildNumber) throws ValidationException, GitAPIException, MojoExecutionException {
        DiffDetector detector = new DiffDetector(git.getRepository());
        List modules = new ArrayList();
        VersionNamer versionNamer = new VersionNamer();
        for (MavenProject project : projects) {
            String relativePathToModule = calculateModulePath(rootProject, project);
            List previousTagsForThisModule = previousTagsForModule(git, project);

            VersionName newVersion = versionNamer.name(project.getVersion(), buildNumber, previousTagsForThisModule);

            boolean oneOfTheDependenciesHasChanged = false;
            String changedDependency = null;
            for (ReleasableModule module : modules) {
                if (module.willBeReleased()) {
                    for (Dependency dependency : project.getModel().getDependencies()) {
                        if (dependency.getGroupId().equals(module.getGroupId()) && dependency.getArtifactId().equals(module.getArtifactId())) {
                            oneOfTheDependenciesHasChanged = true;
                            changedDependency = dependency.getArtifactId();
                            break;
                        }
                    }
                }
                if (oneOfTheDependenciesHasChanged) {
                    break;
                }
            }

            String equivalentVersion = null;

            if (oneOfTheDependenciesHasChanged) {
                log.info("Releasing " + project.getArtifactId() + " " + newVersion.releaseVersion() + " as " + changedDependency + " has changed.");
            } else {
                AnnotatedTag previousTagThatIsTheSameAsHEADForThisModule = hasChangedSinceLastRelease(previousTagsForThisModule, detector, project, relativePathToModule);
                if (previousTagThatIsTheSameAsHEADForThisModule != null) {
                    equivalentVersion = previousTagThatIsTheSameAsHEADForThisModule.version() + "." + previousTagThatIsTheSameAsHEADForThisModule.buildNumber();
                    log.info("Will use version " + equivalentVersion + " for " + project.getArtifactId() + " as it has not been changed since that release.");
                } else {
                    log.debug("Will use version " + newVersion.releaseVersion() + " for " + project.getArtifactId() + " as it has changed since the last release.");
                }
            }
            ReleasableModule module = new ReleasableModule(project, newVersion, equivalentVersion, relativePathToModule);
            modules.add(module);
        }

        if (!atLeastOneBeingReleased(modules)) {
            log.warn("No changes have been detected in any modules so will re-release them all");
            List newList = new ArrayList();
            for (ReleasableModule module : modules) {
                newList.add(module.createReleasableVersion());
            }
            modules = newList;
        }

        return new Reactor(modules);
    }

    private static boolean atLeastOneBeingReleased(List modules) {
        for (ReleasableModule module : modules) {
            if (module.willBeReleased()) {
                return true;
            }
        }
        return false;
    }

    private static String calculateModulePath(MavenProject rootProject, MavenProject project) {
        String relativePathToModule = Repository.stripWorkDir(rootProject.getBasedir(), project.getBasedir());
        if (relativePathToModule.length() == 0) {
            relativePathToModule = ".";
        }
        return relativePathToModule;
    }

    private static AnnotatedTag hasChangedSinceLastRelease(List previousTagsForThisModule, DiffDetector detector, MavenProject project, String relativePathToModule) throws MojoExecutionException {
        try {
            if (previousTagsForThisModule.size() == 0) return null;
            boolean hasChanged = detector.hasChangedSince(relativePathToModule, project.getModel().getModules(), previousTagsForThisModule);
            return hasChanged ? null : previousTagsForThisModule.get(0);
        } catch (Exception e) {
            throw new MojoExecutionException("Error while detecting whether or not " + project.getArtifactId() + " has changed since the last release", e);
        }
    }

    public static List previousTagsForModule(Git git, MavenProject project) throws MojoExecutionException {
        try {
            return AnnotatedTagFinder.mostRecent(git, project.getArtifactId(), project.getVersion().replace("-SNAPSHOT", ""));
        } catch (Exception e) {
            throw new MojoExecutionException("Error while looking up tags for " + project.getArtifactId(), e);
        }
    }

    public ReleasableModule findByLabel(String label) {
        for (ReleasableModule module : modulesInBuildOrder) {
            String currentLabel = module.getGroupId() + ":" + module.getArtifactId();
            if (currentLabel.equals(label)) {
                return module;
            }
        }
        return null;
    }

    public ReleasableModule find(String groupId, String artifactId, String version) throws UnresolvedSnapshotDependencyException {
        ReleasableModule value = findByLabel(groupId + ":" + artifactId);
        if (value == null) {
            throw new UnresolvedSnapshotDependencyException(groupId, artifactId, version);
        }
        return value;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy