Voice et bot modif
This commit is contained in:
parent
189d56026b
commit
7333a22bcd
10774 changed files with 634644 additions and 933308 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -1,6 +1,5 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
from typing import List, Optional, Tuple
|
||||
|
||||
from pip._internal.utils.misc import HiddenText, display_path
|
||||
from pip._internal.utils.subprocess import make_command
|
||||
|
|
@ -31,7 +30,7 @@ class Bazaar(VersionControl):
|
|||
)
|
||||
|
||||
@staticmethod
|
||||
def get_base_rev_args(rev: str) -> list[str]:
|
||||
def get_base_rev_args(rev: str) -> List[str]:
|
||||
return ["-r", rev]
|
||||
|
||||
def fetch_new(
|
||||
|
|
@ -45,51 +44,34 @@ class Bazaar(VersionControl):
|
|||
display_path(dest),
|
||||
)
|
||||
if verbosity <= 0:
|
||||
flags = ["--quiet"]
|
||||
flag = "--quiet"
|
||||
elif verbosity == 1:
|
||||
flags = []
|
||||
flag = ""
|
||||
else:
|
||||
flags = [f"-{'v'*verbosity}"]
|
||||
flag = f"-{'v'*verbosity}"
|
||||
cmd_args = make_command(
|
||||
"checkout", "--lightweight", *flags, rev_options.to_args(), url, dest
|
||||
"checkout", "--lightweight", flag, rev_options.to_args(), url, dest
|
||||
)
|
||||
self.run_command(cmd_args)
|
||||
|
||||
def switch(
|
||||
self,
|
||||
dest: str,
|
||||
url: HiddenText,
|
||||
rev_options: RevOptions,
|
||||
verbosity: int = 0,
|
||||
) -> None:
|
||||
def switch(self, dest: str, url: HiddenText, rev_options: RevOptions) -> None:
|
||||
self.run_command(make_command("switch", url), cwd=dest)
|
||||
|
||||
def update(
|
||||
self,
|
||||
dest: str,
|
||||
url: HiddenText,
|
||||
rev_options: RevOptions,
|
||||
verbosity: int = 0,
|
||||
) -> None:
|
||||
flags = []
|
||||
|
||||
if verbosity <= 0:
|
||||
flags.append("-q")
|
||||
|
||||
def update(self, dest: str, url: HiddenText, rev_options: RevOptions) -> None:
|
||||
output = self.run_command(
|
||||
make_command("info"), show_stdout=False, stdout_only=True, cwd=dest
|
||||
)
|
||||
if output.startswith("Standalone "):
|
||||
# Older versions of pip used to create standalone branches.
|
||||
# Convert the standalone branch to a checkout by calling "bzr bind".
|
||||
cmd_args = make_command("bind", *flags, url)
|
||||
cmd_args = make_command("bind", "-q", url)
|
||||
self.run_command(cmd_args, cwd=dest)
|
||||
|
||||
cmd_args = make_command("update", *flags, rev_options.to_args())
|
||||
cmd_args = make_command("update", "-q", rev_options.to_args())
|
||||
self.run_command(cmd_args, cwd=dest)
|
||||
|
||||
@classmethod
|
||||
def get_url_rev_and_auth(cls, url: str) -> tuple[str, str | None, AuthInfo]:
|
||||
def get_url_rev_and_auth(cls, url: str) -> Tuple[str, Optional[str], AuthInfo]:
|
||||
# hotfix the URL scheme after removing bzr+ from bzr+ssh:// re-add it
|
||||
url, rev, user_pass = super().get_url_rev_and_auth(url)
|
||||
if url.startswith("ssh://"):
|
||||
|
|
@ -122,7 +104,7 @@ class Bazaar(VersionControl):
|
|||
return revision.splitlines()[-1]
|
||||
|
||||
@classmethod
|
||||
def is_commit_id_equal(cls, dest: str, name: str | None) -> bool:
|
||||
def is_commit_id_equal(cls, dest: str, name: Optional[str]) -> bool:
|
||||
"""Always assume the versions don't match"""
|
||||
return False
|
||||
|
||||
|
|
|
|||
|
|
@ -1,13 +1,10 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import os.path
|
||||
import pathlib
|
||||
import re
|
||||
import urllib.parse
|
||||
import urllib.request
|
||||
from dataclasses import replace
|
||||
from typing import Any
|
||||
from typing import List, Optional, Tuple
|
||||
|
||||
from pip._internal.exceptions import BadCommand, InstallationError
|
||||
from pip._internal.utils.misc import HiddenText, display_path, hide_url
|
||||
|
|
@ -76,18 +73,9 @@ class Git(VersionControl):
|
|||
default_arg_rev = "HEAD"
|
||||
|
||||
@staticmethod
|
||||
def get_base_rev_args(rev: str) -> list[str]:
|
||||
def get_base_rev_args(rev: str) -> List[str]:
|
||||
return [rev]
|
||||
|
||||
@classmethod
|
||||
def run_command(cls, *args: Any, **kwargs: Any) -> str:
|
||||
if os.environ.get("PIP_NO_INPUT"):
|
||||
extra_environ = kwargs.get("extra_environ", {})
|
||||
extra_environ["GIT_TERMINAL_PROMPT"] = "0"
|
||||
extra_environ["GIT_SSH_COMMAND"] = "ssh -oBatchMode=yes"
|
||||
kwargs["extra_environ"] = extra_environ
|
||||
return super().run_command(*args, **kwargs)
|
||||
|
||||
def is_immutable_rev_checkout(self, url: str, dest: str) -> bool:
|
||||
_, rev_options = self.get_url_rev_options(hide_url(url))
|
||||
if not rev_options.rev:
|
||||
|
|
@ -102,7 +90,7 @@ class Git(VersionControl):
|
|||
is_tag_or_branch = bool(self.get_revision_sha(dest, rev_options.rev)[0])
|
||||
return not is_tag_or_branch
|
||||
|
||||
def get_git_version(self) -> tuple[int, ...]:
|
||||
def get_git_version(self) -> Tuple[int, ...]:
|
||||
version = self.run_command(
|
||||
["version"],
|
||||
command_desc="git version",
|
||||
|
|
@ -116,7 +104,7 @@ class Git(VersionControl):
|
|||
return (int(match.group(1)), int(match.group(2)))
|
||||
|
||||
@classmethod
|
||||
def get_current_branch(cls, location: str) -> str | None:
|
||||
def get_current_branch(cls, location: str) -> Optional[str]:
|
||||
"""
|
||||
Return the current branch, or None if HEAD isn't at a branch
|
||||
(e.g. detached HEAD).
|
||||
|
|
@ -141,7 +129,7 @@ class Git(VersionControl):
|
|||
return None
|
||||
|
||||
@classmethod
|
||||
def get_revision_sha(cls, dest: str, rev: str) -> tuple[str | None, bool]:
|
||||
def get_revision_sha(cls, dest: str, rev: str) -> Tuple[Optional[str], bool]:
|
||||
"""
|
||||
Return (sha_or_none, is_branch), where sha_or_none is a commit hash
|
||||
if the revision names a remote branch or tag, otherwise None.
|
||||
|
|
@ -229,14 +217,14 @@ class Git(VersionControl):
|
|||
|
||||
if sha is not None:
|
||||
rev_options = rev_options.make_new(sha)
|
||||
rev_options = replace(rev_options, branch_name=(rev if is_branch else None))
|
||||
rev_options.branch_name = rev if is_branch else None
|
||||
|
||||
return rev_options
|
||||
|
||||
# Do not show a warning for the common case of something that has
|
||||
# the form of a Git commit hash.
|
||||
if not looks_like_hash(rev):
|
||||
logger.info(
|
||||
logger.warning(
|
||||
"Did not find branch or tag '%s', assuming revision or ref.",
|
||||
rev,
|
||||
)
|
||||
|
|
@ -256,7 +244,7 @@ class Git(VersionControl):
|
|||
return rev_options
|
||||
|
||||
@classmethod
|
||||
def is_commit_id_equal(cls, dest: str, name: str | None) -> bool:
|
||||
def is_commit_id_equal(cls, dest: str, name: Optional[str]) -> bool:
|
||||
"""
|
||||
Return whether the current commit hash equals the given name.
|
||||
|
||||
|
|
@ -276,7 +264,7 @@ class Git(VersionControl):
|
|||
rev_display = rev_options.to_display()
|
||||
logger.info("Cloning %s%s to %s", url, rev_display, display_path(dest))
|
||||
if verbosity <= 0:
|
||||
flags: tuple[str, ...] = ("--quiet",)
|
||||
flags: Tuple[str, ...] = ("--quiet",)
|
||||
elif verbosity == 1:
|
||||
flags = ()
|
||||
else:
|
||||
|
|
@ -331,59 +319,31 @@ class Git(VersionControl):
|
|||
logger.info("Resolved %s to commit %s", url, rev_options.rev)
|
||||
|
||||
#: repo may contain submodules
|
||||
self.update_submodules(dest, verbosity=verbosity)
|
||||
self.update_submodules(dest)
|
||||
|
||||
def switch(
|
||||
self,
|
||||
dest: str,
|
||||
url: HiddenText,
|
||||
rev_options: RevOptions,
|
||||
verbosity: int = 0,
|
||||
) -> None:
|
||||
def switch(self, dest: str, url: HiddenText, rev_options: RevOptions) -> None:
|
||||
self.run_command(
|
||||
make_command("config", "remote.origin.url", url),
|
||||
cwd=dest,
|
||||
)
|
||||
|
||||
extra_flags = []
|
||||
|
||||
if verbosity <= 0:
|
||||
extra_flags.append("-q")
|
||||
|
||||
cmd_args = make_command("checkout", *extra_flags, rev_options.to_args())
|
||||
cmd_args = make_command("checkout", "-q", rev_options.to_args())
|
||||
self.run_command(cmd_args, cwd=dest)
|
||||
|
||||
self.update_submodules(dest, verbosity=verbosity)
|
||||
|
||||
def update(
|
||||
self,
|
||||
dest: str,
|
||||
url: HiddenText,
|
||||
rev_options: RevOptions,
|
||||
verbosity: int = 0,
|
||||
) -> None:
|
||||
extra_flags = []
|
||||
|
||||
if verbosity <= 0:
|
||||
extra_flags.append("-q")
|
||||
self.update_submodules(dest)
|
||||
|
||||
def update(self, dest: str, url: HiddenText, rev_options: RevOptions) -> None:
|
||||
# First fetch changes from the default remote
|
||||
if self.get_git_version() >= (1, 9):
|
||||
# fetch tags in addition to everything else
|
||||
self.run_command(["fetch", "--tags", *extra_flags], cwd=dest)
|
||||
self.run_command(["fetch", "-q", "--tags"], cwd=dest)
|
||||
else:
|
||||
self.run_command(["fetch", *extra_flags], cwd=dest)
|
||||
self.run_command(["fetch", "-q"], cwd=dest)
|
||||
# Then reset to wanted revision (maybe even origin/master)
|
||||
rev_options = self.resolve_revision(dest, url, rev_options)
|
||||
cmd_args = make_command(
|
||||
"reset",
|
||||
"--hard",
|
||||
*extra_flags,
|
||||
rev_options.to_args(),
|
||||
)
|
||||
cmd_args = make_command("reset", "--hard", "-q", rev_options.to_args())
|
||||
self.run_command(cmd_args, cwd=dest)
|
||||
#: update submodules
|
||||
self.update_submodules(dest, verbosity=verbosity)
|
||||
self.update_submodules(dest)
|
||||
|
||||
@classmethod
|
||||
def get_remote_url(cls, location: str) -> str:
|
||||
|
|
@ -463,7 +423,7 @@ class Git(VersionControl):
|
|||
return True
|
||||
|
||||
@classmethod
|
||||
def get_revision(cls, location: str, rev: str | None = None) -> str:
|
||||
def get_revision(cls, location: str, rev: Optional[str] = None) -> str:
|
||||
if rev is None:
|
||||
rev = "HEAD"
|
||||
current_rev = cls.run_command(
|
||||
|
|
@ -475,7 +435,7 @@ class Git(VersionControl):
|
|||
return current_rev.strip()
|
||||
|
||||
@classmethod
|
||||
def get_subdirectory(cls, location: str) -> str | None:
|
||||
def get_subdirectory(cls, location: str) -> Optional[str]:
|
||||
"""
|
||||
Return the path to Python project root, relative to the repo root.
|
||||
Return None if the project root is in the repo root.
|
||||
|
|
@ -493,7 +453,7 @@ class Git(VersionControl):
|
|||
return find_path_to_project_root_from_repo_root(location, repo_root)
|
||||
|
||||
@classmethod
|
||||
def get_url_rev_and_auth(cls, url: str) -> tuple[str, str | None, AuthInfo]:
|
||||
def get_url_rev_and_auth(cls, url: str) -> Tuple[str, Optional[str], AuthInfo]:
|
||||
"""
|
||||
Prefixes stub URLs like 'user@hostname:user/repo.git' with 'ssh://'.
|
||||
That's required because although they use SSH they sometimes don't
|
||||
|
|
@ -524,21 +484,16 @@ class Git(VersionControl):
|
|||
return url, rev, user_pass
|
||||
|
||||
@classmethod
|
||||
def update_submodules(cls, location: str, verbosity: int = 0) -> None:
|
||||
argv = ["submodule", "update", "--init", "--recursive"]
|
||||
|
||||
if verbosity <= 0:
|
||||
argv.append("-q")
|
||||
|
||||
def update_submodules(cls, location: str) -> None:
|
||||
if not os.path.exists(os.path.join(location, ".gitmodules")):
|
||||
return
|
||||
cls.run_command(
|
||||
argv,
|
||||
["submodule", "update", "--init", "--recursive", "-q"],
|
||||
cwd=location,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def get_repository_root(cls, location: str) -> str | None:
|
||||
def get_repository_root(cls, location: str) -> Optional[str]:
|
||||
loc = super().get_repository_root(location)
|
||||
if loc:
|
||||
return loc
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import configparser
|
||||
import logging
|
||||
import os
|
||||
from typing import List, Optional, Tuple
|
||||
|
||||
from pip._internal.exceptions import BadCommand, InstallationError
|
||||
from pip._internal.utils.misc import HiddenText, display_path
|
||||
|
|
@ -31,7 +30,7 @@ class Mercurial(VersionControl):
|
|||
)
|
||||
|
||||
@staticmethod
|
||||
def get_base_rev_args(rev: str) -> list[str]:
|
||||
def get_base_rev_args(rev: str) -> List[str]:
|
||||
return [f"--rev={rev}"]
|
||||
|
||||
def fetch_new(
|
||||
|
|
@ -45,7 +44,7 @@ class Mercurial(VersionControl):
|
|||
display_path(dest),
|
||||
)
|
||||
if verbosity <= 0:
|
||||
flags: tuple[str, ...] = ("--quiet",)
|
||||
flags: Tuple[str, ...] = ("--quiet",)
|
||||
elif verbosity == 1:
|
||||
flags = ()
|
||||
elif verbosity == 2:
|
||||
|
|
@ -58,20 +57,9 @@ class Mercurial(VersionControl):
|
|||
cwd=dest,
|
||||
)
|
||||
|
||||
def switch(
|
||||
self,
|
||||
dest: str,
|
||||
url: HiddenText,
|
||||
rev_options: RevOptions,
|
||||
verbosity: int = 0,
|
||||
) -> None:
|
||||
extra_flags = []
|
||||
def switch(self, dest: str, url: HiddenText, rev_options: RevOptions) -> None:
|
||||
repo_config = os.path.join(dest, self.dirname, "hgrc")
|
||||
config = configparser.RawConfigParser()
|
||||
|
||||
if verbosity <= 0:
|
||||
extra_flags.append("-q")
|
||||
|
||||
try:
|
||||
config.read(repo_config)
|
||||
config.set("paths", "default", url.secret)
|
||||
|
|
@ -80,23 +68,12 @@ class Mercurial(VersionControl):
|
|||
except (OSError, configparser.NoSectionError) as exc:
|
||||
logger.warning("Could not switch Mercurial repository to %s: %s", url, exc)
|
||||
else:
|
||||
cmd_args = make_command("update", *extra_flags, rev_options.to_args())
|
||||
cmd_args = make_command("update", "-q", rev_options.to_args())
|
||||
self.run_command(cmd_args, cwd=dest)
|
||||
|
||||
def update(
|
||||
self,
|
||||
dest: str,
|
||||
url: HiddenText,
|
||||
rev_options: RevOptions,
|
||||
verbosity: int = 0,
|
||||
) -> None:
|
||||
extra_flags = []
|
||||
|
||||
if verbosity <= 0:
|
||||
extra_flags.append("-q")
|
||||
|
||||
self.run_command(["pull", *extra_flags], cwd=dest)
|
||||
cmd_args = make_command("update", *extra_flags, rev_options.to_args())
|
||||
def update(self, dest: str, url: HiddenText, rev_options: RevOptions) -> None:
|
||||
self.run_command(["pull", "-q"], cwd=dest)
|
||||
cmd_args = make_command("update", "-q", rev_options.to_args())
|
||||
self.run_command(cmd_args, cwd=dest)
|
||||
|
||||
@classmethod
|
||||
|
|
@ -139,12 +116,12 @@ class Mercurial(VersionControl):
|
|||
return current_rev_hash
|
||||
|
||||
@classmethod
|
||||
def is_commit_id_equal(cls, dest: str, name: str | None) -> bool:
|
||||
def is_commit_id_equal(cls, dest: str, name: Optional[str]) -> bool:
|
||||
"""Always assume the versions don't match"""
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
def get_subdirectory(cls, location: str) -> str | None:
|
||||
def get_subdirectory(cls, location: str) -> Optional[str]:
|
||||
"""
|
||||
Return the path to Python project root, relative to the repo root.
|
||||
Return None if the project root is in the repo root.
|
||||
|
|
@ -158,7 +135,7 @@ class Mercurial(VersionControl):
|
|||
return find_path_to_project_root_from_repo_root(location, repo_root)
|
||||
|
||||
@classmethod
|
||||
def get_repository_root(cls, location: str) -> str | None:
|
||||
def get_repository_root(cls, location: str) -> Optional[str]:
|
||||
loc = super().get_repository_root(location)
|
||||
if loc:
|
||||
return loc
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
from typing import List, Optional, Tuple
|
||||
|
||||
from pip._internal.utils.misc import (
|
||||
HiddenText,
|
||||
|
|
@ -39,7 +38,7 @@ class Subversion(VersionControl):
|
|||
return True
|
||||
|
||||
@staticmethod
|
||||
def get_base_rev_args(rev: str) -> list[str]:
|
||||
def get_base_rev_args(rev: str) -> List[str]:
|
||||
return ["-r", rev]
|
||||
|
||||
@classmethod
|
||||
|
|
@ -74,7 +73,7 @@ class Subversion(VersionControl):
|
|||
@classmethod
|
||||
def get_netloc_and_auth(
|
||||
cls, netloc: str, scheme: str
|
||||
) -> tuple[str, tuple[str | None, str | None]]:
|
||||
) -> Tuple[str, Tuple[Optional[str], Optional[str]]]:
|
||||
"""
|
||||
This override allows the auth information to be passed to svn via the
|
||||
--username and --password options instead of via the URL.
|
||||
|
|
@ -87,7 +86,7 @@ class Subversion(VersionControl):
|
|||
return split_auth_from_netloc(netloc)
|
||||
|
||||
@classmethod
|
||||
def get_url_rev_and_auth(cls, url: str) -> tuple[str, str | None, AuthInfo]:
|
||||
def get_url_rev_and_auth(cls, url: str) -> Tuple[str, Optional[str], AuthInfo]:
|
||||
# hotfix the URL scheme after removing svn+ from svn+ssh:// re-add it
|
||||
url, rev, user_pass = super().get_url_rev_and_auth(url)
|
||||
if url.startswith("ssh://"):
|
||||
|
|
@ -95,7 +94,9 @@ class Subversion(VersionControl):
|
|||
return url, rev, user_pass
|
||||
|
||||
@staticmethod
|
||||
def make_rev_args(username: str | None, password: HiddenText | None) -> CommandArgs:
|
||||
def make_rev_args(
|
||||
username: Optional[str], password: Optional[HiddenText]
|
||||
) -> CommandArgs:
|
||||
extra_args: CommandArgs = []
|
||||
if username:
|
||||
extra_args += ["--username", username]
|
||||
|
|
@ -129,7 +130,7 @@ class Subversion(VersionControl):
|
|||
return url
|
||||
|
||||
@classmethod
|
||||
def _get_svn_url_rev(cls, location: str) -> tuple[str | None, int]:
|
||||
def _get_svn_url_rev(cls, location: str) -> Tuple[Optional[str], int]:
|
||||
from pip._internal.exceptions import InstallationError
|
||||
|
||||
entries_path = os.path.join(location, cls.dirname, "entries")
|
||||
|
|
@ -140,7 +141,7 @@ class Subversion(VersionControl):
|
|||
data = ""
|
||||
|
||||
url = None
|
||||
if data.startswith(("8", "9", "10")):
|
||||
if data.startswith("8") or data.startswith("9") or data.startswith("10"):
|
||||
entries = list(map(str.splitlines, data.split("\n\x0c\n")))
|
||||
del entries[0][0] # get rid of the '8'
|
||||
url = entries[0][3]
|
||||
|
|
@ -179,11 +180,11 @@ class Subversion(VersionControl):
|
|||
return url, rev
|
||||
|
||||
@classmethod
|
||||
def is_commit_id_equal(cls, dest: str, name: str | None) -> bool:
|
||||
def is_commit_id_equal(cls, dest: str, name: Optional[str]) -> bool:
|
||||
"""Always assume the versions don't match"""
|
||||
return False
|
||||
|
||||
def __init__(self, use_interactive: bool | None = None) -> None:
|
||||
def __init__(self, use_interactive: Optional[bool] = None) -> None:
|
||||
if use_interactive is None:
|
||||
use_interactive = is_console_interactive()
|
||||
self.use_interactive = use_interactive
|
||||
|
|
@ -193,11 +194,11 @@ class Subversion(VersionControl):
|
|||
# Special value definitions:
|
||||
# None: Not evaluated yet.
|
||||
# Empty tuple: Could not parse version.
|
||||
self._vcs_version: tuple[int, ...] | None = None
|
||||
self._vcs_version: Optional[Tuple[int, ...]] = None
|
||||
|
||||
super().__init__()
|
||||
|
||||
def call_vcs_version(self) -> tuple[int, ...]:
|
||||
def call_vcs_version(self) -> Tuple[int, ...]:
|
||||
"""Query the version of the currently installed Subversion client.
|
||||
|
||||
:return: A tuple containing the parts of the version information or
|
||||
|
|
@ -225,7 +226,7 @@ class Subversion(VersionControl):
|
|||
|
||||
return parsed_version
|
||||
|
||||
def get_vcs_version(self) -> tuple[int, ...]:
|
||||
def get_vcs_version(self) -> Tuple[int, ...]:
|
||||
"""Return the version of the currently installed Subversion client.
|
||||
|
||||
If the version of the Subversion client has already been queried,
|
||||
|
|
@ -287,12 +288,12 @@ class Subversion(VersionControl):
|
|||
display_path(dest),
|
||||
)
|
||||
if verbosity <= 0:
|
||||
flags = ["--quiet"]
|
||||
flag = "--quiet"
|
||||
else:
|
||||
flags = []
|
||||
flag = ""
|
||||
cmd_args = make_command(
|
||||
"checkout",
|
||||
*flags,
|
||||
flag,
|
||||
self.get_remote_call_options(),
|
||||
rev_options.to_args(),
|
||||
url,
|
||||
|
|
@ -300,13 +301,7 @@ class Subversion(VersionControl):
|
|||
)
|
||||
self.run_command(cmd_args)
|
||||
|
||||
def switch(
|
||||
self,
|
||||
dest: str,
|
||||
url: HiddenText,
|
||||
rev_options: RevOptions,
|
||||
verbosity: int = 0,
|
||||
) -> None:
|
||||
def switch(self, dest: str, url: HiddenText, rev_options: RevOptions) -> None:
|
||||
cmd_args = make_command(
|
||||
"switch",
|
||||
self.get_remote_call_options(),
|
||||
|
|
@ -316,13 +311,7 @@ class Subversion(VersionControl):
|
|||
)
|
||||
self.run_command(cmd_args)
|
||||
|
||||
def update(
|
||||
self,
|
||||
dest: str,
|
||||
url: HiddenText,
|
||||
rev_options: RevOptions,
|
||||
verbosity: int = 0,
|
||||
) -> None:
|
||||
def update(self, dest: str, url: HiddenText, rev_options: RevOptions) -> None:
|
||||
cmd_args = make_command(
|
||||
"update",
|
||||
self.get_remote_call_options(),
|
||||
|
|
|
|||
|
|
@ -1,18 +1,22 @@
|
|||
"""Handles all VCS (version control) support"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
import urllib.parse
|
||||
from collections.abc import Iterable, Iterator, Mapping
|
||||
from dataclasses import dataclass, field
|
||||
from typing import (
|
||||
TYPE_CHECKING,
|
||||
Any,
|
||||
Literal,
|
||||
Dict,
|
||||
Iterable,
|
||||
Iterator,
|
||||
List,
|
||||
Mapping,
|
||||
Optional,
|
||||
Tuple,
|
||||
Type,
|
||||
Union,
|
||||
)
|
||||
|
||||
from pip._internal.cli.spinners import SpinnerInterface
|
||||
|
|
@ -33,27 +37,35 @@ from pip._internal.utils.subprocess import (
|
|||
format_command_args,
|
||||
make_command,
|
||||
)
|
||||
from pip._internal.utils.urls import get_url_scheme
|
||||
|
||||
if TYPE_CHECKING:
|
||||
# Literal was introduced in Python 3.8.
|
||||
#
|
||||
# TODO: Remove `if TYPE_CHECKING` when dropping support for Python 3.7.
|
||||
from typing import Literal
|
||||
|
||||
|
||||
__all__ = ["vcs"]
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
AuthInfo = tuple[Optional[str], Optional[str]]
|
||||
AuthInfo = Tuple[Optional[str], Optional[str]]
|
||||
|
||||
|
||||
def is_url(name: str) -> bool:
|
||||
"""
|
||||
Return true if the name looks like a URL.
|
||||
"""
|
||||
scheme = urllib.parse.urlsplit(name).scheme
|
||||
if not scheme:
|
||||
scheme = get_url_scheme(name)
|
||||
if scheme is None:
|
||||
return False
|
||||
return scheme in ["http", "https", "file", "ftp"] + vcs.all_schemes
|
||||
|
||||
|
||||
def make_vcs_requirement_url(
|
||||
repo_url: str, rev: str, project_name: str, subdir: str | None = None
|
||||
repo_url: str, rev: str, project_name: str, subdir: Optional[str] = None
|
||||
) -> str:
|
||||
"""
|
||||
Return the URL for a VCS requirement.
|
||||
|
|
@ -72,7 +84,7 @@ def make_vcs_requirement_url(
|
|||
|
||||
def find_path_to_project_root_from_repo_root(
|
||||
location: str, repo_root: str
|
||||
) -> str | None:
|
||||
) -> Optional[str]:
|
||||
"""
|
||||
Find the the Python project's root by searching up the filesystem from
|
||||
`location`. Return the path to project root relative to `repo_root`.
|
||||
|
|
@ -109,28 +121,40 @@ class RemoteNotValidError(Exception):
|
|||
self.url = url
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class RevOptions:
|
||||
|
||||
"""
|
||||
Encapsulates a VCS-specific revision to install, along with any VCS
|
||||
install options.
|
||||
|
||||
Args:
|
||||
vc_class: a VersionControl subclass.
|
||||
rev: the name of the revision to install.
|
||||
extra_args: a list of extra options.
|
||||
Instances of this class should be treated as if immutable.
|
||||
"""
|
||||
|
||||
vc_class: type[VersionControl]
|
||||
rev: str | None = None
|
||||
extra_args: CommandArgs = field(default_factory=list)
|
||||
branch_name: str | None = None
|
||||
def __init__(
|
||||
self,
|
||||
vc_class: Type["VersionControl"],
|
||||
rev: Optional[str] = None,
|
||||
extra_args: Optional[CommandArgs] = None,
|
||||
) -> None:
|
||||
"""
|
||||
Args:
|
||||
vc_class: a VersionControl subclass.
|
||||
rev: the name of the revision to install.
|
||||
extra_args: a list of extra options.
|
||||
"""
|
||||
if extra_args is None:
|
||||
extra_args = []
|
||||
|
||||
self.extra_args = extra_args
|
||||
self.rev = rev
|
||||
self.vc_class = vc_class
|
||||
self.branch_name: Optional[str] = None
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"<RevOptions {self.vc_class.name}: rev={self.rev!r}>"
|
||||
|
||||
@property
|
||||
def arg_rev(self) -> str | None:
|
||||
def arg_rev(self) -> Optional[str]:
|
||||
if self.rev is None:
|
||||
return self.vc_class.default_arg_rev
|
||||
|
||||
|
|
@ -154,7 +178,7 @@ class RevOptions:
|
|||
|
||||
return f" (to revision {self.rev})"
|
||||
|
||||
def make_new(self, rev: str) -> RevOptions:
|
||||
def make_new(self, rev: str) -> "RevOptions":
|
||||
"""
|
||||
Make a copy of the current instance, but with a new rev.
|
||||
|
||||
|
|
@ -165,7 +189,7 @@ class RevOptions:
|
|||
|
||||
|
||||
class VcsSupport:
|
||||
_registry: dict[str, VersionControl] = {}
|
||||
_registry: Dict[str, "VersionControl"] = {}
|
||||
schemes = ["ssh", "git", "hg", "bzr", "sftp", "svn"]
|
||||
|
||||
def __init__(self) -> None:
|
||||
|
|
@ -178,21 +202,21 @@ class VcsSupport:
|
|||
return self._registry.__iter__()
|
||||
|
||||
@property
|
||||
def backends(self) -> list[VersionControl]:
|
||||
def backends(self) -> List["VersionControl"]:
|
||||
return list(self._registry.values())
|
||||
|
||||
@property
|
||||
def dirnames(self) -> list[str]:
|
||||
def dirnames(self) -> List[str]:
|
||||
return [backend.dirname for backend in self.backends]
|
||||
|
||||
@property
|
||||
def all_schemes(self) -> list[str]:
|
||||
schemes: list[str] = []
|
||||
def all_schemes(self) -> List[str]:
|
||||
schemes: List[str] = []
|
||||
for backend in self.backends:
|
||||
schemes.extend(backend.schemes)
|
||||
return schemes
|
||||
|
||||
def register(self, cls: type[VersionControl]) -> None:
|
||||
def register(self, cls: Type["VersionControl"]) -> None:
|
||||
if not hasattr(cls, "name"):
|
||||
logger.warning("Cannot register VCS %s", cls.__name__)
|
||||
return
|
||||
|
|
@ -204,7 +228,7 @@ class VcsSupport:
|
|||
if name in self._registry:
|
||||
del self._registry[name]
|
||||
|
||||
def get_backend_for_dir(self, location: str) -> VersionControl | None:
|
||||
def get_backend_for_dir(self, location: str) -> Optional["VersionControl"]:
|
||||
"""
|
||||
Return a VersionControl object if a repository of that type is found
|
||||
at the given directory.
|
||||
|
|
@ -227,7 +251,7 @@ class VcsSupport:
|
|||
inner_most_repo_path = max(vcs_backends, key=len)
|
||||
return vcs_backends[inner_most_repo_path]
|
||||
|
||||
def get_backend_for_scheme(self, scheme: str) -> VersionControl | None:
|
||||
def get_backend_for_scheme(self, scheme: str) -> Optional["VersionControl"]:
|
||||
"""
|
||||
Return a VersionControl object or None.
|
||||
"""
|
||||
|
|
@ -236,7 +260,7 @@ class VcsSupport:
|
|||
return vcs_backend
|
||||
return None
|
||||
|
||||
def get_backend(self, name: str) -> VersionControl | None:
|
||||
def get_backend(self, name: str) -> Optional["VersionControl"]:
|
||||
"""
|
||||
Return a VersionControl object or None.
|
||||
"""
|
||||
|
|
@ -252,10 +276,10 @@ class VersionControl:
|
|||
dirname = ""
|
||||
repo_name = ""
|
||||
# List of supported schemes for this Version Control
|
||||
schemes: tuple[str, ...] = ()
|
||||
schemes: Tuple[str, ...] = ()
|
||||
# Iterable of environment variable names to pass to call_subprocess().
|
||||
unset_environ: tuple[str, ...] = ()
|
||||
default_arg_rev: str | None = None
|
||||
unset_environ: Tuple[str, ...] = ()
|
||||
default_arg_rev: Optional[str] = None
|
||||
|
||||
@classmethod
|
||||
def should_add_vcs_url_prefix(cls, remote_url: str) -> bool:
|
||||
|
|
@ -266,7 +290,7 @@ class VersionControl:
|
|||
return not remote_url.lower().startswith(f"{cls.name}:")
|
||||
|
||||
@classmethod
|
||||
def get_subdirectory(cls, location: str) -> str | None:
|
||||
def get_subdirectory(cls, location: str) -> Optional[str]:
|
||||
"""
|
||||
Return the path to Python project root, relative to the repo root.
|
||||
Return None if the project root is in the repo root.
|
||||
|
|
@ -305,7 +329,7 @@ class VersionControl:
|
|||
return req
|
||||
|
||||
@staticmethod
|
||||
def get_base_rev_args(rev: str) -> list[str]:
|
||||
def get_base_rev_args(rev: str) -> List[str]:
|
||||
"""
|
||||
Return the base revision arguments for a vcs command.
|
||||
|
||||
|
|
@ -329,7 +353,7 @@ class VersionControl:
|
|||
|
||||
@classmethod
|
||||
def make_rev_options(
|
||||
cls, rev: str | None = None, extra_args: CommandArgs | None = None
|
||||
cls, rev: Optional[str] = None, extra_args: Optional[CommandArgs] = None
|
||||
) -> RevOptions:
|
||||
"""
|
||||
Return a RevOptions object.
|
||||
|
|
@ -338,7 +362,7 @@ class VersionControl:
|
|||
rev: the name of a revision to install.
|
||||
extra_args: a list of extra options.
|
||||
"""
|
||||
return RevOptions(cls, rev, extra_args=extra_args or [])
|
||||
return RevOptions(cls, rev, extra_args=extra_args)
|
||||
|
||||
@classmethod
|
||||
def _is_local_repository(cls, repo: str) -> bool:
|
||||
|
|
@ -352,7 +376,7 @@ class VersionControl:
|
|||
@classmethod
|
||||
def get_netloc_and_auth(
|
||||
cls, netloc: str, scheme: str
|
||||
) -> tuple[str, tuple[str | None, str | None]]:
|
||||
) -> Tuple[str, Tuple[Optional[str], Optional[str]]]:
|
||||
"""
|
||||
Parse the repository URL's netloc, and return the new netloc to use
|
||||
along with auth information.
|
||||
|
|
@ -371,7 +395,7 @@ class VersionControl:
|
|||
return netloc, (None, None)
|
||||
|
||||
@classmethod
|
||||
def get_url_rev_and_auth(cls, url: str) -> tuple[str, str | None, AuthInfo]:
|
||||
def get_url_rev_and_auth(cls, url: str) -> Tuple[str, Optional[str], AuthInfo]:
|
||||
"""
|
||||
Parse the repository URL to use, and return the URL, revision,
|
||||
and auth info to use.
|
||||
|
|
@ -401,20 +425,22 @@ class VersionControl:
|
|||
return url, rev, user_pass
|
||||
|
||||
@staticmethod
|
||||
def make_rev_args(username: str | None, password: HiddenText | None) -> CommandArgs:
|
||||
def make_rev_args(
|
||||
username: Optional[str], password: Optional[HiddenText]
|
||||
) -> CommandArgs:
|
||||
"""
|
||||
Return the RevOptions "extra arguments" to use in obtain().
|
||||
"""
|
||||
return []
|
||||
|
||||
def get_url_rev_options(self, url: HiddenText) -> tuple[HiddenText, RevOptions]:
|
||||
def get_url_rev_options(self, url: HiddenText) -> Tuple[HiddenText, RevOptions]:
|
||||
"""
|
||||
Return the URL and RevOptions object to use in obtain(),
|
||||
as a tuple (url, rev_options).
|
||||
"""
|
||||
secret_url, rev, user_pass = self.get_url_rev_and_auth(url.secret)
|
||||
username, secret_password = user_pass
|
||||
password: HiddenText | None = None
|
||||
password: Optional[HiddenText] = None
|
||||
if secret_password is not None:
|
||||
password = hide_value(secret_password)
|
||||
extra_args = self.make_rev_args(username, password)
|
||||
|
|
@ -451,13 +477,7 @@ class VersionControl:
|
|||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def switch(
|
||||
self,
|
||||
dest: str,
|
||||
url: HiddenText,
|
||||
rev_options: RevOptions,
|
||||
verbosity: int = 0,
|
||||
) -> None:
|
||||
def switch(self, dest: str, url: HiddenText, rev_options: RevOptions) -> None:
|
||||
"""
|
||||
Switch the repo at ``dest`` to point to ``URL``.
|
||||
|
||||
|
|
@ -466,13 +486,7 @@ class VersionControl:
|
|||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def update(
|
||||
self,
|
||||
dest: str,
|
||||
url: HiddenText,
|
||||
rev_options: RevOptions,
|
||||
verbosity: int = 0,
|
||||
) -> None:
|
||||
def update(self, dest: str, url: HiddenText, rev_options: RevOptions) -> None:
|
||||
"""
|
||||
Update an already-existing repo to the given ``rev_options``.
|
||||
|
||||
|
|
@ -482,7 +496,7 @@ class VersionControl:
|
|||
raise NotImplementedError
|
||||
|
||||
@classmethod
|
||||
def is_commit_id_equal(cls, dest: str, name: str | None) -> bool:
|
||||
def is_commit_id_equal(cls, dest: str, name: Optional[str]) -> bool:
|
||||
"""
|
||||
Return whether the id of the current commit equals the given name.
|
||||
|
||||
|
|
@ -524,7 +538,7 @@ class VersionControl:
|
|||
self.repo_name,
|
||||
rev_display,
|
||||
)
|
||||
self.update(dest, url, rev_options, verbosity=verbosity)
|
||||
self.update(dest, url, rev_options)
|
||||
else:
|
||||
logger.info("Skipping because already up-to-date.")
|
||||
return
|
||||
|
|
@ -579,7 +593,7 @@ class VersionControl:
|
|||
url,
|
||||
rev_display,
|
||||
)
|
||||
self.switch(dest, url, rev_options, verbosity=verbosity)
|
||||
self.switch(dest, url, rev_options)
|
||||
|
||||
def unpack(self, location: str, url: HiddenText, verbosity: int) -> None:
|
||||
"""
|
||||
|
|
@ -613,14 +627,14 @@ class VersionControl:
|
|||
@classmethod
|
||||
def run_command(
|
||||
cls,
|
||||
cmd: list[str] | CommandArgs,
|
||||
cmd: Union[List[str], CommandArgs],
|
||||
show_stdout: bool = True,
|
||||
cwd: str | None = None,
|
||||
on_returncode: Literal["raise", "warn", "ignore"] = "raise",
|
||||
extra_ok_returncodes: Iterable[int] | None = None,
|
||||
command_desc: str | None = None,
|
||||
extra_environ: Mapping[str, Any] | None = None,
|
||||
spinner: SpinnerInterface | None = None,
|
||||
cwd: Optional[str] = None,
|
||||
on_returncode: 'Literal["raise", "warn", "ignore"]' = "raise",
|
||||
extra_ok_returncodes: Optional[Iterable[int]] = None,
|
||||
command_desc: Optional[str] = None,
|
||||
extra_environ: Optional[Mapping[str, Any]] = None,
|
||||
spinner: Optional[SpinnerInterface] = None,
|
||||
log_failed_cmd: bool = True,
|
||||
stdout_only: bool = False,
|
||||
) -> str:
|
||||
|
|
@ -646,8 +660,6 @@ class VersionControl:
|
|||
log_failed_cmd=log_failed_cmd,
|
||||
stdout_only=stdout_only,
|
||||
)
|
||||
except NotADirectoryError:
|
||||
raise BadCommand(f"Cannot find command {cls.name!r} - invalid PATH")
|
||||
except FileNotFoundError:
|
||||
# errno.ENOENT = no such file or directory
|
||||
# In other words, the VCS executable isn't available
|
||||
|
|
@ -677,7 +689,7 @@ class VersionControl:
|
|||
return os.path.exists(os.path.join(path, cls.dirname))
|
||||
|
||||
@classmethod
|
||||
def get_repository_root(cls, location: str) -> str | None:
|
||||
def get_repository_root(cls, location: str) -> Optional[str]:
|
||||
"""
|
||||
Return the "root" (top-level) directory controlled by the vcs,
|
||||
or `None` if the directory is not in any.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue