Skip to content

Commit

Permalink
checkpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
moshez committed Jan 19, 2024
1 parent 03fe1f9 commit aadda6b
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 6 deletions.
17 changes: 14 additions & 3 deletions README.rst
Original file line number Diff line number Diff line change
@@ -1,4 +1,15 @@
silly_pyproject_name
========================
Silly PyProject Name
====================

Stuff
This is an example application for a
multi-command
application
using
:code:`gather`.

The most important code is in:

* ``__init__.py``: This registers the :code:`ENTRY_DATA` object.
* ``__main__.py``: This is the CLI entrypoint, using :code:`ENTRY_DATA`.
* ``git.py``: This shows how to run command-line tools.
* ``name.py``: This shows how to log and support dry-run manually.
7 changes: 6 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,12 @@ is_main_match = ".*/trunk$"
[project.entry-points.gather]
placeholder = "silly_pyproject_name"

# This allows running the scripts using
# script entry points. Note that `python -m silly_project_name` still
# works correctly.
[project.scripts]
# The eponymous command allows running all subcommands.
silly-pyproject-name = "silly_pyproject_name:ENTRY_DATA.main_command"
silly-pyproject-change = "silly_pyproject_name:ENTRY_DATA.sub_command"
# This allows running a subcommand directly.
silly-pyproject-name-rename = "silly_pyproject_name:ENTRY_DATA.sub_command"

2 changes: 1 addition & 1 deletion src/silly_pyproject_name/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import importlib.metadata
from gather import entry

ENTRY_DATA = entry.EntryData.create(__name__)
ENTRY_DATA = entry.EntryData.create(__name__, prefix="silly-pyproject-name")
__version__ = importlib.metadata.version(__name__)
33 changes: 33 additions & 0 deletions src/silly_pyproject_name/git.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
"""
Showcase how to use commands.
This is a wrapper around Git commands.
"""
import logging

from commander_data import COMMAND
Expand All @@ -8,24 +13,52 @@
from . import ENTRY_DATA


# It is recommended to use the Logger to print data.
# This allows easier understanding of where messages
# come from.
LOGGER = logging.getLogger(__name__)


@ENTRY_DATA.register()
def status(args):
# Getting the *status* is safe:
# it can be spawned even in dry run mode.
#
# Also, note that commands are run with
# output/error capturing on by default,
# and automatically converting to text.
#
# Commands are also automatically checked.
# A return value is always successful.
# In case of an error, the default traceback
# will print out stdout/stderr to aid in
# debugging.
result = args.safe_run(
# Note the use of GIT.
# This runs "git status --porcelain pyproject.toml"
# with a more Pythonic interface to create the command line.
GIT.status(porcelain=None)("pyproject.toml"),
cwd=args.env["PWD"],
).stdout.splitlines()

# Since the command is precise, there's no need for further
# analysis of the output.
# Feedback is given via log.
if len(result) != 0:
LOGGER.warning("pyproject.toml should be committed")
else:
LOGGER.warning("pyproject.toml is up to date")

@ENTRY_DATA.register(
# The commit command has side-effects.
# By default, it will skip side effects --
# `--no-dry-run` should be passed to actually
# make changes.
add_argument("--no-dry-run", action="store_true", default=False),
)
def commit(args):
# 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(
GIT.commit(message="Updating pyproject.toml")("pyproject.toml"),
cwd=args.env["PWD"],
Expand Down
10 changes: 9 additions & 1 deletion src/silly_pyproject_name/name.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,16 @@ def _pyproject_toml(args):
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):
name = tomlkit.loads(_pyproject_toml(args).read_text())["project"]["name"]
# Regular output can be logged at "INFO" levels.
LOGGER.info("Current name: %s", name)

# This command modifies the name.
# It will only effect the modification
# if explicitly requested via --no-dry-run.
@ENTRY_DATA.register(
add_argument("--no-dry-run", action="store_true", default=False),
add_argument("new_name"),
Expand All @@ -39,8 +43,12 @@ def rename(args):
new_contents.splitlines(),
lineterm="",
)
# This logs the diffs. The end-user can see what will
# change.
for a_diff in diffs:
LOGGER.info("Difference: %s", a_diff.rstrip())
# Explicitly check no-dry-run before writing the file.
# Otherwise, clearly log that the actual side-effect is skipped.
if args.no_dry_run:
toml_file.write_text(new_contents)
else:
Expand Down

0 comments on commit aadda6b

Please sign in to comment.