|
2 | 2 | publication date. Compare it against requirements/py36-min-all-deps.yml to verify the |
3 | 3 | policy on obsolete dependencies is being followed. Print a pretty report :) |
4 | 4 | """ |
5 | | -import subprocess |
| 5 | +import itertools |
6 | 6 | import sys |
7 | | -from concurrent.futures import ThreadPoolExecutor |
8 | 7 | from datetime import datetime, timedelta |
9 | 8 | from typing import Dict, Iterator, Optional, Tuple |
10 | 9 |
|
| 10 | +import conda.api |
11 | 11 | import yaml |
12 | 12 |
|
| 13 | +CHANNELS = ["conda-forge", "defaults"] |
13 | 14 | IGNORE_DEPS = { |
14 | 15 | "black", |
15 | 16 | "coveralls", |
@@ -91,30 +92,23 @@ def query_conda(pkg: str) -> Dict[Tuple[int, int], datetime]: |
91 | 92 |
|
92 | 93 | Return map of {(major version, minor version): publication date} |
93 | 94 | """ |
94 | | - stdout = subprocess.check_output( |
95 | | - ["conda", "search", pkg, "--info", "-c", "defaults", "-c", "conda-forge"] |
96 | | - ) |
97 | | - out = {} # type: Dict[Tuple[int, int], datetime] |
98 | | - major = None |
99 | | - minor = None |
100 | | - |
101 | | - for row in stdout.decode("utf-8").splitlines(): |
102 | | - label, _, value = row.partition(":") |
103 | | - label = label.strip() |
104 | | - if label == "file name": |
105 | | - value = value.strip()[len(pkg) :] |
106 | | - smajor, sminor = value.split("-")[1].split(".")[:2] |
107 | | - major = int(smajor) |
108 | | - minor = int(sminor) |
109 | | - if label == "timestamp": |
110 | | - assert major is not None |
111 | | - assert minor is not None |
112 | | - ts = datetime.strptime(value.split()[0].strip(), "%Y-%m-%d") |
113 | | - |
114 | | - if (major, minor) in out: |
115 | | - out[major, minor] = min(out[major, minor], ts) |
116 | | - else: |
117 | | - out[major, minor] = ts |
| 95 | + |
| 96 | + def metadata(entry): |
| 97 | + version = entry.version |
| 98 | + |
| 99 | + time = datetime.fromtimestamp(entry.timestamp) |
| 100 | + major, minor = map(int, version.split(".")[:2]) |
| 101 | + |
| 102 | + return (major, minor), time |
| 103 | + |
| 104 | + raw_data = conda.api.SubdirData.query_all(pkg, channels=CHANNELS) |
| 105 | + data = sorted(metadata(entry) for entry in raw_data if entry.timestamp != 0) |
| 106 | + |
| 107 | + release_dates = { |
| 108 | + version: [time for _, time in group if time is not None] |
| 109 | + for version, group in itertools.groupby(data, key=lambda x: x[0]) |
| 110 | + } |
| 111 | + out = {version: min(dates) for version, dates in release_dates.items() if dates} |
118 | 112 |
|
119 | 113 | # Hardcoded fix to work around incorrect dates in conda |
120 | 114 | if pkg == "python": |
@@ -202,16 +196,14 @@ def fmt_version(major: int, minor: int, patch: int = None) -> str: |
202 | 196 |
|
203 | 197 | def main() -> None: |
204 | 198 | fname = sys.argv[1] |
205 | | - with ThreadPoolExecutor(8) as ex: |
206 | | - futures = [ |
207 | | - ex.submit(process_pkg, pkg, major, minor, patch) |
208 | | - for pkg, major, minor, patch in parse_requirements(fname) |
209 | | - ] |
210 | | - rows = [f.result() for f in futures] |
211 | | - |
212 | | - print("Package Required Policy Status") |
213 | | - print("------------- -------------------- -------------------- ------") |
214 | | - fmt = "{:13} {:7} ({:10}) {:7} ({:10}) {}" |
| 199 | + rows = [ |
| 200 | + process_pkg(pkg, major, minor, patch) |
| 201 | + for pkg, major, minor, patch in parse_requirements(fname) |
| 202 | + ] |
| 203 | + |
| 204 | + print("Package Required Policy Status") |
| 205 | + print("----------------- -------------------- -------------------- ------") |
| 206 | + fmt = "{:17} {:7} ({:10}) {:7} ({:10}) {}" |
215 | 207 | for row in rows: |
216 | 208 | print(fmt.format(*row)) |
217 | 209 |
|
|
0 commit comments