bear-utils 0.9.0__tar.gz → 0.9.2__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 (131) hide show
  1. {bear_utils-0.9.0 → bear_utils-0.9.2}/.gitignore +4 -0
  2. {bear_utils-0.9.0 → bear_utils-0.9.2}/PKG-INFO +2 -2
  3. {bear_utils-0.9.0 → bear_utils-0.9.2}/README.md +1 -1
  4. {bear_utils-0.9.0 → bear_utils-0.9.2}/maskfile.md +20 -1
  5. {bear_utils-0.9.0 → bear_utils-0.9.2}/pyproject.toml +20 -2
  6. bear_utils-0.9.2/src/bear_utils/_internal/_version.py +1 -0
  7. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/_internal/cli.py +39 -7
  8. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/_internal/debug.py +4 -2
  9. bear_utils-0.9.2/src/bear_utils/cli/_get_version.py +206 -0
  10. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/constants/__init__.py +6 -2
  11. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/constants/_exit_code.py +1 -1
  12. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/constants/_http_status_code.py +1 -1
  13. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/constants/_meta.py +33 -4
  14. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/graphics/font/block_font.py +16 -7
  15. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/logger_manager/_log_level.py +14 -14
  16. bear_utils-0.9.0/.bumpversion.cfg +0 -8
  17. {bear_utils-0.9.0 → bear_utils-0.9.2}/.python-version +0 -0
  18. {bear_utils-0.9.0 → bear_utils-0.9.2}/AGENTS.md +0 -0
  19. {bear_utils-0.9.0 → bear_utils-0.9.2}/config/coverage.ini +0 -0
  20. {bear_utils-0.9.0 → bear_utils-0.9.2}/config/default.toml +0 -0
  21. {bear_utils-0.9.0 → bear_utils-0.9.2}/config/git-changelog.toml +0 -0
  22. {bear_utils-0.9.0 → bear_utils-0.9.2}/config/pytest.ini +0 -0
  23. {bear_utils-0.9.0 → bear_utils-0.9.2}/config/ruff.toml +0 -0
  24. {bear_utils-0.9.0 → bear_utils-0.9.2}/config/vscode/launch.json +0 -0
  25. {bear_utils-0.9.0 → bear_utils-0.9.2}/config/vscode/settings.json +0 -0
  26. {bear_utils-0.9.0 → bear_utils-0.9.2}/config/vscode/tasks.json +0 -0
  27. {bear_utils-0.9.0 → bear_utils-0.9.2}/directory_structure.txt +0 -0
  28. {bear_utils-0.9.0 → bear_utils-0.9.2}/directory_structure.xml +0 -0
  29. {bear_utils-0.9.0 → bear_utils-0.9.2}/noxfile.py +0 -0
  30. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/__init__.py +0 -0
  31. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/__main__.py +0 -0
  32. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/_internal/__init__.py +0 -0
  33. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/ai/__init__.py +0 -0
  34. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/ai/ai_helpers/__init__.py +0 -0
  35. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/ai/ai_helpers/_common.py +0 -0
  36. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/ai/ai_helpers/_config.py +0 -0
  37. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/ai/ai_helpers/_parsers.py +0 -0
  38. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/ai/ai_helpers/_types.py +0 -0
  39. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/cache/__init__.py +0 -0
  40. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/cli/__init__.py +0 -0
  41. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/cli/_args.py +0 -0
  42. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/cli/commands.py +0 -0
  43. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/cli/prompt_helpers.py +0 -0
  44. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/cli/shell/__init__.py +0 -0
  45. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/cli/shell/_base_command.py +0 -0
  46. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/cli/shell/_base_shell.py +0 -0
  47. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/cli/shell/_common.py +0 -0
  48. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/cli/typer_bridge.py +0 -0
  49. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/config/__init__.py +0 -0
  50. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/config/config_manager.py +0 -0
  51. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/config/dir_manager.py +0 -0
  52. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/config/settings_manager.py +0 -0
  53. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/constants/_exceptions.py +0 -0
  54. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/constants/_lazy_typing.py +0 -0
  55. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/constants/date_related.py +0 -0
  56. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/constants/time_related.py +0 -0
  57. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/database/__init__.py +0 -0
  58. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/database/_db_manager.py +0 -0
  59. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/events/__init__.py +0 -0
  60. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/events/events_class.py +0 -0
  61. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/events/events_module.py +0 -0
  62. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/extras/__init__.py +0 -0
  63. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/extras/_async_helpers.py +0 -0
  64. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/extras/_tools.py +0 -0
  65. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/extras/platform_utils.py +0 -0
  66. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/extras/responses/__init__.py +0 -0
  67. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/extras/responses/function_response.py +0 -0
  68. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/extras/wrappers/__init__.py +0 -0
  69. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/extras/wrappers/add_methods.py +0 -0
  70. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/extras/wrappers/string_io.py +0 -0
  71. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/files/__init__.py +0 -0
  72. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/files/file_handlers/__init__.py +0 -0
  73. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/files/file_handlers/_base_file_handler.py +0 -0
  74. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/files/file_handlers/file_handler_factory.py +0 -0
  75. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/files/file_handlers/json_file_handler.py +0 -0
  76. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/files/file_handlers/log_file_handler.py +0 -0
  77. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/files/file_handlers/toml_file_handler.py +0 -0
  78. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/files/file_handlers/txt_file_handler.py +0 -0
  79. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/files/file_handlers/yaml_file_handler.py +0 -0
  80. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/files/ignore_parser.py +0 -0
  81. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/graphics/__init__.py +0 -0
  82. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/graphics/bear_gradient.py +0 -0
  83. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/graphics/font/__init__.py +0 -0
  84. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/graphics/font/_raw_block_letters.py +0 -0
  85. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/graphics/font/_theme.py +0 -0
  86. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/graphics/font/glitch_font.py +0 -0
  87. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/graphics/image_helpers.py +0 -0
  88. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/gui/__init__.py +0 -0
  89. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/gui/gui_tools/__init__.py +0 -0
  90. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/gui/gui_tools/_settings.py +0 -0
  91. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/gui/gui_tools/_types.py +0 -0
  92. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/gui/gui_tools/qt_app.py +0 -0
  93. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/gui/gui_tools/qt_color_picker.py +0 -0
  94. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/gui/gui_tools/qt_file_handler.py +0 -0
  95. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/gui/gui_tools/qt_input_dialog.py +0 -0
  96. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/logger_manager/__init__.py +0 -0
  97. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/logger_manager/_common.py +0 -0
  98. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/logger_manager/_console_junk.py +0 -0
  99. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/logger_manager/_styles.py +0 -0
  100. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/logger_manager/logger_protocol.py +0 -0
  101. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/logger_manager/loggers/__init__.py +0 -0
  102. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/logger_manager/loggers/_console.py +0 -0
  103. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/logger_manager/loggers/_level_sin.py +0 -0
  104. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/logger_manager/loggers/_logger.py +0 -0
  105. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/logger_manager/loggers/base_logger.py +0 -0
  106. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/logger_manager/loggers/base_logger.pyi +0 -0
  107. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/logger_manager/loggers/basic_logger/__init__.py +0 -0
  108. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/logger_manager/loggers/basic_logger/logger.py +0 -0
  109. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/logger_manager/loggers/basic_logger/logger.pyi +0 -0
  110. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/logger_manager/loggers/buffer_logger.py +0 -0
  111. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/logger_manager/loggers/console_logger.py +0 -0
  112. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/logger_manager/loggers/console_logger.pyi +0 -0
  113. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/logger_manager/loggers/fastapi_logger.py +0 -0
  114. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/logger_manager/loggers/file_logger.py +0 -0
  115. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/logger_manager/loggers/simple_logger.py +0 -0
  116. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/logger_manager/loggers/sub_logger.py +0 -0
  117. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/logger_manager/loggers/sub_logger.pyi +0 -0
  118. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/monitoring/__init__.py +0 -0
  119. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/monitoring/_common.py +0 -0
  120. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/monitoring/host_monitor.py +0 -0
  121. {bear_utils-0.9.0 → bear_utils-0.9.2}/src/bear_utils/time/__init__.py +0 -0
  122. {bear_utils-0.9.0 → bear_utils-0.9.2}/tests/__init__.py +0 -0
  123. {bear_utils-0.9.0 → bear_utils-0.9.2}/tests/test_add_ord_suffix.py +0 -0
  124. {bear_utils-0.9.0 → bear_utils-0.9.2}/tests/test_clipboard.py +0 -0
  125. {bear_utils-0.9.0 → bear_utils-0.9.2}/tests/test_database_manager.py +0 -0
  126. {bear_utils-0.9.0 → bear_utils-0.9.2}/tests/test_default_shell.py +0 -0
  127. {bear_utils-0.9.0 → bear_utils-0.9.2}/tests/test_function_response.py +0 -0
  128. {bear_utils-0.9.0 → bear_utils-0.9.2}/tests/test_gradient.py +0 -0
  129. {bear_utils-0.9.0 → bear_utils-0.9.2}/tests/test_logger.py +0 -0
  130. {bear_utils-0.9.0 → bear_utils-0.9.2}/tests/test_platform_utils.py +0 -0
  131. {bear_utils-0.9.0 → bear_utils-0.9.2}/tests/test_prompt_helpers.py +0 -0
@@ -163,3 +163,7 @@ cython_debug/
163
163
  #.idea/
164
164
 
165
165
  **/.vscode
166
+
167
+ src/bear_utils/_internal/_version.pyi
168
+ src/bear_utils/_internal/_version.py
169
+ uv.lock
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bear-utils
3
- Version: 0.9.0
3
+ Version: 0.9.2
4
4
  Summary: Various utilities for Bear programmers, including a rich logging utility, a disk cache, and a SQLite database wrapper amongst other things.
5
5
  Author-email: chaz <bright.lid5647@fastmail.com>
6
6
  Requires-Python: >=3.12
@@ -25,7 +25,7 @@ Provides-Extra: gui
25
25
  Requires-Dist: pyqt6>=6.9.0; extra == 'gui'
26
26
  Description-Content-Type: text/markdown
27
27
 
28
- # Bear Utils v# Bear Utils v0.9.0
28
+ # Bear Utils
29
29
 
30
30
  Personal set of tools and utilities for Python projects, focusing on modularity and ease of use. This library includes components for caching, database management, logging, time handling, file operations, CLI prompts, image processing, clipboard interaction, gradient utilities, event systems, and async helpers.
31
31
 
@@ -1,4 +1,4 @@
1
- # Bear Utils v# Bear Utils v0.9.0
1
+ # Bear Utils
2
2
 
3
3
  Personal set of tools and utilities for Python projects, focusing on modularity and ease of use. This library includes components for caching, database management, logging, time handling, file operations, CLI prompts, image processing, clipboard interaction, gradient utilities, event systems, and async helpers.
4
4
 
@@ -13,7 +13,26 @@ rm -rf dist/
13
13
  > Bump the version of the local project specifying the patch level: `minor`, `major`, `patch`
14
14
 
15
15
  ```bash
16
- bump2version ${patch_version} --allow-dirty
16
+ uv sync
17
+ current_version=$(uv run get-version bear-utils)
18
+ echo "Current version: ${current_version}"
19
+ if [ -z "${patch_version}" ]; then
20
+ echo "Please specify a patch version: minor, major, or patch"
21
+ exit 1
22
+ fi
23
+ if [ "${patch_version}" != "minor" ] && [ "${patch_version}" != "major" ] && [ "${patch_version}" != "patch" ]; then
24
+ echo "Invalid patch version specified. Use minor, major, or patch."
25
+ exit 1
26
+ fi
27
+ # Ensure the current version is set
28
+ if [ -z "${current_version}" ]; then
29
+ echo "Current version is not set. Please run 'uv run get-version' first."
30
+ exit 1
31
+ fi
32
+ new_version=$(uv run bump ${patch_version})
33
+ echo "New version: ${new_version}"
34
+ git tag -a "v${new_version}" -m "Bump version to v${new_version}"
35
+ git push origin "v${new_version}"
17
36
  ```
18
37
 
19
38
  ## build
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "bear-utils"
3
- version = "0.9.0"
3
+ dynamic = ["version"]
4
4
  description = "Various utilities for Bear programmers, including a rich logging utility, a disk cache, and a SQLite database wrapper amongst other things."
5
5
  authors = [{ name = "chaz", email = "bright.lid5647@fastmail.com" }]
6
6
  readme = "README.md"
@@ -30,8 +30,12 @@ gui = [
30
30
  "pyqt6>=6.9.0",
31
31
  ]
32
32
 
33
+ [project.scripts]
34
+ get-version = "bear_utils._internal.cli:get_version"
35
+ bump = "bear_utils._internal.cli:bump_version"
36
+
33
37
  [build-system]
34
- requires = ["hatchling"]
38
+ requires = ["hatchling", "uv-dynamic-versioning"]
35
39
  build-backend = "hatchling.build"
36
40
 
37
41
  [dependency-groups]
@@ -85,3 +89,17 @@ pythonVersion = "3.13"
85
89
  typeCheckingMode = "standard"
86
90
  reportMissingImports = true
87
91
  reportMissingTypeStubs = false
92
+
93
+ [tool.hatch.version]
94
+ source = "uv-dynamic-versioning"
95
+
96
+ [tool.uv-dynamic-versioning]
97
+ vcs = "git"
98
+ style = "semver"
99
+ metadata = false
100
+
101
+ [tool.hatch.build.hooks.version]
102
+ path = "src/bear_utils/_internal/_version.py"
103
+ template = '''
104
+ version = "{version}"
105
+ '''
@@ -0,0 +1 @@
1
+ version = "0.9.2"
@@ -15,6 +15,9 @@ import sys
15
15
  from typing import Any
16
16
 
17
17
  from bear_utils._internal import debug
18
+ from bear_utils._internal._version import version as _version
19
+ from bear_utils.cli._get_version import VALID_BUMP_TYPES, cli_bump
20
+ from bear_utils.constants import ExitCode
18
21
 
19
22
 
20
23
  class _DebugInfo(Action):
@@ -23,7 +26,7 @@ class _DebugInfo(Action):
23
26
 
24
27
  def __call__(self, *_: Any, **__: Any) -> None:
25
28
  debug._print_debug_info()
26
- sys.exit(0)
29
+ sys.exit(ExitCode.SUCCESS)
27
30
 
28
31
 
29
32
  class _About(Action):
@@ -32,14 +35,43 @@ class _About(Action):
32
35
 
33
36
  def __call__(self, *_: Any, **__: Any) -> None:
34
37
  print(debug._get_package_info())
35
- sys.exit(0)
38
+ sys.exit(ExitCode.SUCCESS)
39
+
40
+
41
+ class _Version(Action):
42
+ def __init__(self, nargs: int | str | None = 0, **kwargs: Any) -> None:
43
+ super().__init__(nargs=nargs, **kwargs)
44
+
45
+ def __call__(self, *_: Any, **__: Any) -> None:
46
+ version: str = f"{debug._get_name()} v{_version}"
47
+ print(version)
48
+ sys.exit(ExitCode.SUCCESS)
49
+
50
+
51
+ def get_version() -> ExitCode:
52
+ """CLI command to get the version of the package."""
53
+ print(_version)
54
+ return ExitCode.SUCCESS
55
+
56
+
57
+ def bump_version() -> ExitCode:
58
+ """CLI command to bump the version of the package."""
59
+ parser = ArgumentParser(description="Bump the version of the package.")
60
+ parser.add_argument(
61
+ "bump_type",
62
+ type=str,
63
+ choices=VALID_BUMP_TYPES,
64
+ help=f"Type of version bump: {', '.join(VALID_BUMP_TYPES)}",
65
+ )
66
+ args: Namespace = parser.parse_args(sys.argv[1:])
67
+ bump_args = [args.bump_type, debug.__PACKAGE_NAME__, _version]
68
+ return cli_bump(bump_args)
36
69
 
37
70
 
38
71
  def get_parser() -> ArgumentParser:
39
- name: str = debug._get_name()
40
- version: str = f"{name} v{debug._get_version()}"
72
+ name = debug._get_name()
41
73
  parser = ArgumentParser(description=name.capitalize(), prog=name, exit_on_error=False)
42
- parser.add_argument("-V", "--version", action="version", version=version)
74
+ parser.add_argument("-V", "--version", action=_Version, help="Print the version of the package")
43
75
  parser.add_argument("--about", action=_About, help="Print information about the package")
44
76
  parser.add_argument("--debug_info", action=_DebugInfo, help="Print debug information")
45
77
  return parser
@@ -65,8 +97,8 @@ def main(args: list[str] | None = None) -> int:
65
97
  print(opts)
66
98
  except Exception as e:
67
99
  print(f"Error initializing CLI: {e}", file=sys.stderr)
68
- return 1
69
- return 0
100
+ return ExitCode.FAILURE
101
+ return ExitCode.SUCCESS
70
102
 
71
103
 
72
104
  if __name__ == "__main__":
@@ -7,6 +7,8 @@ import os
7
7
  import platform
8
8
  import sys
9
9
 
10
+ from bear_utils._internal._version import version as _version
11
+
10
12
  __PACKAGE_NAME__ = "bear-utils"
11
13
 
12
14
 
@@ -16,7 +18,7 @@ class _Package:
16
18
 
17
19
  name: str = __PACKAGE_NAME__
18
20
  """Package name."""
19
- version: str = "0.0.0"
21
+ version: str = _version
20
22
  """Package version."""
21
23
  description: str = "No description available."
22
24
  """Package description."""
@@ -69,7 +71,7 @@ def _get_package_info(dist: str = __PACKAGE_NAME__) -> _Package:
69
71
  try:
70
72
  return _Package(
71
73
  name=dist,
72
- version=version(dist),
74
+ version=_version or version(dist),
73
75
  description=metadata(dist)["Summary"],
74
76
  )
75
77
  except PackageNotFoundError:
@@ -0,0 +1,206 @@
1
+ from __future__ import annotations
2
+
3
+ from argparse import ArgumentParser, Namespace
4
+ from contextlib import redirect_stdout
5
+ from importlib.metadata import PackageNotFoundError, version
6
+ from io import StringIO
7
+ import sys
8
+ from typing import Literal, Self
9
+
10
+ from pydantic import BaseModel
11
+
12
+ from bear_utils.constants import ExitCode
13
+ from bear_utils.constants._meta import RichStrEnum, StrValue as Value
14
+
15
+
16
+ class VersionParts(RichStrEnum):
17
+ """Enumeration for version parts."""
18
+
19
+ MAJOR = Value("major", "Major version")
20
+ MINOR = Value("minor", "Minor version")
21
+ PATCH = Value("patch", "Patch version")
22
+
23
+ @classmethod
24
+ def choices(cls) -> list[str]:
25
+ """Return a list of valid version parts."""
26
+ return [version_part.value for version_part in cls]
27
+
28
+ @classmethod
29
+ def num(cls) -> int:
30
+ """Return the number of valid version parts."""
31
+ return len(cls.choices())
32
+
33
+
34
+ VALID_BUMP_TYPES: list[str] = VersionParts.choices()
35
+ NUM_PARTS: int = VersionParts.num()
36
+ MAJOR = VersionParts.MAJOR.str()
37
+ MINOR = VersionParts.MINOR.str()
38
+ PATCH = VersionParts.PATCH.str()
39
+
40
+
41
+ class Version(BaseModel):
42
+ """Model to represent a version string."""
43
+
44
+ major: int
45
+ """Major version number."""
46
+ minor: int
47
+ """Minor version number."""
48
+ patch: int
49
+ """Patch version number."""
50
+
51
+ @classmethod
52
+ def from_string(cls, version_str: str) -> Self:
53
+ """Create a Version instance from a version string.
54
+
55
+ Args:
56
+ version_str: A version string in the format "major.minor.patch".
57
+
58
+ Returns:
59
+ A Version instance.
60
+
61
+ Raises:
62
+ ValueError: If the version string is not in the correct format.
63
+ """
64
+ parts = version_str.split(".")
65
+ if len(parts) != VersionParts.num() or not all(part.isdigit() for part in parts):
66
+ raise ValueError(f"Invalid version format: {version_str}")
67
+ return cls(major=int(parts[0]), minor=int(parts[1]), patch=int(parts[2]))
68
+
69
+ @property
70
+ def version_string(self) -> str:
71
+ """Return the version as a string in the format "major.minor.patch".
72
+
73
+ Returns:
74
+ A string representation of the version.
75
+ """
76
+ return f"{self.major}.{self.minor}.{self.patch}"
77
+
78
+ def new_version(self, bump_type: Literal["major", "minor", "patch"]) -> Version:
79
+ """Return a new version string based on the bump type.
80
+
81
+ Args:
82
+ bump_type: The type of bump ("major", "minor", or "patch").
83
+
84
+ Returns:
85
+ A new version string.
86
+
87
+ Raises:
88
+ ValueError: If the bump_type is unsupported.
89
+ """
90
+ match bump_type:
91
+ case VersionParts.MAJOR:
92
+ self.major += 1
93
+ self.minor = 0
94
+ self.patch = 0
95
+ case VersionParts.MINOR:
96
+ self.minor += 1
97
+ self.patch = 0
98
+ case VersionParts.PATCH:
99
+ self.patch += 1
100
+ case _:
101
+ raise ValueError(f"Unsupported bump type: {bump_type}")
102
+ return self
103
+
104
+ @classmethod
105
+ def from_func(cls, package_name: str) -> Self:
106
+ """Create a Version instance from the current package version.
107
+
108
+ Returns:
109
+ A Version instance with the current package version.
110
+
111
+ Raises:
112
+ PackageNotFoundError: If the package is not found.
113
+ """
114
+ try:
115
+ current_version = version(package_name)
116
+ return cls.from_string(current_version)
117
+ except PackageNotFoundError as e:
118
+ raise PackageNotFoundError(f"Package '{package_name}' not found: {e}") from e
119
+
120
+
121
+ def _bump_version(version: str, bump_type: Literal["major", "minor", "patch"]) -> Version:
122
+ """Bump the version based on the specified type.
123
+
124
+ Args:
125
+ version: The current version string (e.g., "1.2.3").
126
+ bump_type: The type of bump ("major", "minor", or "patch").
127
+
128
+ Returns:
129
+ The new version string.
130
+
131
+ Raises:
132
+ ValueError: If the version format is invalid or bump_type is unsupported.
133
+ """
134
+ ver: Version = Version.from_string(version)
135
+ return ver.new_version(bump_type)
136
+
137
+
138
+ def cli_get_version(args: list[str] | None = None) -> ExitCode:
139
+ """Get the version of the current package.
140
+
141
+ Returns:
142
+ The version of the package.
143
+ """
144
+ if args is None:
145
+ args = sys.argv[1:]
146
+ parser = ArgumentParser(description="Get the version of the package.")
147
+ parser.add_argument("package_name", nargs="?", type=str, help="Name of the package to get the version for.")
148
+ arguments: Namespace = parser.parse_args(args)
149
+ if not arguments.package_name:
150
+ print("No package name provided. Please specify a package name.")
151
+ return ExitCode.FAILURE
152
+ package_name: str = arguments.package_name
153
+ try:
154
+ current_version = version(package_name)
155
+ print(current_version)
156
+ except PackageNotFoundError:
157
+ print(f"Package '{package_name}' not found.")
158
+ return ExitCode.FAILURE
159
+ return ExitCode.SUCCESS
160
+
161
+
162
+ def _get_version(package_name: str) -> str:
163
+ """Get the version of the specified package.
164
+
165
+ Args:
166
+ package_name: The name of the package to get the version for.
167
+
168
+ Returns:
169
+ A Version instance representing the current version of the package.
170
+
171
+ Raises:
172
+ PackageNotFoundError: If the package is not found.
173
+ """
174
+ record = StringIO()
175
+ with redirect_stdout(record):
176
+ cli_get_version([package_name])
177
+ return record.getvalue().strip()
178
+
179
+
180
+ def cli_bump(args: list[str] | None = None) -> ExitCode:
181
+ if args is None:
182
+ args = sys.argv[1:]
183
+ parser = ArgumentParser(description="Bump the version of the package.")
184
+ parser.add_argument("bump_type", type=str, choices=VALID_BUMP_TYPES, default="patch")
185
+ parser.add_argument("package_name", nargs="?", type=str, help="Name of the package to bump the version for.")
186
+ parser.add_argument("current_version", type=str, help="Current version of the package.")
187
+ arguments: Namespace = parser.parse_args(args)
188
+ bump_type: Literal["major", "minor", "patch"] = arguments.bump_type
189
+ if not arguments.package_name:
190
+ print("No package name provided.")
191
+ return ExitCode.FAILURE
192
+ package_name: str = arguments.package_name
193
+ if bump_type not in VALID_BUMP_TYPES:
194
+ print(f"Invalid argument '{bump_type}'. Use one of: {', '.join(VALID_BUMP_TYPES)}.")
195
+ return ExitCode.FAILURE
196
+ current_version: str = arguments.current_version or _get_version(package_name)
197
+ try:
198
+ new_version: Version = _bump_version(version=current_version, bump_type=bump_type)
199
+ print(new_version.version_string)
200
+ return ExitCode.SUCCESS
201
+ except ValueError as e:
202
+ print(f"Error: {e}")
203
+ return ExitCode.FAILURE
204
+ except Exception as e:
205
+ print(f"Unexpected error: {e}")
206
+ return ExitCode.FAILURE
@@ -9,6 +9,7 @@ from bear_utils.constants._exit_code import (
9
9
  COMMAND_NOT_FOUND,
10
10
  EXIT_STATUS_OUT_OF_RANGE,
11
11
  FAIL,
12
+ FAILURE,
12
13
  INVALID_ARGUMENT_TO_EXIT,
13
14
  MISUSE_OF_SHELL_COMMAND,
14
15
  PROCESS_KILLED_BY_SIGKILL,
@@ -28,7 +29,7 @@ from bear_utils.constants._http_status_code import (
28
29
  UNAUTHORIZED,
29
30
  HTTPStatusCode,
30
31
  )
31
- from bear_utils.constants._meta import NullFile, RichIntEnum, Value
32
+ from bear_utils.constants._meta import IntValue, NullFile, RichIntEnum, RichStrEnum, StrValue
32
33
 
33
34
  VIDEO_EXTS = [".mp4", ".mov", ".avi", ".mkv"]
34
35
  """Extensions for video files."""
@@ -58,6 +59,7 @@ __all__ = [
58
59
  "CONFLICT",
59
60
  "EXIT_STATUS_OUT_OF_RANGE",
60
61
  "FAIL",
62
+ "FAILURE",
61
63
  "FILE_EXTS",
62
64
  "FORBIDDEN",
63
65
  "GLOBAL_VENV",
@@ -80,7 +82,9 @@ __all__ = [
80
82
  "VIDEO_EXTS",
81
83
  "ExitCode",
82
84
  "HTTPStatusCode",
85
+ "IntValue",
83
86
  "NullFile",
84
87
  "RichIntEnum",
85
- "Value",
88
+ "RichStrEnum",
89
+ "StrValue",
86
90
  ]
@@ -1,4 +1,4 @@
1
- from bear_utils.constants._meta import RichIntEnum, Value
1
+ from bear_utils.constants._meta import RichIntEnum, IntValue as Value
2
2
 
3
3
 
4
4
  class ExitCode(RichIntEnum):
@@ -1,6 +1,6 @@
1
1
  """HTTP status codes."""
2
2
 
3
- from bear_utils.constants._meta import RichIntEnum, Value
3
+ from bear_utils.constants._meta import IntValue as Value, RichIntEnum
4
4
 
5
5
 
6
6
  class HTTPStatusCode(RichIntEnum):
@@ -1,22 +1,51 @@
1
1
  from dataclasses import dataclass
2
- from enum import IntEnum
2
+ from enum import IntEnum, StrEnum
3
3
  from typing import Any, Self, TextIO
4
4
 
5
5
 
6
6
  @dataclass(frozen=True)
7
- class Value:
8
- """A frozen dataclass for holding constant values."""
7
+ class IntValue:
8
+ """A frozen dataclass for holding constant integer values."""
9
9
 
10
10
  value: int
11
11
  text: str
12
12
 
13
13
 
14
+ @dataclass(frozen=True)
15
+ class StrValue:
16
+ """A frozen dataclass for holding constant string values."""
17
+
18
+ value: str
19
+ text: str
20
+
21
+
22
+ class RichStrEnum(StrEnum):
23
+ """Base class for StrEnums with rich metadata."""
24
+
25
+ text: str
26
+
27
+ def __new__(cls, value: StrValue) -> Self:
28
+ _value: str = value.value
29
+ text: str = value.text
30
+ obj: Self = str.__new__(cls, _value)
31
+ obj._value_ = _value
32
+ obj.text = text
33
+ return obj
34
+
35
+ def __str__(self) -> str:
36
+ return f"{self.name} ({self.value}): {self.text}"
37
+
38
+ def str(self) -> str:
39
+ """Return the string value of the enum."""
40
+ return self.value
41
+
42
+
14
43
  class RichIntEnum(IntEnum):
15
44
  """Base class for IntEnums with rich metadata."""
16
45
 
17
46
  text: str
18
47
 
19
- def __new__(cls, value: Value) -> Self:
48
+ def __new__(cls, value: IntValue) -> Self:
20
49
  _value: int = value.value
21
50
  text: str = value.text
22
51
  obj: Self = int.__new__(cls, _value)
@@ -3,9 +3,7 @@
3
3
  from rich.align import Align
4
4
  from rich.console import Console
5
5
 
6
- from bear_utils.graphics.font._theme import CyberTheme as Theme
7
-
8
- from ._raw_block_letters import (
6
+ from bear_utils.graphics.font._raw_block_letters import (
9
7
  ASTERISK,
10
8
  AT,
11
9
  BACKWARD_SLASH,
@@ -58,6 +56,7 @@ from ._raw_block_letters import (
58
56
  Y,
59
57
  Z,
60
58
  )
59
+ from bear_utils.graphics.font._theme import CyberTheme as Theme
61
60
 
62
61
  BLOCK_LETTERS: dict[str, list[str]] = {
63
62
  "A": A,
@@ -121,7 +120,7 @@ def char_to_block(char: str) -> list[str]:
121
120
  return BLOCK_LETTERS.get(char.upper(), [" "] * 5)
122
121
 
123
122
 
124
- def word_to_block(word: str) -> list[str]:
123
+ def _word_to_block(word: str) -> list[str]:
125
124
  """Convert a word to its block font representation."""
126
125
  clean_text: str = "".join(char for char in word.upper() if char in BLOCK_LETTERS)
127
126
 
@@ -136,15 +135,25 @@ def word_to_block(word: str) -> list[str]:
136
135
  return rows
137
136
 
138
137
 
138
+ def word_to_block(word: str) -> str:
139
+ """Convert a word to its block font representation as a single string."""
140
+ block_rows = _word_to_block(word)
141
+ return "\n".join(block_rows)
142
+
143
+
139
144
  def print_block_font(text: str, color: str = Theme.neon_green) -> None:
140
145
  """Print block font text with cyberpunk styling."""
141
- block_rows = word_to_block(text)
146
+ block_rows = _word_to_block(text)
142
147
 
143
- console.print()
144
148
  for row in block_rows:
145
149
  console.print(Align.center(f"[{color}]{row}[/{color}]"))
146
- console.print()
147
150
 
148
151
 
149
152
  __all__ = ["BLOCK_LETTERS", "char_to_block", "word_to_block"]
150
153
  # fmt: on
154
+
155
+ if __name__ == "__main__":
156
+ WORD = "BANKER"
157
+ BANKER = word_to_block(WORD)
158
+
159
+ console.print(Align.center(f"[{Theme.error}]{BANKER}[/{Theme.error}]"))
@@ -1,6 +1,6 @@
1
1
  from typing import Literal
2
2
 
3
- from bear_utils.constants._meta import RichIntEnum, Value
3
+ from bear_utils.constants._meta import IntValue as Value, RichIntEnum
4
4
 
5
5
  FAILURE: Literal[45] = 45
6
6
  ERROR: Literal[40] = 40
@@ -13,6 +13,19 @@ VERBOSE: Literal[5] = 5
13
13
  NOTSET: Literal[0] = 0
14
14
 
15
15
 
16
+ class LogLevel(RichIntEnum):
17
+ """Enumeration for logging levels."""
18
+
19
+ NOTSET = Value(NOTSET, "NOTSET")
20
+ VERBOSE = Value(VERBOSE, "VERBOSE")
21
+ DEBUG = Value(DEBUG, "DEBUG")
22
+ INFO = Value(INFO, "INFO")
23
+ WARNING = Value(WARNING, "WARNING")
24
+ ERROR = Value(ERROR, "ERROR")
25
+ FAILURE = Value(FAILURE, "FAILURE")
26
+ SUCCESS = Value(SUCCESS, "SUCCESS")
27
+
28
+
16
29
  level_to_name = {
17
30
  FAILURE: "FAILURE",
18
31
  ERROR: "ERROR",
@@ -35,16 +48,3 @@ name_to_level = {
35
48
  "VERBOSE": VERBOSE,
36
49
  "NOTSET": NOTSET,
37
50
  }
38
-
39
-
40
- class LogLevel(RichIntEnum):
41
- """Enumeration for logging levels."""
42
-
43
- NOTSET = Value(NOTSET, "NOTSET")
44
- VERBOSE = Value(VERBOSE, "VERBOSE")
45
- DEBUG = Value(DEBUG, "DEBUG")
46
- INFO = Value(INFO, "INFO")
47
- WARNING = Value(WARNING, "WARNING")
48
- ERROR = Value(ERROR, "ERROR")
49
- FAILURE = Value(FAILURE, "FAILURE")
50
- SUCCESS = Value(SUCCESS, "SUCCESS")
@@ -1,8 +0,0 @@
1
- [bumpversion]
2
- current_version = 0.9.0
3
-
4
- [bumpversion:file:pyproject.toml]
5
-
6
- [bumpversion:file:README.md]
7
- search = # Bear Utils v{current_version}
8
- replace = # Bear Utils v{new_version}
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes