Search in sources :

Example 1 with CommonState

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

the class DependencyManipulator method applyOverrides.

/**
 * Apply a set of version overrides to a list of dependencies. Return a set of the overrides which were not applied.
 *
 * @param project The current Project
 * @param dependencies The list of dependencies
 * @param explicitOverrides Any explicitOverrides to track for ignoring
 * @param overrides The map of dependency version overrides
 * @return The map of overrides that were not matched in the dependencies
 * @throws ManipulationException if an error occurs
 */
private Map<ArtifactRef, String> applyOverrides(final Project project, final HashMap<ArtifactRef, Dependency> dependencies, final WildcardMap<String> explicitOverrides, final Map<ArtifactRef, String> overrides) throws ManipulationException {
    // Duplicate the override map so unused overrides can be easily recorded
    final Map<ArtifactRef, String> unmatchedVersionOverrides = new LinkedHashMap<>();
    unmatchedVersionOverrides.putAll(overrides);
    if (dependencies == null || dependencies.size() == 0) {
        return unmatchedVersionOverrides;
    }
    final CommonState commonState = session.getState(CommonState.class);
    final boolean strict = commonState.getStrict();
    // Apply matching overrides to dependencies
    for (final ArtifactRef dependency : dependencies.keySet()) {
        ProjectRef depPr = new SimpleProjectRef(dependency.getGroupId(), dependency.getArtifactId());
        // will most likely happen is last-wins.
        for (final Map.Entry<ArtifactRef, String> entry : overrides.entrySet()) {
            ProjectRef groupIdArtifactId = entry.getKey().asProjectRef();
            if (depPr.equals(groupIdArtifactId)) {
                final String oldVersion = dependencies.get(dependency).getVersion();
                final String overrideVersion = entry.getValue();
                final String resolvedValue = dependency.getVersionString();
                if (isEmpty(overrideVersion)) {
                    logger.warn("Unable to align with an empty override version for " + groupIdArtifactId + "; ignoring");
                } else if (isEmpty(oldVersion)) {
                    logger.debug("Dependency is a managed version for " + groupIdArtifactId + "; ignoring");
                } else // By avoiding the potential duplicate work it also avoids a possible property clash problem.
                if (explicitOverrides.containsKey(depPr)) {
                    logger.debug("Dependency {} matches known explicit override so not performing initial override pass.", depPr);
                    unmatchedVersionOverrides.remove(entry.getKey());
                } else // have immediate access to the original property so the closest that is feasible is verify strict matching.
                if (strict && oldVersion.contains("$") && !PropertiesUtils.checkStrictValue(session, resolvedValue, overrideVersion)) {
                    logger.debug("Original fully resolved version {} of {} does not match override version {} -> {} so ignoring", resolvedValue, dependency, entry.getKey(), overrideVersion);
                    if (commonState.getFailOnStrictViolation()) {
                        throw new ManipulationException("For {} replacing original property version {} (fully resolved: {} ) with new version {} for {} violates the strict version-alignment rule!", depPr.toString(), dependencies.get(dependency).getVersion(), resolvedValue, entry.getKey().getVersionString(), entry.getKey().asProjectRef().toString());
                    } else {
                        logger.warn("Replacing original property version {} with new version {} for {} violates the strict version-alignment rule!", resolvedValue, overrideVersion, dependencies.get(dependency).getVersion());
                    }
                } else {
                    // Too much spurious logging with project.version.
                    if (!oldVersion.equals("${project.version}")) {
                        logger.info("Updating version {} for dependency {} from {}.", overrideVersion, dependency, project.getPom());
                    }
                    if (!PropertiesUtils.cacheProperty(project, commonState, versionPropertyUpdateMap, oldVersion, overrideVersion, entry.getKey(), false)) {
                        if (oldVersion.equals("${project.version}")) {
                            logger.debug("For dependency {} ; version is built in {} so skipping inlining {}", groupIdArtifactId, oldVersion, overrideVersion);
                        } else if (strict && !PropertiesUtils.checkStrictValue(session, resolvedValue, overrideVersion)) {
                            if (commonState.getFailOnStrictViolation()) {
                                throw new ManipulationException("Replacing original version {} in dependency {} with new version {} violates the strict version-alignment rule!", oldVersion, groupIdArtifactId.toString(), overrideVersion);
                            } else {
                                logger.warn("Replacing original version {} in dependency {} with new version {} violates the strict version-alignment rule!", oldVersion, groupIdArtifactId, overrideVersion);
                            }
                        } else {
                            logger.debug("Altered dependency {} : {} -> {}", groupIdArtifactId, oldVersion, overrideVersion);
                            if (oldVersion.contains("${")) {
                                String suffix = PropertiesUtils.getSuffix(session);
                                String replaceVersion;
                                if (commonState.getStrictIgnoreSuffix() && oldVersion.contains(suffix)) {
                                    replaceVersion = StringUtils.substringBefore(oldVersion, suffix);
                                    replaceVersion += suffix + StringUtils.substringAfter(overrideVersion, suffix);
                                } else {
                                    replaceVersion = oldVersion + StringUtils.removeStart(overrideVersion, resolvedValue);
                                }
                                logger.debug("Resolved value is {} and replacement version is {} ", resolvedValue, replaceVersion);
                                // In this case the previous value couldn't be cached even though it contained a property
                                // as it was either multiple properties or a property combined with a hardcoded value. Therefore
                                // just append the suffix.
                                dependencies.get(dependency).setVersion(replaceVersion);
                            } else {
                                dependencies.get(dependency).setVersion(overrideVersion);
                            }
                        }
                    }
                    unmatchedVersionOverrides.remove(entry.getKey());
                }
            }
        }
    }
    return unmatchedVersionOverrides;
}
Also used : CommonState(org.commonjava.maven.ext.core.state.CommonState) SimpleProjectRef(org.commonjava.maven.atlas.ident.ref.SimpleProjectRef) ManipulationException(org.commonjava.maven.ext.common.ManipulationException) SimpleProjectRef(org.commonjava.maven.atlas.ident.ref.SimpleProjectRef) ProjectRef(org.commonjava.maven.atlas.ident.ref.ProjectRef) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) WildcardMap(org.commonjava.maven.ext.core.util.WildcardMap) ArtifactRef(org.commonjava.maven.atlas.ident.ref.ArtifactRef) SimpleArtifactRef(org.commonjava.maven.atlas.ident.ref.SimpleArtifactRef) LinkedHashMap(java.util.LinkedHashMap)

Example 2 with CommonState

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

the class PropertiesUtilsTest method testCacheProperty.

@Test
public void testCacheProperty() throws Exception {
    Map<Project, Map<String, String>> propertyMap = new HashMap<>();
    CommonState state = new CommonState(new Properties());
    Project project = getProject();
    assertFalse(PropertiesUtils.cacheProperty(project, state, propertyMap, "${foobar}${foobar2}", null, null, false));
    assertFalse(PropertiesUtils.cacheProperty(project, state, propertyMap, "suffix.${foobar}", null, null, false));
    assertFalse(PropertiesUtils.cacheProperty(project, state, propertyMap, null, "2.0", null, false));
    assertFalse(PropertiesUtils.cacheProperty(project, state, propertyMap, "1.0", "2.0", null, false));
    assertTrue(PropertiesUtils.cacheProperty(project, state, propertyMap, "${version.org.jboss}", "2.0", null, false));
    assertFalse(PropertiesUtils.cacheProperty(project, state, propertyMap, "${project.version}", "2.0", null, false));
    // DependencyManipulator does dependency.getVersion(). This could return e.g. ${version.scala} which can
    // refer to <version.scala>${version.scala.major}.7</version.scala>. If we are attempting to change version.scala
    // to e.g. 2.11.7.redhat-1 then in this case we need to ignore the version.scala.major property and append the .redhat-1.
    // If the property is ${...}.foobar then we only want to append suffix to foobar to change the version
    // However we don't need to change the value of the property. If the property is foobar.${....} then
    // we want to append suffix to the property ... but we need to handle that part of the property is hardcoded.
    assertFalse(PropertiesUtils.cacheProperty(project, state, propertyMap, "${version.scala}.7", "2.0", null, false));
    assertFalse(PropertiesUtils.cacheProperty(project, state, propertyMap, "${version.foo}.${version.scala}.7", "2.0", null, false));
    try {
        PropertiesUtils.cacheProperty(project, state, propertyMap, "${version.scala}.7.${version.scala2}", "2.0", null, false);
    } catch (ManipulationException e) {
    // Pass.
    }
}
Also used : CommonState(org.commonjava.maven.ext.core.state.CommonState) Project(org.commonjava.maven.ext.common.model.Project) HashMap(java.util.HashMap) ManipulationException(org.commonjava.maven.ext.common.ManipulationException) PropertiesUtils.updateProperties(org.commonjava.maven.ext.core.util.PropertiesUtils.updateProperties) Properties(java.util.Properties) HashMap(java.util.HashMap) Map(java.util.Map) Test(org.junit.Test)

Example 3 with CommonState

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

the class ManipulationManager method init.

/**
 * Initialize {@link ManipulationSession} using the given {@link MavenSession} instance, along with any state managed by the individual
 * {@link Manipulator} components.
 *
 * @param session the container session for manipulation.
 * @throws ManipulationException if an error occurs.
 */
public void init(final ManipulationSession session) throws ManipulationException {
    logger.debug("Initialising ManipulationManager with user properties {}", session.getUserProperties());
    for (final ExtensionInfrastructure infra : infrastructure.values()) {
        infra.init(session.getTargetDir(), session.getRemoteRepositories(), session.getLocalRepository(), session.getSettings(), session.getActiveProfiles());
    }
    orderedManipulators = new ArrayList<>(manipulators.values());
    // The RESTState depends upon the VersionState being initialised. Therefore initialise in reverse order
    // and do a final sort to run in the correct order. See the Manipulator interface for detailed discussion
    // on ordered.
    Collections.sort(orderedManipulators, Collections.reverseOrder(new ManipulatorPriorityComparator()));
    for (final Manipulator manipulator : orderedManipulators) {
        logger.debug("Initialising manipulator " + manipulator.getClass().getSimpleName());
        manipulator.init(session);
    }
    Collections.sort(orderedManipulators, new ManipulatorPriorityComparator());
    // Now init the common state
    session.setState(new CommonState(session.getUserProperties()));
}
Also used : CommonState(org.commonjava.maven.ext.core.state.CommonState) ExtensionInfrastructure(org.commonjava.maven.ext.io.resolver.ExtensionInfrastructure) ManipulatorPriorityComparator(org.commonjava.maven.ext.core.util.ManipulatorPriorityComparator) Manipulator(org.commonjava.maven.ext.core.impl.Manipulator)

Example 4 with CommonState

use of org.commonjava.maven.ext.core.state.CommonState 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 5 with CommonState

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

the class PropertiesUtils method internalUpdateProperty.

private static PropertyUpdate internalUpdateProperty(ManipulationSession session, Project p, boolean ignoreStrict, String key, String newValue, String resolvedValue, Properties props) throws ManipulationException {
    final CommonState state = session.getState(CommonState.class);
    final String oldValue = props.getProperty(key);
    logger.info("Updating property {} / {} with {} ", key, oldValue, newValue);
    PropertyUpdate found = PropertyUpdate.FOUND;
    // update it with a portion of the new value.
    if (oldValue != null && oldValue.startsWith("${") && oldValue.endsWith("}") && !(StringUtils.countMatches(oldValue, "${") > 1)) {
        logger.debug("Recursively resolving {} ", oldValue.substring(2, oldValue.length() - 1));
        if (updateProperties(session, p, ignoreStrict, oldValue.substring(2, oldValue.length() - 1), newValue) == PropertyUpdate.NOTFOUND) {
            logger.error("Recursive property not found for {} with {} ", oldValue, newValue);
            return PropertyUpdate.NOTFOUND;
        }
    } else {
        if (state.getStrict() && !ignoreStrict) {
            if (!checkStrictValue(session, resolvedValue, newValue)) {
                if (state.getFailOnStrictViolation()) {
                    throw new ManipulationException("Replacing original property version {} (fully resolved: {} ) with new version {} for {} violates the strict version-alignment rule!", oldValue, resolvedValue, newValue, key);
                } else {
                    logger.warn("Replacing original property version {} with new version {} for {} violates the strict version-alignment rule!", oldValue, newValue, key);
                    // a new property either.
                    return found;
                }
            }
        }
        // TODO: Does not handle explicit overrides.
        if (oldValue != null && oldValue.contains("${") && !(oldValue.startsWith("${") && oldValue.endsWith("}")) || (StringUtils.countMatches(oldValue, "${") > 1)) {
            if (ignoreStrict) {
                throw new ManipulationException("NYI : handling for versions with explicit overrides (" + oldValue + ") with multiple embedded properties is NYI. ");
            }
            if (resolvedValue.equals(newValue)) {
                logger.warn("Nothing to update as original key {} value matches new value {} ", key, newValue);
                found = PropertyUpdate.IGNORE;
            }
            newValue = oldValue + StringUtils.removeStart(newValue, resolvedValue);
            logger.info("Ignoring new value due to embedded property {} and appending {} ", oldValue, newValue);
        }
        props.setProperty(key, newValue);
    }
    return found;
}
Also used : CommonState(org.commonjava.maven.ext.core.state.CommonState) ManipulationException(org.commonjava.maven.ext.common.ManipulationException)

Aggregations

CommonState (org.commonjava.maven.ext.core.state.CommonState)9 ManipulationException (org.commonjava.maven.ext.common.ManipulationException)5 HashMap (java.util.HashMap)3 LinkedHashMap (java.util.LinkedHashMap)3 Map (java.util.Map)3 VersioningState (org.commonjava.maven.ext.core.state.VersioningState)3 Properties (java.util.Properties)2 Dependency (org.apache.maven.model.Dependency)2 ArtifactRef (org.commonjava.maven.atlas.ident.ref.ArtifactRef)2 SimpleArtifactRef (org.commonjava.maven.atlas.ident.ref.SimpleArtifactRef)2 DependencyState (org.commonjava.maven.ext.core.state.DependencyState)2 WildcardMap (org.commonjava.maven.ext.core.util.WildcardMap)2 ArrayList (java.util.ArrayList)1 HashSet (java.util.HashSet)1 DefaultMavenExecutionRequest (org.apache.maven.execution.DefaultMavenExecutionRequest)1 DefaultMavenExecutionResult (org.apache.maven.execution.DefaultMavenExecutionResult)1 MavenExecutionRequest (org.apache.maven.execution.MavenExecutionRequest)1 MavenSession (org.apache.maven.execution.MavenSession)1 DependencyManagement (org.apache.maven.model.DependencyManagement)1 Plugin (org.apache.maven.model.Plugin)1