usecli 0.1.46__tar.gz → 0.1.47__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.
- {usecli-0.1.46 → usecli-0.1.47}/PKG-INFO +1 -1
- {usecli-0.1.46 → usecli-0.1.47}/pyproject.toml +1 -1
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/cli/commands/defaults/base/about_command.py +136 -17
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/usecli.config.toml +1 -1
- {usecli-0.1.46 → usecli-0.1.47}/LICENSE +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/README.md +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/__init__.py +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/cli/__init__.py +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/cli/commands/README.md +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/cli/commands/__init__.py +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/cli/commands/custom/README.md +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/cli/commands/custom/__init__.py +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/cli/commands/defaults/__init__.py +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/cli/commands/defaults/base/__init__.py +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/cli/commands/defaults/base/help_command.py +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/cli/commands/defaults/base/inspire_command.py +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/cli/commands/defaults/base/internal/__init__.py +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/cli/commands/defaults/base/internal/fzf_command.py +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/cli/commands/defaults/core/__init__.py +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/cli/commands/defaults/core/utils.py +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/cli/commands/defaults/make/__init__.py +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/cli/commands/defaults/make/make_command.py +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/cli/commands/defaults/make/make_theme_command.py +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/cli/commands/init_command.py +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/cli/config/__init__.py +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/cli/config/colors.py +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/cli/core/__init__.py +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/cli/core/base_command.py +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/cli/core/error/__init__.py +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/cli/core/error/handler.py +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/cli/core/error/utils.py +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/cli/core/exceptions/__init__.py +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/cli/core/exceptions/base.py +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/cli/core/exceptions/config.py +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/cli/core/exceptions/usage.py +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/cli/core/exceptions/validation.py +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/cli/core/skill_generator.py +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/cli/core/ui/__init__.py +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/cli/core/ui/list.py +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/cli/core/ui/title.py +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/cli/core/ui/title.txt +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/cli/core/validators/__init__.py +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/cli/core/validators/network.py +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/cli/core/validators/numeric.py +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/cli/core/validators/path.py +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/cli/core/validators/string.py +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/cli/services/__init__.py +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/cli/services/command_service.py +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/cli/templates/command.py.j2 +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/cli/templates/theme.toml.j2 +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/cli/templates/usecli.config.toml.j2 +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/cli/themes/ayu_dark.toml +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/cli/themes/catppuccin_frappe.toml +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/cli/themes/catppuccin_latte.toml +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/cli/themes/catppuccin_macchiato.toml +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/cli/themes/catppuccin_mocha.toml +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/cli/themes/default.toml +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/cli/themes/dracula.toml +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/cli/themes/gruvbox_dark.toml +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/cli/themes/nord.toml +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/cli/themes/tokyo_night.toml +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/cli/utils/__init__.py +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/cli/utils/interactive/__init__.py +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/cli/utils/interactive/terminal_menu.py +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/menu.py +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/params.py +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/shared/__init__.py +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/shared/config/__init__.py +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/shared/config/globals.py +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/shared/config/manager.py +0 -0
- {usecli-0.1.46 → usecli-0.1.47}/src/usecli/ui.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "usecli"
|
|
3
|
-
version = "0.1.
|
|
3
|
+
version = "0.1.47"
|
|
4
4
|
description = "A powerful Python CLI framework for building beautiful, developer-friendly command-line tools."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
authors = [{ name = "Edward Boswell", email = "thememium@gmail.com" }]
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import importlib.metadata
|
|
4
|
+
import os
|
|
3
5
|
import platform
|
|
4
6
|
import re
|
|
5
7
|
import sys
|
|
@@ -55,7 +57,51 @@ def _parse_dependency_requirement(req: str) -> tuple[str, str | None]:
|
|
|
55
57
|
return name, remainder
|
|
56
58
|
|
|
57
59
|
|
|
60
|
+
def _get_console_script_distribution(
|
|
61
|
+
command_name: str | None,
|
|
62
|
+
) -> importlib.metadata.Distribution | None:
|
|
63
|
+
if not command_name:
|
|
64
|
+
return None
|
|
65
|
+
try:
|
|
66
|
+
distributions = importlib.metadata.distributions()
|
|
67
|
+
except Exception:
|
|
68
|
+
return None
|
|
69
|
+
for dist in distributions:
|
|
70
|
+
try:
|
|
71
|
+
entry_points = dist.entry_points
|
|
72
|
+
except Exception:
|
|
73
|
+
continue
|
|
74
|
+
for entry_point in entry_points:
|
|
75
|
+
if entry_point.group != "console_scripts":
|
|
76
|
+
continue
|
|
77
|
+
if entry_point.name == command_name:
|
|
78
|
+
return dist
|
|
79
|
+
return None
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def _get_package_dependencies_from_distribution(
|
|
83
|
+
dist: importlib.metadata.Distribution,
|
|
84
|
+
) -> list[tuple[str, str | None]]:
|
|
85
|
+
requires = dist.requires or []
|
|
86
|
+
result: list[tuple[str, str | None]] = []
|
|
87
|
+
for req in requires:
|
|
88
|
+
if not isinstance(req, str):
|
|
89
|
+
continue
|
|
90
|
+
name, spec = _parse_dependency_requirement(req)
|
|
91
|
+
if name and not req.startswith("("):
|
|
92
|
+
result.append((name, spec))
|
|
93
|
+
return result
|
|
94
|
+
|
|
95
|
+
|
|
58
96
|
def _get_dependencies(config: ConfigManager) -> list[tuple[str, str | None]]:
|
|
97
|
+
command_name = os.path.basename(sys.argv[0]) if sys.argv else None
|
|
98
|
+
dist = _get_console_script_distribution(command_name)
|
|
99
|
+
if dist is None:
|
|
100
|
+
primary_command = get_script_command_name(default=None)
|
|
101
|
+
dist = _get_console_script_distribution(primary_command)
|
|
102
|
+
if dist is not None:
|
|
103
|
+
return _get_package_dependencies_from_distribution(dist)
|
|
104
|
+
|
|
59
105
|
pyproject_path = config.pyproject_path
|
|
60
106
|
if not pyproject_path.exists():
|
|
61
107
|
return []
|
|
@@ -79,8 +125,91 @@ def _get_dependencies(config: ConfigManager) -> list[tuple[str, str | None]]:
|
|
|
79
125
|
return result
|
|
80
126
|
|
|
81
127
|
|
|
128
|
+
def _get_application_distribution() -> importlib.metadata.Distribution | None:
|
|
129
|
+
command_name = os.path.basename(sys.argv[0]) if sys.argv else None
|
|
130
|
+
dist = _get_console_script_distribution(command_name)
|
|
131
|
+
if dist is None:
|
|
132
|
+
primary_command = get_script_command_name(default=None)
|
|
133
|
+
dist = _get_console_script_distribution(primary_command)
|
|
134
|
+
return dist
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def _get_application_version(config: ConfigManager) -> str:
|
|
138
|
+
dist = _get_application_distribution()
|
|
139
|
+
if dist is not None:
|
|
140
|
+
return dist.version
|
|
141
|
+
|
|
142
|
+
config_version = config.get_project_version()
|
|
143
|
+
if config_version:
|
|
144
|
+
return config_version
|
|
145
|
+
|
|
146
|
+
return _get_version()
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def _get_application_description(config: ConfigManager) -> str:
|
|
150
|
+
description = config.get("description")
|
|
151
|
+
if (
|
|
152
|
+
config.has_key("description")
|
|
153
|
+
and isinstance(description, str)
|
|
154
|
+
and description.strip()
|
|
155
|
+
):
|
|
156
|
+
return description.strip()
|
|
157
|
+
|
|
158
|
+
project_description = _get_project_description(config)
|
|
159
|
+
if project_description:
|
|
160
|
+
return project_description
|
|
161
|
+
|
|
162
|
+
return (
|
|
163
|
+
"An elegant CLI framework for Python with prefix matching, "
|
|
164
|
+
"rich UI, and command scaffolding."
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
def _get_project_description(config: ConfigManager) -> str | None:
|
|
169
|
+
pyproject_path = config.pyproject_path
|
|
170
|
+
if not pyproject_path.exists():
|
|
171
|
+
return None
|
|
172
|
+
|
|
173
|
+
try:
|
|
174
|
+
data = tomllib.loads(pyproject_path.read_text())
|
|
175
|
+
except (tomllib.TOMLDecodeError, OSError):
|
|
176
|
+
return None
|
|
177
|
+
|
|
178
|
+
description = data.get("project", {}).get("description")
|
|
179
|
+
if isinstance(description, str) and description.strip():
|
|
180
|
+
return description.strip()
|
|
181
|
+
return None
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
def _get_installed_script_commands(command_name: str | None) -> list[str]:
|
|
185
|
+
dist = _get_console_script_distribution(command_name)
|
|
186
|
+
if dist is None:
|
|
187
|
+
return []
|
|
188
|
+
try:
|
|
189
|
+
entry_points = dist.entry_points
|
|
190
|
+
except Exception:
|
|
191
|
+
return []
|
|
192
|
+
script_names = [
|
|
193
|
+
entry_point.name
|
|
194
|
+
for entry_point in entry_points
|
|
195
|
+
if entry_point.group == "console_scripts"
|
|
196
|
+
]
|
|
197
|
+
if not script_names:
|
|
198
|
+
return []
|
|
199
|
+
if command_name and command_name in script_names:
|
|
200
|
+
return [command_name, *[name for name in script_names if name != command_name]]
|
|
201
|
+
return script_names
|
|
202
|
+
|
|
203
|
+
|
|
82
204
|
def _get_script_commands() -> list[str]:
|
|
83
205
|
primary_command = get_script_command_name(default=None)
|
|
206
|
+
command_name = os.path.basename(sys.argv[0]) if sys.argv else primary_command
|
|
207
|
+
installed_commands = _get_installed_script_commands(command_name)
|
|
208
|
+
if installed_commands:
|
|
209
|
+
if primary_command and primary_command not in installed_commands:
|
|
210
|
+
return [primary_command, *installed_commands]
|
|
211
|
+
return installed_commands
|
|
212
|
+
|
|
84
213
|
pyproject_path = Path.cwd() / "pyproject.toml"
|
|
85
214
|
if not pyproject_path.exists():
|
|
86
215
|
if primary_command:
|
|
@@ -115,19 +244,9 @@ class AboutCommand(BaseCommand):
|
|
|
115
244
|
|
|
116
245
|
def handle(self) -> None:
|
|
117
246
|
config = get_config()
|
|
118
|
-
version = config
|
|
247
|
+
version = _get_application_version(config)
|
|
119
248
|
app_name = get_project_name()
|
|
120
|
-
description = config
|
|
121
|
-
if not (
|
|
122
|
-
config.has_key("description")
|
|
123
|
-
and isinstance(description, str)
|
|
124
|
-
and description.strip()
|
|
125
|
-
):
|
|
126
|
-
description = (
|
|
127
|
-
"An elegant CLI framework for Python with prefix matching, "
|
|
128
|
-
"rich UI, and command scaffolding."
|
|
129
|
-
)
|
|
130
|
-
description = description.strip() if isinstance(description, str) else ""
|
|
249
|
+
description = _get_application_description(config)
|
|
131
250
|
|
|
132
251
|
console.print()
|
|
133
252
|
console.print(f"[bold {COLOR.PRIMARY}]Description[/bold {COLOR.PRIMARY}]")
|
|
@@ -138,8 +257,11 @@ class AboutCommand(BaseCommand):
|
|
|
138
257
|
console.print(f"[bold {COLOR.PRIMARY}]Environment[/bold {COLOR.PRIMARY}]")
|
|
139
258
|
console.print(f"[{COLOR.PRIMARY}]─" * 78)
|
|
140
259
|
|
|
141
|
-
|
|
142
|
-
|
|
260
|
+
dist = _get_application_distribution()
|
|
261
|
+
name_label = "Cli Name" if dist is not None else "Application Name"
|
|
262
|
+
version_label = "Cli Version" if dist is not None else "Application Version"
|
|
263
|
+
self._print_row(name_label, app_name)
|
|
264
|
+
self._print_row(version_label, version)
|
|
143
265
|
self._print_row("Python Version", platform.python_version())
|
|
144
266
|
self._print_row("Platform", f"[{COLOR.FOREGROUND_MUTED}]{platform.platform()}")
|
|
145
267
|
|
|
@@ -159,9 +281,6 @@ class AboutCommand(BaseCommand):
|
|
|
159
281
|
deps = _get_dependencies(config)
|
|
160
282
|
if deps:
|
|
161
283
|
for dep_name, spec in deps:
|
|
162
|
-
if dep_name == "usecli" and spec:
|
|
163
|
-
self._print_row(dep_name, spec)
|
|
164
|
-
continue
|
|
165
284
|
try:
|
|
166
285
|
installed_version = get_version(dep_name)
|
|
167
286
|
self._print_row(dep_name, installed_version)
|
|
@@ -3,7 +3,7 @@ command_name = "usecli"
|
|
|
3
3
|
title = "usecli"
|
|
4
4
|
title_file = "cli/core/ui/title.txt"
|
|
5
5
|
title_font = "ansi_shadow"
|
|
6
|
-
description = "A
|
|
6
|
+
description = "A powerful Python CLI framework for building beautiful, developer-friendly command-line tools."
|
|
7
7
|
commands_dir = "cli/commands/custom"
|
|
8
8
|
templates_dir = "cli/templates"
|
|
9
9
|
themes_dir = "cli/themes"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{usecli-0.1.46 → usecli-0.1.47}/src/usecli/cli/commands/defaults/base/internal/fzf_command.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|