From be02c3fbe9a29b82ad1fdcf460472811f02736de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bern=C3=A1t=20G=C3=A1bor?= Date: Tue, 14 May 2024 11:30:25 -0700 Subject: [PATCH] Add API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Bernát Gábor --- docs/index.rst | 19 ++++++++++--- pyproject.toml | 1 + src/pyproject_fmt/__init__.py | 2 ++ src/pyproject_fmt/__main__.py | 6 +++-- src/pyproject_fmt/cli.py | 43 ++++++++++++++++++++--------- tests/test_main.py | 51 +++++++++++++++++++++++++++++++++++ 6 files changed, 104 insertions(+), 18 deletions(-) diff --git a/docs/index.rst b/docs/index.rst index 8bafabe..db40616 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -7,8 +7,8 @@ See `changelog here `_. Use --- -As a CLI tool -~~~~~~~~~~~~~ +Via ``CLI`` +~~~~~~~~~~~ Use `pipx `_ to install the project: @@ -17,8 +17,8 @@ Use `pipx `_ to install the project: pipx install pyproject-fmt -As a ``pre-commit`` hook -~~~~~~~~~~~~~~~~~~~~~~~~ +Via ``pre-commit`` hook +~~~~~~~~~~~~~~~~~~~~~~~ See :gh:`pre-commit/pre-commit` for instructions, sample ``.pre-commit-config.yaml``: @@ -29,6 +29,17 @@ See :gh:`pre-commit/pre-commit` for instructions, sample ``.pre-commit-config.ya hooks: - id: pyproject-fmt +Via Python +~~~~~~~~~~ + +.. automodule:: pyproject_fmt + :members: + +.. toctree:: + :hidden: + + self + Configuration via file ---------------------- diff --git a/pyproject.toml b/pyproject.toml index c944392..41d4cff 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -131,6 +131,7 @@ run.parallel = true run.plugins = [ "covdefaults", ] +covdefaults.subtract_omit = "*/__main__.py" [tool.mypy] show_error_codes = true diff --git a/src/pyproject_fmt/__init__.py b/src/pyproject_fmt/__init__.py index 80521e7..3727ab5 100644 --- a/src/pyproject_fmt/__init__.py +++ b/src/pyproject_fmt/__init__.py @@ -2,8 +2,10 @@ from __future__ import annotations +from .__main__ import run from ._version import __version__ __all__ = [ "__version__", + "run", ] diff --git a/src/pyproject_fmt/__main__.py b/src/pyproject_fmt/__main__.py index a7baa6b..1904027 100644 --- a/src/pyproject_fmt/__main__.py +++ b/src/pyproject_fmt/__main__.py @@ -44,6 +44,8 @@ def _handle_one(config: Config) -> bool: if before != formatted and not config.check: config.pyproject_toml.write_text(formatted, encoding="utf-8") + if config.no_print_diff: + return changed try: name = str(config.pyproject_toml.relative_to(Path.cwd())) except ValueError: @@ -64,8 +66,8 @@ def run(args: Sequence[str] | None = None) -> int: """ Run the formatter. - :param args: CLI arguments - :return: exit code + :param args: command line arguments, by default use sys.argv[1:] + :return: exit code - 0 means already formatted correctly, otherwise 1 """ configs = cli_args(sys.argv[1:] if args is None else args) results = [_handle_one(config) for config in configs] diff --git a/src/pyproject_fmt/cli.py b/src/pyproject_fmt/cli.py index 273936b..687621f 100644 --- a/src/pyproject_fmt/cli.py +++ b/src/pyproject_fmt/cli.py @@ -29,6 +29,7 @@ class PyProjectFmtNamespace(Namespace): inputs: list[Path] stdout: bool check: bool + no_print_diff: bool column_width: int indent: int @@ -43,6 +44,7 @@ class Config: pyproject_toml: Path stdout: bool # push to standard out check: bool # check only + no_print_diff: bool # don't print diff settings: Settings @property @@ -100,36 +102,52 @@ def _build_cli() -> ArgumentParser: help="print package version of pyproject_fmt", version=f"%(prog)s ({version('pyproject-fmt')})", ) - group = parser.add_mutually_exclusive_group() - msg = "print the formatted text to the stdout (instead of update in-place)" - group.add_argument("-s", "--stdout", action="store_true", help=msg) + + mode_group = parser.add_argument_group("run mode") + mode = mode_group.add_mutually_exclusive_group() + msg = "print the formatted TOML to the stdout" + mode.add_argument("-s", "--stdout", action="store_true", help=msg) msg = "check and fail if any input would be formatted, printing any diffs" - group.add_argument("--check", action="store_true", help=msg) - parser.add_argument( + mode.add_argument("--check", action="store_true", help=msg) + mode_group.add_argument( + "-n", + "--no-print-diff", + action="store_true", + help="Flag indicating to print diff for the check mode", + ) + + format_group = parser.add_argument_group("formatting behavior") + format_group.add_argument( "--column-width", type=int, default=1, - help="max column width in the file", + help="max column width in the TOML file", metavar="count", ) - parser.add_argument( + format_group.add_argument( "--indent", type=int, default=2, - help="number of spaces to indent", + help="number of spaces to use for indentation", metavar="count", ) - parser.add_argument( + msg = "keep full dependency versions - do not remove redundant .0 from versions" + format_group.add_argument("--keep-full-version", action="store_true", help=msg) + format_group.add_argument( "--max-supported-python", metavar="minor.major", type=_version_argument, default=(3, 12), help="latest Python version the project supports (e.g. 3.13)", ) - msg = "keep full dependency versions - do not remove redundant .0 from versions" - parser.add_argument("--keep-full-version", action="store_true", help=msg) + msg = "pyproject.toml file(s) to format" - parser.add_argument("inputs", nargs="+", type=pyproject_toml_path_creator, help=msg) + parser.add_argument( + "inputs", + nargs="+", + type=pyproject_toml_path_creator, + help=msg, + ) return parser @@ -166,6 +184,7 @@ def cli_args(args: Sequence[str]) -> list[Config]: pyproject_toml=pyproject_toml, stdout=opt.stdout, check=opt.check, + no_print_diff=opt.no_print_diff, settings=Settings( column_width=column_width, indent=indent, diff --git a/tests/test_main.py b/tests/test_main.py index 59dec1a..ac5fca6 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -249,3 +249,54 @@ def test_pyproject_toml_config(tmp_path: Path, capsys: pytest.CaptureFixture[str out, err = capsys.readouterr() assert out assert not err + + +def test_pyproject_ftm_api_changed(tmp_path: Path, capsys: pytest.CaptureFixture[str]) -> None: + txt = """ + [project] + requires-python = "==3.12" + """ + filename = tmp_path / "pyproject.toml" + filename.write_text(dedent(txt)) + res = run([str(filename), "--no-print-diff"]) + + assert res == 1 + + got = filename.read_text() + expected = """\ + [project] + requires-python = "==3.12" + classifiers = [ + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.12", + ] + """ + assert got == dedent(expected) + + out, err = capsys.readouterr() + assert not out + assert not err + + +def test_pyproject_ftm_api_no_change(tmp_path: Path, capsys: pytest.CaptureFixture[str]) -> None: + txt = """\ + [project] + requires-python = "==3.12" + classifiers = [ + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.12", + ] + """ + filename = tmp_path / "pyproject.toml" + filename.write_text(dedent(txt)) + res = run([str(filename), "--no-print-diff"]) + + assert res == 0 + + got = filename.read_text() + + assert got == dedent(txt) + + out, err = capsys.readouterr() + assert not out + assert not err