Search in sources :

Example 1 with PluginState

use of org.commonjava.maven.ext.core.state.PluginState in project pom-manipulation-ext by release-engineering.

the class PluginManipulator method applyChanges.

/**
 * Apply the alignment changes to the list of {@link Project}'s given.
 */
@Override
public Set<Project> applyChanges(final List<Project> projects) throws ManipulationException {
    final PluginState state = session.getState(PluginState.class);
    if (!session.isEnabled() || !state.isEnabled()) {
        logger.debug(getClass().getSimpleName() + ": Nothing to do!");
        return Collections.emptySet();
    }
    final Set<Project> changed = new HashSet<>();
    final Set<Plugin> mgmtOverrides = loadRemoteBOM(PluginType.RemotePM);
    final Set<Plugin> pluginOverrides = loadRemoteBOM(PluginType.RemoteP);
    for (final Project project : projects) {
        final Model model = project.getModel();
        if (!mgmtOverrides.isEmpty()) {
            apply(project, model, PluginType.RemotePM, mgmtOverrides);
            changed.add(project);
        }
        if (!pluginOverrides.isEmpty()) {
            apply(project, model, PluginType.RemoteP, pluginOverrides);
            changed.add(project);
        }
    }
    // If we've changed something now update any old properties with the new values.
    if (!changed.isEmpty()) {
        logger.info("Iterating for standard overrides...");
        for (Project project : versionPropertyUpdateMap.keySet()) {
            for (final Map.Entry<String, String> entry : versionPropertyUpdateMap.get(project).entrySet()) {
                // Ignore strict alignment for plugins ; if we're attempting to use a differing plugin
                // its unlikely to be an exact match.
                PropertiesUtils.PropertyUpdate found = PropertiesUtils.updateProperties(session, project, true, entry.getKey(), entry.getValue());
                if (found == PropertiesUtils.PropertyUpdate.NOTFOUND) {
                    // Problem in this scenario is that we know we have a property update map but we have not found a
                    // property to update. Its possible this property has been inherited from a parent. Override in the
                    // top pom for safety.
                    logger.info("Unable to find a property for {} to update", entry.getKey());
                    for (final Project p : changed) {
                        if (p.isInheritanceRoot()) {
                            logger.info("Adding property {} with {} ", entry.getKey(), entry.getValue());
                            p.getModel().getProperties().setProperty(entry.getKey(), entry.getValue());
                        }
                    }
                }
            }
        }
    }
    return changed;
}
Also used : PluginState(org.commonjava.maven.ext.core.state.PluginState) Project(org.commonjava.maven.ext.common.model.Project) Model(org.apache.maven.model.Model) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) PropertiesUtils(org.commonjava.maven.ext.core.util.PropertiesUtils) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet) Plugin(org.apache.maven.model.Plugin)

Example 2 with PluginState

use of org.commonjava.maven.ext.core.state.PluginState in project pom-manipulation-ext by release-engineering.

the class PluginManipulator method loadRemoteBOM.

private Set<Plugin> loadRemoteBOM(PluginType type) throws ManipulationException {
    final RESTState rState = session.getState(RESTState.class);
    final PluginState pState = session.getState(PluginState.class);
    final Set<Plugin> restOverrides = pState.getRemoteRESTOverrides();
    final Set<Plugin> bomOverrides = new LinkedHashSet<>();
    final List<ProjectVersionRef> gavs = pState.getRemotePluginMgmt();
    Set<Plugin> mergedOverrides = new LinkedHashSet<>();
    if (gavs != null) {
        // We used to iterate in reverse order so that the first GAV in the list overwrites the last
        // but due to the simplification moving to a single Set, as that doesn't support replace operation,
        // we now iterate in normal order.
        final Iterator<ProjectVersionRef> iter = gavs.iterator();
        final Properties exclusions = (Properties) session.getUserProperties().clone();
        exclusions.putAll(System.getProperties());
        while (iter.hasNext()) {
            final ProjectVersionRef ref = iter.next();
            if (type == PluginType.RemotePM) {
                bomOverrides.addAll(effectiveModelBuilder.getRemotePluginManagementVersionOverrides(ref, exclusions));
            } else {
                bomOverrides.addAll(effectiveModelBuilder.getRemotePluginVersionOverrides(ref, exclusions));
            }
        }
    }
    // TODO: Remote Plugin (as opposed to Remote PluginManagement) alignment is deprecated. Therefore we don't support combining it with REST.
    if (type == PluginType.RemoteP) {
        if (pState.getPrecedence() != PluginPrecedence.BOM) {
            logger.warn("Remote plugin alignment is only supported with precedence type of BOM");
        }
        mergedOverrides = bomOverrides;
    } else {
        if (pState.getPrecedence() == PluginPrecedence.BOM) {
            mergedOverrides = bomOverrides;
            if (mergedOverrides.isEmpty()) {
                String msg = rState.isEnabled() ? "pluginSource for restURL" : "pluginManagement";
                logger.warn("No dependencies found for pluginSource {}. Has {} been configured? ", pState.getPrecedence(), msg);
            }
        }
        if (pState.getPrecedence() == PluginPrecedence.REST) {
            mergedOverrides = restOverrides;
            if (mergedOverrides.isEmpty()) {
                logger.warn("No dependencies found for pluginSource {}. Has restURL been configured? ", pState.getPrecedence());
            }
        } else if (pState.getPrecedence() == PluginPrecedence.RESTBOM) {
            mergedOverrides = restOverrides;
            mergedOverrides.addAll(bomOverrides);
        } else if (pState.getPrecedence() == PluginPrecedence.BOMREST) {
            mergedOverrides = bomOverrides;
            mergedOverrides.addAll(restOverrides);
        }
    }
    logger.debug("Final remote override list for type {} with precedence {} is {}", type.toString(), pState.getPrecedence(), mergedOverrides);
    return mergedOverrides;
}
Also used : PluginState(org.commonjava.maven.ext.core.state.PluginState) LinkedHashSet(java.util.LinkedHashSet) ProjectVersionRef(org.commonjava.maven.atlas.ident.ref.ProjectVersionRef) Properties(java.util.Properties) RESTState(org.commonjava.maven.ext.core.state.RESTState) Plugin(org.apache.maven.model.Plugin)

Example 3 with PluginState

use of org.commonjava.maven.ext.core.state.PluginState in project pom-manipulation-ext by release-engineering.

the class PluginManipulator method applyOverrides.

/**
 * Set the versions of any plugins which match the contents of the list of plugin overrides.
 *
 * Currently this method takes the remote plugin type (note that remote plugins are deprecated) and the local plugin type.
 * It will ONLY apply configurations, executions and dependencies from the remote pluginMgmt to the local pluginMgmt.
 *   If the local pluginMgmt does not have a matching plugin then, if {@link CommonState#getOverrideTransitive()} is true
 * then it will inject a new plugin into the local pluginMgmt.
 *   It will however apply version changes to both local pluginMgmt and local plugins.
 * Note that if the deprecated injectRemotePlugins is enabled then remote plugin version, executions, dependencies and
 * configurations will also be applied to the local plugins.
 *
 * @param project the current project
 * @param remotePluginType The type of the remote plugin (mgmt or plugins)
 * @param localPluginType The type of local block (mgmt or plugins). Only used to determine whether to inject configs/deps/executions.
 * @param plugins The list of plugins to modify
 * @param pluginVersionOverrides The list of version overrides to apply to the plugins
 * @throws ManipulationException if an error occurs.
 */
private void applyOverrides(Project project, PluginType remotePluginType, final PluginType localPluginType, final HashMap<ProjectVersionRef, Plugin> plugins, final Set<Plugin> pluginVersionOverrides) throws ManipulationException {
    if (plugins == null) {
        throw new ManipulationException("Original plugins should not be null");
    }
    final PluginState pluginState = session.getState(PluginState.class);
    final CommonState commonState = session.getState(CommonState.class);
    final HashMap<String, ProjectVersionRef> pluginsByGA = new LinkedHashMap<>();
    // Secondary map of original plugins group:artifact to pvr mapping.
    for (ProjectVersionRef pvr : plugins.keySet()) {
        // We should NEVER have multiple group:artifact with different versions in the same project. If we do,
        // like with dependencies, the behaviour is undefined - although its most likely the last-wins.
        pluginsByGA.put(pvr.asProjectRef().toString(), pvr);
    }
    for (final Plugin override : pluginVersionOverrides) {
        Plugin plugin = null;
        String newValue = override.getVersion();
        // override version.
        if (pluginsByGA.containsKey(override.getKey())) {
            // Potential match of override group:artifact to original plugin group:artifact.
            String oldValue = pluginsByGA.get(override.getKey()).getVersionString();
            plugin = plugins.get(pluginsByGA.get(override.getKey()));
            if (commonState.getStrict()) {
                if (!PropertiesUtils.checkStrictValue(session, oldValue, newValue)) {
                    if (commonState.getFailOnStrictViolation()) {
                        throw new ManipulationException("Plugin reference {} replacement: {} of original version: {} violates the strict version-alignment rule!", plugin.getId(), newValue, oldValue);
                    } else {
                        logger.warn("Plugin reference {} replacement: {} of original version: {} violates the strict version-alignment rule!", plugin.getId(), newValue, oldValue);
                        // a new property either.
                        continue;
                    }
                }
            }
        }
        logger.debug("Plugin override {} and local plugin {} with remotePluginType {} / localPluginType {}", override.getId(), plugin, remotePluginType, localPluginType);
        if (plugin != null) {
            if (localPluginType == PluginType.LocalPM) {
                if (override.getConfiguration() != null) {
                    logger.debug("Injecting plugin configuration" + override.getConfiguration());
                    if (plugin.getConfiguration() == null) {
                        plugin.setConfiguration(override.getConfiguration());
                        logger.debug("Altered plugin configuration: " + plugin.getKey() + "=" + plugin.getConfiguration());
                    } else if (plugin.getConfiguration() != null) {
                        logger.debug("Existing plugin configuration: " + plugin.getConfiguration());
                        if (!(plugin.getConfiguration() instanceof Xpp3Dom) || !(override.getConfiguration() instanceof Xpp3Dom)) {
                            throw new ManipulationException("Incorrect DOM type " + plugin.getConfiguration().getClass().getName() + " and" + override.getConfiguration().getClass().getName());
                        }
                        if (pluginState.getConfigPrecedence() == Precedence.REMOTE) {
                            plugin.setConfiguration(Xpp3DomUtils.mergeXpp3Dom((Xpp3Dom) override.getConfiguration(), (Xpp3Dom) plugin.getConfiguration()));
                        } else if (pluginState.getConfigPrecedence() == Precedence.LOCAL) {
                            plugin.setConfiguration(Xpp3DomUtils.mergeXpp3Dom((Xpp3Dom) plugin.getConfiguration(), (Xpp3Dom) override.getConfiguration()));
                        }
                        logger.debug("Altered plugin configuration: " + plugin.getKey() + "=" + plugin.getConfiguration());
                    }
                } else {
                    logger.debug("No remote configuration to inject from " + override.toString());
                }
                if (override.getExecutions() != null) {
                    Map<String, PluginExecution> newExecutions = override.getExecutionsAsMap();
                    Map<String, PluginExecution> originalExecutions = plugin.getExecutionsAsMap();
                    for (PluginExecution pe : newExecutions.values()) {
                        if (originalExecutions.containsKey(pe.getId())) {
                            logger.warn("Unable to inject execution " + pe.getId() + " as it clashes with an existing execution");
                        } else {
                            logger.debug("Injecting execution {} ", pe);
                            plugin.getExecutions().add(pe);
                        }
                    }
                } else {
                    logger.debug("No remote executions to inject from " + override.toString());
                }
                if (!override.getDependencies().isEmpty()) {
                    // TODO: ### Review this - is it still required?
                    logger.debug("Checking original plugin dependencies versus override");
                    // First, remove any Dependency from the original Plugin if the GA exists in the override.
                    Iterator<Dependency> originalIt = plugin.getDependencies().iterator();
                    while (originalIt.hasNext()) {
                        Dependency originalD = originalIt.next();
                        Iterator<Dependency> overrideIt = override.getDependencies().iterator();
                        while (overrideIt.hasNext()) {
                            Dependency newD = overrideIt.next();
                            if (originalD.getGroupId().equals(newD.getGroupId()) && originalD.getArtifactId().equals(newD.getArtifactId())) {
                                logger.debug("Removing original dependency {} in favour of {} ", originalD, newD);
                                originalIt.remove();
                                break;
                            }
                        }
                    }
                    // Now merge them together. Only inject dependencies in the management block.
                    logger.debug("Adding in plugin dependencies {}", override.getDependencies());
                    plugin.getDependencies().addAll(override.getDependencies());
                }
            }
            // Explicitly using the original non-resolved original version.
            String oldVersion = plugin.getVersion();
            // will never be null.
            if (!PropertiesUtils.cacheProperty(project, commonState, versionPropertyUpdateMap, oldVersion, newValue, plugin, false)) {
                if (oldVersion != null && oldVersion.equals("${project.version}")) {
                    logger.debug("For plugin {} ; version is built in {} so skipping inlining {}", plugin, oldVersion, newValue);
                } else if (oldVersion != null && oldVersion.contains("${")) {
                    throw new ManipulationException("NYI : Multiple embedded properties for plugins.");
                } else {
                    plugin.setVersion(newValue);
                    logger.info("Altered plugin version: " + override.getKey() + "=" + newValue);
                }
            }
        } else // get the correct config.
        if (remotePluginType == PluginType.RemotePM && localPluginType == PluginType.LocalPM && commonState.getOverrideTransitive() && (override.getConfiguration() != null || override.getExecutions().size() > 0)) {
            project.getModel().getBuild().getPluginManagement().getPlugins().add(override);
            logger.info("Added plugin version: " + override.getKey() + "=" + newValue);
        } else // TODO: Deprecated section.
        if (remotePluginType == PluginType.RemoteP && localPluginType == PluginType.LocalP && pluginState.getInjectRemotePlugins() && (override.getConfiguration() != null || override.getExecutions().size() > 0)) {
            project.getModel().getBuild().getPlugins().add(override);
            logger.info("For non-pluginMgmt, added plugin version : " + override.getKey() + "=" + newValue);
        }
    }
}
Also used : PluginState(org.commonjava.maven.ext.core.state.PluginState) CommonState(org.commonjava.maven.ext.core.state.CommonState) PluginExecution(org.apache.maven.model.PluginExecution) Xpp3Dom(org.codehaus.plexus.util.xml.Xpp3Dom) Dependency(org.apache.maven.model.Dependency) LinkedHashMap(java.util.LinkedHashMap) ProjectVersionRef(org.commonjava.maven.atlas.ident.ref.ProjectVersionRef) ManipulationException(org.commonjava.maven.ext.common.ManipulationException) Plugin(org.apache.maven.model.Plugin)

Example 4 with PluginState

use of org.commonjava.maven.ext.core.state.PluginState in project pom-manipulation-ext by release-engineering.

the class PluginManipulator method init.

/**
 * Initialize the {@link PluginState} state holder in the {@link ManipulationSession}. This state holder detects
 * version-change configuration from the Maven user properties (-D properties from the CLI) and makes it available for
 * later.
 */
@Override
public void init(final ManipulationSession session) throws ManipulationException {
    this.session = session;
    session.setState(new PluginState(session.getUserProperties()));
}
Also used : PluginState(org.commonjava.maven.ext.core.state.PluginState)

Example 5 with PluginState

use of org.commonjava.maven.ext.core.state.PluginState in project pom-manipulation-ext by release-engineering.

the class RESTCollector method collect.

/**
 * Prescans the Project to build up a list of Project GAs and also the various Dependencies.
 */
private void collect(final List<Project> projects) throws ManipulationException {
    final RESTState state = session.getState(RESTState.class);
    final VersioningState vs = session.getState(VersioningState.class);
    final DependencyState ds = session.getState(DependencyState.class);
    final PluginState ps = session.getState(PluginState.class);
    if (!session.isEnabled() || !state.isEnabled()) {
        logger.debug(getClass().getSimpleName() + ": Nothing to do!");
        return;
    }
    final ArrayList<ProjectVersionRef> restParam = new ArrayList<>();
    final ArrayList<ProjectVersionRef> newProjectKeys = new ArrayList<>();
    final String override = vs.getOverride();
    for (final Project project : projects) {
        if (isEmpty(override)) {
            // TODO: Check this : For the rest API I think we need to check every project GA not just inheritance root.
            // Strip SNAPSHOT from the version for matching. DA will handle OSGi conversion.
            ProjectVersionRef newKey = new SimpleProjectVersionRef(project.getKey());
            if (project.getKey().getVersionString().endsWith("-SNAPSHOT")) {
                if (!vs.preserveSnapshot()) {
                    newKey = new SimpleProjectVersionRef(project.getKey().asProjectRef(), project.getKey().getVersionString().substring(0, project.getKey().getVersionString().indexOf("-SNAPSHOT")));
                } else {
                    logger.warn("SNAPSHOT detected for REST call but preserve-snapshots is enabled.");
                }
            }
            newProjectKeys.add(newKey);
        } else if (project.isExecutionRoot()) {
            // We want to manually override the version ; therefore ignore what is in the project and calculate potential
            // matches for that instead.
            Project p = projects.get(0);
            newProjectKeys.add(new SimpleProjectVersionRef(p.getGroupId(), p.getArtifactId(), override));
        }
    }
    restParam.addAll(newProjectKeys);
    // We only recognise dependencyManagement of the form g:a:version-rebuild not g:a:version-rebuild-<numeric>.
    for (ProjectVersionRef bom : (ds.getRemoteBOMDepMgmt() == null ? Collections.<ProjectVersionRef>emptyList() : ds.getRemoteBOMDepMgmt())) {
        if (!Version.hasBuildNumber(bom.getVersionString()) && bom.getVersionString().contains(PropertiesUtils.getSuffix(session))) {
            // Create the dummy PVR to send to DA (which requires a numeric suffix).
            ProjectVersionRef newBom = new SimpleProjectVersionRef(bom.asProjectRef(), bom.getVersionString() + "-0");
            logger.debug("Adding dependencyManagement BOM {} into REST call.", newBom);
            restParam.add(newBom);
        }
    }
    Set<ArtifactRef> localDeps = establishAllDependencies(session, projects, null);
    // Need to send that to the rest interface to get a translation.
    for (ArtifactRef p : localDeps) {
        restParam.add(p.asProjectVersionRef());
    }
    // Call the REST to populate the result.
    logger.debug("Passing {} GAVs following into the REST client api {} ", restParam.size(), restParam);
    logger.info("Calling REST client...");
    long start = System.nanoTime();
    Map<ProjectVersionRef, String> restResult = null;
    try {
        restResult = state.getVersionTranslator().translateVersions(restParam);
    } finally {
        printFinishTime(start, (restResult != null));
    }
    logger.debug("REST Client returned {} ", restResult);
    // Process rest result for boms
    ListIterator<ProjectVersionRef> iterator = (ds.getRemoteBOMDepMgmt() == null ? Collections.<ProjectVersionRef>emptyList().listIterator() : ds.getRemoteBOMDepMgmt().listIterator());
    while (iterator.hasNext()) {
        ProjectVersionRef pvr = iterator.next();
        // As before, only process the BOMs if they are of the format <rebuild suffix> without a numeric portion.
        if (!Version.hasBuildNumber(pvr.getVersionString()) && pvr.getVersionString().contains(PropertiesUtils.getSuffix(session))) {
            // Create the dummy PVR to compare with results to...
            ProjectVersionRef newBom = new SimpleProjectVersionRef(pvr.asProjectRef(), pvr.getVersionString() + "-0");
            if (restResult.keySet().contains(newBom)) {
                ProjectVersionRef replacementBOM = new SimpleProjectVersionRef(pvr.asProjectRef(), restResult.get(newBom));
                logger.debug("Replacing BOM value of {} with {}.", pvr, replacementBOM);
                iterator.remove();
                iterator.add(replacementBOM);
            }
        }
    }
    vs.setRESTMetadata(parseVersions(session, projects, state, newProjectKeys, restResult));
    final Map<ArtifactRef, String> overrides = new HashMap<>();
    // Convert the loaded remote ProjectVersionRefs to the original ArtifactRefs
    for (ArtifactRef a : localDeps) {
        if (restResult.containsKey(a.asProjectVersionRef())) {
            overrides.put(a, restResult.get(a.asProjectVersionRef()));
        }
    }
    logger.debug("Setting REST Overrides {} ", overrides);
    ds.setRemoteRESTOverrides(overrides);
    // Unfortunately as everything is just GAVs we have to send everything to the PluginManipulator as well.
    ps.setRemoteRESTOverrides(overrides);
}
Also used : PluginState(org.commonjava.maven.ext.core.state.PluginState) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) SimpleProjectVersionRef(org.commonjava.maven.atlas.ident.ref.SimpleProjectVersionRef) ArtifactRef(org.commonjava.maven.atlas.ident.ref.ArtifactRef) SimpleScopedArtifactRef(org.commonjava.maven.ext.common.model.SimpleScopedArtifactRef) SimpleArtifactRef(org.commonjava.maven.atlas.ident.ref.SimpleArtifactRef) Project(org.commonjava.maven.ext.common.model.Project) DependencyState(org.commonjava.maven.ext.core.state.DependencyState) ProjectVersionRef(org.commonjava.maven.atlas.ident.ref.ProjectVersionRef) SimpleProjectVersionRef(org.commonjava.maven.atlas.ident.ref.SimpleProjectVersionRef) VersioningState(org.commonjava.maven.ext.core.state.VersioningState) RESTState(org.commonjava.maven.ext.core.state.RESTState)

Aggregations

PluginState (org.commonjava.maven.ext.core.state.PluginState)5 Plugin (org.apache.maven.model.Plugin)3 ProjectVersionRef (org.commonjava.maven.atlas.ident.ref.ProjectVersionRef)3 HashMap (java.util.HashMap)2 LinkedHashMap (java.util.LinkedHashMap)2 LinkedHashSet (java.util.LinkedHashSet)2 Project (org.commonjava.maven.ext.common.model.Project)2 RESTState (org.commonjava.maven.ext.core.state.RESTState)2 ArrayList (java.util.ArrayList)1 HashSet (java.util.HashSet)1 Map (java.util.Map)1 Properties (java.util.Properties)1 Dependency (org.apache.maven.model.Dependency)1 Model (org.apache.maven.model.Model)1 PluginExecution (org.apache.maven.model.PluginExecution)1 Xpp3Dom (org.codehaus.plexus.util.xml.Xpp3Dom)1 ArtifactRef (org.commonjava.maven.atlas.ident.ref.ArtifactRef)1 SimpleArtifactRef (org.commonjava.maven.atlas.ident.ref.SimpleArtifactRef)1 SimpleProjectVersionRef (org.commonjava.maven.atlas.ident.ref.SimpleProjectVersionRef)1 ManipulationException (org.commonjava.maven.ext.common.ManipulationException)1