usecli 0.1.48__tar.gz → 0.1.50__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.
Files changed (70) hide show
  1. {usecli-0.1.48 → usecli-0.1.50}/PKG-INFO +1 -1
  2. {usecli-0.1.48 → usecli-0.1.50}/pyproject.toml +1 -1
  3. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/cli/commands/defaults/base/inspire_command.py +8 -3
  4. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/cli/core/base_command.py +8 -7
  5. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/cli/core/ui/list.py +15 -3
  6. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/cli/templates/command.py.j2 +1 -1
  7. {usecli-0.1.48 → usecli-0.1.50}/LICENSE +0 -0
  8. {usecli-0.1.48 → usecli-0.1.50}/README.md +0 -0
  9. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/__init__.py +0 -0
  10. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/cli/__init__.py +0 -0
  11. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/cli/commands/README.md +0 -0
  12. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/cli/commands/__init__.py +0 -0
  13. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/cli/commands/custom/README.md +0 -0
  14. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/cli/commands/custom/__init__.py +0 -0
  15. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/cli/commands/defaults/__init__.py +0 -0
  16. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/cli/commands/defaults/base/__init__.py +0 -0
  17. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/cli/commands/defaults/base/about_command.py +0 -0
  18. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/cli/commands/defaults/base/help_command.py +0 -0
  19. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/cli/commands/defaults/base/internal/__init__.py +0 -0
  20. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/cli/commands/defaults/base/internal/fzf_command.py +0 -0
  21. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/cli/commands/defaults/core/__init__.py +0 -0
  22. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/cli/commands/defaults/core/utils.py +0 -0
  23. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/cli/commands/defaults/make/__init__.py +0 -0
  24. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/cli/commands/defaults/make/make_command.py +0 -0
  25. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/cli/commands/defaults/make/make_theme_command.py +0 -0
  26. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/cli/commands/init_command.py +0 -0
  27. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/cli/config/__init__.py +0 -0
  28. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/cli/config/colors.py +0 -0
  29. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/cli/core/__init__.py +0 -0
  30. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/cli/core/error/__init__.py +0 -0
  31. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/cli/core/error/handler.py +0 -0
  32. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/cli/core/error/utils.py +0 -0
  33. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/cli/core/exceptions/__init__.py +0 -0
  34. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/cli/core/exceptions/base.py +0 -0
  35. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/cli/core/exceptions/config.py +0 -0
  36. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/cli/core/exceptions/usage.py +0 -0
  37. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/cli/core/exceptions/validation.py +0 -0
  38. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/cli/core/ui/__init__.py +0 -0
  39. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/cli/core/ui/title.py +0 -0
  40. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/cli/core/ui/title.txt +0 -0
  41. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/cli/core/validators/__init__.py +0 -0
  42. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/cli/core/validators/network.py +0 -0
  43. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/cli/core/validators/numeric.py +0 -0
  44. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/cli/core/validators/path.py +0 -0
  45. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/cli/core/validators/string.py +0 -0
  46. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/cli/services/__init__.py +0 -0
  47. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/cli/services/command_service.py +0 -0
  48. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/cli/templates/theme.toml.j2 +0 -0
  49. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/cli/templates/usecli.config.toml.j2 +0 -0
  50. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/cli/themes/ayu_dark.toml +0 -0
  51. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/cli/themes/catppuccin_frappe.toml +0 -0
  52. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/cli/themes/catppuccin_latte.toml +0 -0
  53. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/cli/themes/catppuccin_macchiato.toml +0 -0
  54. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/cli/themes/catppuccin_mocha.toml +0 -0
  55. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/cli/themes/default.toml +0 -0
  56. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/cli/themes/dracula.toml +0 -0
  57. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/cli/themes/gruvbox_dark.toml +0 -0
  58. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/cli/themes/nord.toml +0 -0
  59. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/cli/themes/tokyo_night.toml +0 -0
  60. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/cli/utils/__init__.py +0 -0
  61. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/cli/utils/interactive/__init__.py +0 -0
  62. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/cli/utils/interactive/terminal_menu.py +0 -0
  63. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/menu.py +0 -0
  64. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/params.py +0 -0
  65. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/shared/__init__.py +0 -0
  66. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/shared/config/__init__.py +0 -0
  67. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/shared/config/globals.py +0 -0
  68. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/shared/config/manager.py +0 -0
  69. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/ui.py +0 -0
  70. {usecli-0.1.48 → usecli-0.1.50}/src/usecli/usecli.config.toml +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: usecli
3
- Version: 0.1.48
3
+ Version: 0.1.50
4
4
  Summary: A powerful Python CLI framework for building beautiful, developer-friendly command-line tools.
5
5
  Author: Edward Boswell
6
6
  Author-email: Edward Boswell <thememium@gmail.com>
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "usecli"
3
- version = "0.1.48"
3
+ version = "0.1.50"
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" }]
@@ -33,9 +33,14 @@ class InspireCommand(BaseCommand):
33
33
  def handle(self) -> None:
34
34
  """Handle the command execution."""
35
35
  try:
36
- with urllib.request.urlopen(
37
- "https://zenquotes.io/api/random/inspiration"
38
- ) as response:
36
+ req = urllib.request.Request(
37
+ "https://zenquotes.io/api/random/inspiration",
38
+ headers={
39
+ "User-Agent": "Mozilla/5.0 (compatible; usecli/1.0)",
40
+ "Accept": "application/json",
41
+ },
42
+ )
43
+ with urllib.request.urlopen(req, timeout=10) as response:
39
44
  data: list[dict[str, str]] = json.loads(response.read().decode())
40
45
  quote = data[0]["q"]
41
46
  author = data[0]["a"]
@@ -6,10 +6,9 @@ from abc import ABC, abstractmethod
6
6
  from typing import TYPE_CHECKING, Any, ClassVar
7
7
 
8
8
  import typer
9
- from click import Argument, Option
10
9
  from click.exceptions import Exit
11
10
  from rich.console import Console
12
- from typer.core import TyperCommand
11
+ from typer.core import TyperArgument, TyperCommand, TyperOption
13
12
 
14
13
  from usecli.cli.config.colors import COLOR
15
14
  from usecli.cli.core.ui.title import get_script_command_name
@@ -179,8 +178,8 @@ class CustomHelpCommand(TyperCommand):
179
178
  self.params = []
180
179
  if not self._has_interactive_option():
181
180
  self.params.append(
182
- Option(
183
- ["--interactive", "-i"],
181
+ TyperOption(
182
+ param_decls=["--interactive", "-i"],
184
183
  is_flag=True,
185
184
  help="Run in interactive mode.",
186
185
  )
@@ -188,7 +187,7 @@ class CustomHelpCommand(TyperCommand):
188
187
 
189
188
  def _has_interactive_option(self) -> bool:
190
189
  return any(
191
- isinstance(param, Option)
190
+ isinstance(param, TyperOption)
192
191
  and ("--interactive" in param.opts or "-i" in param.opts)
193
192
  for param in getattr(self, "params", [])
194
193
  )
@@ -217,10 +216,12 @@ class CustomHelpCommand(TyperCommand):
217
216
  Raises:
218
217
  Exit: After displaying help.
219
218
  """
220
- arguments = [p for p in self.params if isinstance(p, Argument)]
219
+ arguments = [p for p in self.params if isinstance(p, TyperArgument)]
221
220
  argument_names = [p.name for p in arguments if p.name]
222
221
  options = [
223
- p for p in self.params if isinstance(p, Option) and "--help" not in p.opts
222
+ p
223
+ for p in self.params
224
+ if isinstance(p, TyperOption) and "--help" not in p.opts
224
225
  ]
225
226
 
226
227
  arg_usage = " ".join(rf"\[{name.upper()}]" for name in argument_names)
@@ -23,6 +23,17 @@ console = Console()
23
23
  SPACER_LENGTH = 6
24
24
 
25
25
 
26
+ def _is_click_group(obj: object) -> bool:
27
+ """Check if an object is a Click group (has subcommands).
28
+
29
+ Works with both standard click.Group and Typer's vendored click
30
+ (TyperGroup in typer>=0.26 no longer extends click.Group directly).
31
+ """
32
+ return isinstance(obj, click.Group) or (
33
+ hasattr(obj, "commands") and isinstance(getattr(obj, "commands", None), dict)
34
+ )
35
+
36
+
26
37
  class CommandEntry(TypedDict):
27
38
  name: str
28
39
  display_name: str
@@ -87,9 +98,10 @@ def list_commands(app: typer.Typer, prefix_filter: str | None = None) -> None:
87
98
  commands.sort(key=lambda x: x["name"])
88
99
 
89
100
  groups: dict[str, str] = {}
90
- if isinstance(click_group, click.Group):
91
- for cmd_name, cmd_obj in click_group.commands.items():
92
- if isinstance(cmd_obj, click.Group):
101
+ if _is_click_group(click_group):
102
+ sub_commands: dict[str, object] = getattr(click_group, "commands", {})
103
+ for cmd_name, cmd_obj in sub_commands.items():
104
+ if _is_click_group(cmd_obj):
93
105
  if (
94
106
  cmd_name in group_alias_to_primary
95
107
  and group_alias_to_primary[cmd_name] != cmd_name
@@ -13,7 +13,7 @@ class {{ class_name }}(BaseCommand):
13
13
  return "Description for {{ command_name }} command"
14
14
 
15
15
  # def aliases(self) -> list[str]:
16
- # return [{{ command_name[:3] }}]
16
+ # return ["{{ command_name[:3] }}"]
17
17
 
18
18
  def handle(
19
19
  self,
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes