From c47b91f513052cd39b818ea7c19716423c85c04e Mon Sep 17 00:00:00 2001 From: Shantanu <12621235+hauntsaninja@users.noreply.github.com> Date: Fri, 26 Aug 2022 14:07:25 -0700 Subject: [PATCH] Fix misdetection of project root with `--stdin-filename` (#3216) There are a number of places this behaviour could be patched, for instance, it's quite tempting to patch it in `get_sources`. However I believe we generally have the invariant that project root contains all files we want to format, in which case it seems prudent to keep that invariant. This also improves the accuracy of the "sources to be formatted" log message with --stdin-filename. Fixes GH-3207. --- CHANGES.md | 2 ++ src/black/__init__.py | 8 ++++++-- src/black/files.py | 6 +++++- tests/test_black.py | 6 ++++++ 4 files changed, 19 insertions(+), 3 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 39db0fb95b8..17659522fd1 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -40,6 +40,8 @@ - Black now uses the presence of debug f-strings to detect target version. (#3215) +- Fix misdetection of project root and verbose logging of sources in cases involving + `--stdin-filename` (#3216) ### Documentation diff --git a/src/black/__init__.py b/src/black/__init__.py index b8a9d031896..a0c1ad4b416 100644 --- a/src/black/__init__.py +++ b/src/black/__init__.py @@ -469,7 +469,9 @@ def main( # noqa: C901 out(main.get_usage(ctx) + "\n\nOne of 'SRC' or 'code' is required.") ctx.exit(1) - root, method = find_project_root(src) if code is None else (None, None) + root, method = ( + find_project_root(src, stdin_filename) if code is None else (None, None) + ) ctx.obj["root"] = root if verbose: @@ -480,7 +482,9 @@ def main( # noqa: C901 ) normalized = [ - (normalize_path_maybe_ignore(Path(source), root), source) + (source, source) + if source == "-" + else (normalize_path_maybe_ignore(Path(source), root), source) for source in src ] srcs_string = ", ".join( diff --git a/src/black/files.py b/src/black/files.py index 17515d52b57..d51c1bc7a90 100644 --- a/src/black/files.py +++ b/src/black/files.py @@ -39,7 +39,9 @@ @lru_cache() -def find_project_root(srcs: Sequence[str]) -> Tuple[Path, str]: +def find_project_root( + srcs: Sequence[str], stdin_filename: Optional[str] = None +) -> Tuple[Path, str]: """Return a directory containing .git, .hg, or pyproject.toml. That directory will be a common parent of all files and directories @@ -52,6 +54,8 @@ def find_project_root(srcs: Sequence[str]) -> Tuple[Path, str]: the second element as a string describing the method by which the project root was discovered. """ + if stdin_filename is not None: + srcs = tuple(stdin_filename if s == "-" else s for s in srcs) if not srcs: srcs = [str(Path.cwd().resolve())] diff --git a/tests/test_black.py b/tests/test_black.py index 81e7a9a7d0d..c76b3faddf5 100644 --- a/tests/test_black.py +++ b/tests/test_black.py @@ -1396,6 +1396,12 @@ def test_find_project_root(self) -> None: (src_dir.resolve(), "pyproject.toml"), ) + with change_directory(test_dir): + self.assertEqual( + black.find_project_root(("-",), stdin_filename="../src/a.py"), + (src_dir.resolve(), "pyproject.toml"), + ) + @patch( "black.files.find_user_pyproject_toml", )