tailwhip 0.9a2__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.
- tailwhip-0.9a2/LICENSE +25 -0
- tailwhip-0.9a2/PKG-INFO +92 -0
- tailwhip-0.9a2/README.md +63 -0
- tailwhip-0.9a2/pyproject.toml +69 -0
- tailwhip-0.9a2/setup.cfg +4 -0
- tailwhip-0.9a2/tailwhip/__init__.py +11 -0
- tailwhip-0.9a2/tailwhip/__main__.py +8 -0
- tailwhip-0.9a2/tailwhip/cli.py +148 -0
- tailwhip-0.9a2/tailwhip/constants.py +311 -0
- tailwhip-0.9a2/tailwhip/datatypes.py +23 -0
- tailwhip-0.9a2/tailwhip/files.py +170 -0
- tailwhip-0.9a2/tailwhip/process.py +240 -0
- tailwhip-0.9a2/tailwhip/sorting.py +243 -0
- tailwhip-0.9a2/tailwhip/tests/__init__.py +1 -0
- tailwhip-0.9a2/tailwhip/tests/conftest.py +33 -0
- tailwhip-0.9a2/tailwhip/tests/test_cli.py +36 -0
- tailwhip-0.9a2/tailwhip/tests/test_file_finder.py +219 -0
- tailwhip-0.9a2/tailwhip/tests/test_sorting.py +317 -0
- tailwhip-0.9a2/tailwhip.egg-info/PKG-INFO +92 -0
- tailwhip-0.9a2/tailwhip.egg-info/SOURCES.txt +22 -0
- tailwhip-0.9a2/tailwhip.egg-info/dependency_links.txt +1 -0
- tailwhip-0.9a2/tailwhip.egg-info/entry_points.txt +2 -0
- tailwhip-0.9a2/tailwhip.egg-info/requires.txt +2 -0
- tailwhip-0.9a2/tailwhip.egg-info/top_level.txt +1 -0
tailwhip-0.9a2/LICENSE
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
Copyright (c) 2025, Martin Mahner <https://elephant.house/>
|
|
2
|
+
All rights reserved.
|
|
3
|
+
|
|
4
|
+
Redistribution and use in source and binary forms, with or without modification,
|
|
5
|
+
are permitted provided that the following conditions are met:
|
|
6
|
+
|
|
7
|
+
* Redistributions of source code must retain the above copyright notice,
|
|
8
|
+
this list of conditions and the following disclaimer.
|
|
9
|
+
* Redistributions in binary form must reproduce the above copyright notice,
|
|
10
|
+
this list of conditions and the following disclaimer in the documentation
|
|
11
|
+
and/or other materials provided with the distribution.
|
|
12
|
+
* Neither the name django-markup nor the names of its contributors
|
|
13
|
+
may be used to endorse or promote products derived from this software without
|
|
14
|
+
specific prior written permission.
|
|
15
|
+
|
|
16
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
17
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
18
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
19
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
|
20
|
+
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
21
|
+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
22
|
+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|
23
|
+
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
24
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
25
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
tailwhip-0.9a2/PKG-INFO
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: tailwhip
|
|
3
|
+
Version: 0.9a2
|
|
4
|
+
Summary: A pure Python Tailwind CSS class sorter that works with any HTML or CSS file, including Django templates and other template languages.
|
|
5
|
+
Author-email: Martin Mahner <martin@mahner.org>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/bartTC/tailwhip/
|
|
8
|
+
Project-URL: Repository, https://github.com/bartTC/tailwhip/
|
|
9
|
+
Classifier: Development Status :: 3 - Alpha
|
|
10
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
11
|
+
Classifier: Environment :: Web Environment
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: Programming Language :: Python
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
21
|
+
Classifier: Topic :: Internet :: WWW/HTTP
|
|
22
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
23
|
+
Requires-Python: >=3.10
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
License-File: LICENSE
|
|
26
|
+
Requires-Dist: rich
|
|
27
|
+
Requires-Dist: typer
|
|
28
|
+
Dynamic: license-file
|
|
29
|
+
|
|
30
|
+
# Tailwhip — Tailwind CSS class sorter
|
|
31
|
+
|
|
32
|
+
Tailwhip is a pure Python Tailwind CSS class sorter that works with any HTML or CSS
|
|
33
|
+
file — including Django templates and other templating languages.
|
|
34
|
+
|
|
35
|
+

|
|
36
|
+
|
|
37
|
+
## Why Tailwhip?
|
|
38
|
+
|
|
39
|
+
The [official Prettier plugin][1] for sorting Tailwind classes doesn’t play well
|
|
40
|
+
with many template languages, such as Django. While there are Prettier plugins that
|
|
41
|
+
add limited support for [Jinja templates][2], they often require configuration
|
|
42
|
+
workarounds or restrict what you can do with Prettier.
|
|
43
|
+
|
|
44
|
+
Tailwhip takes a more pragmatic approach. Instead of trying to parse and understand
|
|
45
|
+
every possible template syntax, it focuses on sorting Tailwind classes reliably.
|
|
46
|
+
|
|
47
|
+
[1]: https://github.com/tailwindlabs/prettier-plugin-tailwindcss
|
|
48
|
+
[2]: https://github.com/davidodenwald/prettier-plugin-jinja-template
|
|
49
|
+
|
|
50
|
+
How it works:
|
|
51
|
+
|
|
52
|
+
1. It finds all `class=""` attributes and `@apply` directives in the given files.
|
|
53
|
+
2. It sorts the contained classes according to the official Tailwind CSS class order.
|
|
54
|
+
3. If a class attribute contains template syntax (e.g., `{{ ... }}` or `{% ... %}`),
|
|
55
|
+
Tailwhip leaves it untouched.
|
|
56
|
+
|
|
57
|
+
This approach ensures Tailwhip works across diverse environments — Django, Flask,
|
|
58
|
+
Jinja2, or even custom templating engines — without breaking your templates or
|
|
59
|
+
requiring complicated setup.
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
## Usage
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
$ uvx tailwhip [options] [filepath...]
|
|
66
|
+
|
|
67
|
+
# Find all .html and .css files in the templates directory
|
|
68
|
+
$ uvx tailwhip templates/
|
|
69
|
+
|
|
70
|
+
# Preview changes
|
|
71
|
+
$ uvx tailwhip templates/ -vv
|
|
72
|
+
|
|
73
|
+
# Actually apply changes
|
|
74
|
+
$ uvx tailwhip templates/ --write
|
|
75
|
+
|
|
76
|
+
# Sort classes in .scss files
|
|
77
|
+
$ uvx tailwhip templates/**/*.scss
|
|
78
|
+
|
|
79
|
+
# Standard glob patterns are supported
|
|
80
|
+
$ uvx tailwhip templates/**/*.html templates/**/*.css myapp/**/*.xhtml
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
You can also install it with pip or use it as a Python library:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
$ pip install tailwhip
|
|
87
|
+
|
|
88
|
+
$ tailwhip templates/
|
|
89
|
+
$ python -m tailwhip templates/
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
See `--help` for all options and features.
|
tailwhip-0.9a2/README.md
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Tailwhip — Tailwind CSS class sorter
|
|
2
|
+
|
|
3
|
+
Tailwhip is a pure Python Tailwind CSS class sorter that works with any HTML or CSS
|
|
4
|
+
file — including Django templates and other templating languages.
|
|
5
|
+
|
|
6
|
+

|
|
7
|
+
|
|
8
|
+
## Why Tailwhip?
|
|
9
|
+
|
|
10
|
+
The [official Prettier plugin][1] for sorting Tailwind classes doesn’t play well
|
|
11
|
+
with many template languages, such as Django. While there are Prettier plugins that
|
|
12
|
+
add limited support for [Jinja templates][2], they often require configuration
|
|
13
|
+
workarounds or restrict what you can do with Prettier.
|
|
14
|
+
|
|
15
|
+
Tailwhip takes a more pragmatic approach. Instead of trying to parse and understand
|
|
16
|
+
every possible template syntax, it focuses on sorting Tailwind classes reliably.
|
|
17
|
+
|
|
18
|
+
[1]: https://github.com/tailwindlabs/prettier-plugin-tailwindcss
|
|
19
|
+
[2]: https://github.com/davidodenwald/prettier-plugin-jinja-template
|
|
20
|
+
|
|
21
|
+
How it works:
|
|
22
|
+
|
|
23
|
+
1. It finds all `class=""` attributes and `@apply` directives in the given files.
|
|
24
|
+
2. It sorts the contained classes according to the official Tailwind CSS class order.
|
|
25
|
+
3. If a class attribute contains template syntax (e.g., `{{ ... }}` or `{% ... %}`),
|
|
26
|
+
Tailwhip leaves it untouched.
|
|
27
|
+
|
|
28
|
+
This approach ensures Tailwhip works across diverse environments — Django, Flask,
|
|
29
|
+
Jinja2, or even custom templating engines — without breaking your templates or
|
|
30
|
+
requiring complicated setup.
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
## Usage
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
$ uvx tailwhip [options] [filepath...]
|
|
37
|
+
|
|
38
|
+
# Find all .html and .css files in the templates directory
|
|
39
|
+
$ uvx tailwhip templates/
|
|
40
|
+
|
|
41
|
+
# Preview changes
|
|
42
|
+
$ uvx tailwhip templates/ -vv
|
|
43
|
+
|
|
44
|
+
# Actually apply changes
|
|
45
|
+
$ uvx tailwhip templates/ --write
|
|
46
|
+
|
|
47
|
+
# Sort classes in .scss files
|
|
48
|
+
$ uvx tailwhip templates/**/*.scss
|
|
49
|
+
|
|
50
|
+
# Standard glob patterns are supported
|
|
51
|
+
$ uvx tailwhip templates/**/*.html templates/**/*.css myapp/**/*.xhtml
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
You can also install it with pip or use it as a Python library:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
$ pip install tailwhip
|
|
58
|
+
|
|
59
|
+
$ tailwhip templates/
|
|
60
|
+
$ python -m tailwhip templates/
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
See `--help` for all options and features.
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "tailwhip"
|
|
3
|
+
version = "0.9a2"
|
|
4
|
+
description = "A pure Python Tailwind CSS class sorter that works with any HTML or CSS file, including Django templates and other template languages."
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
authors = [
|
|
7
|
+
{ name = "Martin Mahner", email = "martin@mahner.org" }
|
|
8
|
+
]
|
|
9
|
+
license = "MIT"
|
|
10
|
+
classifiers = [
|
|
11
|
+
"Development Status :: 3 - Alpha",
|
|
12
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
13
|
+
"Environment :: Web Environment",
|
|
14
|
+
"Intended Audience :: Developers",
|
|
15
|
+
"Operating System :: OS Independent",
|
|
16
|
+
"Programming Language :: Python",
|
|
17
|
+
"Programming Language :: Python :: 3.9",
|
|
18
|
+
"Programming Language :: Python :: 3.10",
|
|
19
|
+
"Programming Language :: Python :: 3.11",
|
|
20
|
+
"Programming Language :: Python :: 3.12",
|
|
21
|
+
"Programming Language :: Python :: 3.13",
|
|
22
|
+
"Programming Language :: Python :: 3.14",
|
|
23
|
+
"Topic :: Internet :: WWW/HTTP",
|
|
24
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
25
|
+
]
|
|
26
|
+
requires-python = ">=3.10"
|
|
27
|
+
dependencies = [
|
|
28
|
+
"rich",
|
|
29
|
+
"typer",
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
[project.urls]
|
|
33
|
+
Homepage = "https://github.com/bartTC/tailwhip/"
|
|
34
|
+
Repository = "https://github.com/bartTC/tailwhip/"
|
|
35
|
+
|
|
36
|
+
[dependency-groups]
|
|
37
|
+
dev = [
|
|
38
|
+
"pytest",
|
|
39
|
+
"pytest-cov",
|
|
40
|
+
]
|
|
41
|
+
|
|
42
|
+
[project.scripts]
|
|
43
|
+
tailwhip = "tailwhip:main"
|
|
44
|
+
|
|
45
|
+
[tool.uv]
|
|
46
|
+
package = true
|
|
47
|
+
|
|
48
|
+
[tool.ruff]
|
|
49
|
+
target-version = "py39"
|
|
50
|
+
lint.select = ["ALL"]
|
|
51
|
+
lint.ignore = [
|
|
52
|
+
# Valid exclusions.
|
|
53
|
+
"COM812", # Conflicts with ruff format
|
|
54
|
+
"E501", # Line too long (>88)
|
|
55
|
+
"D203", # incorrect-blank-line-before-class (conflicts with D211)
|
|
56
|
+
"D213", # multi-line-summary-second-line (conflicts with D212)
|
|
57
|
+
"ERA001", # Found commented-out code
|
|
58
|
+
"FBT", # Flake Boolean Trap (don't use arg=True in functions)
|
|
59
|
+
"FIX", # Line contains TODO/FIXME. Consider resolving.
|
|
60
|
+
]
|
|
61
|
+
|
|
62
|
+
[tool.ruff.lint.extend-per-file-ignores]
|
|
63
|
+
"test*.py" = [
|
|
64
|
+
"S101", # Use of `assert` detected
|
|
65
|
+
"PLR2004", # Magic value used in comparison, consider replacing <int> with a constant variable
|
|
66
|
+
]
|
|
67
|
+
|
|
68
|
+
[tool.pytest.ini_options]
|
|
69
|
+
python_files = ["*.py"]
|
tailwhip-0.9a2/setup.cfg
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"""Tailwhip - Sort Tailwind CSS classes in HTML and CSS files."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from importlib import metadata
|
|
6
|
+
|
|
7
|
+
from tailwhip.cli import main
|
|
8
|
+
|
|
9
|
+
__all__ = ["main"]
|
|
10
|
+
__version__ = metadata.version("tailwhip")
|
|
11
|
+
__author__ = "Martin Mahner"
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
"""CLI entrypoint."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import sys
|
|
6
|
+
import time
|
|
7
|
+
from importlib import metadata
|
|
8
|
+
from pathlib import Path # noqa: TC003
|
|
9
|
+
from typing import Annotated
|
|
10
|
+
|
|
11
|
+
import typer
|
|
12
|
+
from rich.console import Console
|
|
13
|
+
|
|
14
|
+
from tailwhip.constants import CONSOLE_THEME, GLOBS, SKIP_EXPRESSIONS, VERBOSITY_LOUD
|
|
15
|
+
from tailwhip.datatypes import Config
|
|
16
|
+
from tailwhip.files import apply_changes, find_files
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def version_callback(value: bool) -> None:
|
|
20
|
+
"""Print version and exit."""
|
|
21
|
+
if value:
|
|
22
|
+
version = metadata.version("tailwhip")
|
|
23
|
+
typer.echo(f"tailwhip {version}")
|
|
24
|
+
raise typer.Exit
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
app = typer.Typer(
|
|
28
|
+
help="Sort Tailwind CSS classes in HTML and CSS files",
|
|
29
|
+
add_completion=False,
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def main() -> None:
|
|
34
|
+
"""Entrypoint for the CLI."""
|
|
35
|
+
app()
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
@app.command()
|
|
39
|
+
def run( # noqa: PLR0913
|
|
40
|
+
paths: Annotated[
|
|
41
|
+
list[Path],
|
|
42
|
+
typer.Argument(
|
|
43
|
+
help=(
|
|
44
|
+
f"File or directory paths to process. Plain directories "
|
|
45
|
+
f"(e.g., 'templates/') use default patterns ({', '.join(GLOBS)}). "
|
|
46
|
+
f"Glob patterns (e.g., 'templates/**/*.postcss') are matched as-is."
|
|
47
|
+
)
|
|
48
|
+
),
|
|
49
|
+
],
|
|
50
|
+
version: Annotated[ # noqa: ARG001
|
|
51
|
+
bool,
|
|
52
|
+
typer.Option(
|
|
53
|
+
"--version",
|
|
54
|
+
callback=version_callback,
|
|
55
|
+
is_eager=True,
|
|
56
|
+
help="Show version and exit.",
|
|
57
|
+
),
|
|
58
|
+
] = False,
|
|
59
|
+
write_mode: Annotated[
|
|
60
|
+
bool,
|
|
61
|
+
typer.Option(
|
|
62
|
+
"--write",
|
|
63
|
+
help="Apply sorting changes to files. Without this flag, runs in check-only mode to preview changes.",
|
|
64
|
+
),
|
|
65
|
+
] = False,
|
|
66
|
+
skip_expressions: Annotated[
|
|
67
|
+
str,
|
|
68
|
+
typer.Option(
|
|
69
|
+
"--skip-expressions",
|
|
70
|
+
help="Template syntax markers that indicate code blocks to skip sorting. Comma-separated list (e.g., '{{,{%,<%'). Prevents sorting dynamic template expressions.",
|
|
71
|
+
),
|
|
72
|
+
] = ",".join(SKIP_EXPRESSIONS),
|
|
73
|
+
quiet: Annotated[
|
|
74
|
+
bool,
|
|
75
|
+
typer.Option(
|
|
76
|
+
"--quiet",
|
|
77
|
+
"-q",
|
|
78
|
+
help="Minimal output mode. Only displays errors and warnings.",
|
|
79
|
+
),
|
|
80
|
+
] = False,
|
|
81
|
+
verbosity: Annotated[
|
|
82
|
+
int,
|
|
83
|
+
typer.Option(
|
|
84
|
+
"--verbose",
|
|
85
|
+
"-v",
|
|
86
|
+
count=True,
|
|
87
|
+
help="Increase output detail level. Use -v for changes, -vv for file processing, -vvv for debug info.",
|
|
88
|
+
),
|
|
89
|
+
] = 0,
|
|
90
|
+
custom_colors: Annotated[
|
|
91
|
+
str,
|
|
92
|
+
typer.Option(
|
|
93
|
+
"--custom-colors",
|
|
94
|
+
help=(
|
|
95
|
+
"Comma-separated list of custom color names from your Tailwind config "
|
|
96
|
+
"(e.g., 'brand,company,accent'). These colors will be recognized and sorted "
|
|
97
|
+
"alongside standard Tailwind colors. WARNING: Classes using these custom colors "
|
|
98
|
+
"will sort differently if you run tailwhip again without providing the same "
|
|
99
|
+
"--custom-colors values. Omitting previously-used custom colors will cause those "
|
|
100
|
+
"utilities to be treated as non-color classes and sorted into different positions."
|
|
101
|
+
),
|
|
102
|
+
),
|
|
103
|
+
] = "",
|
|
104
|
+
) -> None:
|
|
105
|
+
"""Sort Tailwind CSS classes in HTML and CSS files."""
|
|
106
|
+
console = Console(quiet=quiet, theme=CONSOLE_THEME)
|
|
107
|
+
skip_expressions = [
|
|
108
|
+
expr.strip() for expr in skip_expressions.split(",") if expr.strip()
|
|
109
|
+
]
|
|
110
|
+
custom_colors_list = {
|
|
111
|
+
color.strip() for color in custom_colors.split(",") if color.strip()
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
config = Config(
|
|
115
|
+
console=console,
|
|
116
|
+
paths=paths,
|
|
117
|
+
write=write_mode,
|
|
118
|
+
skip_expressions=skip_expressions,
|
|
119
|
+
verbosity=verbosity + 1,
|
|
120
|
+
custom_colors=custom_colors_list,
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
console.print("")
|
|
124
|
+
|
|
125
|
+
start_time = time.time()
|
|
126
|
+
targets = find_files(config=config)
|
|
127
|
+
found_any, skipped, changed = apply_changes(targets=targets, config=config)
|
|
128
|
+
duration = time.time() - start_time
|
|
129
|
+
|
|
130
|
+
if not found_any:
|
|
131
|
+
config.console.print("[red]Error: No files found[/red]")
|
|
132
|
+
sys.exit(1)
|
|
133
|
+
|
|
134
|
+
if config.verbosity < VERBOSITY_LOUD:
|
|
135
|
+
console.print(
|
|
136
|
+
"\nUse [important] -v [/important] (show unchanged files) or [important] -vv [/important] (show diff preview) for more detail."
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
if not config.write:
|
|
140
|
+
console.print(
|
|
141
|
+
"\n:warning: Dry Run. No files were actually written. "
|
|
142
|
+
"Use [important] --write [/important] to write changes."
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
console.print(
|
|
146
|
+
f"⏱ Completed in [bold]{duration:.3f}s[/bold] for {changed} files. [dim]({skipped} skipped)[/dim]",
|
|
147
|
+
highlight=False,
|
|
148
|
+
)
|