sql-sp-harness 1.0.0__tar.gz

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.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright © 2026 Deepraj Adhikary
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,11 @@
1
+ include LICENSE
2
+ include README.md
3
+ graft src
4
+ prune tests
5
+ prune dist
6
+ prune build
7
+ prune .github
8
+ prune .venv
9
+ global-exclude __pycache__
10
+ global-exclude *.py[cod]
11
+ global-exclude .DS_Store
@@ -0,0 +1,120 @@
1
+ Metadata-Version: 2.4
2
+ Name: sql-sp-harness
3
+ Version: 1.0.0
4
+ Summary: Generate safe T-SQL stored-procedure debug harness scripts (analyze + DML previews)
5
+ Author: Deepraj Adhikary
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/DeeprajDeveloper/sql-sp-harness
8
+ Project-URL: Documentation, https://github.com/DeeprajDeveloper/sql-sp-harness#readme
9
+ Project-URL: Repository, https://github.com/DeeprajDeveloper/sql-sp-harness
10
+ Project-URL: Issues, https://github.com/DeeprajDeveloper/sql-sp-harness/issues
11
+ Project-URL: Changelog, https://github.com/DeeprajDeveloper/sql-sp-harness/releases
12
+ Project-URL: Extension, https://github.com/DeeprajDeveloper/mssql-sp-debug-scripter
13
+ Keywords: sql,sql-server,t-sql,stored-procedure,debug-harness,test-harness
14
+ Classifier: Development Status :: 4 - Beta
15
+ Classifier: Environment :: Console
16
+ Classifier: Intended Audience :: Developers
17
+ Classifier: Operating System :: OS Independent
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3.10
20
+ Classifier: Programming Language :: Python :: 3.11
21
+ Classifier: Programming Language :: Python :: 3.12
22
+ Classifier: Programming Language :: Python :: 3.13
23
+ Classifier: Topic :: Database
24
+ Classifier: Topic :: Software Development :: Code Generators
25
+ Requires-Python: >=3.10
26
+ Description-Content-Type: text/markdown
27
+ License-File: LICENSE
28
+ Requires-Dist: sqlglot>=25.0.0
29
+ Requires-Dist: typer>=0.12.0
30
+ Provides-Extra: dev
31
+ Requires-Dist: pytest>=8.0.0; extra == "dev"
32
+ Requires-Dist: build>=1.0.0; extra == "dev"
33
+ Requires-Dist: twine>=5.0.0; extra == "dev"
34
+ Dynamic: license-file
35
+
36
+ <p align="center">
37
+ <img
38
+ src="https://raw.githubusercontent.com/DeeprajDeveloper/sql-sp-harness/master/docs/BANNER.png"
39
+ alt="sql-sp-harness"
40
+ >
41
+ </p>
42
+
43
+ [![PyPI](https://badge.fury.io/py/sql-sp-harness.svg)](https://pypi.python.org/pypi/sql-sp-harness)
44
+ [![Python 3.10|3.12|3.13](https://img.shields.io/badge/python-3.10&nbsp;|&nbsp;3.12&nbsp;|&nbsp;3.13-blue.svg)](https://github.com/DeeprajDeveloper/sql-sp-harness)
45
+
46
+ # sql-sp-harness
47
+
48
+ **T-SQL Stored Procedure Debug Harness** — turn SQL Server stored procedures into **safe, runnable debug scripts** you can execute on a pre-production database without writing to real tables.
49
+
50
+ > Not a live debugger. This tool generates a **static test harness** (DML previews + variable traces), not breakpoints or step-into debugging.
51
+ >
52
+ > Not affiliated with Microsoft. "SQL Server" and T-SQL are used descriptively only.
53
+
54
+ ## What it does
55
+
56
+ | Command | Purpose |
57
+ |---------|---------|
58
+ | `analyze` | See what keyword elements that procedure contains along with counts — DML, TRY/CATCH, loops, SET, line-level detail |
59
+ | `generate` | Create a debug harness: real-table DML → `SELECT` previews, `PRINT` traces on variables |
60
+
61
+ Output includes a banner on the top of the procedure stating: **DEBUG HARNESS — DO NOT RUN ON PRODUCTION**.
62
+
63
+ ## Install
64
+
65
+ ```bash
66
+ pip install sql-sp-harness
67
+ ```
68
+
69
+ Requires **Python 3.10+**.
70
+
71
+ Verify:
72
+
73
+ ```bash
74
+ sql-sp-harness version
75
+ python -m sql_sp_harness version
76
+ ```
77
+
78
+ ## Quick start
79
+
80
+ ```bash
81
+ sql-sp-harness analyze -i MyProc.sql
82
+ sql-sp-harness generate -i MyProc.sql -o MyProc_debug.sql
83
+ ```
84
+
85
+ With traces in the Messages tab (default):
86
+
87
+ ```bash
88
+ sql-sp-harness generate -i MyProc.sql -o MyProc_debug.sql --trace-style print
89
+ ```
90
+
91
+ ## Development
92
+
93
+ ```bash
94
+ git clone https://github.com/DeeprajDeveloper/sql-sp-harness.git
95
+ cd sql-sp-harness
96
+ pip install -e ".[dev]"
97
+ pytest
98
+ ```
99
+
100
+ Build for PyPI:
101
+
102
+ ```bash
103
+ ./scripts/publish-pypi.sh
104
+ ./scripts/publish-pypi.sh upload
105
+ ```
106
+
107
+ ## Limitations
108
+
109
+ | Pattern | Behavior |
110
+ |---------|----------|
111
+ | Dynamic SQL | Not analyzed |
112
+ | Encrypted procedures | No source |
113
+ | Cursors | Not rewritten |
114
+ | DDL inside proc | Not stubbed |
115
+
116
+ Always review generated scripts before running on a shared server.
117
+
118
+ ## License
119
+
120
+ MIT
@@ -0,0 +1,85 @@
1
+ <p align="center">
2
+ <img
3
+ src="https://raw.githubusercontent.com/DeeprajDeveloper/sql-sp-harness/master/docs/BANNER.png"
4
+ alt="sql-sp-harness"
5
+ >
6
+ </p>
7
+
8
+ [![PyPI](https://badge.fury.io/py/sql-sp-harness.svg)](https://pypi.python.org/pypi/sql-sp-harness)
9
+ [![Python 3.10|3.12|3.13](https://img.shields.io/badge/python-3.10&nbsp;|&nbsp;3.12&nbsp;|&nbsp;3.13-blue.svg)](https://github.com/DeeprajDeveloper/sql-sp-harness)
10
+
11
+ # sql-sp-harness
12
+
13
+ **T-SQL Stored Procedure Debug Harness** — turn SQL Server stored procedures into **safe, runnable debug scripts** you can execute on a pre-production database without writing to real tables.
14
+
15
+ > Not a live debugger. This tool generates a **static test harness** (DML previews + variable traces), not breakpoints or step-into debugging.
16
+ >
17
+ > Not affiliated with Microsoft. "SQL Server" and T-SQL are used descriptively only.
18
+
19
+ ## What it does
20
+
21
+ | Command | Purpose |
22
+ |---------|---------|
23
+ | `analyze` | See what keyword elements that procedure contains along with counts — DML, TRY/CATCH, loops, SET, line-level detail |
24
+ | `generate` | Create a debug harness: real-table DML → `SELECT` previews, `PRINT` traces on variables |
25
+
26
+ Output includes a banner on the top of the procedure stating: **DEBUG HARNESS — DO NOT RUN ON PRODUCTION**.
27
+
28
+ ## Install
29
+
30
+ ```bash
31
+ pip install sql-sp-harness
32
+ ```
33
+
34
+ Requires **Python 3.10+**.
35
+
36
+ Verify:
37
+
38
+ ```bash
39
+ sql-sp-harness version
40
+ python -m sql_sp_harness version
41
+ ```
42
+
43
+ ## Quick start
44
+
45
+ ```bash
46
+ sql-sp-harness analyze -i MyProc.sql
47
+ sql-sp-harness generate -i MyProc.sql -o MyProc_debug.sql
48
+ ```
49
+
50
+ With traces in the Messages tab (default):
51
+
52
+ ```bash
53
+ sql-sp-harness generate -i MyProc.sql -o MyProc_debug.sql --trace-style print
54
+ ```
55
+
56
+ ## Development
57
+
58
+ ```bash
59
+ git clone https://github.com/DeeprajDeveloper/sql-sp-harness.git
60
+ cd sql-sp-harness
61
+ pip install -e ".[dev]"
62
+ pytest
63
+ ```
64
+
65
+ Build for PyPI:
66
+
67
+ ```bash
68
+ ./scripts/publish-pypi.sh
69
+ ./scripts/publish-pypi.sh upload
70
+ ```
71
+
72
+ ## Limitations
73
+
74
+ | Pattern | Behavior |
75
+ |---------|----------|
76
+ | Dynamic SQL | Not analyzed |
77
+ | Encrypted procedures | No source |
78
+ | Cursors | Not rewritten |
79
+ | DDL inside proc | Not stubbed |
80
+
81
+ Always review generated scripts before running on a shared server.
82
+
83
+ ## License
84
+
85
+ MIT
@@ -0,0 +1,66 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "sql-sp-harness"
7
+ dynamic = ["version"]
8
+ description = "Generate safe T-SQL stored-procedure debug harness scripts (analyze + DML previews)"
9
+ readme = { file = "README.md", content-type = "text/markdown" }
10
+ license = "MIT"
11
+ license-files = ["LICENSE"]
12
+ requires-python = ">=3.10"
13
+ authors = [{ name = "Deepraj Adhikary" }]
14
+ keywords = [
15
+ "sql",
16
+ "sql-server",
17
+ "t-sql",
18
+ "stored-procedure",
19
+ "debug-harness",
20
+ "test-harness",
21
+ ]
22
+ classifiers = [
23
+ "Development Status :: 4 - Beta",
24
+ "Environment :: Console",
25
+ "Intended Audience :: Developers",
26
+ "Operating System :: OS Independent",
27
+ "Programming Language :: Python :: 3",
28
+ "Programming Language :: Python :: 3.10",
29
+ "Programming Language :: Python :: 3.11",
30
+ "Programming Language :: Python :: 3.12",
31
+ "Programming Language :: Python :: 3.13",
32
+ "Topic :: Database",
33
+ "Topic :: Software Development :: Code Generators",
34
+ ]
35
+ dependencies = [
36
+ "sqlglot>=25.0.0",
37
+ "typer>=0.12.0",
38
+ ]
39
+
40
+ [project.urls]
41
+ Homepage = "https://github.com/DeeprajDeveloper/sql-sp-harness"
42
+ Documentation = "https://github.com/DeeprajDeveloper/sql-sp-harness#readme"
43
+ Repository = "https://github.com/DeeprajDeveloper/sql-sp-harness"
44
+ Issues = "https://github.com/DeeprajDeveloper/sql-sp-harness/issues"
45
+ Changelog = "https://github.com/DeeprajDeveloper/sql-sp-harness/releases"
46
+ Extension = "https://github.com/DeeprajDeveloper/mssql-sp-debug-scripter"
47
+
48
+ [project.optional-dependencies]
49
+ dev = ["pytest>=8.0.0", "build>=1.0.0", "twine>=5.0.0"]
50
+
51
+ [project.scripts]
52
+ sql-sp-harness = "sql_sp_harness.cli:app"
53
+ sp-harness = "sql_sp_harness.cli:app"
54
+
55
+ [tool.setuptools.packages.find]
56
+ where = ["src"]
57
+
58
+ [tool.setuptools.dynamic]
59
+ version = { attr = "sql_sp_harness.__version__" }
60
+
61
+ [tool.setuptools]
62
+ include-package-data = false
63
+
64
+ [tool.pytest.ini_options]
65
+ testpaths = ["tests"]
66
+ pythonpath = ["src"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,4 @@
1
+ """T-SQL stored procedure debug harness — safe SQL test-harness generator."""
2
+
3
+ __version__ = "1.0.0"
4
+ __pypi_name__ = "sql-sp-harness"
@@ -0,0 +1,4 @@
1
+ from sql_sp_harness.cli import main
2
+
3
+ if __name__ == "__main__":
4
+ main()
@@ -0,0 +1,297 @@
1
+ """CLI for sql-sp-harness."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import sys
6
+ from pathlib import Path
7
+ from typing import Optional
8
+
9
+ import typer
10
+
11
+ from sql_sp_harness import __version__
12
+ from sql_sp_harness.console import supports_color
13
+ from sql_sp_harness.inventory import inventory_from_sql
14
+ from sql_sp_harness.transform import transform_sql
15
+
16
+ APP_HELP = """
17
+ Turn T-SQL stored procedures into safe, runnable debug scripts.
18
+
19
+ \b
20
+ Commands:
21
+ analyze See what a procedure does (DML, TRY/CATCH, loops, variables)
22
+ generate Create a debug harness script safe to run on a dev database
23
+
24
+ \b
25
+ Quick start:
26
+ sql-sp-harness analyze -i MyProc.sql
27
+ sql-sp-harness generate -i MyProc.sql -o MyProc_debug.sql
28
+
29
+ \b
30
+ More help:
31
+ sql-sp-harness analyze --help
32
+ sql-sp-harness generate --help
33
+ """
34
+
35
+ app = typer.Typer(
36
+ name="sql-sp-harness",
37
+ help=APP_HELP,
38
+ no_args_is_help=True,
39
+ add_completion=False,
40
+ )
41
+
42
+
43
+ @app.command("version")
44
+ def cmd_version() -> None:
45
+ """Print package version."""
46
+ typer.echo(__version__)
47
+
48
+
49
+ def _version() -> str:
50
+ try:
51
+ from importlib.metadata import version
52
+
53
+ return version("sql-sp-harness")
54
+ except Exception:
55
+ return __version__
56
+
57
+
58
+ @app.callback()
59
+ def _root_callback(
60
+ ctx: typer.Context,
61
+ version: Optional[bool] = typer.Option(
62
+ None,
63
+ "--version",
64
+ "-V",
65
+ help="Show version and exit.",
66
+ is_eager=True,
67
+ ),
68
+ ) -> None:
69
+ """T-SQL stored procedure debug harness generator."""
70
+ if version:
71
+ typer.echo(f"sql-sp-harness {_version()}")
72
+ raise typer.Exit()
73
+
74
+
75
+ def _read_input(path: Optional[Path]) -> str:
76
+ if path is None or str(path) == "-":
77
+ return sys.stdin.read()
78
+ return path.read_text(encoding="utf-8")
79
+
80
+
81
+ def _write_output(path: Optional[Path], content: str) -> None:
82
+ if path is None or str(path) == "-":
83
+ sys.stdout.write(content)
84
+ return
85
+ path.write_text(content, encoding="utf-8")
86
+
87
+
88
+ def _run_analyze(
89
+ input: Path,
90
+ report: Optional[Path],
91
+ plain: bool,
92
+ full: bool,
93
+ ) -> None:
94
+ sql = _read_input(input)
95
+ inv = inventory_from_sql(sql)
96
+ colorize = supports_color() and not plain and report is None
97
+ text = inv.to_text(colorize=colorize, non_zero_only=not full)
98
+ if report:
99
+ report.write_text(text + "\n", encoding="utf-8")
100
+ typer.echo(f"Report written to {report}")
101
+ else:
102
+ typer.echo(text)
103
+
104
+
105
+ @app.command("analyze")
106
+ def analyze_cmd(
107
+ input: Path = typer.Option(
108
+ ...,
109
+ "--input",
110
+ "-i",
111
+ help="Input .sql file (use - for stdin).",
112
+ ),
113
+ report: Optional[Path] = typer.Option(
114
+ None,
115
+ "--report",
116
+ "-r",
117
+ help="Write plain-text report to file (no ANSI colors).",
118
+ ),
119
+ plain: bool = typer.Option(
120
+ False,
121
+ "--plain",
122
+ help="Disable ANSI colors on terminal output.",
123
+ ),
124
+ full: bool = typer.Option(
125
+ False,
126
+ "--full",
127
+ help="Show all sections, including zero counts.",
128
+ ),
129
+ ) -> None:
130
+ """
131
+ Analyze a stored procedure and show what it does.
132
+
133
+ Summarizes DML against real tables, TRY/CATCH blocks, loops, SET statements,
134
+ and other structural detail — useful before generating a debug harness.
135
+ """
136
+ _run_analyze(input, report, plain, full)
137
+
138
+
139
+ @app.command("inventory", hidden=True)
140
+ def inventory_cmd(
141
+ input: Path = typer.Option(
142
+ ...,
143
+ "--input",
144
+ "-i",
145
+ help="Input .sql file (use - for stdin).",
146
+ ),
147
+ report: Optional[Path] = typer.Option(
148
+ None,
149
+ "--report",
150
+ "-r",
151
+ help="Write plain-text report to file (no ANSI colors).",
152
+ ),
153
+ plain: bool = typer.Option(
154
+ False,
155
+ "--plain",
156
+ help="Disable ANSI colors on terminal output.",
157
+ ),
158
+ full: bool = typer.Option(
159
+ False,
160
+ "--full",
161
+ help="Show all sections, including zero counts.",
162
+ ),
163
+ ) -> None:
164
+ """Deprecated alias for analyze."""
165
+ _run_analyze(input, report, plain, full)
166
+
167
+
168
+ def _run_generate(
169
+ input: Path,
170
+ output: Optional[Path],
171
+ trace_style: str,
172
+ no_stub_dml: bool,
173
+ block_markers: bool,
174
+ quiet: bool,
175
+ ) -> None:
176
+ if trace_style not in ("raiserror", "print"):
177
+ typer.echo("trace-style must be 'raiserror' or 'print'", err=True)
178
+ raise typer.Exit(1)
179
+
180
+ sql = _read_input(input)
181
+ progress = None if quiet else lambda msg: typer.echo(msg, err=True)
182
+
183
+ result = transform_sql(
184
+ sql,
185
+ trace_style=trace_style,
186
+ stub_dml=not no_stub_dml,
187
+ add_block_markers=block_markers,
188
+ on_progress=progress,
189
+ )
190
+
191
+ out_path = output
192
+ if out_path is None and str(input) != "-":
193
+ out_path = input.with_name(f"{input.stem}_debug{input.suffix}")
194
+
195
+ _write_output(out_path, result.sql)
196
+
197
+ summary = (
198
+ f"Done: {result.stats.dml_stubbed} DML stubbed, "
199
+ f"{result.stats.traces_added} traces added."
200
+ )
201
+ if out_path and str(out_path) != "-":
202
+ typer.echo(f"{summary} Written to {out_path}")
203
+ else:
204
+ typer.echo(summary)
205
+
206
+ if result.parse_errors:
207
+ typer.echo("Parse warnings present — review banner in output.", err=True)
208
+ raise typer.Exit(2)
209
+
210
+
211
+ @app.command("generate")
212
+ def generate_cmd(
213
+ input: Path = typer.Option(
214
+ ...,
215
+ "--input",
216
+ "-i",
217
+ help="Input .sql file (use - for stdin).",
218
+ ),
219
+ output: Optional[Path] = typer.Option(
220
+ None,
221
+ "--output",
222
+ "-o",
223
+ help="Output path (default: <input>_debug.sql).",
224
+ ),
225
+ trace_style: str = typer.Option(
226
+ "print",
227
+ "--trace-style",
228
+ help="Trace style: print (default) or raiserror (NOWAIT).",
229
+ ),
230
+ no_stub_dml: bool = typer.Option(
231
+ False, "--no-stub-dml", help="Skip DML stubbing; only add traces."
232
+ ),
233
+ block_markers: bool = typer.Option(
234
+ False,
235
+ "--block-markers",
236
+ help="Insert -- [DBG] Step N markers before IF/WHILE.",
237
+ ),
238
+ quiet: bool = typer.Option(
239
+ False,
240
+ "--quiet",
241
+ "-q",
242
+ help="Suppress progress messages on stderr.",
243
+ ),
244
+ ) -> None:
245
+ """
246
+ Generate a debug harness script from a stored procedure.
247
+
248
+ Replaces writes to real tables with SELECT previews and adds PRINT traces on
249
+ variables so you can run the script on a dev database without side effects.
250
+ """
251
+ _run_generate(input, output, trace_style, no_stub_dml, block_markers, quiet)
252
+
253
+
254
+ @app.command("transform", hidden=True)
255
+ def transform_cmd(
256
+ input: Path = typer.Option(
257
+ ...,
258
+ "--input",
259
+ "-i",
260
+ help="Input .sql file (use - for stdin).",
261
+ ),
262
+ output: Optional[Path] = typer.Option(
263
+ None,
264
+ "--output",
265
+ "-o",
266
+ help="Output path (default: <input>_debug.sql).",
267
+ ),
268
+ trace_style: str = typer.Option(
269
+ "print",
270
+ "--trace-style",
271
+ help="Trace style: print (default) or raiserror (NOWAIT).",
272
+ ),
273
+ no_stub_dml: bool = typer.Option(
274
+ False, "--no-stub-dml", help="Skip DML stubbing; only add traces."
275
+ ),
276
+ block_markers: bool = typer.Option(
277
+ False,
278
+ "--block-markers",
279
+ help="Insert -- [DBG] Step N markers before IF/WHILE.",
280
+ ),
281
+ quiet: bool = typer.Option(
282
+ False,
283
+ "--quiet",
284
+ "-q",
285
+ help="Suppress progress messages on stderr.",
286
+ ),
287
+ ) -> None:
288
+ """Deprecated alias for generate."""
289
+ _run_generate(input, output, trace_style, no_stub_dml, block_markers, quiet)
290
+
291
+
292
+ def main() -> None:
293
+ app()
294
+
295
+
296
+ if __name__ == "__main__":
297
+ main()
@@ -0,0 +1,45 @@
1
+ """Terminal styling helpers for CLI output."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import os
6
+ import sys
7
+
8
+ RESET = "\033[0m"
9
+ GREEN = "\033[32m"
10
+ RED = "\033[31m"
11
+ YELLOW = "\033[33m"
12
+ CYAN = "\033[36m"
13
+ BOLD = "\033[1m"
14
+ ITALIC = "\033[3m"
15
+ DIM = "\033[2m"
16
+
17
+
18
+ def supports_color() -> bool:
19
+ return sys.stdout.isatty() and os.environ.get("NO_COLOR") is None
20
+
21
+
22
+ def style(text: str, color: str, *, enabled: bool = True) -> str:
23
+ if not enabled:
24
+ return text
25
+ return f"{color}{text}{RESET}"
26
+
27
+
28
+ def success(text: str, *, enabled: bool = True) -> str:
29
+ return style(text, GREEN, enabled=enabled)
30
+
31
+
32
+ def failure(text: str, *, enabled: bool = True) -> str:
33
+ return style(text, RED, enabled=enabled)
34
+
35
+
36
+ def warning(text: str, *, enabled: bool = True) -> str:
37
+ return style(text, YELLOW, enabled=enabled)
38
+
39
+
40
+ def heading(text: str, *, enabled: bool = True) -> str:
41
+ return style(text, CYAN + BOLD, enabled=enabled)
42
+
43
+
44
+ def dim(text: str, *, enabled: bool = True) -> str:
45
+ return style(text, DIM, enabled=enabled)