use of org.gradle.internal.graph.DirectedGraphRenderer in project gradle by gradle.
the class DefaultTaskExecutionPlan method onOrderingCycle.
private void onOrderingCycle() {
CachingDirectedGraphWalker<TaskInfo, Void> graphWalker = new CachingDirectedGraphWalker<TaskInfo, Void>(new DirectedGraph<TaskInfo, Void>() {
public void getNodeValues(TaskInfo node, Collection<? super Void> values, Collection<? super TaskInfo> connectedNodes) {
connectedNodes.addAll(node.getDependencySuccessors());
connectedNodes.addAll(node.getMustSuccessors());
}
});
graphWalker.add(entryTasks);
final List<TaskInfo> firstCycle = new ArrayList<TaskInfo>(graphWalker.findCycles().get(0));
Collections.sort(firstCycle);
DirectedGraphRenderer<TaskInfo> graphRenderer = new DirectedGraphRenderer<TaskInfo>(new GraphNodeRenderer<TaskInfo>() {
public void renderTo(TaskInfo node, StyledTextOutput output) {
output.withStyle(StyledTextOutput.Style.Identifier).text(node.getTask().getIdentityPath());
}
}, new DirectedGraph<TaskInfo, Object>() {
public void getNodeValues(TaskInfo node, Collection<? super Object> values, Collection<? super TaskInfo> connectedNodes) {
for (TaskInfo dependency : firstCycle) {
if (node.getDependencySuccessors().contains(dependency) || node.getMustSuccessors().contains(dependency)) {
connectedNodes.add(dependency);
}
}
}
});
StringWriter writer = new StringWriter();
graphRenderer.renderTo(firstCycle.get(0), writer);
throw new CircularReferenceException(String.format("Circular dependency between the following tasks:%n%s", writer.toString()));
}
use of org.gradle.internal.graph.DirectedGraphRenderer in project gradle by gradle.
the class NativeDependentBinariesResolutionStrategy method onCircularDependencies.
private void onCircularDependencies(final State state, final Deque<NativeBinarySpecInternal> stack, NativeBinarySpecInternal target) {
GraphNodeRenderer<NativeBinarySpecInternal> nodeRenderer = new GraphNodeRenderer<NativeBinarySpecInternal>() {
@Override
public void renderTo(NativeBinarySpecInternal node, StyledTextOutput output) {
String name = DependentComponentsUtils.getBuildScopedTerseName(node.getId());
output.withStyle(StyledTextOutput.Style.Identifier).text(name);
}
};
DirectedGraph<NativeBinarySpecInternal, Object> directedGraph = new DirectedGraph<NativeBinarySpecInternal, Object>() {
@Override
public void getNodeValues(NativeBinarySpecInternal node, Collection<? super Object> values, Collection<? super NativeBinarySpecInternal> connectedNodes) {
for (NativeBinarySpecInternal binary : stack) {
if (state.getDependents(node).contains(binary)) {
connectedNodes.add(binary);
}
}
}
};
DirectedGraphRenderer<NativeBinarySpecInternal> graphRenderer = new DirectedGraphRenderer<NativeBinarySpecInternal>(nodeRenderer, directedGraph);
StringWriter writer = new StringWriter();
graphRenderer.renderTo(target, writer);
throw new CircularReferenceException(String.format("Circular dependency between the following binaries:%n%s", writer.toString()));
}
use of org.gradle.internal.graph.DirectedGraphRenderer in project gradle by gradle.
the class DefaultBuildController method checkForCyclesFor.
private void checkForCyclesFor(TaskInternal task, Set<TaskInternal> visited, Set<TaskInternal> visiting) {
if (visited.contains(task)) {
// Already checked
return;
}
if (!visiting.add(task)) {
// Visiting dependencies -> have found a cycle
CachingDirectedGraphWalker<TaskInternal, Void> graphWalker = new CachingDirectedGraphWalker<>((node, values, connectedNodes) -> visitDependenciesOf(node, connectedNodes::add));
graphWalker.add(task);
List<Set<TaskInternal>> cycles = graphWalker.findCycles();
Set<TaskInternal> cycle = cycles.get(0);
DirectedGraphRenderer<TaskInternal> graphRenderer = new DirectedGraphRenderer<>((node, output) -> output.withStyle(StyledTextOutput.Style.Identifier).text(node.getIdentityPath()), (node, values, connectedNodes) -> visitDependenciesOf(node, dep -> {
if (cycle.contains(dep)) {
connectedNodes.add(dep);
}
}));
StringWriter writer = new StringWriter();
graphRenderer.renderTo(task, writer);
throw new CircularReferenceException(String.format("Circular dependency between the following tasks:%n%s", writer));
}
visitDependenciesOf(task, dep -> checkForCyclesFor(dep, visited, visiting));
visiting.remove(task);
visited.add(task);
}
use of org.gradle.internal.graph.DirectedGraphRenderer in project gradle by gradle.
the class DefaultExecutionPlan method onOrderingCycle.
private void onOrderingCycle(Node successor, Node currentNode) {
CachingDirectedGraphWalker<Node, Void> graphWalker = new CachingDirectedGraphWalker<>((node, values, connectedNodes) -> {
connectedNodes.addAll(node.getDependencySuccessors());
if (node instanceof TaskNode) {
TaskNode taskNode = (TaskNode) node;
connectedNodes.addAll(taskNode.getMustSuccessors());
connectedNodes.addAll(taskNode.getFinalizingSuccessors());
}
});
graphWalker.add(successor);
List<Set<Node>> cycles = graphWalker.findCycles();
if (cycles.isEmpty()) {
// https://github.com/gradle/gradle/issues/2293
throw new GradleException("Misdetected cycle between " + currentNode + " and " + successor + ". Help us by reporting this to https://github.com/gradle/gradle/issues/2293");
}
List<Node> firstCycle = new ArrayList<>(cycles.get(0));
Collections.sort(firstCycle);
DirectedGraphRenderer<Node> graphRenderer = new DirectedGraphRenderer<>((it, output) -> output.withStyle(StyledTextOutput.Style.Identifier).text(it), (it, values, connectedNodes) -> {
for (Node dependency : firstCycle) {
if (it.hasHardSuccessor(dependency)) {
connectedNodes.add(dependency);
}
}
});
StringWriter writer = new StringWriter();
graphRenderer.renderTo(firstCycle.get(0), writer);
throw new CircularReferenceException(String.format("Circular dependency between the following tasks:%n%s", writer.toString()));
}
Aggregations