1010#
1111
1212import json
13- import sys
1413from typing import List
1514
1615import click
3433
3534
3635@click .command ()
36+ @click .pass_context
3737@click .option (
3838 "-r" ,
3939 "--requirement" ,
9999 "--json" ,
100100 "json_output" ,
101101 type = FileOptionType (mode = "w" , encoding = "utf-8" , lazy = True ),
102- required = True ,
102+ required = False ,
103103 metavar = "FILE" ,
104104 help = "Write output as pretty-printed JSON to FILE. "
105105 "Use the special '-' file name to print results on screen/stdout." ,
106106)
107+ @click .option (
108+ "--json-pdt" ,
109+ "pdt_output" ,
110+ type = FileOptionType (mode = "w" , encoding = "utf-8" , lazy = True ),
111+ required = False ,
112+ metavar = "FILE" ,
113+ help = "Write output as pretty-printed JSON to FILE as a tree in the style of pipdeptree. "
114+ "Use the special '-' file name to print results on screen/stdout." ,
115+ )
107116@click .option (
108117 "--max-rounds" ,
109118 "max_rounds" ,
124133 "--index-url are ignored when this option is active." ,
125134)
126135@click .option (
127- "--debug " ,
136+ "--verbose " ,
128137 is_flag = True ,
129138 hidden = True ,
130139 help = "Enable debug output." ,
131140)
132141@click .help_option ("-h" , "--help" )
133142def resolve_dependencies (
143+ ctx ,
134144 requirement_files ,
135145 netrc_file ,
136146 specifiers ,
137147 python_version ,
138148 operating_system ,
139149 index_urls ,
140150 json_output ,
151+ pdt_output ,
141152 max_rounds ,
142153 use_cached_index = False ,
143154 use_pypi_json_api = False ,
144- debug = TRACE ,
155+ verbose = TRACE ,
145156):
146157 """
147158 Resolve the dependencies of the packages listed in REQUIREMENT-FILE(s) file
@@ -161,7 +172,15 @@ def resolve_dependencies(
161172
162173 dad --spec "flask==2.1.2" --json -
163174 """
164- if debug :
175+ if not (json_output or pdt_output ):
176+ click .secho ("No output file specified. Use --json or --json-pdt." , err = True )
177+ ctx .exit (1 )
178+
179+ if json_output and pdt_output :
180+ click .secho ("Only one of --json or --json-pdt can be used." , err = True )
181+ ctx .exit (1 )
182+
183+ if verbose :
165184 click .secho (f"Resolving dependencies..." )
166185
167186 netrc = None
@@ -184,11 +203,10 @@ def resolve_dependencies(
184203 direct_dependencies .append (dep )
185204
186205 if not direct_dependencies :
187- if debug :
188- click .secho ("Error: no requirements requested." )
189- sys .exit (1 )
206+ click .secho ("Error: no requirements requested." )
207+ ctx .exit (1 )
190208
191- if debug :
209+ if verbose :
192210 click .secho ("direct_dependencies:" )
193211 for dep in direct_dependencies :
194212 click .secho (f" { dep } " )
@@ -198,7 +216,7 @@ def resolve_dependencies(
198216 python_version = python_version , operating_system = operating_system
199217 )
200218
201- if debug :
219+ if verbose :
202220 click .secho (f"environment: { environment } " )
203221
204222 repos = []
@@ -224,7 +242,7 @@ def resolve_dependencies(
224242 )
225243 repos .append (repo )
226244
227- if debug :
245+ if verbose :
228246 click .secho ("repos:" )
229247 for repo in repos :
230248 click .secho (f" { repo } " )
@@ -236,7 +254,8 @@ def resolve_dependencies(
236254 repos = repos ,
237255 as_tree = False ,
238256 max_rounds = max_rounds ,
239- debug = debug ,
257+ verbose = verbose ,
258+ pdt_output = pdt_output ,
240259 )
241260
242261 cli_options = [f"--requirement { rf } " for rf in requirement_files ]
@@ -262,19 +281,35 @@ def resolve_dependencies(
262281 errors = [],
263282 )
264283
265- write_output (
266- headers = headers ,
267- requirements = requirements ,
268- resolved_dependencies = resolved_dependencies ,
269- json_output = json_output ,
270- )
271-
272- if debug :
284+ if json_output :
285+ write_output (
286+ headers = headers ,
287+ requirements = requirements ,
288+ resolved_dependencies = resolved_dependencies ,
289+ json_output = json_output ,
290+ )
291+
292+ else :
293+ write_output (
294+ headers = headers ,
295+ requirements = requirements ,
296+ resolved_dependencies = resolved_dependencies ,
297+ json_output = pdt_output ,
298+ pdt_output = True ,
299+ )
300+
301+ if verbose :
273302 click .secho ("done!" )
274303
275304
276305def resolve (
277- direct_dependencies , environment , repos = tuple (), as_tree = False , max_rounds = 200000 , debug = False
306+ direct_dependencies ,
307+ environment ,
308+ repos = tuple (),
309+ as_tree = False ,
310+ max_rounds = 200000 ,
311+ verbose = False ,
312+ pdt_output = False ,
278313):
279314 """
280315 Resolve dependencies given a ``direct_dependencies`` list of
@@ -292,7 +327,8 @@ def resolve(
292327 repos = repos ,
293328 as_tree = as_tree ,
294329 max_rounds = max_rounds ,
295- debug = debug ,
330+ verbose = verbose ,
331+ pdt_output = pdt_output ,
296332 )
297333
298334 initial_requirements = [d .to_dict () for d in direct_dependencies ]
@@ -312,16 +348,19 @@ def get_requirements_from_direct_dependencies(
312348 yield Requirement (requirement_string = dependency .extracted_requirement )
313349
314350
315- def write_output (headers , requirements , resolved_dependencies , json_output ):
351+ def write_output (headers , requirements , resolved_dependencies , json_output , pdt_output = False ):
316352 """
317353 Write headers, requirements and resolved_dependencies as JSON to ``json_output``.
318354 Return the output data.
319355 """
320- output = dict (
321- headers = headers ,
322- requirements = requirements ,
323- resolved_dependencies = resolved_dependencies ,
324- )
356+ if not pdt_output :
357+ output = dict (
358+ headers = headers ,
359+ requirements = requirements ,
360+ resolved_dependencies = resolved_dependencies ,
361+ )
362+ else :
363+ output = resolved_dependencies
325364
326365 json .dump (output , json_output , indent = 2 )
327366 return output
0 commit comments