Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit ceecd5e

Browse filesBrowse files
authored
Merge pull request #1625 from stonebig/master
post-simplification of diff.py after Wheelhouse addition
2 parents 32a9834 + f1b8883 commit ceecd5e
Copy full SHA for ceecd5e

File tree

Expand file treeCollapse file tree

1 file changed

+78
-112
lines changed
Filter options
Expand file treeCollapse file tree

1 file changed

+78
-112
lines changed

‎diff.py

Copy file name to clipboardExpand all lines: diff.py
+78-112Lines changed: 78 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -17,120 +17,94 @@
1717
assert CHANGELOGS_DIR.is_dir()
1818

1919
class Package:
20-
# SourceForge Wiki syntax:
21-
PATTERN = r"\[([a-zA-Z\-\:\/\.\_0-9]*)\]\(([^\]\ ]*)\) \| ([^\|]*) \| ([^\|]*)"
22-
# Google Code Wiki syntax:
23-
PATTERN_OLD = r"\[([a-zA-Z\-\:\/\.\_0-9]*) ([^\]\ ]*)\] \| ([^\|]*) \| ([^\|]*)"
20+
PATTERNS = [
21+
r"\[([\w\-\:\/\.\_]+)\]\(([^)]+)\) \| ([^\|]*) \| ([^\|]*)", # SourceForge
22+
r"\[([\w\-\:\/\.\_]+) ([^\]\ ]+)\] \| ([^\|]*) \| ([^\|]*)" # Google Code
23+
]
2424

25-
def __init__(self):
26-
self.name = self.version = self.description = self.url = None
27-
28-
def __str__(self):
29-
return f"{self.name} {self.version}\r\n{self.description}\r\nWebsite: {self.url}"
25+
def __init__(self, text=None):
26+
self.name = self.url = self.version = self.description = None
27+
if text:
28+
self.from_text(text)
3029

3130
def from_text(self, text):
32-
match = re.match(self.PATTERN_OLD, text) or re.match(self.PATTERN, text)
33-
if not match:
34-
raise ValueError("Text does not match expected pattern: "+ text)
35-
self.name, self.url, self.version, self.description = match.groups()
31+
for pattern in self.PATTERNS:
32+
match = re.match(pattern, text)
33+
if match:
34+
self.name, self.url, self.version, self.description = match.groups()
35+
return
36+
raise ValueError(f"Unrecognized package line format: {text}")
3637

3738
def to_wiki(self):
3839
return f" * [{self.name}]({self.url}) {self.version} ({self.description})\r\n"
3940

4041
def upgrade_wiki(self, other):
41-
assert self.name.replace("-", "_").lower() == other.name.replace("-", "_").lower()
4242
return f" * [{self.name}]({self.url}) {other.version}{self.version} ({self.description})\r\n"
4343

4444
class PackageIndex:
45-
WINPYTHON_PATTERN = r"\#\# WinPython\-*[0-9b-t]* ([0-9\.a-zA-Z]*)"
46-
TOOLS_LINE = "### Tools"
47-
PYTHON_PACKAGES_LINE = "### Python packages"
48-
WHEELHOUSE_PACKAGES_LINE = "### WheelHouse packages"
49-
HEADER_LINE1 = "Name | Version | Description"
50-
HEADER_LINE2 = "-----|---------|------------"
45+
HEADERS = {"tools": "### Tools", "python": "### Python packages", "wheelhouse": "### WheelHouse packages"}
46+
BLANKS = ["Name | Version | Description", "-----|---------|------------", "", "<details>", "</details>"]
5147

5248
def __init__(self, version, basedir=None, flavor="", architecture=64):
5349
self.version = version
5450
self.flavor = flavor
5551
self.basedir = basedir
5652
self.architecture = architecture
57-
self.other_packages = {}
58-
self.python_packages = {}
59-
self.wheelhouse_packages = {}
60-
self.from_file(basedir)
61-
62-
def from_file(self, basedir):
63-
fname = CHANGELOGS_DIR / f"WinPython{self.flavor}-{self.architecture}bit-{self.version}.md"
64-
if not fname.exists():
65-
raise FileNotFoundError(f"Changelog file not found: {fname}")
66-
with open(fname, "r", encoding=utils.guess_encoding(fname)[0]) as fdesc:
67-
self.from_text(fdesc.read())
53+
self.packages = {"tools": {}, "python": {}, "wheelhouse": {}}
54+
self._load_index()
6855

69-
def from_text(self, text):
70-
version = re.match(self.WINPYTHON_PATTERN + self.flavor, text).groups()[0]
71-
assert version == self.version
72-
tools_flag = python_flag = wheelhouse_flag = False
56+
def _load_index(self):
57+
filename = CHANGELOGS_DIR / f"WinPython{self.flavor}-{self.architecture}bit-{self.version}.md"
58+
if not filename.exists():
59+
raise FileNotFoundError(f"Changelog not found: {filename}")
60+
61+
with open(filename, "r", encoding=utils.guess_encoding(filename)[0]) as f:
62+
self._parse_index(f.read())
63+
64+
def _parse_index(self, text):
65+
current = None
7366
for line in text.splitlines():
74-
if line:
75-
if line == self.TOOLS_LINE:
76-
tools_flag, python_flag, wheelhouse_flag = True, False, False
77-
continue
78-
elif line == self.PYTHON_PACKAGES_LINE:
79-
tools_flag, python_flag, wheelhouse_flag = False, True, False
80-
continue
81-
elif line == self.WHEELHOUSE_PACKAGES_LINE:
82-
tools_flag, python_flag, wheelhouse_flag = False, False, True
83-
continue
84-
elif line in (self.HEADER_LINE1, self.HEADER_LINE2, "<details>", "</details>"):
85-
continue
86-
if tools_flag or python_flag or wheelhouse_flag:
87-
package = Package()
88-
package.from_text(line)
89-
if tools_flag:
90-
self.other_packages[package.name] = package
91-
elif python_flag:
92-
self.python_packages[package.name] = package
93-
else:
94-
self.wheelhouse_packages[package.name] = package
95-
96-
def diff_package_dicts(old_packages, new_packages):
67+
if line in self.HEADERS.values():
68+
current = [k for k, v in self.HEADERS.items() if v == line][0]
69+
continue
70+
if line.strip() in self.BLANKS:
71+
continue
72+
if current:
73+
pkg = Package(line)
74+
self.packages[current][pkg.name] = pkg
75+
76+
def compare_packages(old, new):
9777
"""Return difference between package old and package new"""
9878

9979
# wheel replace '-' per '_' in key
100-
old = {k.replace("-", "_").lower(): v for k, v in old_packages.items()}
101-
new = {k.replace("-", "_").lower(): v for k, v in new_packages.items()}
102-
text = ""
103-
104-
if new_keys := sorted(set(new) - set(old)):
105-
text += "New packages:\r\n\r\n" + "".join(new[k].to_wiki() for k in new_keys) + "\r\n"
106-
107-
if upgraded := [new[k].upgrade_wiki(old[k]) for k in sorted(set(old) & set(new)) if old[k].version != new[k].version]:
108-
text += "Upgraded packages:\r\n\r\n" + f"{''.join(upgraded)}" + "\r\n"
109-
110-
if removed_keys := sorted(set(old) - set(new)):
111-
text += "Removed packages:\r\n\r\n" + "".join(old[k].to_wiki() for k in removed_keys) + "\r\n"
112-
return text
113-
114-
def find_closer_version(version1, basedir=None, flavor="", architecture=64):
80+
def normalize(d): return {k.replace("-", "_").lower(): v for k, v in d.items()}
81+
old, new = normalize(old), normalize(new)
82+
output = ""
83+
84+
added = [new[k].to_wiki() for k in new if k not in old]
85+
upgraded = [new[k].upgrade_wiki(old[k]) for k in new if k in old and new[k].version != old[k].version]
86+
removed = [old[k].to_wiki() for k in old if k not in new]
87+
88+
if added:
89+
output += "New packages:\r\n\r\n" + "".join(added) + "\r\n"
90+
if upgraded:
91+
output += "Upgraded packages:\r\n\r\n" + "".join(upgraded) + "\r\n"
92+
if removed:
93+
output += "Removed packages:\r\n\r\n" + "".join(removed) + "\r\n"
94+
return output
95+
96+
def find_previous_version(target_version, basedir=None, flavor="", architecture=64):
11597
"""Find version which is the closest to `version`"""
116-
builddir = Path(basedir) / f"bu{flavor}"
117-
pattern = re.compile(rf"WinPython{flavor}-{architecture}bit-([0-9\.]*)\.(txt|md)")
118-
versions = [pattern.match(name).groups()[0] for name in os.listdir(builddir) if pattern.match(name)]
119-
120-
if version1 not in versions:
121-
raise ValueError(f"Unknown version {version1}")
122-
123-
version_below = '0.0.0.0'
124-
for v in versions:
125-
if version.parse(version_below) < version.parse(v) and version.parse(v) < version.parse(version1):
126-
version_below = v
98+
build_dir = Path(basedir) / f"bu{flavor}"
99+
pattern = re.compile(rf"WinPython{flavor}-{architecture}bit-([0-9\.]+)\.(txt|md)")
100+
versions = [pattern.match(f).group(1) for f in os.listdir(build_dir) if pattern.match(f)]
101+
versions = [v for v in versions if version.parse(v) < version.parse(target_version)]
102+
return max(versions, key=version.parse, default=target_version)
127103

128-
return version_below if version_below != '0.0.0.0' else version1
104+
def compare_package_indexes(version2, version1=None, basedir=None, flavor="", flavor1=None, architecture=64):
105+
version1 = version1 or find_previous_version(version2, basedir, flavor, architecture)
106+
flavor1 = flavor1 or flavor
129107

130-
def compare_package_indexes(version2, version1=None, basedir=None, flavor="", flavor1=None,architecture=64):
131-
"""Compare two package index Wiki pages"""
132-
version1 = version1 if version1 else find_closer_version(version2, basedir, flavor, architecture)
133-
flavor1 = flavor1 if flavor1 else flavor
134108
pi1 = PackageIndex(version1, basedir, flavor1, architecture)
135109
pi2 = PackageIndex(version2, basedir, flavor, architecture)
136110

@@ -140,37 +114,29 @@ def compare_package_indexes(version2, version1=None, basedir=None, flavor="", fl
140114
"<details>\r\n\r\n"
141115
)
142116

143-
tools_text = diff_package_dicts(pi1.other_packages, pi2.other_packages)
144-
if tools_text:
145-
text += PackageIndex.TOOLS_LINE + "\r\n\r\n" + tools_text
117+
for key in PackageIndex.HEADERS:
118+
diff = compare_packages(pi1.packages[key], pi2.packages[key])
119+
if diff:
120+
text += f"{PackageIndex.HEADERS[key]}\r\n\r\n{diff}"
146121

147-
py_text = diff_package_dicts(pi1.python_packages, pi2.python_packages)
148-
if py_text:
149-
text += PackageIndex.PYTHON_PACKAGES_LINE + "\r\n\r\n" + py_text
122+
return text + "\r\n</details>\r\n* * *\r\n"
150123

151-
py_text = diff_package_dicts(pi1.wheelhouse_packages, pi2.wheelhouse_packages)
152-
if py_text:
153-
text += PackageIndex.WHEELHOUSE_PACKAGES_LINE + "\r\n\r\n" + py_text
154-
155-
text += "\r\n</details>\r\n* * *\r\n"
156-
return text
157-
158-
def _copy_all_changelogs(version, basedir, flavor="", architecture=64):
124+
def copy_changelogs(version, basedir, flavor="", architecture=64):
159125
basever = ".".join(version.split(".")[:2])
160-
pattern = re.compile(rf"WinPython{flavor}-{architecture}bit-{basever}([0-9\.]*)\.(txt|md)")
161-
for name in os.listdir(CHANGELOGS_DIR):
162-
if pattern.match(name):
163-
shutil.copyfile(CHANGELOGS_DIR / name, Path(basedir) / f"bu{flavor}" / name)
126+
pattern = re.compile(rf"WinPython{flavor}-{architecture}bit-{basever}[0-9\.]*\.(txt|md)")
127+
dest = Path(basedir) / f"bu{flavor}"
128+
for fname in os.listdir(CHANGELOGS_DIR):
129+
if pattern.match(fname):
130+
shutil.copyfile(CHANGELOGS_DIR / fname, dest / fname)
164131

165132
def write_changelog(version2, version1=None, basedir=None, flavor="", architecture=64):
166133
"""Write changelog between version1 and version2 of WinPython"""
167-
_copy_all_changelogs(version2, basedir, flavor, architecture)
134+
copy_changelogs(version2, basedir, flavor, architecture)
168135
print("comparing_package_indexes", version2, basedir, flavor, architecture)
169-
changelog_text = compare_package_indexes(version2, version1, basedir, flavor, architecture=architecture)
136+
changelog = compare_package_indexes(version2, version1, basedir, flavor, architecture=architecture)
170137
output_file = Path(basedir) / f"bu{flavor}" / f"WinPython{flavor}-{architecture}bit-{version2}_History.md"
171-
172-
with open(output_file, "w", encoding="utf-8") as fdesc:
173-
fdesc.write(changelog_text)
138+
with open(output_file, "w", encoding="utf-8") as f:
139+
f.write(changelog)
174140
# Copy to winpython/changelogs
175141
shutil.copyfile(output_file, CHANGELOGS_DIR / output_file.name)
176142

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.