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

Enhance --verbose #2526

Merged
merged 22 commits into from
Jan 10, 2022
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
b9b9cb8
`--verbose` mode prints location of project root
Shivansh-007 Oct 2, 2021
96f4fba
Add changelog entry
Shivansh-007 Oct 8, 2021
d60fef5
Enhance verbose output to include relative path to root
Shivansh-007 Oct 15, 2021
27ac2f5
Update changelog to relfect change
Shivansh-007 Oct 15, 2021
4b92fd1
Merge branch 'main' into feat/project-root-verbose
Shivansh-007 Nov 2, 2021
7a5bac6
Remove redundant quotes while patching 'find_project_root'
Shivansh-007 Nov 2, 2021
44cfd6c
Document the new return value in docstring
Shivansh-007 Nov 2, 2021
b821ed8
Remove quotes from project root verbose statement
Shivansh-007 Nov 2, 2021
bd4fc39
Store project root in ctx.obj to avoid passing it around and make it …
Shivansh-007 Dec 11, 2021
e35c190
Merge remote-tracking branch 'upstream/main' into feat/project-root-v…
Shivansh-007 Dec 11, 2021
513c9ae
Don't normalize path in logs to root parent
Shivansh-007 Dec 11, 2021
8e312d6
Edit changelog to reflect new changes
Shivansh-007 Dec 11, 2021
4a81c23
Merge branch 'main' into feat/project-root-verbose
Shivansh-007 Dec 13, 2021
7317a37
Call resolve to remove relative paths when getting SRCs log
Shivansh-007 Dec 15, 2021
9d2ca6e
Move identified root log above using config log
Shivansh-007 Dec 17, 2021
12e41ba
Update docstring
Shivansh-007 Dec 17, 2021
baa73d6
Update changelog, make more explicit
Shivansh-007 Dec 17, 2021
6a5dcb4
Use normalize path ignore to resolve and format root
Shivansh-007 Dec 19, 2021
2f2fc40
Merge branch 'main' into feat/project-root-verbose
JelleZijlstra Dec 19, 2021
857eeb3
Fix tests, add a dummy root since most don't care about it
Shivansh-007 Dec 19, 2021
092675a
Return file system root as default value of `find_pyproject_toml`
Shivansh-007 Jan 10, 2022
c02122a
Merge branch 'main' into feat/project-root-verbose
Shivansh-007 Jan 10, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
- Improve error message for invalid regular expression (#2678)
- Fix mapping cases that contain as-expressions, like `case {"key": 1 | 2 as password}`
(#2686)
- `--verbose` enhancements (project root, how is config found) (#2526)
Shivansh-007 marked this conversation as resolved.
Show resolved Hide resolved

## 21.12b0

Expand Down
22 changes: 20 additions & 2 deletions src/black/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
)

import click
from click.core import ParameterSource
from dataclasses import replace
from mypy_extensions import mypyc_attr

Expand Down Expand Up @@ -411,7 +412,11 @@ def main(
) -> None:
"""The uncompromising code formatter."""
if config and verbose:
out(f"Using configuration from {config}.", bold=False, fg="blue")
config_source = ctx.get_parameter_source("config")
if config_source in (ParameterSource.DEFAULT, ParameterSource.DEFAULT_MAP):
out("Using configuration from project root.", fg="blue")
else:
out(f"Using configuration in '{config}'.", fg="blue")

error_msg = "Oh no! 💥 💔 💥"
if required_version and required_version != __version__:
Expand Down Expand Up @@ -515,8 +520,21 @@ def get_sources(
stdin_filename: Optional[str],
) -> Set[Path]:
"""Compute the set of files to be formatted."""
Shivansh-007 marked this conversation as resolved.
Show resolved Hide resolved
root, method = find_project_root(src)

if verbose:
if method:
out(
f"Identified `{root}` as project root containing a {method}.",
fg="blue",
)
else:
out(f"Identified `{root}` as project root.", fg="blue")
paths = '", "'.join(
str(Path(source).resolve().relative_to(root)) for source in src
)
Shivansh-007 marked this conversation as resolved.
Show resolved Hide resolved
out(f'Sources to be formatted: "{paths}"', fg="blue")
Shivansh-007 marked this conversation as resolved.
Show resolved Hide resolved

root = find_project_root(src)
sources: Set[Path] = set()
path_empty(src, "No Path provided. Nothing to do 😴", quiet, verbose, ctx)

Expand Down
17 changes: 11 additions & 6 deletions src/black/files.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,19 @@


@lru_cache()
def find_project_root(srcs: Sequence[str]) -> Path:
def find_project_root(srcs: Sequence[str]) -> Tuple[Path, Optional[str]]:
Shivansh-007 marked this conversation as resolved.
Show resolved Hide resolved
"""Return a directory containing .git, .hg, or pyproject.toml.
Shivansh-007 marked this conversation as resolved.
Show resolved Hide resolved

That directory will be a common parent of all files and directories
passed in `srcs`.

If no directory in the tree contains a marker that would specify it's the
project root, the root of the file system is returned.

Returns a tuple with the first element as the project root path and the
second element as a string which describes the method by which black
found out the project root (None, if `None` of the registered method
was used).
Shivansh-007 marked this conversation as resolved.
Show resolved Hide resolved
"""
if not srcs:
srcs = [str(Path.cwd().resolve())]
Expand All @@ -58,20 +63,20 @@ def find_project_root(srcs: Sequence[str]) -> Path:

for directory in (common_base, *common_base.parents):
if (directory / ".git").exists():
return directory
return directory, ".git directory"

if (directory / ".hg").is_dir():
return directory
return directory, ".hg directory"

if (directory / "pyproject.toml").is_file():
return directory
return directory, "pyproject.toml"

return directory
return directory, None
Shivansh-007 marked this conversation as resolved.
Show resolved Hide resolved


def find_pyproject_toml(path_search_start: Tuple[str, ...]) -> Optional[str]:
"""Find the absolute filepath to a pyproject.toml if it exists"""
path_project_root = find_project_root(path_search_start)
path_project_root, _ = find_project_root(path_search_start)
path_pyproject_toml = path_project_root / "pyproject.toml"
if path_pyproject_toml.is_file():
return str(path_pyproject_toml)
Expand Down
25 changes: 16 additions & 9 deletions tests/test_black.py
Original file line number Diff line number Diff line change
Expand Up @@ -1321,10 +1321,17 @@ def test_find_project_root(self) -> None:
src_python.touch()

self.assertEqual(
black.find_project_root((src_dir, test_dir)), root.resolve()
black.find_project_root((src_dir, test_dir)),
(root.resolve(), "pyproject.toml"),
)
self.assertEqual(
black.find_project_root((src_dir,)),
(src_dir.resolve(), "pyproject.toml"),
)
self.assertEqual(
black.find_project_root((src_python,)),
(src_dir.resolve(), "pyproject.toml"),
)
self.assertEqual(black.find_project_root((src_dir,)), src_dir.resolve())
self.assertEqual(black.find_project_root((src_python,)), src_dir.resolve())

@patch(
"black.files.find_user_pyproject_toml",
Expand Down Expand Up @@ -1791,7 +1798,7 @@ def test_gitignore_used_as_default(self) -> None:
src = [base / "b/"]
assert_collected_sources(src, expected, extend_exclude=r"/exclude/")

@patch("black.find_project_root", lambda *args: THIS_DIR.resolve())
@patch("black.find_project_root", lambda *args: (THIS_DIR.resolve(), None))
def test_exclude_for_issue_1572(self) -> None:
# Exclude shouldn't touch files that were explicitly given to Black through the
# CLI. Exclude is supposed to only apply to the recursive discovery of files.
Expand Down Expand Up @@ -1974,13 +1981,13 @@ def test_symlink_out_of_root_directory(self) -> None:
child.is_symlink.assert_called()
assert child.is_symlink.call_count == 2

@patch("black.find_project_root", lambda *args: THIS_DIR.resolve())
@patch("black.find_project_root", lambda *args: (THIS_DIR.resolve(), None))
def test_get_sources_with_stdin(self) -> None:
src = ["-"]
expected = ["-"]
assert_collected_sources(src, expected, include="", exclude=r"/exclude/|a\.py")

@patch("black.find_project_root", lambda *args: THIS_DIR.resolve())
@patch("black.find_project_root", lambda *args: (THIS_DIR.resolve(), None))
def test_get_sources_with_stdin_filename(self) -> None:
src = ["-"]
stdin_filename = str(THIS_DIR / "data/collections.py")
Expand All @@ -1992,7 +1999,7 @@ def test_get_sources_with_stdin_filename(self) -> None:
stdin_filename=stdin_filename,
)

@patch("black.find_project_root", lambda *args: THIS_DIR.resolve())
@patch("black.find_project_root", lambda *args: (THIS_DIR.resolve(), None))
def test_get_sources_with_stdin_filename_and_exclude(self) -> None:
# Exclude shouldn't exclude stdin_filename since it is mimicking the
# file being passed directly. This is the same as
Expand All @@ -2008,7 +2015,7 @@ def test_get_sources_with_stdin_filename_and_exclude(self) -> None:
stdin_filename=stdin_filename,
)

@patch("black.find_project_root", lambda *args: THIS_DIR.resolve())
@patch("black.find_project_root", lambda *args: (THIS_DIR.resolve(), None))
def test_get_sources_with_stdin_filename_and_extend_exclude(self) -> None:
# Extend exclude shouldn't exclude stdin_filename since it is mimicking the
# file being passed directly. This is the same as
Expand All @@ -2024,7 +2031,7 @@ def test_get_sources_with_stdin_filename_and_extend_exclude(self) -> None:
stdin_filename=stdin_filename,
)

@patch("black.find_project_root", lambda *args: THIS_DIR.resolve())
@patch("black.find_project_root", lambda *args: (THIS_DIR.resolve(), None))
def test_get_sources_with_stdin_filename_and_force_exclude(self) -> None:
# Force exclude should exclude the file when passing it through
# stdin_filename
Expand Down