diff --git a/CHANGES.md b/CHANGES.md index 634db79bf73..458d48cd2c1 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -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 diff --git a/docs/usage_and_configuration/the_basics.md b/docs/usage_and_configuration/the_basics.md index fd39b6c8979..b82cef4a52d 100644 --- a/docs/usage_and_configuration/the_basics.md +++ b/docs/usage_and_configuration/the_basics.md @@ -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; - 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. ## Usage diff --git a/src/black/__init__.py b/src/black/__init__.py index eaf72f9c2b3..7024c9d52b0 100644 --- a/src/black/__init__.py +++ b/src/black/__init__.py @@ -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 @@ -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) if exclude is None: exclude = re_compile_maybe_verbose(DEFAULT_EXCLUDES) diff --git a/tests/test_black.py b/tests/test_black.py index 559690938a8..8d691d2f019 100644 --- a/tests/test_black.py +++ b/tests/test_black.py @@ -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: @@ -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: