bear-utils 0.9.0__tar.gz → 0.9.3__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 (137) hide show
  1. {bear_utils-0.9.0 → bear_utils-0.9.3}/.gitignore +6 -0
  2. {bear_utils-0.9.0 → bear_utils-0.9.3}/PKG-INFO +3 -2
  3. {bear_utils-0.9.0 → bear_utils-0.9.3}/README.md +1 -1
  4. {bear_utils-0.9.0 → bear_utils-0.9.3}/config/ruff.toml +1 -0
  5. bear_utils-0.9.3/maskfile.md +84 -0
  6. {bear_utils-0.9.0 → bear_utils-0.9.3}/pyproject.toml +24 -4
  7. bear_utils-0.9.3/src/bear_utils/_internal/_version.py +1 -0
  8. bear_utils-0.9.3/src/bear_utils/_internal/cli.py +119 -0
  9. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/_internal/debug.py +19 -4
  10. bear_utils-0.9.3/src/bear_utils/cli/_get_version.py +207 -0
  11. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/constants/__init__.py +6 -2
  12. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/constants/_exit_code.py +1 -1
  13. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/constants/_http_status_code.py +1 -1
  14. bear_utils-0.9.3/src/bear_utils/constants/_meta.py +198 -0
  15. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/extras/__init__.py +6 -0
  16. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/extras/_tools.py +11 -119
  17. bear_utils-0.9.3/src/bear_utils/extras/_zapper.py +399 -0
  18. bear_utils-0.9.3/src/bear_utils/graphics/font/_utils.py +188 -0
  19. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/graphics/font/block_font.py +68 -7
  20. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/logger_manager/_log_level.py +14 -14
  21. bear_utils-0.9.3/tests/test_font_utils.py +209 -0
  22. bear_utils-0.9.0/.bumpversion.cfg +0 -8
  23. bear_utils-0.9.0/config/vscode/launch.json +0 -46
  24. bear_utils-0.9.0/config/vscode/settings.json +0 -25
  25. bear_utils-0.9.0/config/vscode/tasks.json +0 -76
  26. bear_utils-0.9.0/maskfile.md +0 -57
  27. bear_utils-0.9.0/src/bear_utils/_internal/cli.py +0 -73
  28. bear_utils-0.9.0/src/bear_utils/constants/_meta.py +0 -107
  29. {bear_utils-0.9.0 → bear_utils-0.9.3}/.python-version +0 -0
  30. {bear_utils-0.9.0 → bear_utils-0.9.3}/AGENTS.md +0 -0
  31. {bear_utils-0.9.0 → bear_utils-0.9.3}/config/coverage.ini +0 -0
  32. {bear_utils-0.9.0 → bear_utils-0.9.3}/config/default.toml +0 -0
  33. {bear_utils-0.9.0 → bear_utils-0.9.3}/config/git-changelog.toml +0 -0
  34. {bear_utils-0.9.0 → bear_utils-0.9.3}/config/pytest.ini +0 -0
  35. {bear_utils-0.9.0 → bear_utils-0.9.3}/directory_structure.txt +0 -0
  36. {bear_utils-0.9.0 → bear_utils-0.9.3}/directory_structure.xml +0 -0
  37. {bear_utils-0.9.0 → bear_utils-0.9.3}/noxfile.py +0 -0
  38. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/__init__.py +0 -0
  39. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/__main__.py +0 -0
  40. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/_internal/__init__.py +0 -0
  41. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/ai/__init__.py +0 -0
  42. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/ai/ai_helpers/__init__.py +0 -0
  43. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/ai/ai_helpers/_common.py +0 -0
  44. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/ai/ai_helpers/_config.py +0 -0
  45. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/ai/ai_helpers/_parsers.py +0 -0
  46. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/ai/ai_helpers/_types.py +0 -0
  47. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/cache/__init__.py +0 -0
  48. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/cli/__init__.py +0 -0
  49. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/cli/_args.py +0 -0
  50. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/cli/commands.py +0 -0
  51. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/cli/prompt_helpers.py +0 -0
  52. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/cli/shell/__init__.py +0 -0
  53. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/cli/shell/_base_command.py +0 -0
  54. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/cli/shell/_base_shell.py +0 -0
  55. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/cli/shell/_common.py +0 -0
  56. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/cli/typer_bridge.py +0 -0
  57. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/config/__init__.py +0 -0
  58. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/config/config_manager.py +0 -0
  59. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/config/dir_manager.py +0 -0
  60. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/config/settings_manager.py +0 -0
  61. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/constants/_exceptions.py +0 -0
  62. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/constants/_lazy_typing.py +0 -0
  63. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/constants/date_related.py +0 -0
  64. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/constants/time_related.py +0 -0
  65. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/database/__init__.py +0 -0
  66. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/database/_db_manager.py +0 -0
  67. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/events/__init__.py +0 -0
  68. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/events/events_class.py +0 -0
  69. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/events/events_module.py +0 -0
  70. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/extras/_async_helpers.py +0 -0
  71. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/extras/platform_utils.py +0 -0
  72. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/extras/responses/__init__.py +0 -0
  73. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/extras/responses/function_response.py +0 -0
  74. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/extras/wrappers/__init__.py +0 -0
  75. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/extras/wrappers/add_methods.py +0 -0
  76. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/extras/wrappers/string_io.py +0 -0
  77. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/files/__init__.py +0 -0
  78. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/files/file_handlers/__init__.py +0 -0
  79. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/files/file_handlers/_base_file_handler.py +0 -0
  80. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/files/file_handlers/file_handler_factory.py +0 -0
  81. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/files/file_handlers/json_file_handler.py +0 -0
  82. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/files/file_handlers/log_file_handler.py +0 -0
  83. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/files/file_handlers/toml_file_handler.py +0 -0
  84. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/files/file_handlers/txt_file_handler.py +0 -0
  85. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/files/file_handlers/yaml_file_handler.py +0 -0
  86. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/files/ignore_parser.py +0 -0
  87. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/graphics/__init__.py +0 -0
  88. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/graphics/bear_gradient.py +0 -0
  89. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/graphics/font/__init__.py +0 -0
  90. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/graphics/font/_raw_block_letters.py +0 -0
  91. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/graphics/font/_theme.py +0 -0
  92. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/graphics/font/glitch_font.py +0 -0
  93. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/graphics/image_helpers.py +0 -0
  94. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/gui/__init__.py +0 -0
  95. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/gui/gui_tools/__init__.py +0 -0
  96. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/gui/gui_tools/_settings.py +0 -0
  97. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/gui/gui_tools/_types.py +0 -0
  98. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/gui/gui_tools/qt_app.py +0 -0
  99. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/gui/gui_tools/qt_color_picker.py +0 -0
  100. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/gui/gui_tools/qt_file_handler.py +0 -0
  101. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/gui/gui_tools/qt_input_dialog.py +0 -0
  102. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/logger_manager/__init__.py +0 -0
  103. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/logger_manager/_common.py +0 -0
  104. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/logger_manager/_console_junk.py +0 -0
  105. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/logger_manager/_styles.py +0 -0
  106. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/logger_manager/logger_protocol.py +0 -0
  107. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/logger_manager/loggers/__init__.py +0 -0
  108. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/logger_manager/loggers/_console.py +0 -0
  109. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/logger_manager/loggers/_level_sin.py +0 -0
  110. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/logger_manager/loggers/_logger.py +0 -0
  111. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/logger_manager/loggers/base_logger.py +0 -0
  112. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/logger_manager/loggers/base_logger.pyi +0 -0
  113. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/logger_manager/loggers/basic_logger/__init__.py +0 -0
  114. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/logger_manager/loggers/basic_logger/logger.py +0 -0
  115. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/logger_manager/loggers/basic_logger/logger.pyi +0 -0
  116. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/logger_manager/loggers/buffer_logger.py +0 -0
  117. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/logger_manager/loggers/console_logger.py +0 -0
  118. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/logger_manager/loggers/console_logger.pyi +0 -0
  119. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/logger_manager/loggers/fastapi_logger.py +0 -0
  120. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/logger_manager/loggers/file_logger.py +0 -0
  121. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/logger_manager/loggers/simple_logger.py +0 -0
  122. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/logger_manager/loggers/sub_logger.py +0 -0
  123. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/logger_manager/loggers/sub_logger.pyi +0 -0
  124. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/monitoring/__init__.py +0 -0
  125. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/monitoring/_common.py +0 -0
  126. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/monitoring/host_monitor.py +0 -0
  127. {bear_utils-0.9.0 → bear_utils-0.9.3}/src/bear_utils/time/__init__.py +0 -0
  128. {bear_utils-0.9.0 → bear_utils-0.9.3}/tests/__init__.py +0 -0
  129. {bear_utils-0.9.0 → bear_utils-0.9.3}/tests/test_add_ord_suffix.py +0 -0
  130. {bear_utils-0.9.0 → bear_utils-0.9.3}/tests/test_clipboard.py +0 -0
  131. {bear_utils-0.9.0 → bear_utils-0.9.3}/tests/test_database_manager.py +0 -0
  132. {bear_utils-0.9.0 → bear_utils-0.9.3}/tests/test_default_shell.py +0 -0
  133. {bear_utils-0.9.0 → bear_utils-0.9.3}/tests/test_function_response.py +0 -0
  134. {bear_utils-0.9.0 → bear_utils-0.9.3}/tests/test_gradient.py +0 -0
  135. {bear_utils-0.9.0 → bear_utils-0.9.3}/tests/test_logger.py +0 -0
  136. {bear_utils-0.9.0 → bear_utils-0.9.3}/tests/test_platform_utils.py +0 -0
  137. {bear_utils-0.9.0 → bear_utils-0.9.3}/tests/test_prompt_helpers.py +0 -0
@@ -163,3 +163,9 @@ cython_debug/
163
163
  #.idea/
164
164
 
165
165
  **/.vscode
166
+
167
+ *.db
168
+ *.log
169
+ src/bear_utils/_internal/_version.pyi
170
+ src/bear_utils/_internal/_version.py
171
+ 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.3
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
@@ -12,6 +12,7 @@ Requires-Dist: pathspec>=0.12.1
12
12
  Requires-Dist: pillow<12.0.0,>=11.2.1
13
13
  Requires-Dist: prompt-toolkit<4.0.0,>=3.0.51
14
14
  Requires-Dist: pydantic>=2.11.5
15
+ Requires-Dist: pyfiglet>=1.0.3
15
16
  Requires-Dist: pyglm<3.0.0,>=2.8.2
16
17
  Requires-Dist: pyyaml>=6.0.2
17
18
  Requires-Dist: rich<15.0.0,>=14.0.0
@@ -25,7 +26,7 @@ Provides-Extra: gui
25
26
  Requires-Dist: pyqt6>=6.9.0; extra == 'gui'
26
27
  Description-Content-Type: text/markdown
27
28
 
28
- # Bear Utils v# Bear Utils v0.9.0
29
+ # Bear Utils
29
30
 
30
31
  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
32
 
@@ -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
 
@@ -109,3 +109,4 @@ exclude = [
109
109
  ]
110
110
  docstring-code-format = true
111
111
  docstring-code-line-length = 80
112
+ skip-magic-trailing-comma = false
@@ -0,0 +1,84 @@
1
+ # Singleton Mask File
2
+
3
+ ## clean
4
+
5
+ > This command cleans the build artifacts
6
+
7
+ ```bash
8
+ rm -rf dist/
9
+ ```
10
+
11
+ ## bump (patch_version)
12
+
13
+ > Bump the version of the local project specifying the patch level: `minor`, `major`, `patch`
14
+
15
+ ```bash
16
+ uv sync
17
+ current_version=$(python3 -m bear_utils._internal.cli get-version)
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=$(python3 -m bear_utils._internal.cli bump-version "${patch_version}")
33
+ if [ $? -ne 0 ]; then
34
+ echo "Failed to bump version. Please check the current version and try again."
35
+ exit 1
36
+ fi
37
+ if [ -z "${new_version}" ]; then
38
+ echo "Failed to bump version. Please check the current version and try again."
39
+ exit 1
40
+ fi
41
+ echo "New version: ${new_version}"
42
+ git tag -a "v${new_version}" -m "Bump version to v${new_version}"
43
+ git push origin "v${new_version}"
44
+ ```
45
+
46
+ ## build
47
+
48
+ > This command builds the project via uv
49
+
50
+ ```bash
51
+ uv build
52
+ ```
53
+
54
+ ## test
55
+
56
+ > This command runs the tests using pytest
57
+
58
+ ```bash
59
+ pytest -s
60
+ ```
61
+
62
+ ## publish (publish_location)
63
+
64
+ > This command publishes the package to PyPI (or locally) officially, isn't that great?
65
+
66
+ ```bash
67
+ if [ "${publish_location}" = "twine" ]; then
68
+ twine upload -r local dist/* # uploads to a local repository
69
+ else
70
+ export UV_PUBLISH_TOKEN=$(op read "op://Private/PyPI Prod/api_key")
71
+ uv publish --index pypi dist/* --token $UV_PUBLISH_TOKEN
72
+ fi
73
+ ```
74
+
75
+ ## full (patch_version) (publish_location)
76
+
77
+ > This command runs the full build and publish process
78
+
79
+ ```bash
80
+ $MASK clean
81
+ $MASK bump ${patch_version}
82
+ $MASK build
83
+ $MASK publish ${publish_location}
84
+ ```
@@ -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"
@@ -23,6 +23,7 @@ dependencies = [
23
23
  "uvicorn>=0.35.0",
24
24
  "bear-epoch-time>=1.1.4",
25
25
  "typer>=0.16.0",
26
+ "pyfiglet>=1.0.3",
26
27
  ]
27
28
 
28
29
  [project.optional-dependencies]
@@ -30,8 +31,12 @@ gui = [
30
31
  "pyqt6>=6.9.0",
31
32
  ]
32
33
 
34
+ # [project.scripts]
35
+ # get-version = "bear_utils._internal.cli:get_version"
36
+ # bump = "bear_utils._internal.cli:bump_version"
37
+
33
38
  [build-system]
34
- requires = ["hatchling"]
39
+ requires = ["hatchling", "uv-dynamic-versioning"]
35
40
  build-backend = "hatchling.build"
36
41
 
37
42
  [dependency-groups]
@@ -51,7 +56,6 @@ ci = [
51
56
  "types-markdown>=3.6",
52
57
  "types-pyyaml>=6.0",
53
58
  "nox>=2025.5.1",
54
- "bump2version>=1.0.1",
55
59
  "twine>=6.1.0",
56
60
  ]
57
61
  gui = [
@@ -77,7 +81,8 @@ filterwarnings = [
77
81
  ]
78
82
 
79
83
  [tool.pyright]
80
- include = ["src"]
84
+ include = ["src", "tests"]
85
+ testpaths = ["tests"]
81
86
  exclude = ["**/__pycache__"]
82
87
  venvPath = "."
83
88
  venv = ".venv"
@@ -85,3 +90,18 @@ pythonVersion = "3.13"
85
90
  typeCheckingMode = "standard"
86
91
  reportMissingImports = true
87
92
  reportMissingTypeStubs = false
93
+
94
+ [tool.hatch.version]
95
+ source = "uv-dynamic-versioning"
96
+
97
+ [tool.uv-dynamic-versioning]
98
+ vcs = "git"
99
+ style = "semver"
100
+ metadata = false
101
+ format = "{base}"
102
+
103
+ [tool.hatch.build.hooks.version]
104
+ path = "src/bear_utils/_internal/_version.py"
105
+ template = '''
106
+ version = "{version}"
107
+ '''
@@ -0,0 +1 @@
1
+ version = "0.9.3"
@@ -0,0 +1,119 @@
1
+ # Why does this file exist, and why not put this in `__main__`?
2
+ #
3
+ # You might be tempted to import things from `__main__` later,
4
+ # but that will cause problems: the code will get executed twice:
5
+ #
6
+ # - When you run `python -m bear_utils` python will execute
7
+ # `__main__.py` as a script. That means there won't be any
8
+ # `bear_utils.__main__` in `sys.modules`.
9
+ # - When you import `__main__` it will get executed again (as a module) because
10
+ # there's no `bear_utils.__main__` in `sys.modules`.
11
+ from __future__ import annotations
12
+
13
+ from argparse import Action, ArgumentParser, Namespace
14
+ import sys
15
+ from typing import Any
16
+
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
21
+
22
+
23
+ class _DebugInfo(Action):
24
+ def __init__(self, nargs: int | str | None = 0, **kwargs: Any) -> None:
25
+ super().__init__(nargs=nargs, **kwargs)
26
+
27
+ def __call__(self, *_: Any, **__: Any) -> None:
28
+ debug._print_debug_info()
29
+ sys.exit(ExitCode.SUCCESS)
30
+
31
+
32
+ class _About(Action):
33
+ def __init__(self, nargs: int | str | None = 0, **kwargs: Any) -> None:
34
+ super().__init__(nargs=nargs, **kwargs)
35
+
36
+ def __call__(self, *_: Any, **__: Any) -> None:
37
+ print(debug._get_package_info())
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(args: list[str] | None = None) -> 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(args or sys.argv[1:])
67
+ return cli_bump([_args.bump_type, debug.__PACKAGE_NAME__, _version])
68
+
69
+
70
+ def get_parser() -> ArgumentParser:
71
+ name = debug._get_name()
72
+ parser = ArgumentParser(description=name.capitalize(), prog=name, exit_on_error=False)
73
+ parser.add_argument("-V", "--version", action=_Version, help="Print the version of the package")
74
+ subparser = parser.add_subparsers(dest="command", required=False, help="Available commands")
75
+ subparser.add_parser("get-version", help="Get the current version of the package")
76
+ bump = subparser.add_parser("bump-version", help="Bump the version of the package")
77
+ bump.add_argument("bump_type", type=str, choices=VALID_BUMP_TYPES, help="major, minor, or patch")
78
+ parser.add_argument("--about", action=_About, help="Print information about the package")
79
+ parser.add_argument("--debug_info", action=_DebugInfo, help="Print debug information")
80
+ return parser
81
+
82
+
83
+ def main(args: list[str] | None = None) -> ExitCode:
84
+ """Main entry point for the CLI.
85
+
86
+ This function is called when the CLI is executed. It can be used to
87
+ initialize the CLI, parse arguments, and execute commands.
88
+
89
+ Args:
90
+ args (list[str] | None): A list of command-line arguments. If None, uses sys.argv[1:].
91
+
92
+ Returns:
93
+ int: Exit code of the CLI execution. 0 for success, non-zero for failure.
94
+ """
95
+ if args is None:
96
+ args = sys.argv[1:]
97
+ try:
98
+ parser: ArgumentParser = get_parser()
99
+ opts: Namespace = parser.parse_args(args)
100
+ command = opts.command
101
+ if command is None:
102
+ parser.print_help()
103
+ return ExitCode.SUCCESS
104
+ if command == "get-version":
105
+ return get_version()
106
+ if command == "bump-version":
107
+ if not hasattr(opts, "bump_type"):
108
+ print("Error: 'bump-version' command requires a 'bump_type' argument.", file=sys.stderr)
109
+ return ExitCode.FAILURE
110
+ bump_type = opts.bump_type
111
+ return bump_version([bump_type])
112
+ except Exception as e:
113
+ print(f"Error initializing CLI: {e}", file=sys.stderr)
114
+ return ExitCode.FAILURE
115
+ return ExitCode.SUCCESS
116
+
117
+
118
+ if __name__ == "__main__":
119
+ main()
@@ -1,12 +1,15 @@
1
1
  from __future__ import annotations
2
2
 
3
- from dataclasses import dataclass
3
+ from dataclasses import dataclass, field
4
4
  import importlib.metadata
5
5
  from importlib.metadata import PackageNotFoundError, metadata, version
6
6
  import os
7
7
  import platform
8
8
  import sys
9
9
 
10
+ from bear_utils._internal._version import version as _version
11
+ from bear_utils.cli._get_version import Version
12
+
10
13
  __PACKAGE_NAME__ = "bear-utils"
11
14
 
12
15
 
@@ -16,11 +19,22 @@ class _Package:
16
19
 
17
20
  name: str = __PACKAGE_NAME__
18
21
  """Package name."""
19
- version: str = "0.0.0"
22
+ version: str = _version
20
23
  """Package version."""
24
+ _version: Version = field(default_factory=lambda: Version.from_string(_version))
21
25
  description: str = "No description available."
22
26
  """Package description."""
23
27
 
28
+ def __post_init__(self) -> None:
29
+ """Post-initialization to ensure version is a string."""
30
+ if not isinstance(self.version, str) or "0.0.0" in self.version:
31
+ self.version = version(self.name) if self.name else "0.0.0"
32
+ if not self.description:
33
+ try:
34
+ self.description = metadata(self.name)["Summary"]
35
+ except PackageNotFoundError:
36
+ self.description = "No description available."
37
+
24
38
  def __str__(self) -> str:
25
39
  """String representation of the package information."""
26
40
  return f"{self.name} v{self.version}: {self.description}"
@@ -69,7 +83,7 @@ def _get_package_info(dist: str = __PACKAGE_NAME__) -> _Package:
69
83
  try:
70
84
  return _Package(
71
85
  name=dist,
72
- version=version(dist),
86
+ version=_version or version(dist),
73
87
  description=metadata(dist)["Summary"],
74
88
  )
75
89
  except PackageNotFoundError:
@@ -156,4 +170,5 @@ def _print_debug_info() -> None:
156
170
 
157
171
 
158
172
  if __name__ == "__main__":
159
- _print_debug_info()
173
+ # _print_debug_info()
174
+ print(_get_package_info())
@@ -0,0 +1,207 @@
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 IntValue as Value, RichIntEnum
14
+ from bear_utils.extras import zap_as
15
+
16
+
17
+ class VerParts(RichIntEnum):
18
+ """Enumeration for version parts."""
19
+
20
+ MAJOR = Value(0, "major")
21
+ MINOR = Value(1, "minor")
22
+ PATCH = Value(2, "patch")
23
+
24
+ @classmethod
25
+ def choices(cls) -> list[str]:
26
+ """Return a list of valid version parts."""
27
+ return [version_part.text for version_part in cls]
28
+
29
+ @classmethod
30
+ def parts(cls) -> int:
31
+ """Return the total number of version parts."""
32
+ return len(cls.choices())
33
+
34
+
35
+ VALID_BUMP_TYPES: list[str] = VerParts.choices()
36
+ ALL_PARTS: int = VerParts.parts()
37
+
38
+
39
+ class Version(BaseModel):
40
+ """Model to represent a version string."""
41
+
42
+ major: int = 0
43
+ """Major version number."""
44
+ minor: int = 0
45
+ """Minor version number."""
46
+ patch: int = 0
47
+ """Patch version number."""
48
+
49
+ @classmethod
50
+ def from_string(cls, version_str: str) -> Self:
51
+ """Create a Version instance from a version string.
52
+
53
+ Args:
54
+ version_str: A version string in the format "major.minor.patch".
55
+
56
+ Returns:
57
+ A Version instance.
58
+
59
+ Raises:
60
+ ValueError: If the version string is not in the correct format.
61
+ """
62
+ try:
63
+ major, minor, patch = zap_as("-+", version_str, 3, replace=".", func=int)
64
+ return cls(major=int(major), minor=int(minor), patch=int(patch))
65
+ except ValueError as e:
66
+ raise ValueError(
67
+ f"Invalid version string format: {version_str}. Expected integers for major, minor, and patch."
68
+ ) from e
69
+
70
+ def increment(self, attr_name: str) -> None:
71
+ """Increment the specified part of the version."""
72
+ setattr(self, attr_name, getattr(self, attr_name) + 1)
73
+
74
+ @property
75
+ def version_string(self) -> str:
76
+ """Return the version as a string in the format "major.minor.patch".
77
+
78
+ Returns:
79
+ A string representation of the version.
80
+ """
81
+ return f"{self.major}.{self.minor}.{self.patch}"
82
+
83
+ def default(self, part: str) -> None:
84
+ """Clear the specified part of the version.
85
+
86
+ Args:
87
+ part: The part of the version to clear.
88
+ """
89
+ if hasattr(self, part):
90
+ setattr(self, part, 0)
91
+
92
+ def new_version(self, bump_type: str) -> Version:
93
+ """Return a new version string based on the bump type."""
94
+ bump_part: VerParts = VerParts.get(bump_type, default=VerParts.PATCH)
95
+ self.increment(bump_part.text)
96
+ for part in VerParts:
97
+ if part.value > bump_part.value:
98
+ self.default(part.text)
99
+ return self
100
+
101
+ @classmethod
102
+ def from_func(cls, package_name: str) -> Self:
103
+ """Create a Version instance from the current package version.
104
+
105
+ Returns:
106
+ A Version instance with the current package version.
107
+
108
+ Raises:
109
+ PackageNotFoundError: If the package is not found.
110
+ """
111
+ try:
112
+ current_version = version(package_name)
113
+ return cls.from_string(current_version)
114
+ except PackageNotFoundError as e:
115
+ raise PackageNotFoundError(f"Package '{package_name}' not found: {e}") from e
116
+
117
+
118
+ def _bump_version(version: str, bump_type: Literal["major", "minor", "patch"]) -> Version:
119
+ """Bump the version based on the specified type.
120
+
121
+ Args:
122
+ version: The current version string (e.g., "1.2.3").
123
+ bump_type: The type of bump ("major", "minor", or "patch").
124
+
125
+ Returns:
126
+ The new version string.
127
+
128
+ Raises:
129
+ ValueError: If the version format is invalid or bump_type is unsupported.
130
+ """
131
+ ver: Version = Version.from_string(version)
132
+ return ver.new_version(bump_type)
133
+
134
+
135
+ def _get_version(package_name: str) -> str:
136
+ """Get the version of the specified package.
137
+
138
+ Args:
139
+ package_name: The name of the package to get the version for.
140
+
141
+ Returns:
142
+ A Version instance representing the current version of the package.
143
+
144
+ Raises:
145
+ PackageNotFoundError: If the package is not found.
146
+ """
147
+ record = StringIO()
148
+ with redirect_stdout(record):
149
+ cli_get_version([package_name])
150
+ return record.getvalue().strip()
151
+
152
+
153
+ def cli_get_version(args: list[str] | None = None) -> ExitCode:
154
+ """Get the version of the current package.
155
+
156
+ Returns:
157
+ The version of the package.
158
+ """
159
+ if args is None:
160
+ args = sys.argv[1:]
161
+ parser = ArgumentParser(description="Get the version of the package.")
162
+ parser.add_argument("package_name", nargs="?", type=str, help="Name of the package to get the version for.")
163
+ arguments: Namespace = parser.parse_args(args)
164
+ if not arguments.package_name:
165
+ print("No package name provided. Please specify a package name.")
166
+ return ExitCode.FAILURE
167
+ package_name: str = arguments.package_name
168
+ try:
169
+ current_version = version(package_name)
170
+ print(current_version)
171
+ except PackageNotFoundError:
172
+ print(f"Package '{package_name}' not found.")
173
+ return ExitCode.FAILURE
174
+ return ExitCode.SUCCESS
175
+
176
+
177
+ def cli_bump(args: list[str] | None = None) -> ExitCode:
178
+ if args is None:
179
+ args = sys.argv[1:]
180
+ parser = ArgumentParser(description="Bump the version of the package.")
181
+ parser.add_argument("bump_type", type=str, choices=VALID_BUMP_TYPES, default="patch")
182
+ parser.add_argument("package_name", nargs="?", type=str, help="Name of the package to bump the version for.")
183
+ parser.add_argument("current_version", type=str, help="Current version of the package.")
184
+ arguments: Namespace = parser.parse_args(args)
185
+ bump_type: Literal["major", "minor", "patch"] = arguments.bump_type
186
+ if not arguments.package_name:
187
+ print("No package name provided.")
188
+ return ExitCode.FAILURE
189
+ package_name: str = arguments.package_name
190
+ if bump_type not in VALID_BUMP_TYPES:
191
+ print(f"Invalid argument '{bump_type}'. Use one of: {', '.join(VALID_BUMP_TYPES)}.")
192
+ return ExitCode.FAILURE
193
+ current_version: str = arguments.current_version or _get_version(package_name)
194
+ try:
195
+ new_version: Version = _bump_version(version=current_version, bump_type=bump_type)
196
+ print(new_version.version_string)
197
+ return ExitCode.SUCCESS
198
+ except ValueError as e:
199
+ print(f"Error: {e}")
200
+ return ExitCode.FAILURE
201
+ except Exception as e:
202
+ print(f"Unexpected error: {e}")
203
+ return ExitCode.FAILURE
204
+
205
+
206
+ if __name__ == "__main__":
207
+ cli_bump(["patch", "bear-utils", "0.9.2-fart.build-alpha"])
@@ -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 IntValue as Value, RichIntEnum
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):