1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.internal.aether;
20
21 import java.io.IOException;
22 import java.io.UncheckedIOException;
23 import java.nio.charset.StandardCharsets;
24 import java.nio.file.Files;
25 import java.nio.file.Path;
26 import java.util.ArrayList;
27 import java.util.ListIterator;
28 import java.util.Objects;
29
30 import org.eclipse.aether.AbstractRepositoryListener;
31 import org.eclipse.aether.RepositoryEvent;
32 import org.eclipse.aether.RepositorySystemSession;
33 import org.eclipse.aether.RequestTrace;
34 import org.eclipse.aether.artifact.Artifact;
35 import org.eclipse.aether.collection.CollectStepData;
36 import org.eclipse.aether.graph.Dependency;
37 import org.eclipse.aether.graph.DependencyNode;
38
39 import static java.util.Objects.requireNonNull;
40
41
42
43
44
45
46
47 class ReverseTreeRepositoryListener extends AbstractRepositoryListener {
48 @Override
49 public void artifactResolved(RepositoryEvent event) {
50 requireNonNull(event, "event cannot be null");
51
52 if (!isLocalRepositoryArtifact(event.getSession(), event.getArtifact())) {
53 return;
54 }
55
56 CollectStepData collectStepTrace = lookupCollectStepData(event.getTrace());
57 if (collectStepTrace == null) {
58 return;
59 }
60
61 Artifact resolvedArtifact = event.getArtifact();
62 Artifact nodeArtifact = collectStepTrace.getNode().getArtifact();
63
64 if (isInScope(resolvedArtifact, nodeArtifact)) {
65 Dependency node = collectStepTrace.getNode();
66 ArrayList<String> trackingData = new ArrayList<>();
67 trackingData.add(node + " (" + collectStepTrace.getContext() + ")");
68 String indent = "";
69 ListIterator<DependencyNode> iter = collectStepTrace
70 .getPath()
71 .listIterator(collectStepTrace.getPath().size());
72 while (iter.hasPrevious()) {
73 DependencyNode curr = iter.previous();
74 indent += " ";
75 trackingData.add(indent + curr + " (" + collectStepTrace.getContext() + ")");
76 }
77 try {
78 Path trackingDir =
79 resolvedArtifact.getFile().getParentFile().toPath().resolve(".tracking");
80 Files.createDirectories(trackingDir);
81 Path trackingFile = trackingDir.resolve(collectStepTrace
82 .getPath()
83 .get(0)
84 .getArtifact()
85 .toString()
86 .replace(":", "_"));
87 Files.write(trackingFile, trackingData, StandardCharsets.UTF_8);
88 } catch (IOException e) {
89 throw new UncheckedIOException(e);
90 }
91 }
92 }
93
94
95
96
97
98
99
100
101
102 static boolean isLocalRepositoryArtifact(RepositorySystemSession session, Artifact artifact) {
103 return artifact.getFile()
104 .getPath()
105 .startsWith(session.getLocalRepository().getBasedir().getPath());
106 }
107
108
109
110
111
112
113
114 static CollectStepData lookupCollectStepData(RequestTrace trace) {
115 CollectStepData collectStepTrace = null;
116 while (trace != null) {
117 if (trace.getData() instanceof CollectStepData) {
118 collectStepTrace = (CollectStepData) trace.getData();
119 break;
120 }
121 trace = trace.getParent();
122 }
123 return collectStepTrace;
124 }
125
126
127
128
129
130
131
132 static boolean isInScope(Artifact artifact, Artifact nodeArtifact) {
133 return Objects.equals(artifact.getGroupId(), nodeArtifact.getGroupId())
134 && Objects.equals(artifact.getArtifactId(), nodeArtifact.getArtifactId())
135 && Objects.equals(artifact.getVersion(), nodeArtifact.getVersion());
136 }
137 }