Last active
January 14, 2022 16:08
-
-
Save mtwebster/eec06bb6fa1385ff05cf9624c4c6c414 to your computer and use it in GitHub Desktop.
This file contains 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 json | |
import sys | |
import subprocess | |
import re | |
import sysconfig | |
import shutil | |
if len(sys.argv) < 2: | |
print("Single argument must be the system package manager name (apt, rpm)") | |
exit(1) | |
PM = sys.argv[1] | |
if shutil.which("pip3") == None: | |
print("Program pip3 missing") | |
if PM == "apt": | |
print("Install it with 'apt install python3-pip' and run this script again") | |
elif PM == "rpm": | |
print("Install it with 'dnf install python3-pip' and run this script again") | |
exit(1) | |
# user_prefix = sysconfig.get_config_var("userbase") | |
# print("User python module location: %s" % user_prefix) | |
path_finder = re.compile(r"(?:Location:[\s]+?)([\S]+lib\/python3[\.]*[\d]*[\/]*[\S]*)") | |
# user_path_finder = re.compile(f"({{}})".format(re.escape(user_prefix))) | |
print("What this does...\n") | |
print("1 - Gather a list of all python3 modules on the system.") | |
print("2 - Filter out all non-system-managed modules.") | |
print("3 - Look for installed, system-managed python modules whose names are included in that filtered list.") | |
input("\nEnter to proceed\n") | |
def match_apt(name): | |
ret = subprocess.run(["dpkg-query", "--status", name], | |
stdout=subprocess.DEVNULL, | |
stderr=subprocess.DEVNULL | |
) | |
return ret.returncode == 0 | |
def match_rpm(name): | |
ret = subprocess.run(["rpm", "-q", name], | |
stdout=subprocess.DEVNULL, | |
stderr=subprocess.DEVNULL | |
) | |
return ret.returncode == 0 | |
print("Gathering all python3 module names...") | |
try: | |
pip3_list_out = subprocess.check_output(["pip3", "list", "--format", "json"], | |
stderr=subprocess.DEVNULL | |
).decode("utf-8") | |
pip3_json = json.loads(pip3_list_out) | |
except Exception as e: | |
print(e) | |
exit(0) | |
mod_candidates = [] | |
for item in pip3_json: | |
name = item["name"] | |
info = subprocess.check_output(["pip3", "show", "-f", name], | |
stderr=subprocess.DEVNULL | |
).decode("utf-8") | |
match = path_finder.search(info) | |
if match: | |
if "Cannot locate RECORD" in info: | |
continue | |
if match == "pip": | |
print("Skipping pip") | |
continue | |
print("Found %s" % name) | |
mod_candidates.append(name.lower()) | |
print("\nNow comparing those against system packages...\n") | |
overlapping_modules = [] | |
# "pip name" : "pm name" | |
APT_RENAMES = { | |
"pillow": "pil" | |
} | |
RPM_RENAMES = { | |
} | |
def adjusted(dict, pip_name): | |
if pip_name in dict.keys(): | |
print("Using %s in place of %s" % (dict[pip_name], pip_name)) | |
return dict[pip_name] | |
else: | |
return pip_name | |
for module in mod_candidates: | |
if PM == "apt": | |
sysmod = "python3-%s" % adjusted(APT_RENAMES, module) | |
if match_apt(sysmod): | |
print("Possible module conflict: %s -> %s" % (module, sysmod)) | |
overlapping_modules.append(sysmod) | |
elif PM == "rpm": | |
sysmod = "python3-%s" % adjusted (RPM_RENAMES, module) | |
if match_rpm(sysmod): | |
print("Possible module conflict: %s -> %s" % (module, sysmod)) | |
overlapping_modules.append(sysmod) | |
if PM == "apt": | |
cmd = ["apt", "reinstall"] + overlapping_modules | |
elif PM == "rpm": | |
cmd = ["dnf", "reinstall"] + overlapping_modules | |
pass | |
print("\nWill now use %s to re-install the system versions of these packages:\n" % PM) | |
print(" ".join(cmd)) | |
input("\nEnter to proceed (or hit ctrl-c now to abort)\n") | |
ret = subprocess.run(cmd) | |
if ret.returncode == 0: | |
print("Success!\n") | |
else: | |
print("Something went wrong...") | |
exit(0) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment