@@ -127,6 +127,72 @@ To include the original target itself, use `--closed`:
127
127
helloworld/main.py:lib
128
128
```
129
129
130
+ ## Export dependency graph
131
+
132
+ Both ` dependencies ` and ` dependents ` goals have the ` --format ` option allowing you to export data in multiple formats.
133
+ Exporting information about the dependencies and dependents in JSON format will produce the
134
+ [ adjacency list] ( https://en.wikipedia.org/wiki/Adjacency_list ) of your dependency graph:
135
+
136
+ ``` bash
137
+ $ pants dependencies --format=json \
138
+ helloworld/greet/greeting.py \
139
+ helloworld/translator/translator_test.py
140
+
141
+ {
142
+ " helloworld/greet/greeting.py:lib" : [
143
+ " //:reqs#setuptools" ,
144
+ " //:reqs#types-setuptools" ,
145
+ " helloworld/greet:translations" ,
146
+ " helloworld/translator/translator.py:lib"
147
+ ],
148
+ " helloworld/translator/translator_test.py:tests" : [
149
+ " //:reqs#pytest" ,
150
+ " helloworld/translator/translator.py:lib"
151
+ ]
152
+ }
153
+ ```
154
+
155
+ This has various applications, and you could analyze, visualize, and process the data further. Sometimes, a fairly
156
+ straightforward ` jq ` query would suffice, but for anything more complex, it may make sense to write a small program
157
+ to process the exported graph. For instance, you could:
158
+
159
+ * find tests with most transitive dependencies
160
+
161
+ ``` bash
162
+ $ pants dependencies --filter-target-type=python_test --format=json :: \
163
+ | jq -r ' to_entries[] | "\(.key)\t\(.value | length)"' \
164
+ | sort -k2
165
+ ```
166
+
167
+ * find build targets that no one depends on
168
+
169
+ ``` bash
170
+ $ pants dependents --filter-target-type=resource --format=json :: \
171
+ jq -r ' to_entries[] | select(.value | length == 0)'
172
+ ```
173
+
174
+ * find project source files that transitively lead to most tests
175
+
176
+ ``` python
177
+ # depgraph.py
178
+ import json
179
+
180
+ with open (" data.json" ) as fh:
181
+ data = json.load(fh)
182
+
183
+ for source, dependents in data.items():
184
+ print (source, len ([d for d in dependents if d.startswith(" tests/" )]))
185
+ ```
186
+
187
+ ``` bash
188
+ $ pants dependents --transitive --format=json cheeseshop:: > data.json
189
+ $ python3 depgraph.py | sort -k2
190
+ ```
191
+
192
+ For more sophisticated graph querying, you may want to look into graph libraries such as [ ` networkx ` ] ( https://networkx.org/ ) .
193
+ In a larger repository, it may make sense to track the health of the dependency graph and use the output
194
+ of the graph export to identify parts of your codebase that would benefit from refactoring.
195
+
130
196
## ` filedeps ` - find which files a target owns
131
197
132
198
` filedeps ` outputs all of the files belonging to a target, based on its ` sources ` field.
0 commit comments