Last active
September 16, 2025 15:28
-
-
Save schorschii/7c0c72e72bb36dde966ba9f58b4a8da9 to your computer and use it in GitHub Desktop.
This is the apt downgrade logic of the mintupgrade GUI tool - useful if you want to upgrade many computers via CLI. After changing apt's sources.list and executing `apt dist-upgrade`, you need to downgrade some packages, e.g. base-files to show the correct Mint version in system info dialog (/etc/lsb-release).
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/python3 | |
| import apt | |
| import apt_pkg | |
| import aptsources.sourceslist | |
| import subprocess | |
| # Returns a tuple containing two lists | |
| # The first list is a list of orphaned packages (packages which have no origin) | |
| # The second list is a list of packages which version is not the official version (this does not | |
| # include packages which simply aren't up to date) | |
| def get_foreign_packages(find_orphans=True, find_downgradable_packages=True): | |
| orphan_packages = [] | |
| orphan_t64_names = [] | |
| downgradable_packages = [] | |
| cache = apt.Cache() | |
| for key in cache.keys(): | |
| if key == "mintupgrade": | |
| # Ignore mintupgrade, so we can test foreign versions of it. | |
| continue | |
| pkg = cache[key] | |
| if (pkg.is_installed): | |
| installed_version = pkg.installed.version | |
| # Find packages which aren't downloadable | |
| if (pkg.candidate == None) or (not pkg.candidate.downloadable): | |
| if find_orphans: | |
| downloadable = False | |
| for version in pkg.versions: | |
| if version.downloadable: | |
| downloadable = True | |
| if not downloadable: | |
| t64_name = f"{pkg.name}t64" | |
| if t64_name in cache: | |
| orphan_t64_names.append(t64_name) | |
| else: | |
| orphan_packages.append([pkg, installed_version]) | |
| if (pkg.candidate != None): | |
| if find_downgradable_packages: | |
| best_version = None | |
| archive = None | |
| for version in pkg.versions: | |
| if not version.downloadable: | |
| continue | |
| for origin in version.origins: | |
| if origin.origin != None and origin.origin.lower() in ("ubuntu", "canonical", "debian", "linuxmint"): | |
| if best_version is None: | |
| best_version = version | |
| archive = origin.archive | |
| else: | |
| if version.policy_priority > best_version.policy_priority: | |
| best_version = version | |
| archive = origin.archive | |
| elif version.policy_priority == best_version.policy_priority: | |
| # same priorities, compare version | |
| return_code = subprocess.call(["dpkg", "--compare-versions", version.version, "gt", best_version.version]) | |
| if return_code == 0: | |
| best_version = version | |
| archive = origin.archive | |
| if best_version != None and installed_version != best_version and pkg.candidate.version != best_version.version: | |
| downgradable_packages.append([pkg, installed_version, best_version, archive]) | |
| return (orphan_packages, orphan_t64_names, downgradable_packages) | |
| orphans, orphan_t64_names, foreigns = get_foreign_packages(find_orphans=False, find_downgradable_packages=True) | |
| # print downgradable packages | |
| for foreign in foreigns: | |
| print( foreign[0].name+'\t'+foreign[1]+'\t'+foreign[2].version ) | |
| print() | |
| # print apt command line for direct execution | |
| print( 'apt install', end=' ' ) | |
| for foreign in foreigns: | |
| print( foreign[0].name+'='+foreign[2].version, end=' ' ) | |
| print() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment