Skip to content

Commit

Permalink
Cache wheels built from immutable Git requirements
Browse files Browse the repository at this point in the history
Cache wheels that are built from Git requirements
that contain an immutable revision (i.e. a sha).
  • Loading branch information
sbidoul committed Nov 2, 2019
1 parent ab65900 commit 9086820
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 2 deletions.
3 changes: 3 additions & 0 deletions docs/html/reference/pip_install.rst
Original file line number Diff line number Diff line change
Expand Up @@ -573,6 +573,9 @@ and use any packages found there. This is disabled via the same
of that is not part of the pip API. As of 7.0, pip makes a subdirectory for
each sdist that wheels are built from and places the resulting wheels inside.

As of version 20.0, pip also caches wheels it built from Git requirements
when such requirements reference an immutable commit hash.

Pip attempts to choose the best wheels from those built in preference to
building a new wheel. Note that this means when a package has both optional
C extensions and builds ``py`` tagged wheels when the C extension can't be built
Expand Down
2 changes: 2 additions & 0 deletions news/6640.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Cache wheels built from Git requirements that are considered immutable,
because they point to a commit hash.
9 changes: 8 additions & 1 deletion src/pip/_internal/vcs/git.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from pip._vendor.six.moves.urllib import request as urllib_request

from pip._internal.exceptions import BadCommand
from pip._internal.utils.misc import display_path
from pip._internal.utils.misc import display_path, hide_url
from pip._internal.utils.subprocess import make_command
from pip._internal.utils.temp_dir import TempDirectory
from pip._internal.utils.typing import MYPY_CHECK_RUNNING
Expand Down Expand Up @@ -59,6 +59,13 @@ class Git(VersionControl):
def get_base_rev_args(rev):
return [rev]

def is_immutable_rev_checkout(self, url, dest):
# type: (str, str) -> bool
_, rev_options = self.get_url_rev_options(hide_url(url))
if not rev_options.rev:
return False
return self.is_commit_id_equal(dest, rev_options.rev)

def get_git_version(self):
VERSION_PFX = 'git version '
version = self.run_command(['version'], show_stdout=False)
Expand Down
14 changes: 14 additions & 0 deletions src/pip/_internal/vcs/versioncontrol.py
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,20 @@ def get_base_rev_args(rev):
"""
raise NotImplementedError

def is_immutable_rev_checkout(self, url, dest):
# type: (str, str) -> bool
"""
Return true if the commit hash checked out at dest matches
the revision in url.
Always return False, if the VCS does not support immutable commit
hashes.
This method does not check if there are local uncommitted changes
in dest after checkout, as pip currently has no use case for that.
"""
return False

@classmethod
def make_rev_options(cls, rev=None, extra_args=None):
# type: (Optional[str], Optional[CommandArgs]) -> RevOptions
Expand Down
11 changes: 10 additions & 1 deletion src/pip/_internal/wheel.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
from pip._internal.utils.ui import open_spinner
from pip._internal.utils.unpacking import unpack_file
from pip._internal.utils.urls import path_to_url
from pip._internal.vcs import vcs

if MYPY_CHECK_RUNNING:
from typing import (
Expand Down Expand Up @@ -838,7 +839,15 @@ def should_cache(
return False

if req.link and req.link.is_vcs:
# VCS checkout. Build wheel just for this run.
# VCS checkout. Build wheel just for this run
# unless it points to an immutable commit hash in which
# case it can be cached.
assert not req.editable
assert req.source_dir
vcs_backend = vcs.get_backend_for_scheme(req.link.scheme)
assert vcs_backend
if vcs_backend.is_immutable_rev_checkout(req.link.url, req.source_dir):
return True
return False

link = req.link
Expand Down
17 changes: 17 additions & 0 deletions tests/functional/test_vcs_git.py
Original file line number Diff line number Diff line change
Expand Up @@ -221,3 +221,20 @@ def test_is_commit_id_equal(script):
assert not Git.is_commit_id_equal(version_pkg_path, 'abc123')
# Also check passing a None value.
assert not Git.is_commit_id_equal(version_pkg_path, None)


def test_is_immutable_rev_checkout(script):
version_pkg_path = _create_test_package(script)
commit = script.run(
'git', 'rev-parse', 'HEAD',
cwd=version_pkg_path
).stdout.strip()
assert Git().is_immutable_rev_checkout(
"git+https://g.c/o/r@" + commit, version_pkg_path
)
assert not Git().is_immutable_rev_checkout(
"git+https://g.c/o/r", version_pkg_path
)
assert not Git().is_immutable_rev_checkout(
"git+https://g.c/o/r@master", version_pkg_path
)

0 comments on commit 9086820

Please sign in to comment.