Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change VCS tooling verbosity along with pip's verbosity #9639

Merged
merged 11 commits into from
Jan 25, 2022
1 change: 1 addition & 0 deletions news/8819.feature.rst
@@ -0,0 +1 @@
Forward pip's verbosity configuration to VCS tools to control their output accordingly.
2 changes: 2 additions & 0 deletions src/pip/_internal/cli/req_command.py
Expand Up @@ -236,6 +236,7 @@ def make_requirement_preparer(
finder: PackageFinder,
use_user_site: bool,
download_dir: Optional[str] = None,
verbosity: int = 0,
) -> RequirementPreparer:
"""
Create a RequirementPreparer instance for the given parameters.
Expand Down Expand Up @@ -287,6 +288,7 @@ def make_requirement_preparer(
require_hashes=options.require_hashes,
use_user_site=use_user_site,
lazy_wheel=lazy_wheel,
verbosity=verbosity,
in_tree_build=in_tree_build,
)

Expand Down
1 change: 1 addition & 0 deletions src/pip/_internal/commands/download.py
Expand Up @@ -113,6 +113,7 @@ def run(self, options: Values, args: List[str]) -> int:
finder=finder,
download_dir=options.download_dir,
use_user_site=False,
verbosity=self.verbosity,
)

resolver = self.make_resolver(
Expand Down
1 change: 1 addition & 0 deletions src/pip/_internal/commands/install.py
Expand Up @@ -319,6 +319,7 @@ def run(self, options: Values, args: List[str]) -> int:
session=session,
finder=finder,
use_user_site=options.use_user_site,
verbosity=self.verbosity,
)
resolver = self.make_resolver(
preparer=preparer,
Expand Down
1 change: 1 addition & 0 deletions src/pip/_internal/commands/wheel.py
Expand Up @@ -128,6 +128,7 @@ def run(self, options: Values, args: List[str]) -> int:
finder=finder,
download_dir=options.wheel_dir,
use_user_site=False,
verbosity=self.verbosity,
)

resolver = self.make_resolver(
Expand Down
18 changes: 14 additions & 4 deletions src/pip/_internal/operations/prepare.py
Expand Up @@ -59,10 +59,10 @@ def _get_prepared_distribution(
return abstract_dist.get_metadata_distribution()


def unpack_vcs_link(link: Link, location: str) -> None:
def unpack_vcs_link(link: Link, location: str, verbosity: int) -> None:
vcs_backend = vcs.get_backend_for_scheme(link.scheme)
assert vcs_backend is not None
vcs_backend.unpack(location, url=hide_url(link.url))
vcs_backend.unpack(location, url=hide_url(link.url), verbosity=verbosity)


class File:
Expand Down Expand Up @@ -175,6 +175,7 @@ def unpack_url(
link: Link,
location: str,
download: Downloader,
verbosity: int,
download_dir: Optional[str] = None,
hashes: Optional[Hashes] = None,
) -> Optional[File]:
Expand All @@ -187,7 +188,7 @@ def unpack_url(
"""
# non-editable vcs urls
if link.is_vcs:
unpack_vcs_link(link, location)
unpack_vcs_link(link, location, verbosity=verbosity)
return None

# Once out-of-tree-builds are no longer supported, could potentially
Expand Down Expand Up @@ -267,6 +268,7 @@ def __init__(
require_hashes: bool,
use_user_site: bool,
lazy_wheel: bool,
verbosity: int,
in_tree_build: bool,
) -> None:
super().__init__()
Expand Down Expand Up @@ -295,6 +297,9 @@ def __init__(
# Should wheels be downloaded lazily?
self.use_lazy_wheel = lazy_wheel

# How verbose should underlying tooling be?
self.verbosity = verbosity

# Should in-tree builds be used for local paths?
self.in_tree_build = in_tree_build

Expand Down Expand Up @@ -524,7 +529,12 @@ def _prepare_linked_requirement(
elif link.url not in self._downloaded:
try:
local_file = unpack_url(
link, req.source_dir, self._download, self.download_dir, hashes
link,
req.source_dir,
self._download,
self.verbosity,
self.download_dir,
hashes,
)
except NetworkConnectionError as exc:
raise InstallationError(
Expand Down
2 changes: 1 addition & 1 deletion src/pip/_internal/req/req_install.py
Expand Up @@ -667,7 +667,7 @@ def update_editable(self) -> None:
# So here, if it's neither a path nor a valid VCS URL, it's a bug.
assert vcs_backend, f"Unsupported VCS URL {self.link.url}"
hidden_url = hide_url(self.link.url)
vcs_backend.obtain(self.source_dir, url=hidden_url)
vcs_backend.obtain(self.source_dir, url=hidden_url, verbosity=0)

# Top-level Actions
def uninstall(
Expand Down
12 changes: 10 additions & 2 deletions src/pip/_internal/vcs/bazaar.py
Expand Up @@ -33,15 +33,23 @@ class Bazaar(VersionControl):
def get_base_rev_args(rev: str) -> List[str]:
return ["-r", rev]

def fetch_new(self, dest: str, url: HiddenText, rev_options: RevOptions) -> None:
def fetch_new(
self, dest: str, url: HiddenText, rev_options: RevOptions, verbosity: int
) -> None:
rev_display = rev_options.to_display()
logger.info(
"Checking out %s%s to %s",
url,
rev_display,
display_path(dest),
)
cmd_args = make_command("branch", "-q", rev_options.to_args(), url, dest)
if verbosity <= 0:
flag = "--quiet"
elif verbosity == 1:
flag = ""
else:
flag = f"-{'v'*verbosity}"
cmd_args = make_command("branch", flag, rev_options.to_args(), url, dest)
self.run_command(cmd_args)

def switch(self, dest: str, url: HiddenText, rev_options: RevOptions) -> None:
Expand Down
14 changes: 11 additions & 3 deletions src/pip/_internal/vcs/git.py
Expand Up @@ -253,9 +253,17 @@ def is_commit_id_equal(cls, dest: str, name: Optional[str]) -> bool:

return cls.get_revision(dest) == name

def fetch_new(self, dest: str, url: HiddenText, rev_options: RevOptions) -> None:
def fetch_new(
self, dest: str, url: HiddenText, rev_options: RevOptions, verbosity: int
) -> None:
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",)
elif verbosity == 1:
flags = ()
else:
flags = ("--verbose", "--progress")
if self.get_git_version() >= (2, 17):
# Git added support for partial clone in 2.17
# https://git-scm.com/docs/partial-clone
Expand All @@ -264,13 +272,13 @@ def fetch_new(self, dest: str, url: HiddenText, rev_options: RevOptions) -> None
make_command(
"clone",
"--filter=blob:none",
"-q",
*flags,
url,
dest,
)
)
else:
self.run_command(make_command("clone", "-q", url, dest))
self.run_command(make_command("clone", *flags, url, dest))

if rev_options.rev:
# Then a specific revision was requested.
Expand Down
18 changes: 14 additions & 4 deletions src/pip/_internal/vcs/mercurial.py
@@ -1,7 +1,7 @@
import configparser
import logging
import os
from typing import List, Optional
from typing import List, Optional, Tuple

from pip._internal.exceptions import BadCommand, InstallationError
from pip._internal.utils.misc import HiddenText, display_path
Expand Down Expand Up @@ -33,17 +33,27 @@ class Mercurial(VersionControl):
def get_base_rev_args(rev: str) -> List[str]:
return [rev]

def fetch_new(self, dest: str, url: HiddenText, rev_options: RevOptions) -> None:
def fetch_new(
self, dest: str, url: HiddenText, rev_options: RevOptions, verbosity: int
) -> None:
rev_display = rev_options.to_display()
logger.info(
"Cloning hg %s%s to %s",
url,
rev_display,
display_path(dest),
)
self.run_command(make_command("clone", "--noupdate", "-q", url, dest))
if verbosity <= 0:
flags: Tuple[str, ...] = ("--quiet",)
elif verbosity == 1:
flags = ()
elif verbosity == 2:
flags = ("--verbose",)
else:
flags = ("--verbose", "--debug")
self.run_command(make_command("clone", "--noupdate", *flags, url, dest))
self.run_command(
make_command("update", "-q", rev_options.to_args()),
make_command("update", *flags, rev_options.to_args()),
cwd=dest,
)

Expand Down
10 changes: 8 additions & 2 deletions src/pip/_internal/vcs/subversion.py
Expand Up @@ -277,17 +277,23 @@ def get_remote_call_options(self) -> CommandArgs:

return []

def fetch_new(self, dest: str, url: HiddenText, rev_options: RevOptions) -> None:
def fetch_new(
self, dest: str, url: HiddenText, rev_options: RevOptions, verbosity: int
) -> None:
rev_display = rev_options.to_display()
logger.info(
"Checking out %s%s to %s",
url,
rev_display,
display_path(dest),
)
if verbosity <= 0:
flag = "--quiet"
else:
flag = ""
cmd_args = make_command(
"checkout",
"-q",
flag,
self.get_remote_call_options(),
rev_options.to_args(),
url,
Expand Down
19 changes: 12 additions & 7 deletions src/pip/_internal/vcs/versioncontrol.py
Expand Up @@ -458,14 +458,17 @@ def compare_urls(cls, url1: str, url2: str) -> bool:
"""
return cls.normalize_url(url1) == cls.normalize_url(url2)

def fetch_new(self, dest: str, url: HiddenText, rev_options: RevOptions) -> None:
def fetch_new(
self, dest: str, url: HiddenText, rev_options: RevOptions, verbosity: int
) -> None:
"""
Fetch a revision from a repository, in the case that this is the
first fetch from the repository.

Args:
dest: the directory to fetch the repository to.
rev_options: a RevOptions object.
verbosity: verbosity level.
"""
raise NotImplementedError

Expand Down Expand Up @@ -498,18 +501,19 @@ def is_commit_id_equal(cls, dest: str, name: Optional[str]) -> bool:
"""
raise NotImplementedError

def obtain(self, dest: str, url: HiddenText) -> None:
def obtain(self, dest: str, url: HiddenText, verbosity: int) -> None:
"""
Install or update in editable mode the package represented by this
VersionControl object.

:param dest: the repository directory in which to install or update.
:param url: the repository URL starting with a vcs prefix.
:param verbosity: verbosity level.
"""
url, rev_options = self.get_url_rev_options(url)

if not os.path.exists(dest):
self.fetch_new(dest, url, rev_options)
self.fetch_new(dest, url, rev_options, verbosity=verbosity)
return

rev_display = rev_options.to_display()
Expand Down Expand Up @@ -565,14 +569,14 @@ def obtain(self, dest: str, url: HiddenText) -> None:
if response == "w":
logger.warning("Deleting %s", display_path(dest))
rmtree(dest)
self.fetch_new(dest, url, rev_options)
self.fetch_new(dest, url, rev_options, verbosity=verbosity)
return

if response == "b":
dest_dir = backup_dir(dest)
logger.warning("Backing up %s to %s", display_path(dest), dest_dir)
shutil.move(dest, dest_dir)
self.fetch_new(dest, url, rev_options)
self.fetch_new(dest, url, rev_options, verbosity=verbosity)
return

# Do nothing if the response is "i".
Expand All @@ -586,16 +590,17 @@ def obtain(self, dest: str, url: HiddenText) -> None:
)
self.switch(dest, url, rev_options)

def unpack(self, location: str, url: HiddenText) -> None:
def unpack(self, location: str, url: HiddenText, verbosity: int) -> None:
"""
Clean up current location and download the url repository
(and vcs infos) into location

:param url: the repository URL starting with a vcs prefix.
:param verbosity: verbosity level.
"""
if os.path.exists(location):
rmtree(location)
self.obtain(location, url=url)
self.obtain(location, url=url, verbosity=verbosity)

@classmethod
def get_remote_url(cls, location: str) -> str:
Expand Down
22 changes: 16 additions & 6 deletions tests/functional/test_vcs_git.py
Expand Up @@ -277,7 +277,7 @@ def test_resolve_commit_not_on_branch(script, tmp_path):

# check we can fetch our commit
rev_options = Git.make_rev_options(commit)
Git().fetch_new(str(clone_path), repo_path.as_uri(), rev_options)
Git().fetch_new(str(clone_path), repo_path.as_uri(), rev_options, verbosity=0)


def _initialize_clonetest_server(repo_path, script, enable_partial_clone):
Expand Down Expand Up @@ -311,9 +311,13 @@ def test_partial_clone(script, tmp_path):
commit = script.run("git", "rev-parse", "HEAD", cwd=str(repo_path)).stdout.strip()

# Check that we can clone at HEAD
Git().fetch_new(str(clone_path1), repo_path.as_uri(), Git.make_rev_options())
Git().fetch_new(
str(clone_path1), repo_path.as_uri(), Git.make_rev_options(), verbosity=0
)
# Check that we can clone to commit
Git().fetch_new(str(clone_path2), repo_path.as_uri(), Git.make_rev_options(commit))
Git().fetch_new(
str(clone_path2), repo_path.as_uri(), Git.make_rev_options(commit), verbosity=0
)

# Write some additional stuff to git pull
repo_file.write_text(u"..")
Expand Down Expand Up @@ -343,9 +347,13 @@ def test_partial_clone_without_server_support(script, tmp_path):
commit = script.run("git", "rev-parse", "HEAD", cwd=str(repo_path)).stdout.strip()

# Check that we can clone at HEAD
Git().fetch_new(str(clone_path1), repo_path.as_uri(), Git.make_rev_options())
Git().fetch_new(
str(clone_path1), repo_path.as_uri(), Git.make_rev_options(), verbosity=0
)
# Check that we can clone to commit
Git().fetch_new(str(clone_path2), repo_path.as_uri(), Git.make_rev_options(commit))
Git().fetch_new(
str(clone_path2), repo_path.as_uri(), Git.make_rev_options(commit), verbosity=0
)

# Write some additional stuff to git pull
repo_file.write_text(u"..")
Expand All @@ -372,7 +380,9 @@ def test_clone_without_partial_clone_support(script, tmp_path):

# Check that we can clone w/ old version of git w/o --filter
with patch("pip._internal.vcs.git.Git.get_git_version", return_value=(2, 16)):
Git().fetch_new(str(clone_path), repo_path.as_uri(), Git.make_rev_options())
Git().fetch_new(
str(clone_path), repo_path.as_uri(), Git.make_rev_options(), verbosity=0
)

repo_file.write_text(u"...")
script.run("git", "commit", "-am", "third commit", cwd=str(repo_path))
Expand Down
2 changes: 1 addition & 1 deletion tests/lib/local_repos.py
Expand Up @@ -55,7 +55,7 @@ def local_checkout(
else:
vcs_backend = vcs.get_backend(vcs_name)
assert vcs_backend is not None
vcs_backend.obtain(repo_url_path, url=hide_url(remote_repo))
vcs_backend.obtain(repo_url_path, url=hide_url(remote_repo), verbosity=0)

return "{}+{}".format(vcs_name, path_to_url(repo_url_path))

Expand Down
1 change: 1 addition & 0 deletions tests/unit/resolution_resolvelib/conftest.py
Expand Up @@ -46,6 +46,7 @@ def preparer(finder: PackageFinder) -> Iterator[RequirementPreparer]:
session=session,
finder=finder,
use_user_site=False,
verbosity=0,
)

yield preparer
Expand Down