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