mirror of
https://github.com/pypa/pip
synced 2023-12-13 21:30:23 +01:00
Re-implement Git version parsing with regex
After packaging drops LegacyVersion, version.parse() will no longer guarantee to be able to parse Git versions, so we need to invent our own parser. Since we really only care about the major and minor segments, the logic is pretty simple.
This commit is contained in:
parent
bef589d8cb
commit
72e38ca3df
2
news/10117.removal.rst
Normal file
2
news/10117.removal.rst
Normal file
|
@ -0,0 +1,2 @@
|
|||
Git version parsing is now done with regular expression to prepare for the
|
||||
pending upstream removal of non-PEP-440 version parsing logic.
|
|
@ -6,9 +6,6 @@ import urllib.parse
|
|||
import urllib.request
|
||||
from typing import List, Optional, Tuple
|
||||
|
||||
from pip._vendor.packaging.version import _BaseVersion
|
||||
from pip._vendor.packaging.version import parse as parse_version
|
||||
|
||||
from pip._internal.exceptions import BadCommand, InstallationError
|
||||
from pip._internal.utils.misc import HiddenText, display_path, hide_url
|
||||
from pip._internal.utils.subprocess import make_command
|
||||
|
@ -29,6 +26,14 @@ urlunsplit = urllib.parse.urlunsplit
|
|||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
GIT_VERSION_REGEX = re.compile(
|
||||
r"^git version " # Prefix.
|
||||
r"(\d+)" # Major.
|
||||
r"\.(\d+)" # Dot, minor.
|
||||
r"(?:\.(\d+))?" # Optional dot, patch.
|
||||
r".*$" # Suffix, including any pre- and post-release segments we don't care about.
|
||||
)
|
||||
|
||||
HASH_REGEX = re.compile('^[a-fA-F0-9]{40}$')
|
||||
|
||||
# SCP (Secure copy protocol) shorthand. e.g. 'git@example.com:foo/bar.git'
|
||||
|
@ -83,21 +88,14 @@ class Git(VersionControl):
|
|||
)
|
||||
return not is_tag_or_branch
|
||||
|
||||
def get_git_version(self):
|
||||
# type: () -> _BaseVersion
|
||||
VERSION_PFX = 'git version '
|
||||
def get_git_version(self) -> Tuple[int, ...]:
|
||||
version = self.run_command(
|
||||
['version'], show_stdout=False, stdout_only=True
|
||||
)
|
||||
if version.startswith(VERSION_PFX):
|
||||
version = version[len(VERSION_PFX):].split()[0]
|
||||
else:
|
||||
version = ''
|
||||
# get first 3 positions of the git version because
|
||||
# on windows it is x.y.z.windows.t, and this parses as
|
||||
# LegacyVersion which always smaller than a Version.
|
||||
version = '.'.join(version.split('.')[:3])
|
||||
return parse_version(version)
|
||||
match = GIT_VERSION_REGEX.match(version)
|
||||
if not match:
|
||||
return ()
|
||||
return tuple(int(c) for c in match.groups())
|
||||
|
||||
@classmethod
|
||||
def get_current_branch(cls, location):
|
||||
|
@ -301,7 +299,7 @@ class Git(VersionControl):
|
|||
def update(self, dest, url, rev_options):
|
||||
# type: (str, HiddenText, RevOptions) -> None
|
||||
# First fetch changes from the default remote
|
||||
if self.get_git_version() >= parse_version('1.9.0'):
|
||||
if self.get_git_version() >= (1, 9):
|
||||
# fetch tags in addition to everything else
|
||||
self.run_command(['fetch', '-q', '--tags'], cwd=dest)
|
||||
else:
|
||||
|
|
|
@ -4,7 +4,6 @@ from unittest import TestCase
|
|||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
from pip._vendor.packaging.version import parse as parse_version
|
||||
|
||||
from pip._internal.exceptions import BadCommand, InstallationError
|
||||
from pip._internal.utils.misc import hide_url, hide_value
|
||||
|
@ -483,7 +482,7 @@ def test_subversion__get_url_rev_options():
|
|||
|
||||
def test_get_git_version():
|
||||
git_version = Git().get_git_version()
|
||||
assert git_version >= parse_version('1.0.0')
|
||||
assert git_version >= (1, 0, 0)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('use_interactive,is_atty,expected', [
|
||||
|
|
Loading…
Reference in a new issue