Commit c88697ca by Ned Batchelder

Merge pull request #11634 from edx/ned/better-uninstall

A better way to manage the Python packages to uninstall.
parents 85df4eee 526db729
...@@ -5,11 +5,12 @@ Install Python and Node prerequisites. ...@@ -5,11 +5,12 @@ Install Python and Node prerequisites.
from distutils import sysconfig from distutils import sysconfig
import hashlib import hashlib
import os import os
import re
import sys
from paver.easy import sh, task from paver.easy import sh, task
from .utils.envs import Env from .utils.envs import Env
import sys
PREREQS_STATE_DIR = os.getenv('PREREQ_CACHE_DIR', Env.REPO_ROOT / '.prereqs_cache') PREREQS_STATE_DIR = os.getenv('PREREQ_CACHE_DIR', Env.REPO_ROOT / '.prereqs_cache')
...@@ -151,6 +152,16 @@ def install_node_prereqs(): ...@@ -151,6 +152,16 @@ def install_node_prereqs():
prereq_cache("Node prereqs", ["package.json"], node_prereqs_installation) prereq_cache("Node prereqs", ["package.json"], node_prereqs_installation)
# To add a package to the uninstall list, just add it to this list! No need
# to touch any other part of this file.
PACKAGES_TO_UNINSTALL = [
"South", # Because it interferes with Django 1.8 migrations.
"edxval", # Because it was bork-installed somehow.
"django-storages",
"django-oauth2-provider", # Because now it's called edx-django-oauth2-provider.
]
@task @task
def uninstall_python_packages(): def uninstall_python_packages():
""" """
...@@ -162,14 +173,18 @@ def uninstall_python_packages(): ...@@ -162,14 +173,18 @@ def uninstall_python_packages():
them. them.
""" """
# So that we don't constantly uninstall things, use a version number of the # So that we don't constantly uninstall things, use a hash of the packages
# uninstallation needs. Check it, and skip this if we're up to date. # to be uninstalled. Check it, and skip this if we're up to date.
expected_version = 3 hasher = hashlib.sha1()
state_file_path = os.path.join(PREREQS_STATE_DIR, "python_uninstall_version.txt") hasher.update(repr(PACKAGES_TO_UNINSTALL))
expected_version = hasher.hexdigest()
state_file_path = os.path.join(PREREQS_STATE_DIR, "Python_uninstall.sha1")
if os.path.isfile(state_file_path): if os.path.isfile(state_file_path):
with open(state_file_path) as state_file: with open(state_file_path) as state_file:
version = int(state_file.read()) version = state_file.read()
if version == expected_version: if version == expected_version:
print 'Python uninstalls unchanged, skipping...'
return return
# Run pip to find the packages we need to get rid of. Believe it or not, # Run pip to find the packages we need to get rid of. Believe it or not,
...@@ -177,27 +192,13 @@ def uninstall_python_packages(): ...@@ -177,27 +192,13 @@ def uninstall_python_packages():
# to really really get rid of it. # to really really get rid of it.
for _ in range(3): for _ in range(3):
uninstalled = False uninstalled = False
frozen = sh("pip freeze", capture=True).splitlines() frozen = sh("pip freeze", capture=True)
# Uninstall South
if any(line.startswith("South") for line in frozen):
sh("pip uninstall --disable-pip-version-check -y South")
uninstalled = True
# Uninstall edx-val
if any("edxval" in line for line in frozen):
sh("pip uninstall --disable-pip-version-check -y edxval")
uninstalled = True
# Uninstall django-storages
if any("django-storages==" in line for line in frozen):
sh("pip uninstall --disable-pip-version-check -y django-storages")
uninstalled = True
# Uninstall django-oauth2-provider for package_name in PACKAGES_TO_UNINSTALL:
if any(line.startswith("django-oauth2-provider==") for line in frozen): if package_in_frozen(package_name, frozen):
sh("pip uninstall --disable-pip-version-check -y django-oauth2-provider") # Uninstall the pacakge
uninstalled = True sh("pip uninstall --disable-pip-version-check -y {}".format(package_name))
uninstalled = True
if not uninstalled: if not uninstalled:
break break
...@@ -208,7 +209,24 @@ def uninstall_python_packages(): ...@@ -208,7 +209,24 @@ def uninstall_python_packages():
# Write our version. # Write our version.
with open(state_file_path, "w") as state_file: with open(state_file_path, "w") as state_file:
state_file.write(str(expected_version)) state_file.write(expected_version)
def package_in_frozen(package_name, frozen_output):
"""Is this package in the output of 'pip freeze'?"""
# Look for either:
#
# PACKAGE-NAME==
#
# or:
#
# blah_blah#egg=package_name-version
#
pattern = r"(?mi)^{pkg}==|#egg={pkg_under}-".format(
pkg=re.escape(package_name),
pkg_under=re.escape(package_name.replace("-", "_")),
)
return bool(re.search(pattern, frozen_output))
@task @task
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment