Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Option to allow setting a progress tracker prefix when inspecting dependencies #314

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,15 @@ public static DependencyTreeInspector configure() {
private MavenArtifactResolver resolver;
private boolean resolveDependencies;
private DependencyTreeBuilder treeBuilder;
private DependencyTreeVisitor<?> treeVisitor;
private DependencyTreeVisitor<?> visitor;
private boolean parallelProcessing;
private MessageWriter log;
private List<DependencyTreeRequest> roots = new ArrayList<>();
private String progressTrackerPrefix;

private DependencyTreeInspector() {
}

public DependencyTreeInspector setTreeBuilder(DependencyTreeBuilder treeBuilder) {
this.treeBuilder = treeBuilder;
return this;
}

public DependencyTreeInspector setArtifactResolver(MavenArtifactResolver resolver) {
this.resolver = resolver;
return this;
Expand All @@ -49,8 +45,13 @@ public DependencyTreeInspector setResolveDependencies(boolean resolveDependencie
return this;
}

public DependencyTreeInspector setTreeBuilder(DependencyTreeBuilder treeBuilder) {
this.treeBuilder = treeBuilder;
return this;
}

public DependencyTreeInspector setTreeVisitor(DependencyTreeVisitor<?> treeVisitor) {
this.treeVisitor = treeVisitor;
this.visitor = treeVisitor;
return this;
}

Expand Down Expand Up @@ -95,6 +96,11 @@ public DependencyTreeInspector inspect(DependencyTreeRequest request) {
return this;
}

public DependencyTreeInspector setProgressTrackerPrefix(String progressTrackerPrefix) {
this.progressTrackerPrefix = progressTrackerPrefix;
return this;
}

public void complete() {

if (resolver == null) {
Expand Down Expand Up @@ -131,8 +137,8 @@ public void complete() {
log = MessageWriter.info();
}

if (treeVisitor == null) {
treeVisitor = new DependencyTreeVisitor<>() {
if (visitor == null) {
visitor = new DependencyTreeVisitor<>() {
@Override
public void visit(DependencyTreeVisit<Object> ctx) {
}
Expand All @@ -148,15 +154,19 @@ public void handleResolutionFailures(Collection<DependencyTreeError> requests) {
}

var scheduler = parallelProcessing
? DependencyTreeVisitScheduler.parallel(treeBuilder, treeVisitor, log, roots.size())
: DependencyTreeVisitScheduler.sequential(treeBuilder, treeVisitor, log, roots.size());
? new ParallelTreeVisitScheduler<>(
new DependencyTreeVisitContext<>(visitor, log),
roots.size(), treeBuilder, progressTrackerPrefix)
: new SequentialTreeVisitScheduler<>(
new DependencyTreeVisitContext<>(visitor, log),
roots.size(), treeBuilder, progressTrackerPrefix);

for (var r : roots) {
scheduler.process(r);
}
scheduler.waitForCompletion();
if (!scheduler.getResolutionFailures().isEmpty()) {
treeVisitor.handleResolutionFailures(scheduler.getResolutionFailures());
visitor.handleResolutionFailures(scheduler.getResolutionFailures());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.util.Collection;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import org.eclipse.aether.artifact.Artifact;
import org.eclipse.aether.graph.Dependency;
import org.eclipse.aether.graph.Exclusion;
Expand Down Expand Up @@ -32,6 +33,10 @@ public static DependencyTreeRequest ofPlugin(Artifact artifact, Collection<Exclu
return new DependencyTreeRequest(artifact, List.of(), exclusions, PLUGIN);
}

// this is not the best idea but it'll work for now
private static final AtomicInteger counter = new AtomicInteger();

private final Integer id;
private final Artifact root;
private final List<Dependency> constraints;
private final Collection<Exclusion> exclusions;
Expand All @@ -42,10 +47,11 @@ private DependencyTreeRequest(Artifact root, List<Dependency> constraints, Colle
this.constraints = constraints;
this.exclusions = exclusions;
this.type = type;
id = counter.incrementAndGet();
}

String getId() {
return root.toString();
Integer getId() {
return id;
}

public Artifact getArtifact() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@

class DependencyTreeVisitContext<E> implements DependencyTreeVisitor.DependencyTreeVisit<E> {

private final DependencyTreeVisitor<E> visitor;
private final MessageWriter log;
final DependencyTreeVisitor<E> visitor;
final MessageWriter log;
DependencyNode root;

DependencyTreeVisitContext(DependencyTreeVisitor<E> visitor, MessageWriter log) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,9 @@
package io.quarkus.domino.inspect;

import io.quarkus.devtools.messagewriter.MessageWriter;
import java.util.Collection;

public interface DependencyTreeVisitScheduler {

static <E> DependencyTreeVisitScheduler sequential(DependencyTreeBuilder treeBuilder,
DependencyTreeVisitor<E> visitor,
MessageWriter log,
int treesTotal) {
return new SequentialTreeVisitScheduler<>(visitor, log, treesTotal, treeBuilder);
}

static <E> DependencyTreeVisitScheduler parallel(DependencyTreeBuilder treeBuilder,
DependencyTreeVisitor<E> visitor,
MessageWriter log,
int treesTotal) {
return new ParallelTreeVisitScheduler<>(visitor, log, treesTotal, treeBuilder);
}

void process(DependencyTreeRequest root);

void waitForCompletion();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package io.quarkus.domino.inspect;

import io.quarkus.devtools.messagewriter.MessageWriter;
import java.util.ArrayList;
import java.util.Formatter;
import java.util.List;
Expand All @@ -15,10 +14,12 @@ abstract class DependencyTreeVisitSchedulerBase<E> implements DependencyTreeVisi
protected final DependencyTreeVisitContext<E> ctx;
protected final AtomicInteger counter = new AtomicInteger();
protected final int rootsTotal;
private final String progressTrackerPrefix;

DependencyTreeVisitSchedulerBase(DependencyTreeVisitor<E> visitor, MessageWriter log, int rootsTotal) {
ctx = new DependencyTreeVisitContext<>(visitor, log);
DependencyTreeVisitSchedulerBase(DependencyTreeVisitContext<E> ctx, int rootsTotal, String progressTrackerPrefix) {
this.ctx = ctx;
this.rootsTotal = rootsTotal;
this.progressTrackerPrefix = progressTrackerPrefix;
}

@Override
Expand All @@ -27,12 +28,15 @@ public List<DependencyTreeError> getResolutionFailures() {
}

protected String getResolvedTreeMessage(Artifact a) {
var sb = new StringBuilder(160);
var sb = new StringBuilder(180);
var formatter = new Formatter(sb);
var treeIndex = counter.incrementAndGet();
final double percents = ((double) treeIndex * 100) / rootsTotal;

formatter.format(FORMAT_BASE, treeIndex, rootsTotal, percents);
if (progressTrackerPrefix != null) {
sb.append(progressTrackerPrefix);
}

sb.append(a.getGroupId()).append(':').append(a.getArtifactId()).append(':');
if (!a.getClassifier().isEmpty()) {
Expand All @@ -47,10 +51,14 @@ protected String getResolvedTreeMessage(Artifact a) {
return sb.append(a.getVersion()).toString();
}

protected String formatErrorMessage(DependencyTreeRequest request, Exception e) {
protected String formatErrorMessage(DependencyTreeRequest request, Throwable e) {
var sb = new StringBuilder();
sb.append("Failed to process dependencies of ").append(request.getArtifact());
if (e != null) {
if (e.getCause() != null) {
// the outer one is most probably a tree processing wrapper of the actual one thrown by the resolver
e = e.getCause();
}
var error = e.getLocalizedMessage();
sb.append(" because ").append(Character.toLowerCase(error.charAt(0))).append(error.substring(1));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package io.quarkus.domino.inspect;

import io.quarkus.devtools.messagewriter.MessageWriter;
import io.quarkus.domino.processor.ExecutionContext;
import io.quarkus.domino.processor.NodeProcessor;
import io.quarkus.domino.processor.ParallelTreeProcessor;
Expand All @@ -9,34 +8,30 @@
import java.util.function.Function;
import org.eclipse.aether.graph.DependencyNode;

public class ParallelTreeVisitScheduler<E> extends DependencyTreeVisitSchedulerBase<E> {
class ParallelTreeVisitScheduler<E> extends DependencyTreeVisitSchedulerBase<E> {

final ParallelTreeProcessor<String, DependencyTreeRequest, DependencyNode> treeProcessor;
private final DependencyTreeVisitor<E> visitor;
private final MessageWriter log;
final ParallelTreeProcessor<Integer, DependencyTreeRequest, DependencyNode> treeProcessor;

public ParallelTreeVisitScheduler(DependencyTreeVisitor<E> visitor, MessageWriter log, int treesTotal,
DependencyTreeBuilder treeBuilder) {
super(visitor, log, treesTotal);
this.visitor = visitor;
this.log = log;
ParallelTreeVisitScheduler(DependencyTreeVisitContext<E> ctx, int treesTotal,
DependencyTreeBuilder treeBuilder, String progressTrackerPrefix) {
super(ctx, treesTotal, progressTrackerPrefix);
treeProcessor = ParallelTreeProcessor
.with(new NodeProcessor<>() {

private TaskResult<String, DependencyTreeRequest, DependencyNode> apply(
ExecutionContext<String, DependencyTreeRequest, DependencyNode> execution) {
private TaskResult<Integer, DependencyTreeRequest, DependencyNode> apply(
ExecutionContext<Integer, DependencyTreeRequest, DependencyNode> execution) {
var request = execution.getNode();
try {
var node = treeBuilder.buildTree(request);
log.info(getResolvedTreeMessage(request.getArtifact()));
ctx.log.info(getResolvedTreeMessage(request.getArtifact()));
return execution.success(node);
} catch (Exception e) {
return execution.failure(e);
}
}

@Override
public String getNodeId(DependencyTreeRequest request) {
public Integer getNodeId(DependencyTreeRequest request) {
return request.getId();
}

Expand All @@ -46,7 +41,7 @@ public Iterable<DependencyTreeRequest> getChildren(DependencyTreeRequest node) {
}

@Override
public Function<ExecutionContext<String, DependencyTreeRequest, DependencyNode>, TaskResult<String, DependencyTreeRequest, DependencyNode>> createFunction() {
public Function<ExecutionContext<Integer, DependencyTreeRequest, DependencyNode>, TaskResult<Integer, DependencyTreeRequest, DependencyNode>> createFunction() {
return this::apply;
}
});
Expand All @@ -63,10 +58,10 @@ public void waitForCompletion() {
for (var r : results) {
if (r.isFailure()) {
errors.add(new DependencyTreeError(r.getNode(), r.getException()));
log.error(formatErrorMessage(r.getNode(), r.getException()));
ctx.getLog().error(formatErrorMessage(r.getNode(), r.getException()));
} else {
ctx.root = r.getOutcome();
visitor.visit(ctx);
ctx.visitor.visit(ctx);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
package io.quarkus.domino.inspect;

import io.quarkus.devtools.messagewriter.MessageWriter;
import org.eclipse.aether.graph.DependencyNode;

public class SequentialTreeVisitScheduler<E> extends DependencyTreeVisitSchedulerBase<E> {
class SequentialTreeVisitScheduler<E> extends DependencyTreeVisitSchedulerBase<E> {

private final DependencyTreeVisitor<E> visitor;
private final MessageWriter log;
private final DependencyTreeBuilder treeBuilder;

public SequentialTreeVisitScheduler(DependencyTreeVisitor<E> visitor, MessageWriter log, int treesTotal,
DependencyTreeBuilder treeBuilder) {
super(visitor, log, treesTotal);
this.visitor = visitor;
this.log = log;
SequentialTreeVisitScheduler(DependencyTreeVisitContext<E> ctx, int treesTotal,
DependencyTreeBuilder treeBuilder, String progressTrackerPrefix) {
super(ctx, treesTotal, progressTrackerPrefix);
this.treeBuilder = treeBuilder;
}

Expand All @@ -22,14 +17,14 @@ public void process(DependencyTreeRequest req) {
final DependencyNode rootNode;
try {
rootNode = treeBuilder.buildTree(req);
log.info(getResolvedTreeMessage(rootNode.getArtifact()));
ctx.log.info(getResolvedTreeMessage(rootNode.getArtifact()));
} catch (Exception e) {
errors.add(new DependencyTreeError(req, e));
log.error(formatErrorMessage(req, e));
ctx.log.error(formatErrorMessage(req, e));
return;
}
ctx.root = rootNode;
visitor.visit(ctx);
ctx.visitor.visit(ctx);
}

@Override
Expand Down