public void removeOutgoingEdges() { for (DependencyEdge outgoingDependency : outgoingEdges) { outgoingDependency.removeFromTargetConfigurations(); } outgoingEdges.clear(); previousTraversal = null; }
public void visitOutgoingDependencies(Collection<DependencyEdge> target) { // If this configuration's version is in conflict, don't do anything // If not traversed before, add all selected outgoing edges // If traversed before, and the selected modules have changed, remove previous outgoing edges // and add outgoing edges again with // the new selections. // If traversed before, and the selected modules have not changed, ignore // If none of the incoming edges are transitive, then the node has no outgoing edges if (moduleRevision.state != ModuleState.Selected) { LOGGER.debug("version for {} is not selected. ignoring.", this); return; } List<DependencyEdge> transitiveIncoming = new ArrayList<DependencyEdge>(); for (DependencyEdge edge : incomingEdges) { if (edge.isTransitive()) { transitiveIncoming.add(edge); } } if (transitiveIncoming.isEmpty() && this != resolveState.root) { if (previousTraversal != null) { removeOutgoingEdges(); } if (incomingEdges.isEmpty()) { LOGGER.debug("{} has no incoming edges. ignoring.", this); } else { LOGGER.debug("{} has no transitive incoming edges. ignoring outgoing edges.", this); } return; } ModuleResolutionFilter resolutionFilter = getSelector(transitiveIncoming); if (previousTraversal != null) { if (previousTraversal.acceptsSameModulesAs(resolutionFilter)) { LOGGER.debug( "Changed edges for {} selects same versions as previous traversal. ignoring", this); // Don't need to traverse again, but hang on to the new filter as the set of artifact may // have changed previousTraversal = resolutionFilter; return; } removeOutgoingEdges(); } for (DependencyMetaData dependency : metaData.getDependencies()) { ModuleIdentifier targetModuleId = DefaultModuleIdentifier.newId( dependency.getRequested().getGroup(), dependency.getRequested().getName()); if (isExcluded(resolutionFilter, targetModuleId)) { continue; } DependencyEdge dependencyEdge = new DependencyEdge(this, dependency, resolutionFilter, resolveState); outgoingEdges.add(dependencyEdge); target.add(dependencyEdge); } previousTraversal = resolutionFilter; }
public void visitOutgoingDependencies(Collection<DependencyEdge> target) { // If this configuration's version is in conflict, don't do anything // If not traversed before, add all selected outgoing edges // If traversed before, and the selected modules have changed, remove previous outgoing edges // and add outgoing edges again with // the new selections. // If traversed before, and the selected modules have not changed, ignore // If none of the incoming edges are transitive, then the node has no outgoing edges if (moduleRevision.state != ModuleState.Selected) { LOGGER.debug("version for {} is not selected. ignoring.", this); return; } List<DependencyEdge> transitiveIncoming = new ArrayList<DependencyEdge>(); for (DependencyEdge edge : incomingEdges) { if (edge.isTransitive()) { transitiveIncoming.add(edge); } } if (transitiveIncoming.isEmpty() && this != resolveState.root) { if (previousTraversal != null) { removeOutgoingEdges(); } if (incomingEdges.isEmpty()) { LOGGER.debug("{} has no incoming edges. ignoring.", this); } else { LOGGER.debug("{} has no transitive incoming edges. ignoring outgoing edges.", this); } return; } ModuleVersionSpec selectorSpec = getSelector(transitiveIncoming); if (previousTraversal != null) { if (previousTraversal.acceptsSameModulesAs(selectorSpec)) { LOGGER.debug( "Changed edges for {} selects same versions as previous traversal. ignoring", this); return; } removeOutgoingEdges(); } for (DependencyMetaData dependency : metaData.getDependencies()) { DependencyDescriptor dependencyDescriptor = dependency.getDescriptor(); ModuleId targetModuleId = dependencyDescriptor.getDependencyRevisionId().getModuleId(); if (!selectorSpec.isSatisfiedBy(targetModuleId)) { LOGGER.debug("{} is excluded from {}.", targetModuleId, this); continue; } DependencyEdge dependencyEdge = new DependencyEdge(this, dependency, selectorSpec, resolveState); outgoingEdges.add(dependencyEdge); target.add(dependencyEdge); } previousTraversal = selectorSpec; }
public void restart(ModuleVersionResolveState selected) { select(selected); for (ModuleVersionResolveState version : versions.values()) { version.restart(selected); } for (DependencyEdge dependency : new ArrayList<DependencyEdge>(unattachedDependencies)) { dependency.restart(selected); } unattachedDependencies.clear(); }
public void restart(ModuleVersionResolveState selected) { // Restarting this configuration after conflict resolution. // If this configuration belongs to the select version, queue ourselves up for traversal. // If not, then move our incoming edges across to the selected configuration if (moduleRevision == selected) { resolveState.onMoreSelected(this); } else { for (DependencyEdge dependency : incomingEdges) { dependency.restart(selected); } incomingEdges.clear(); } }
private ModuleVersionSpec getSelector(List<DependencyEdge> transitiveEdges) { ModuleVersionSpec selector; if (transitiveEdges.isEmpty()) { selector = ModuleVersionSpec.forExcludes(); // includes all } else { selector = transitiveEdges.get(0).getSelector(); for (int i = 1; i < transitiveEdges.size(); i++) { DependencyEdge dependencyEdge = transitiveEdges.get(i); selector = selector.union(dependencyEdge.getSelector()); } } selector = selector.intersect(ModuleVersionSpec.forExcludes(metaData.getExcludeRules())); return selector; }
private ModuleResolutionFilter getSelector(List<DependencyEdge> transitiveEdges) { ModuleResolutionFilter resolutionFilter; if (transitiveEdges.isEmpty()) { resolutionFilter = DefaultModuleResolutionFilter.all(); } else { resolutionFilter = transitiveEdges.get(0).getSelector(); for (int i = 1; i < transitiveEdges.size(); i++) { DependencyEdge dependencyEdge = transitiveEdges.get(i); resolutionFilter = resolutionFilter.union(dependencyEdge.getSelector()); } } resolutionFilter = resolutionFilter.intersect( DefaultModuleResolutionFilter.excludeAny(metaData.getExcludeRules())); return resolutionFilter; }
public void collectFailures(FailureState failureState) { for (DependencyEdge dependency : outgoingEdges) { dependency.collectFailures(failureState); } }
public void attachToParents(ResolvedConfigurationBuilder result) { LOGGER.debug("Attaching {} to its parents.", this); for (DependencyEdge dependency : incomingEdges) { dependency.attachToParents(this, result); } }
/** * Traverses the dependency graph, resolving conflicts and building the paths from the root * configuration. */ private void traverseGraph(ResolveState resolveState) { Set<ModuleIdentifier> conflicts = new LinkedHashSet<ModuleIdentifier>(); resolveState.onMoreSelected(resolveState.root); List<DependencyEdge> dependencies = new ArrayList<DependencyEdge>(); while (resolveState.peek() != null || !conflicts.isEmpty()) { if (resolveState.peek() != null) { ConfigurationNode node = resolveState.pop(); LOGGER.debug("Visiting configuration {}.", node); // Calculate the outgoing edges of this configuration dependencies.clear(); node.visitOutgoingDependencies(dependencies); for (DependencyEdge dependency : dependencies) { LOGGER.debug("Visiting dependency {}", dependency); // Resolve dependency to a particular revision ModuleVersionResolveState moduleRevision = dependency.resolveModuleRevisionId(); if (moduleRevision == null) { // Failed to resolve. continue; } ModuleIdentifier moduleId = moduleRevision.id.getModule(); // Check for a new conflict if (moduleRevision.state == ModuleState.New) { ModuleResolveState module = resolveState.getModule(moduleId); // A new module revision. Check for conflict Collection<ModuleVersionResolveState> versions = module.getVersions(); if (versions.size() == 1) { // First version of this module. Select it for now LOGGER.debug("Selecting new module version {}", moduleRevision); module.select(moduleRevision); } else { // Not the first version of this module. We have a new conflict LOGGER.debug("Found new conflicting module version {}", moduleRevision); conflicts.add(moduleId); // Deselect the currently selected version, and remove all outgoing edges from the // version // This will propagate through the graph and prune configurations that are no longer // required ModuleVersionResolveState previouslySelected = module.clearSelection(); if (previouslySelected != null) { for (ConfigurationNode configuration : previouslySelected.configurations) { configuration.removeOutgoingEdges(); } } } } dependency.attachToTargetConfigurations(); } } else { // We have some batched up conflicts. Resolve the first, and continue traversing the graph ModuleIdentifier moduleId = conflicts.iterator().next(); conflicts.remove(moduleId); ModuleResolveState module = resolveState.getModule(moduleId); ModuleVersionResolveState selected = conflictResolver.select(module.getVersions(), resolveState.root.moduleRevision); LOGGER.debug("Selected {} from conflicting modules {}.", selected, module.getVersions()); // Restart each configuration. For the evicted configuration, this means moving incoming // dependencies across to the // matching selected configuration. For the select configuration, this mean traversing its // dependencies. module.restart(selected); } } }
/** * Traverses the dependency graph, resolving conflicts and building the paths from the root * configuration. */ private void traverseGraph( final ResolveState resolveState, final ConflictHandler conflictHandler) { resolveState.onMoreSelected(resolveState.root); List<DependencyEdge> dependencies = new ArrayList<DependencyEdge>(); while (resolveState.peek() != null || conflictHandler.hasConflicts()) { if (resolveState.peek() != null) { ConfigurationNode node = resolveState.pop(); LOGGER.debug("Visiting configuration {}.", node); // Calculate the outgoing edges of this configuration dependencies.clear(); node.visitOutgoingDependencies(dependencies); for (DependencyEdge dependency : dependencies) { LOGGER.debug("Visiting dependency {}", dependency); // Resolve dependency to a particular revision ModuleVersionResolveState moduleRevision = dependency.resolveModuleRevisionId(); if (moduleRevision == null) { // Failed to resolve. continue; } ModuleIdentifier moduleId = moduleRevision.id.getModule(); // Check for a new conflict if (moduleRevision.state == ModuleState.New) { ModuleResolveState module = resolveState.getModule(moduleId); // A new module revision. Check for conflict PotentialConflict c = conflictHandler.registerModule(module); if (!c.conflictExists()) { // No conflict. Select it for now LOGGER.debug("Selecting new module version {}", moduleRevision); module.select(moduleRevision); } else { // We have a conflict LOGGER.debug("Found new conflicting module version {}", moduleRevision); // Deselect the currently selected version, and remove all outgoing edges from the // version // This will propagate through the graph and prune configurations that are no longer // required // For each module participating in the conflict (many times there is only one // participating module that has multiple versions) c.withParticipatingModules( new Action<ModuleIdentifier>() { public void execute(ModuleIdentifier module) { ModuleVersionResolveState previouslySelected = resolveState.getModule(module).clearSelection(); if (previouslySelected != null) { for (ConfigurationNode configuration : previouslySelected.configurations) { configuration.deselect(); } } } }); } } dependency.attachToTargetConfigurations(); } } else { // We have some batched up conflicts. Resolve the first, and continue traversing the graph conflictHandler.resolveNextConflict( new Action<ConflictResolutionResult>() { public void execute(final ConflictResolutionResult result) { result .getConflict() .withParticipatingModules( new Action<ModuleIdentifier>() { public void execute(ModuleIdentifier moduleIdentifier) { ModuleVersionResolveState selected = result.getSelected(); // Restart each configuration. For the evicted configuration, this means // moving incoming dependencies across to the // matching selected configuration. For the select configuration, this // mean traversing its dependencies. resolveState.getModule(moduleIdentifier).restart(selected); } }); } }); } } }