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

Added option to manually specifiy project root #3116

Draft
wants to merge 6 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
22 changes: 21 additions & 1 deletion src/black/__init__.py
Expand Up @@ -357,6 +357,17 @@ def validate_regex(
"editors that rely on using stdin."
),
)
@click.option(
"--project-root",
type=click.Path(
exists=True, file_okay=False, dir_okay=True, readable=True, allow_dash=True
),
help=(
"Manually specifiy the project root. This will prevent black from searching "
"for the project root itself. Useful to prevent black from picking up git "
"submodules as the project root which can affect the exclude behaviour."
),
)
@click.option(
"-W",
"--workers",
Expand Down Expand Up @@ -438,6 +449,7 @@ def main( # noqa: C901
extend_exclude: Optional[Pattern[str]],
force_exclude: Optional[Pattern[str]],
stdin_filename: Optional[str],
project_root: Optional[str],
workers: int,
src: Tuple[str, ...],
config: Optional[str],
Expand All @@ -455,7 +467,15 @@ 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)
if project_root:
project_root_abs = Path(project_root).resolve()
root, method = (
(project_root_abs, "manually-specified project root")
if code is None
else (None, None)
)
else:
root, method = find_project_root(src) if code is None else (None, None)
ctx.obj["root"] = root

if verbose:
Expand Down
Empty file.
Empty file.
19 changes: 18 additions & 1 deletion tests/test_black.py
Expand Up @@ -1852,8 +1852,11 @@ def assert_collected_sources(
None if extend_exclude is None else compile_pattern(extend_exclude)
)
gs_force_exclude = None if force_exclude is None else compile_pattern(force_exclude)
if not ctx:
ctx = FakeContext()
ctx.obj["root"], _ = black.find_project_root(gs_src)
collected = black.get_sources(
ctx=ctx or FakeContext(),
ctx=ctx,
src=gs_src,
quiet=False,
verbose=False,
Expand Down Expand Up @@ -2016,6 +2019,20 @@ def test_extend_exclude(self) -> None:
src, expected, exclude=r"\.pyi$", extend_exclude=r"\.definitely_exclude"
)

def test_git_submodule_exclude_full_path(self) -> None:
path = DATA_DIR / "git_submodule_exclude_tests" / "excluded_submodule" / "a.py"
src = [path]
expected: List[str] = []
assert_collected_sources(src, expected, force_exclude=r"excluded_submodule")

def test_git_submodule_exclude_base_path(self) -> None:
path = DATA_DIR / "git_submodule_exclude_tests"
src = [path]
expected = [
Path(path / "a.py"),
]
assert_collected_sources(src, expected, force_exclude=r"excluded_submodule")

@pytest.mark.incompatible_with_mypyc
def test_symlink_out_of_root_directory(self) -> None:
path = MagicMock()
Expand Down