Last active
January 19, 2026 11:53
-
-
Save aziis98/69779039e7f58a3fe70b625577bbbbfa to your computer and use it in GitHub Desktop.
This script parses version update lines from standard input, calculates a "distance" metric between old and new versions (prioritizing major version changes), and then prints the update lines sorted by this distance in descending order
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env python3 | |
| import re | |
| import sys | |
| def parse_version(version_str): | |
| """Parse version string, marking date/timestamp components""" | |
| parts = [] | |
| for x in re.findall(r"\d+", version_str): | |
| is_date = len(x) >= 5 # 5+ digits likely a date/timestamp | |
| parts.append((int(x), is_date)) | |
| return parts | |
| def parse_line(line): | |
| # Match pattern: package old_version -> new_version | |
| match = re.match(r"(\S+)\s+(\S+)\s+->\s+(\S+)", line.strip()) | |
| if not match: | |
| return None | |
| package, old_ver, new_ver = match.groups() | |
| # Extract numeric parts with date detection | |
| old_parts = parse_version(old_ver) | |
| new_parts = parse_version(new_ver) | |
| return {"package": package, "old_parts": old_parts, "new_parts": new_parts, "line": line.strip()} | |
| def version_distance(old_parts, new_parts): | |
| """Calculate a rough metric of version difference""" | |
| # Pad to same length with (0, False) | |
| max_len = max(len(old_parts), len(new_parts)) | |
| old_padded = old_parts + [(0, False)] * (max_len - len(old_parts)) | |
| new_padded = new_parts + [(0, False)] * (max_len - len(new_parts)) | |
| # Weight earlier positions more heavily (major > minor > patch) | |
| weight = 1 | |
| distance = 0 | |
| for (o_val, o_is_date), (n_val, n_is_date) in zip(old_padded, new_padded): | |
| # If either part is a date/timestamp, normalize and use tiny weight | |
| # e.g. luajit 2.1.1765228720 -> 2.1.1767980792 (Unix timestamps) | |
| if o_is_date or n_is_date: | |
| # Normalize: any date/timestamp change counts as ~0.001 regardless of magnitude | |
| if o_val != n_val: | |
| distance += 0.1 * weight | |
| else: | |
| distance += abs(n_val - o_val) * weight | |
| weight *= 0.01 # Each level is 100x less significant | |
| return distance | |
| def main(): | |
| updates = [] | |
| for line in sys.stdin: | |
| parsed = parse_line(line) | |
| if parsed: | |
| dist = version_distance(parsed["old_parts"], parsed["new_parts"]) | |
| updates.append((dist, parsed["line"])) | |
| # Sort by distance (descending - greatest first) | |
| updates.sort(key=lambda x: x[0], reverse=True) | |
| # Print sorted results | |
| for _, line in updates: | |
| print(line) | |
| if __name__ == "__main__": | |
| main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment