Do not use gitignore if explicitly passing excludes (#2170)
Closes #2164. Changes behavior of how .gitignore is handled. With this change, the rules in .gitignore are only used as a fallback if no exclusion rule is explicitly passed on the command line or in pyproject.toml. Previously they were used regardless if explicit exclusion rules were specified, preventing any overriding of .gitignore rules. Those that depend only on .gitignore for their exclusion rules will not be affected. Those that use both .gitignore and exclude will find that exclude will act more like actually specifying exclude and not just another extra-excludes. If the previous behavior was desired, they should move their rules from exclude to extra-excludes.
This commit is contained in:
parent
4b7b5ed5b8
commit
1fe2efd857
@ -22,6 +22,9 @@
|
|||||||
[circumstances](https://github.com/psf/black/blob/master/docs/the_black_code_style.md#pragmatism)
|
[circumstances](https://github.com/psf/black/blob/master/docs/the_black_code_style.md#pragmatism)
|
||||||
in which _Black_ may change the AST (#2159)
|
in which _Black_ may change the AST (#2159)
|
||||||
|
|
||||||
|
- Allow `.gitignore` rules to be overridden by specifying `exclude` in `pyproject.toml`
|
||||||
|
or on the command line. (#2170)
|
||||||
|
|
||||||
#### _Packaging_
|
#### _Packaging_
|
||||||
|
|
||||||
- Install `primer.json` (used by `black-primer` by default) with black. (#2154)
|
- Install `primer.json` (used by `black-primer` by default) with black. (#2154)
|
||||||
|
@ -492,15 +492,15 @@ def validate_regex(
|
|||||||
@click.option(
|
@click.option(
|
||||||
"--exclude",
|
"--exclude",
|
||||||
type=str,
|
type=str,
|
||||||
default=DEFAULT_EXCLUDES,
|
|
||||||
callback=validate_regex,
|
callback=validate_regex,
|
||||||
help=(
|
help=(
|
||||||
"A regular expression that matches files and directories that should be"
|
"A regular expression that matches files and directories that should be"
|
||||||
" excluded on recursive searches. An empty value means no paths are excluded."
|
" excluded on recursive searches. An empty value means no paths are excluded."
|
||||||
" Use forward slashes for directories on all platforms (Windows, too)."
|
" Use forward slashes for directories on all platforms (Windows, too)."
|
||||||
" Exclusions are calculated first, inclusions later."
|
" Exclusions are calculated first, inclusions later. [default:"
|
||||||
|
f" {DEFAULT_EXCLUDES}]"
|
||||||
),
|
),
|
||||||
show_default=True,
|
show_default=False,
|
||||||
)
|
)
|
||||||
@click.option(
|
@click.option(
|
||||||
"--extend-exclude",
|
"--extend-exclude",
|
||||||
@ -587,7 +587,7 @@ def main(
|
|||||||
quiet: bool,
|
quiet: bool,
|
||||||
verbose: bool,
|
verbose: bool,
|
||||||
include: Pattern,
|
include: Pattern,
|
||||||
exclude: Pattern,
|
exclude: Optional[Pattern],
|
||||||
extend_exclude: Optional[Pattern],
|
extend_exclude: Optional[Pattern],
|
||||||
force_exclude: Optional[Pattern],
|
force_exclude: Optional[Pattern],
|
||||||
stdin_filename: Optional[str],
|
stdin_filename: Optional[str],
|
||||||
@ -662,7 +662,7 @@ def get_sources(
|
|||||||
quiet: bool,
|
quiet: bool,
|
||||||
verbose: bool,
|
verbose: bool,
|
||||||
include: Pattern[str],
|
include: Pattern[str],
|
||||||
exclude: Pattern[str],
|
exclude: Optional[Pattern[str]],
|
||||||
extend_exclude: Optional[Pattern[str]],
|
extend_exclude: Optional[Pattern[str]],
|
||||||
force_exclude: Optional[Pattern[str]],
|
force_exclude: Optional[Pattern[str]],
|
||||||
report: "Report",
|
report: "Report",
|
||||||
@ -673,7 +673,12 @@ def get_sources(
|
|||||||
root = find_project_root(src)
|
root = find_project_root(src)
|
||||||
sources: Set[Path] = set()
|
sources: Set[Path] = set()
|
||||||
path_empty(src, "No Path provided. Nothing to do 😴", quiet, verbose, ctx)
|
path_empty(src, "No Path provided. Nothing to do 😴", quiet, verbose, ctx)
|
||||||
gitignore = get_gitignore(root)
|
|
||||||
|
if exclude is None:
|
||||||
|
exclude = re_compile_maybe_verbose(DEFAULT_EXCLUDES)
|
||||||
|
gitignore = get_gitignore(root)
|
||||||
|
else:
|
||||||
|
gitignore = None
|
||||||
|
|
||||||
for s in src:
|
for s in src:
|
||||||
if s == "-" and stdin_filename:
|
if s == "-" and stdin_filename:
|
||||||
@ -6215,12 +6220,12 @@ def path_is_excluded(
|
|||||||
def gen_python_files(
|
def gen_python_files(
|
||||||
paths: Iterable[Path],
|
paths: Iterable[Path],
|
||||||
root: Path,
|
root: Path,
|
||||||
include: Optional[Pattern[str]],
|
include: Pattern[str],
|
||||||
exclude: Pattern[str],
|
exclude: Pattern[str],
|
||||||
extend_exclude: Optional[Pattern[str]],
|
extend_exclude: Optional[Pattern[str]],
|
||||||
force_exclude: Optional[Pattern[str]],
|
force_exclude: Optional[Pattern[str]],
|
||||||
report: "Report",
|
report: "Report",
|
||||||
gitignore: PathSpec,
|
gitignore: Optional[PathSpec],
|
||||||
) -> Iterator[Path]:
|
) -> Iterator[Path]:
|
||||||
"""Generate all files under `path` whose paths are not excluded by the
|
"""Generate all files under `path` whose paths are not excluded by the
|
||||||
`exclude_regex`, `extend_exclude`, or `force_exclude` regexes,
|
`exclude_regex`, `extend_exclude`, or `force_exclude` regexes,
|
||||||
@ -6236,8 +6241,8 @@ def gen_python_files(
|
|||||||
if normalized_path is None:
|
if normalized_path is None:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# First ignore files matching .gitignore
|
# First ignore files matching .gitignore, if passed
|
||||||
if gitignore.match_file(normalized_path):
|
if gitignore is not None and gitignore.match_file(normalized_path):
|
||||||
report.path_ignored(child, "matches the .gitignore file content")
|
report.path_ignored(child, "matches the .gitignore file content")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
1
tests/data/include_exclude_tests/.gitignore
vendored
Normal file
1
tests/data/include_exclude_tests/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
dont_exclude/
|
3
tests/data/include_exclude_tests/pyproject.toml
Normal file
3
tests/data/include_exclude_tests/pyproject.toml
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
[build-system]
|
||||||
|
requires = ["setuptools>=41.0", "setuptools-scm", "wheel"]
|
||||||
|
build-backend = "setuptools.build_meta"
|
@ -1418,6 +1418,32 @@ def test_include_exclude(self) -> None:
|
|||||||
)
|
)
|
||||||
self.assertEqual(sorted(expected), sorted(sources))
|
self.assertEqual(sorted(expected), sorted(sources))
|
||||||
|
|
||||||
|
def test_gitingore_used_as_default(self) -> None:
|
||||||
|
path = Path(THIS_DIR / "data" / "include_exclude_tests")
|
||||||
|
include = re.compile(r"\.pyi?$")
|
||||||
|
extend_exclude = re.compile(r"/exclude/")
|
||||||
|
src = str(path / "b/")
|
||||||
|
report = black.Report()
|
||||||
|
expected: List[Path] = [
|
||||||
|
path / "b/.definitely_exclude/a.py",
|
||||||
|
path / "b/.definitely_exclude/a.pyi",
|
||||||
|
]
|
||||||
|
sources = list(
|
||||||
|
black.get_sources(
|
||||||
|
ctx=FakeContext(),
|
||||||
|
src=(src,),
|
||||||
|
quiet=True,
|
||||||
|
verbose=False,
|
||||||
|
include=include,
|
||||||
|
exclude=None,
|
||||||
|
extend_exclude=extend_exclude,
|
||||||
|
force_exclude=None,
|
||||||
|
report=report,
|
||||||
|
stdin_filename=None,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.assertEqual(sorted(expected), sorted(sources))
|
||||||
|
|
||||||
@patch("black.find_project_root", lambda *args: THIS_DIR.resolve())
|
@patch("black.find_project_root", lambda *args: THIS_DIR.resolve())
|
||||||
def test_exclude_for_issue_1572(self) -> None:
|
def test_exclude_for_issue_1572(self) -> None:
|
||||||
# Exclude shouldn't touch files that were explicitly given to Black through the
|
# Exclude shouldn't touch files that were explicitly given to Black through the
|
||||||
@ -1705,6 +1731,8 @@ def test_empty_include(self) -> None:
|
|||||||
Path(path / "b/.definitely_exclude/a.pie"),
|
Path(path / "b/.definitely_exclude/a.pie"),
|
||||||
Path(path / "b/.definitely_exclude/a.py"),
|
Path(path / "b/.definitely_exclude/a.py"),
|
||||||
Path(path / "b/.definitely_exclude/a.pyi"),
|
Path(path / "b/.definitely_exclude/a.pyi"),
|
||||||
|
Path(path / ".gitignore"),
|
||||||
|
Path(path / "pyproject.toml"),
|
||||||
]
|
]
|
||||||
this_abs = THIS_DIR.resolve()
|
this_abs = THIS_DIR.resolve()
|
||||||
sources.extend(
|
sources.extend(
|
||||||
|
Loading…
Reference in New Issue
Block a user