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

Commit

Permalink
after y-m integration. needs tests. (2)
Browse files Browse the repository at this point in the history
  • Loading branch information
Buck Golemon committed Nov 26, 2014
1 parent e893fb5 commit d1f5715
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 53 deletions.
8 changes: 8 additions & 0 deletions TODO
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@ Should probably do before it hits users

* currently if you get your arguments backwards, your requirements get deleted, replaced with empty dir. this is bad

acceptance tests:
* upgrading from A==1.0 to A==2.0 works
* downgrading "
* updating while active:
shutil.Error: `/nail/home/buck/pg/2/virtualenv_run/bin/python` and `virtualenv_run/bin/python` are the same file
* conflict error message
* all requirements already satisfied -> "must specify at least one requirement" error


Things that I want to do, but would put me past my deadline:

Expand Down
73 changes: 20 additions & 53 deletions venv_update.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,35 +186,6 @@ 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() and pipreq.satisfied_by


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


def format_req(pipreq):
"""un-parse a pip requirement back to commandline arguments"""
if pipreq.editable:
Expand Down Expand Up @@ -264,7 +235,17 @@ def trace_requirements(requirements):
return the set of required packages, given their transitive requirements.
"""
from pip.req import InstallRequirement
from pip._vendor.pkg_resources import get_provider, DistributionNotFound, VersionConflict
from pip._vendor import pkg_resources

class WorkingSetPlusEditableInstalls(pkg_resources.WorkingSet):
def add_entry(self, entry):
"""Same as the original .add_entry, but sets only=False, so that egg-links are honored."""
self.entry_keys.setdefault(entry, [])
self.entries.append(entry)
for dist in pkg_resources.find_distributions(entry, False):
self.add(dist, entry, False)

working_set = WorkingSetPlusEditableInstalls()

stack = list(requirements)
result = []
Expand All @@ -275,26 +256,17 @@ def trace_requirements(requirements):
continue

try:
dist = get_provider(req.req)
except (DistributionNotFound, IOError):
continue
except VersionConflict as conflict:
# provide essential debug information in case of conflict:
print("Version Conflict: %s %s" % (conflict, req))
dist = working_set.find(req.req)
except pkg_resources.VersionConflict as conflict:
# TODO: This should really be an error, but throw a warning for now, while we integrate.
print("Warning: version conflict: %s %s" % (conflict, req))
continue

result.append(dist_to_req(dist))

try:
dist_reqs = dist.requires() # should we support extras?
except IOError:
# This happens sometimes with setuptools. I don't understand why, yet.
# IOError: [Errno 2] No such file or directory: '${site-packages}/setuptools-3.6.dist-info/METADATA'
continue

for dist_req in dist_reqs:
if dist_req.project_name not in result:
stack.append(InstallRequirement(dist_req, str(req)))
for dist_req in dist.requires(): # should we support extras?
# there really shouldn't be any circular dependencies...
stack.append(InstallRequirement(dist_req, str(req)))

return result

Expand Down Expand Up @@ -324,13 +296,8 @@ def do_install(reqs):
previously_installed = pip_get_installed()
required = pip_parse_requirements(reqs)

unsatisfied = filter_exactly_satisfied(required)
requirements_as_options = sum(
(
format_req(req)
for req in unsatisfied
),
()
requirements_as_options = tuple(
'--requirement={0}'.format(requirement) for requirement in reqs
)

# We put the cache in the directory that pip already uses.
Expand Down

0 comments on commit d1f5715

Please sign in to comment.