|
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