diff --git a/pyproject.toml b/pyproject.toml index 580da6f..323cd09 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,6 +11,7 @@ dynamic = ["version"] description = "CLI tools for manipulating Python project's name. Example for Gather." readme = "README.rst" authors = [{name = "Moshe Zadka", email = "moshez@zadka.club"}] +dependencies = ["gather", "tomlkit"] [project.optional-dependencies] tests = ["virtue", "pyhamcrest", "coverage"] diff --git a/requirements-docs.txt b/requirements-docs.txt index 7034d16..a2d46e4 100644 --- a/requirements-docs.txt +++ b/requirements-docs.txt @@ -6,21 +6,29 @@ # alabaster==0.7.16 # via sphinx +attrs==23.2.0 + # via gather babel==2.14.0 # via sphinx certifi==2023.11.17 # via requests charset-normalizer==3.3.2 # via requests +commander-data==2024.1.19.63931 + # via gather docutils==0.20.1 # via sphinx +gather==2024.1.19.74288 + # via -r - idna==3.6 # via requests imagesize==1.4.1 # via sphinx +incremental==22.10.0 + # via gather jinja2==3.1.3 # via sphinx -markupsafe==2.1.3 +markupsafe==2.1.4 # via jinja2 packaging==23.2 # via sphinx @@ -44,5 +52,11 @@ sphinxcontrib-qthelp==1.0.7 # via sphinx sphinxcontrib-serializinghtml==1.1.10 # via sphinx +tomlkit==0.12.3 + # via -r - +toolz==0.12.0 + # via gather urllib3==2.1.0 # via requests +venusian==3.1.0 + # via gather diff --git a/requirements-lint.txt b/requirements-lint.txt index 42b1788..b58dd64 100644 --- a/requirements-lint.txt +++ b/requirements-lint.txt @@ -4,12 +4,20 @@ # # pip-compile --output-file=- - # +attrs==23.2.0 + # via gather black==23.12.1 # via -r - click==8.1.7 # via black +commander-data==2024.1.19.63931 + # via gather flake8==7.0.0 # via -r - +gather==2024.1.19.74288 + # via -r - +incremental==22.10.0 + # via gather mccabe==0.7.0 # via flake8 mypy-extensions==1.0.0 @@ -24,3 +32,9 @@ pycodestyle==2.11.1 # via flake8 pyflakes==3.2.0 # via flake8 +tomlkit==0.12.3 + # via -r - +toolz==0.12.0 + # via gather +venusian==3.1.0 + # via gather diff --git a/requirements-mypy.txt b/requirements-mypy.txt index 57201a5..c0f840a 100644 --- a/requirements-mypy.txt +++ b/requirements-mypy.txt @@ -4,9 +4,23 @@ # # pip-compile --output-file=- - # +attrs==23.2.0 + # via gather +commander-data==2024.1.19.63931 + # via gather +gather==2024.1.19.74288 + # via -r - +incremental==22.10.0 + # via gather mypy==1.8.0 # via -r - mypy-extensions==1.0.0 # via mypy +tomlkit==0.12.3 + # via -r - +toolz==0.12.0 + # via gather typing-extensions==4.9.0 # via mypy +venusian==3.1.0 + # via gather diff --git a/requirements-tests.txt b/requirements-tests.txt index 6f287f8..62c0211 100644 --- a/requirements-tests.txt +++ b/requirements-tests.txt @@ -7,6 +7,7 @@ attrs==23.2.0 # via # automat + # gather # twisted # virtue automat==22.10.0 @@ -15,26 +16,38 @@ click==8.1.7 # via virtue colorama==0.4.6 # via virtue +commander-data==2024.1.19.63931 + # via gather constantly==23.10.4 # via twisted coverage==7.4.0 # via -r - +gather==2024.1.19.74288 + # via -r - hyperlink==21.0.0 # via twisted idna==3.6 # via hyperlink incremental==22.10.0 - # via twisted + # via + # gather + # twisted pyhamcrest==2.1.0 # via -r - pyrsistent==0.20.0 # via virtue six==1.16.0 # via automat +tomlkit==0.12.3 + # via -r - +toolz==0.12.0 + # via gather twisted==23.10.0 # via virtue typing-extensions==4.9.0 # via twisted +venusian==3.1.0 + # via gather virtue==2023.8.2 # via -r - zope-interface==6.1 diff --git a/requirements.txt b/requirements.txt index 98a4bc4..e9e3d2c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,3 +4,17 @@ # # pip-compile --output-file=- - # +attrs==23.2.0 + # via gather +commander-data==2024.1.19.63931 + # via gather +gather==2024.1.19.74288 + # via -r - +incremental==22.10.0 + # via gather +tomlkit==0.12.3 + # via -r - +toolz==0.12.0 + # via gather +venusian==3.1.0 + # via gather diff --git a/src/silly_pyproject_name/git.py b/src/silly_pyproject_name/git.py index acad392..cd24879 100644 --- a/src/silly_pyproject_name/git.py +++ b/src/silly_pyproject_name/git.py @@ -20,7 +20,7 @@ @ENTRY_DATA.register() -def status(args): +def status(args): # pragma: no cover # Getting the *status* is safe: # it can be spawned even in dry run mode. # @@ -56,7 +56,7 @@ def status(args): # make changes. add_argument("--no-dry-run", action="store_true", default=False), ) -def commit(args): +def commit(args): # pragma: no cover # The args.run function only runs the command in non-dry-run mode. # Otherwise, it will log the command and log the fact that it is skipped. args.run( diff --git a/src/silly_pyproject_name/name.py b/src/silly_pyproject_name/name.py index 257ac44..3e22fc2 100644 --- a/src/silly_pyproject_name/name.py +++ b/src/silly_pyproject_name/name.py @@ -15,9 +15,6 @@ def _pyproject_toml(args): return pathlib.Path(args.env["PWD"]) / "pyproject.toml" -def _load_pyproject(pwd): - return tomlkit.loads((pathlib.Path(pwd) / "pyproject.toml").read_text()) - # This commands reads, and logs, the name. @ENTRY_DATA.register() def name(args): diff --git a/src/silly_pyproject_name/tests/test_name.py b/src/silly_pyproject_name/tests/test_name.py new file mode 100644 index 0000000..0b909a4 --- /dev/null +++ b/src/silly_pyproject_name/tests/test_name.py @@ -0,0 +1,79 @@ +import contextlib +import io +import logging +import unittest +import subprocess +import tempfile +import pathlib +import textwrap + +import gather.commands +import commander_data.run +from hamcrest import assert_that, contains_string + +from .. import __version__ +from .. import ENTRY_DATA + +@contextlib.contextmanager +def save_log(): + outfile = io.StringIO() + handler = logging.StreamHandler(outfile) + root_logger = logging.getLogger() + original_level = root_logger.level + try: + root_logger.setLevel(logging.DEBUG) + root_logger.addHandler(handler) + yield outfile + finally: + root_logger.setLevel(original_level) + root_logger.removeHandler(handler) + +def parse_args(entry_data, args, orig_run=subprocess.run): + parser = gather.commands.set_parser(collected=ENTRY_DATA.collector.collect()) + args = parser.parse_args(args) + args.orig_run = subprocess.run + runner = commander_data.run.Runner.from_args(args) + args.run, args.safe_run = runner.run, runner.safe_run + return args + +class TestName(unittest.TestCase): + def test_name(self): + args = parse_args(ENTRY_DATA, ["name"]) + with contextlib.ExitStack() as stack: + temp_dir = pathlib.Path(stack.enter_context(tempfile.TemporaryDirectory())) + outfile = stack.enter_context(save_log()) + args.env = dict(PWD=temp_dir) + (temp_dir / "pyproject.toml").write_text(textwrap.dedent("""\ + [project] + name = "a-name" + """)) + args.__gather_command__(args) + assert_that(outfile.getvalue(), contains_string("a-name")) + + def test_rename_dry_run(self): + args = parse_args(ENTRY_DATA, ["rename", "new-name"]) + with contextlib.ExitStack() as stack: + temp_dir = pathlib.Path(stack.enter_context(tempfile.TemporaryDirectory())) + outfile = stack.enter_context(save_log()) + args.env = dict(PWD=temp_dir) + (temp_dir / "pyproject.toml").write_text(textwrap.dedent("""\ + [project] + name = "old-name" + """)) + args.__gather_command__(args) + assert_that(outfile.getvalue(), contains_string("new-name")) + + def test_rename_no_dry_run(self): + args = parse_args(ENTRY_DATA, ["rename", "new-name", "--no-dry-run"]) + with contextlib.ExitStack() as stack: + temp_dir = pathlib.Path(stack.enter_context(tempfile.TemporaryDirectory())) + outfile = stack.enter_context(save_log()) + args.env = dict(PWD=temp_dir) + (temp_dir / "pyproject.toml").write_text(textwrap.dedent("""\ + [project] + name = "old-name" + """)) + args.__gather_command__(args) + updated = (temp_dir / "pyproject.toml").read_text() + assert_that(updated, contains_string("new-name")) +