pkgdx 0.5.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
pkgdx/__init__.py ADDED
@@ -0,0 +1,17 @@
1
+ """__init__ for pkgdx."""
2
+
3
+ import contextlib
4
+ from importlib import metadata
5
+ from pathlib import Path
6
+
7
+ from pkgdx import exceptions, standards
8
+ from pkgdx.logging import configure_pkg_logging
9
+
10
+ __all__: list[str] = ["exceptions", "standards"]
11
+
12
+ PKGDX_ROOT: Path = Path(__file__).parent
13
+
14
+ configure_pkg_logging()
15
+
16
+ with contextlib.suppress(metadata.PackageNotFoundError):
17
+ __version__: str = metadata.version("pkgdx")
pkgdx/__main__.py ADDED
@@ -0,0 +1,207 @@
1
+ """Main entry point for pkgdx pre-commit hooks and CLI."""
2
+
3
+ import argparse
4
+ import logging
5
+ import sys
6
+ import textwrap
7
+ from collections.abc import Callable
8
+ from typing import NoReturn
9
+
10
+ from pkgdx import __version__, _core, exceptions
11
+ from pkgdx.logging import CLI_CONSOLE, configure_cli_logging
12
+ from pkgdx.standards import _hooks
13
+ from pkgdx.standards._cli import add_subparser as add_standards_subparser
14
+
15
+ logger = logging.getLogger(__package__)
16
+
17
+
18
+ __all__: list[str] = [
19
+ "detect_secrets",
20
+ "main",
21
+ "mypy_typing",
22
+ "pymarkdown_lint",
23
+ "ruff_format",
24
+ "ruff_lint",
25
+ ]
26
+
27
+
28
+ # PRE-COMMIT ENTRYPOINTS [project.scripts]
29
+
30
+
31
+ def _run_hook(func: Callable[[list[str]], int]) -> NoReturn:
32
+ """Run a config hook, reporting `pkgdx` errors without a traceback.
33
+
34
+ Args:
35
+ func: The core hook logic, called with `sys.argv[1:]`.
36
+ """
37
+ try:
38
+ code = func(sys.argv[1:])
39
+ except exceptions.Error as err:
40
+ sys.stderr.write(f"pkgdx: {err}\n")
41
+ sys.exit(_core.ExitCode.EX_FAILURE)
42
+ sys.exit(code)
43
+
44
+
45
+ def ruff_format() -> NoReturn:
46
+ """Run ruff formatting with the configured settings.
47
+
48
+ NOTE: Relates to pre-commit hook ID `pkgdx-format`, with
49
+ entry point `pkgdx-format-hook`.
50
+ """
51
+ _run_hook(_hooks.core_ruff_format)
52
+
53
+
54
+ def ruff_lint() -> NoReturn:
55
+ """Run ruff linting with the configured settings.
56
+
57
+ NOTE: Relates to pre-commit hook ID `pkgdx-lint`, with
58
+ entry point `pkgdx-lint-hook`.
59
+ """
60
+ _run_hook(_hooks.core_ruff_lint)
61
+
62
+
63
+ def mypy_typing() -> NoReturn:
64
+ """Run mypy type checking with the configured settings.
65
+
66
+ NOTE: Relates to pre-commit hook ID `pkgdx-typing`, with
67
+ entry point `pkgdx-typing-hook`.
68
+ """
69
+ _run_hook(_hooks.core_mypy_typing)
70
+
71
+
72
+ def detect_secrets() -> NoReturn:
73
+ """Run detect-secrets with the provided arguments.
74
+
75
+ NOTE: Relates to pre-commit hook ID `pkgdx-secrets`, with
76
+ entry point `pkgdx-secrets-hook`.
77
+ """
78
+ sys.exit(_hooks.core_detect_secrets(sys.argv[1:]))
79
+
80
+
81
+ def pymarkdown_lint() -> NoReturn:
82
+ """Run pymarkdown linting with the configured settings.
83
+
84
+ NOTE: Relates to pre-commit hook ID `pkgdx-markdown`, with
85
+ entry point `pkgdx-markdown-hook`.
86
+ """
87
+ _run_hook(_hooks.core_pymarkdown_lint)
88
+
89
+
90
+ # MAIN CLI COMMANDS
91
+
92
+
93
+ class CLIArgumentParser(argparse.ArgumentParser):
94
+ """Custom CLI ArgumentParser."""
95
+
96
+ def error(self, message: str) -> NoReturn:
97
+ """Handle CLI errors by printing a formatted message and exiting.
98
+
99
+ Args:
100
+ message: The error message to display.
101
+ """
102
+
103
+ CLI_CONSOLE.print(f"[red]ERROR:[/red] [b]{message}[/b]", end="\n\n")
104
+ self.print_usage(sys.stderr)
105
+ CLI_CONSOLE.print(
106
+ f"\n[dim]Try [cyan]{self.prog} --help[/cyan].[/dim]",
107
+ )
108
+
109
+ sys.exit(_core.ExitCode.EX_USAGE)
110
+
111
+
112
+ def main() -> NoReturn:
113
+ """Provide a unified `pkgdx` CLI entrypoint - init."""
114
+
115
+ # Provides a base parser for shared arguments across subcommands
116
+ base_parser = CLIArgumentParser(add_help=False)
117
+ base_parser.add_argument(
118
+ "-h",
119
+ "--help",
120
+ action="help",
121
+ help="Show this help message and exit",
122
+ )
123
+
124
+ description = textwrap.dedent(
125
+ """pkgdx centralises creation and implementation of coding standards
126
+ across projects, providing a single source of truth for toolchain
127
+ configuration."""
128
+ )
129
+
130
+ epilog = textwrap.fill(
131
+ "For more information see https://gitlab.com/andyrids/pkgdx.",
132
+ width=79,
133
+ initial_indent="",
134
+ )
135
+
136
+ # Main parser for the CLI
137
+ parser = CLIArgumentParser(
138
+ prog=__package__,
139
+ description=textwrap.fill(description, width=79),
140
+ usage="USAGE:\n %(prog)s [options] <command>",
141
+ epilog=epilog,
142
+ add_help=False,
143
+ parents=[base_parser],
144
+ formatter_class=_core.CLIGFormatter,
145
+ )
146
+
147
+ parser._optionals.title = "OPTIONS"
148
+
149
+ parser.add_argument(
150
+ "-d",
151
+ "--debug",
152
+ action="store_true",
153
+ help="Show debug logging output",
154
+ )
155
+
156
+ parser.add_argument(
157
+ "-v",
158
+ "--version",
159
+ action="version",
160
+ version=f"v{__version__}",
161
+ help="Show program's version number and exit",
162
+ )
163
+
164
+ subparsers = parser.add_subparsers(
165
+ title="COMMANDS",
166
+ # Mitigate subparser usage display issue by explicitly setting prog
167
+ # https://github.com/python/cpython/issues/86463
168
+ prog=parser.prog,
169
+ dest="command",
170
+ required=False,
171
+ metavar="<command>",
172
+ )
173
+
174
+ add_standards_subparser(subparsers, base_parser)
175
+
176
+ args = parser.parse_args()
177
+
178
+ # Empty command (`pkgdx`) shows header and help
179
+ if args.command is None:
180
+ sys.stdout.write(
181
+ f"Package Developer Experience (DX) Toolkit [v{__version__}]\n\n"
182
+ )
183
+
184
+ # Prints; USAGE, description, OPTIONS, COMMANDS & epilog
185
+ parser.print_help()
186
+
187
+ sys.exit(_core.ExitCode.EX_OK)
188
+
189
+ # Configure logging based on debug flag
190
+ is_debug = args.debug
191
+ configure_cli_logging(logging.DEBUG if is_debug else logging.WARNING)
192
+
193
+ ctx = _core.CLIContext(args=args, console=CLI_CONSOLE, is_debug=is_debug)
194
+
195
+ try:
196
+ exit_code = int(args.func(ctx))
197
+ except exceptions.Error as err:
198
+ logger.error(str(err))
199
+ exit_code = _core.ExitCode.EX_FAILURE
200
+ except Exception:
201
+ logger.exception("Unexpected error")
202
+ exit_code = _core.ExitCode.EX_SYNTAX
203
+ sys.exit(exit_code)
204
+
205
+
206
+ if __name__ == "__main__":
207
+ main()