Skip to content

Commit 65a0c26

Browse files
authored
Fixes the repartition script to put experimental packages in the right file. (#127)
Also adds report output to repartition script to help visualise its output Fixes #126
1 parent 60c7c55 commit 65a0c26

File tree

2 files changed

+61
-11
lines changed

2 files changed

+61
-11
lines changed

ci/repartition-index.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ stages:
4545
- powershell: |
4646
cd (mkdir -Force index)
4747
python "$(Build.SourcesDirectory)\scripts\repartition-index.py" --windows-default
48+
# Show the report
49+
cat index-windows.txt
4850
displayName: 'Repartition index'
4951
workingDirectory: $(Build.BinariesDirectory)
5052

scripts/repartition-index.py

Lines changed: 59 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1+
import contextlib
12
import json
23
import re
34
import sys
45

5-
from collections import OrderedDict
66
from pathlib import Path
7-
from urllib.request import Request, urlopen
87

98
REPO = Path(__file__).absolute().parent.parent
109
sys.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")
@@ -93,14 +93,15 @@ def __init__(self):
9393
self.allow_dup = False
9494
self.only_dup = False
9595
self.pre = False
96-
self.tag_or_range = None
96+
self.tag_or_range = []
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] != "-":
102103
if self._expect_tag_or_range:
103-
self.tag_or_range = tag_or_range(arg)
104+
self.tag_or_range.append(tag_or_range(arg))
104105
self._expect_tag_or_range = False
105106
return False
106107
self.target = arg
@@ -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", {})
@@ -150,7 +158,8 @@ def execute(self, versions, context):
150158
if not self.pre and v.is_prerelease:
151159
continue
152160
if self.tag_or_range and not any(
153-
self.tag_or_range.satisfied_by(CompanyTag(i["company"], t))
161+
r.satisfied_by(CompanyTag(i["company"], t))
162+
for r in self.tag_or_range
154163
for t in i["install-for"]
155164
):
156165
continue
@@ -176,19 +185,56 @@ def add_arg(self, arg):
176185
return False
177186
raise ValueError("Unknown argument: " + arg)
178187

188+
@contextlib.contextmanager
189+
def open(self, file):
190+
file = Path(file)
191+
if file.match("nul"):
192+
import io
193+
yield io.StringIO()
194+
elif file.match("stdout"):
195+
yield sys.stdout
196+
else:
197+
with open(file, "w", encoding="utf-8") as f:
198+
yield f
199+
200+
def st_size(self, file):
201+
file = Path(file)
202+
if file.match("nul"):
203+
return "no data written"
204+
if file.match("stdout"):
205+
return "n/a"
206+
return f"{Path(file).stat().st_size} bytes"
207+
179208
def execute(self, versions, context):
180209
outputs = context.get("outputs") or {}
181210
output_order = context.get("output_order", [])
211+
report_data = {}
182212
for target, next_target in zip(output_order, [*output_order[1:], None]):
183213
data = {
184214
"versions": outputs[target]
185215
}
186216
if next_target:
187217
data["next"] = next_target
188-
with open(target, "w", encoding="utf-8") as f:
218+
for i in outputs[target]:
219+
report_data.setdefault(target, {}).setdefault(i["sort-version"].casefold(), []).append(i)
220+
with self.open(target) as f:
189221
json.dump(data, f, indent=self.indent)
190222
print("Wrote {} ({} entries, {} bytes)".format(
191-
target, len(data["versions"]), Path(target).stat().st_size
223+
target, len(data["versions"]), self.st_size(target)
224+
))
225+
226+
reports = context.get("reports", [])
227+
for target in reports:
228+
with self.open(target) as f:
229+
for output_target in output_order:
230+
print("Written to", output_target, file=f)
231+
data = report_data[output_target]
232+
for key in data:
233+
ids = ", ".join(i["id"] for i in data[key])
234+
print("{}: {}".format(key, ids), file=f)
235+
print(file=f)
236+
print("Wrote {} ({} bytes)".format(
237+
target, self.st_size(target)
192238
))
193239

194240

@@ -203,14 +249,17 @@ def parse_cli(args):
203249
print("Using equivalent of: --pre --latest-micro -r >=3.11.0 index-windows.json")
204250
print(" --pre -r >=3.11.0 index-windows-recent.json")
205251
print(" index-windows-legacy.json")
206-
plan_split = [SplitToFile(), SplitToFile(), SplitToFile()]
252+
print(" --report index-windows.txt")
253+
plan_split = [SplitToFile(), SplitToFile(), SplitToFile(), SplitToFile()]
207254
plan_split[0].target = "index-windows.json"
208255
plan_split[1].target = "index-windows-recent.json"
209256
plan_split[2].target = "index-windows-legacy.json"
257+
plan_split[3].target = "index-windows.txt"
258+
plan_split[3].report = True
210259
plan_split[0].pre = plan_split[1].pre = plan_split[2].pre = True
211260
plan_split[0].latest_micro = True
212-
plan_split[0].tag_or_range = tag_or_range(">=3.11.0")
213-
plan_split[1].tag_or_range = tag_or_range(">=3.11.0")
261+
plan_split[0].tag_or_range = [tag_or_range(">=3.11"), tag_or_range(">=3.13t")]
262+
plan_split[1].tag_or_range = [tag_or_range(">=3.11"), tag_or_range(">=3.13t")]
214263
elif a == "-i":
215264
action = ReadFile()
216265
plan_read.append(action)
@@ -246,4 +295,3 @@ def parse_cli(args):
246295
CONTEXT = {}
247296
for p in plan:
248297
p.execute(VERSIONS, CONTEXT)
249-

0 commit comments

Comments
 (0)