Skip to content
This repository has been archived by the owner on May 23, 2023. It is now read-only.

Commit

Permalink
seems to work?
Browse files Browse the repository at this point in the history
  • Loading branch information
Buck Golemon committed Nov 25, 2014
2 parents d3e2076 + f08fb9a commit a471810
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 16 deletions.
4 changes: 4 additions & 0 deletions TODO
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ Should probably do before it hits users
Things that I want to do, but would put me past my deadline:

* coverage: 155, 209, 226, 230-232, 303-304, 384, 388
* coverage: 155, 208, 225, 229-231, 338, 368, 372

* populate wheels into the cache during build
see also: https://github.com/pypa/pip/pull/1572

* On ubuntu stock python2.7 I have to rm -rf $VIRTUAL_ENV/local
to avoid the AssertionError('unexpected third case')
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
-r requirements.d/prod.txt
pep8==1.0
111 changes: 95 additions & 16 deletions venv_update.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,26 @@ def _get_page(self, link, req):
PackageFinder._get_page = orig_packagefinder['_get_page']


def pip(args):
"""Run pip, in-process."""
import pip as pipmodule

# pip<1.6 needs its logging config reset on each invocation, or else we get duplicate outputs -.-
pipmodule.logger.consumers = []

from sys import stdout
stdout.write(colorize(('pip',) + args))
stdout.write('\n')
stdout.flush()

with faster_pip_packagefinder():
result = pipmodule.main(list(args))

if result != 0:
# pip exited with failure, then we should too
exit(result)


def pip_get_installed():
"""Code extracted from the middle of the pip freeze command.
"""
Expand Down Expand Up @@ -172,24 +192,78 @@ def pip_parse_requirements(requirement_files):
return required


def is_absolute(requirement):
# TODO: unit-test
if not requirement:
# url-style requirement
return False

for qualifier, dummy_version in requirement.specs:
if qualifier == '==':
return True
return False


def exactly_satisfied(pipreq):
if not is_absolute(pipreq.req):
return False

return pipreq.check_if_exists()


def filter_exactly_satisfied(reqs):
result = {}
for pkg, req in reqs.items():
if exactly_satisfied(req):
print('Requirement already up-to-date: %s' % req)
else:
result[pkg] = req
return result


def format_req(pipreq):
"""un-parse a pip requirement back to commandline arguments"""
# TODO: unit-test
if pipreq.editable:
editable = ('-e',)
else:
editable = ()

if pipreq.url:
spec = (pipreq.url,)
else:
spec = (str(pipreq.req),)

return editable + spec


def pip_install(args):
"""Run pip install, and return the set of packages installed.
"""
from sys import stdout
stdout.write(colorize(('pip', 'install') + args))
stdout.write('\n')
stdout.flush()

from pip.commands.install import InstallCommand
install = InstallCommand()
options, args = install.parse_args(list(args))

with faster_pip_packagefinder():
successfully_installed = install.run(options, args)
if successfully_installed is None:
orig_installcommand = vars(InstallCommand).copy()

class _nonlocal(object):
successfully_installed = None

def install(self, options, args):
"""capture the list of successfully installed packages as they pass through"""
result = orig_installcommand['run'](self, options, args)
_nonlocal.successfully_installed = result
return result

# A poor man's dependency injection: monkeypatch :(
InstallCommand.run = install
try:
pip(('install',) + args)
finally:
InstallCommand.run = orig_installcommand['run']

if _nonlocal.successfully_installed is None:
return {}
else:
return dict(successfully_installed.requirements)
return dict(_nonlocal.successfully_installed.requirements)


def trace_requirements(requirements):
Expand Down Expand Up @@ -251,12 +325,17 @@ def venv_uses_system_site_packages():

def do_install(reqs):
from os import environ
from sys import executable as python

previously_installed = pip_get_installed()
required = pip_parse_requirements(reqs)
requirements_as_options = tuple(
'--requirement={0}'.format(requirement) for requirement in reqs

unsatisfied = filter_exactly_satisfied(required)
requirements_as_options = sum(
(
format_req(req)
for pkg, req in unsatisfied.items()
),
()
)

# We put the cache in the directory that pip already uses.
Expand All @@ -273,7 +352,7 @@ def do_install(reqs):
'--find-links=file://' + pip_download_cache,
)

# 3) Install: Use our well-populated cache (only) to do the installations.
# 3) Install: Use our well-populated cache to do the installations.
# --use-wheel is somewhat redundant here, but it means we get an error if we have a bad version of pip/setuptools.
install_opts = ('--upgrade', '--use-wheel',) + cache_opts
if venv_uses_system_site_packages():
Expand All @@ -298,7 +377,7 @@ def do_install(reqs):

# 4) Uninstall any extraneous packages.
if extraneous:
run((python, '-m', 'pip', 'uninstall', '--yes') + tuple(sorted(extraneous)))
pip(('uninstall', '--yes') + tuple(sorted(extraneous)))

return 0 # posix:success!

Expand Down

0 comments on commit a471810

Please sign in to comment.