1+ import contextlib
12import json
23import re
34import sys
45
5- from collections import OrderedDict
66from pathlib import Path
7- from urllib .request import Request , urlopen
87
98REPO = Path (__file__ ).absolute ().parent .parent
109sys .path .append (str (REPO / "src" ))
@@ -30,6 +29,7 @@ def usage():
3029 print (" -t/--tag TAG Include only the specified tags (comma-separated)" )
3130 print (" -r/--range RANGE Include only the specified range (comma-separated)" )
3231 print (" --latest-micro Include only the latest x.y.z version" )
32+ print (" --report Write plain-text summary report" )
3333 print ()
3434 print ("An output of 'nul' is permitted to drop entries." )
3535 print ("Providing the same inputs and outputs is permitted, as all inputs are read" )
@@ -96,6 +96,7 @@ def __init__(self):
9696 self .tag_or_range = None
9797 self ._expect_tag_or_range = False
9898 self .latest_micro = False
99+ self .report = False
99100
100101 def add_arg (self , arg ):
101102 if arg [:1 ] != "-" :
@@ -121,9 +122,16 @@ def add_arg(self, arg):
121122 if arg == "--latest-micro" :
122123 self .latest_micro = True
123124 return False
125+ if arg == "--report" :
126+ self .report = True
127+ return False
124128 raise ValueError ("Unknown argument: " + arg )
125129
126130 def execute (self , versions , context ):
131+ if self .report :
132+ if self .target != "nul" :
133+ context .setdefault ("reports" , []).append (self .target )
134+ return
127135 written = context .setdefault ("written" , set ())
128136 written_now = set ()
129137 outputs = context .setdefault ("outputs" , {})
@@ -176,19 +184,56 @@ def add_arg(self, arg):
176184 return False
177185 raise ValueError ("Unknown argument: " + arg )
178186
187+ @contextlib .contextmanager
188+ def open (self , file ):
189+ file = Path (file )
190+ if file .match ("nul" ):
191+ import io
192+ yield io .StringIO ()
193+ elif file .match ("stdout" ):
194+ yield sys .stdout
195+ else :
196+ with open (file , "w" , encoding = "utf-8" ) as f :
197+ yield f
198+
199+ def st_size (self , file ):
200+ file = Path (file )
201+ if file .match ("nul" ):
202+ return "no data written"
203+ if file .match ("stdout" ):
204+ return "n/a"
205+ return f"{ Path (file ).stat ().st_size } bytes"
206+
179207 def execute (self , versions , context ):
180208 outputs = context .get ("outputs" ) or {}
181209 output_order = context .get ("output_order" , [])
210+ report_data = {}
182211 for target , next_target in zip (output_order , [* output_order [1 :], None ]):
183212 data = {
184213 "versions" : outputs [target ]
185214 }
186215 if next_target :
187216 data ["next" ] = next_target
188- with open (target , "w" , encoding = "utf-8" ) as f :
217+ for i in outputs [target ]:
218+ report_data .setdefault (target , {}).setdefault (i ["sort-version" ].casefold (), []).append (i )
219+ with self .open (target ) as f :
189220 json .dump (data , f , indent = self .indent )
190221 print ("Wrote {} ({} entries, {} bytes)" .format (
191- target , len (data ["versions" ]), Path (target ).stat ().st_size
222+ target , len (data ["versions" ]), self .st_size (target )
223+ ))
224+
225+ reports = context .get ("reports" , [])
226+ for target in reports :
227+ with self .open (target ) as f :
228+ for output_target in output_order :
229+ print ("Written to" , output_target , file = f )
230+ data = report_data [output_target ]
231+ for key in data :
232+ ids = ", " .join (i ["id" ] for i in data [key ])
233+ print ("{}: {}" .format (key , ids ), file = f )
234+ print (file = f )
235+ print ("Wrote {} ({} bytes)" .format (
236+ target , self .st_size (target )
192237 ))
193238
194239
@@ -203,10 +248,13 @@ def parse_cli(args):
203248 print ("Using equivalent of: --pre --latest-micro -r >=3.11.0 index-windows.json" )
204249 print (" --pre -r >=3.11.0 index-windows-recent.json" )
205250 print (" index-windows-legacy.json" )
206- plan_split = [SplitToFile (), SplitToFile (), SplitToFile ()]
251+ print (" --report index-windows.txt" )
252+ plan_split = [SplitToFile (), SplitToFile (), SplitToFile (), SplitToFile ()]
207253 plan_split [0 ].target = "index-windows.json"
208254 plan_split [1 ].target = "index-windows-recent.json"
209255 plan_split [2 ].target = "index-windows-legacy.json"
256+ plan_split [3 ].target = "stdout"
257+ plan_split [3 ].report = True
210258 plan_split [0 ].pre = plan_split [1 ].pre = plan_split [2 ].pre = True
211259 plan_split [0 ].latest_micro = True
212260 plan_split [0 ].tag_or_range = tag_or_range (">=3.11.0" )
@@ -246,4 +294,3 @@ def parse_cli(args):
246294 CONTEXT = {}
247295 for p in plan :
248296 p .execute (VERSIONS , CONTEXT )
249-
0 commit comments