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

Make SRC or code mandatory and mutually exclusive (#2360) #2804

Merged
merged 3 commits into from Jan 24, 2022
Merged
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
1 change: 1 addition & 0 deletions CHANGES.md
Expand Up @@ -38,6 +38,7 @@
`--preview` (#2789)
- Enable Python 3.10+ by default, without any extra need to specify
`--target-version=py310`. (#2758)
- Make passing `SRC` or `--code` mandatory and mutually exclusive (#2804)

### Packaging

Expand Down
4 changes: 2 additions & 2 deletions docs/usage_and_configuration/the_basics.md
Expand Up @@ -4,11 +4,11 @@ Foundational knowledge on using and configuring Black.

_Black_ is a well-behaved Unix-style command-line tool:

- it does nothing if no sources are passed to it;
- it does nothing if it finds no sources to format;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New with this PR. With previous discussions about passing no sources I think it should be considered user error. Finding no files to format still passes and returns success.

- it will read from standard input and write to standard output if `-` is used as the
filename;
- it only outputs messages to users on standard error;
- exits with code 0 unless an internal error occurred (or `--check` was used).
- exits with code 0 unless an internal error occurred or a CLI option prompted it.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We already had --check, --require-version and pyi/ipynb. Now we also have the source arg check.


## Usage

Expand Down
12 changes: 11 additions & 1 deletion src/black/__init__.py
Expand Up @@ -431,6 +431,17 @@ def main(
) -> None:
"""The uncompromising code formatter."""
ctx.ensure_object(dict)

if src and code is not None:
out(
main.get_usage(ctx)
+ "\n\n'SRC' and 'code' cannot be passed simultaneously."
)
ctx.exit(1)
if not src and code is None:
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)
ctx.obj["root"] = root

Expand Down Expand Up @@ -569,7 +580,6 @@ def get_sources(
) -> Set[Path]:
"""Compute the set of files to be formatted."""
sources: Set[Path] = set()
path_empty(src, "No Path provided. Nothing to do 😴", quiet, verbose, ctx)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't happen anymore because the check is done above.


if exclude is None:
exclude = re_compile_maybe_verbose(DEFAULT_EXCLUDES)
Expand Down
20 changes: 14 additions & 6 deletions tests/test_black.py
Expand Up @@ -972,10 +972,13 @@ def test_check_diff_use_together(self) -> None:
# Multi file command.
self.invokeBlack([str(src1), str(src2), "--diff", "--check"], exit_code=1)

def test_no_files(self) -> None:
def test_no_src_fails(self) -> None:
with cache_dir():
# Without an argument, black exits with error code 0.
self.invokeBlack([])
self.invokeBlack([], exit_code=1)

def test_src_and_code_fails(self) -> None:
with cache_dir():
self.invokeBlack([".", "-c", "0"], exit_code=1)

def test_broken_symlink(self) -> None:
with cache_dir() as workspace:
Expand Down Expand Up @@ -1229,13 +1232,18 @@ def test_invalid_cli_regex(self) -> None:

def test_required_version_matches_version(self) -> None:
self.invokeBlack(
["--required-version", black.__version__], exit_code=0, ignore_config=True
["--required-version", black.__version__, "-c", "0"],
exit_code=0,
ignore_config=True,
)

def test_required_version_does_not_match_version(self) -> None:
self.invokeBlack(
["--required-version", "20.99b"], exit_code=1, ignore_config=True
result = BlackRunner().invoke(
black.main,
["--required-version", "20.99b", "-c", "0"],
)
self.assertEqual(result.exit_code, 1)
self.assertIn("required version", result.stderr)

def test_preserves_line_endings(self) -> None:
with TemporaryDirectory() as workspace:
Expand Down