stouputils 1.1.7__tar.gz → 1.2.1__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 (28) hide show
  1. stouputils-1.2.1/PKG-INFO +70 -0
  2. stouputils-1.2.1/README.md +51 -0
  3. {stouputils-1.1.7 → stouputils-1.2.1}/pyproject.toml +2 -1
  4. stouputils-1.2.1/stouputils/__init__.py +31 -0
  5. stouputils-1.2.1/stouputils/applications/__init__.py +15 -0
  6. stouputils-1.2.1/stouputils/applications/automatic_docs.py +507 -0
  7. stouputils-1.2.1/stouputils/continuous_delivery/__init__.py +24 -0
  8. {stouputils-1.1.7 → stouputils-1.2.1}/stouputils/continuous_delivery/cd_utils.py +55 -0
  9. {stouputils-1.1.7 → stouputils-1.2.1}/stouputils/continuous_delivery/github.py +1 -54
  10. stouputils-1.1.7/PKG-INFO +0 -60
  11. stouputils-1.1.7/README.md +0 -42
  12. stouputils-1.1.7/stouputils/__init__.py +0 -15
  13. stouputils-1.1.7/stouputils/continuous_delivery/__init__.py +0 -7
  14. {stouputils-1.1.7 → stouputils-1.2.1}/.gitignore +0 -0
  15. {stouputils-1.1.7 → stouputils-1.2.1}/LICENSE +0 -0
  16. {stouputils-1.1.7 → stouputils-1.2.1}/stouputils/all_doctests.py +0 -0
  17. {stouputils-1.1.7 → stouputils-1.2.1}/stouputils/archive.py +0 -0
  18. {stouputils-1.1.7 → stouputils-1.2.1}/stouputils/backup.py +0 -0
  19. {stouputils-1.1.7 → stouputils-1.2.1}/stouputils/collections.py +0 -0
  20. {stouputils-1.1.7 → stouputils-1.2.1}/stouputils/continuous_delivery/pypi.py +0 -0
  21. {stouputils-1.1.7 → stouputils-1.2.1}/stouputils/continuous_delivery/pyproject.py +0 -0
  22. {stouputils-1.1.7 → stouputils-1.2.1}/stouputils/ctx.py +0 -0
  23. {stouputils-1.1.7 → stouputils-1.2.1}/stouputils/decorators.py +0 -0
  24. {stouputils-1.1.7 → stouputils-1.2.1}/stouputils/dont_look/zip_file_override.py +0 -0
  25. {stouputils-1.1.7 → stouputils-1.2.1}/stouputils/io.py +0 -0
  26. {stouputils-1.1.7 → stouputils-1.2.1}/stouputils/parallel.py +0 -0
  27. {stouputils-1.1.7 → stouputils-1.2.1}/stouputils/print.py +0 -0
  28. {stouputils-1.1.7 → stouputils-1.2.1}/stouputils/py.typed +0 -0
@@ -0,0 +1,70 @@
1
+ Metadata-Version: 2.4
2
+ Name: stouputils
3
+ Version: 1.2.1
4
+ Summary: Stouputils is a collection of utility modules designed to simplify and enhance the development process. It includes a range of tools for tasks such as execution of doctests, display utilities, decorators, as well as context managers, and many more.
5
+ Project-URL: Homepage, https://github.com/Stoupy51/stouputils
6
+ Project-URL: Issues, https://github.com/Stoupy51/stouputils/issues
7
+ Author-email: Stoupy51 <stoupy51@gmail.com>
8
+ License-File: LICENSE
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Operating System :: OS Independent
11
+ Classifier: Programming Language :: Python :: 3
12
+ Requires-Python: >=3.10
13
+ Requires-Dist: m2r2>=0.3.3.post2
14
+ Requires-Dist: pyyaml>=6.0.0
15
+ Requires-Dist: requests>=2.30.0
16
+ Requires-Dist: toml>=0.10.0
17
+ Requires-Dist: tqdm>=4.66.0
18
+ Description-Content-Type: text/markdown
19
+
20
+
21
+ # 🛠️ Project Badges
22
+ [![GitHub](https://img.shields.io/github/v/release/Stoupy51/stouputils?logo=github&label=GitHub)](https://github.com/Stoupy51/stouputils/releases/latest)
23
+ [![PyPI - Downloads](https://img.shields.io/pypi/dm/stouputils?logo=python&label=PyPI%20downloads)](https://pypi.org/project/stouputils/)
24
+ [![Documentation](https://img.shields.io/github/v/release/Stoupy51/stouputils?logo=sphinx&label=Documentation&color=purple)](https://stoupy51.github.io/stouputils/latest/)
25
+
26
+
27
+ # 📚 Project Overview
28
+ Stouputils is a collection of utility modules designed to simplify and enhance the development process.<br>
29
+ It includes a range of tools for tasks such as execution of doctests, display utilities, decorators, as well as context managers.
30
+
31
+
32
+ # 🚀 Project File Tree
33
+ ```bash
34
+ stouputils/
35
+ ├── applications/
36
+ │ ├── automatic_docs.py # 📚 Documentation generation utilities (used to create this documentation)
37
+ │ └── ...
38
+
39
+ ├── continuous_delivery/
40
+ │ ├── cd_utils.py # 🔧 Common utilities for continuous delivery
41
+ │ ├── github.py # 📦 GitHub utilities (upload_to_github)
42
+ │ ├── pypi.py # 📦 PyPI utilities (pypi_full_routine)
43
+ │ ├── pyproject.py # 📝 Pyproject.toml utilities
44
+ │ └── ...
45
+
46
+ ├── print.py # 🖨️ Display utilities (info, debug, warning, error)
47
+ ├── io.py # 💻 I/O utilities (file management, json)
48
+ ├── decorators.py # 🎯 Decorators (silent, measure_time, error_handler, simple_cache)
49
+ ├── ctx.py # 🚫 Context managers (Muffle, LogToFile)
50
+ ├── archive.py # 📦 Archive utilities (zip, repair_zip)
51
+ ├── parallel.py # 🧑‍🤝‍🧑 Parallel processing (multiprocessing, multithreading)
52
+ ├── collections.py # 🧰 Collection utilities (unique_list)
53
+ ├── all_doctests.py # ✅ Execution of all doctests for a given path
54
+ ├── backup.py # 📦 Backup utilities (delta backup, consolidate)
55
+ └── ...
56
+ ```
57
+
58
+
59
+ ## ⭐ Star History
60
+
61
+ <html>
62
+ <a href="https://star-history.com/#Stoupy51/stouputils&Date">
63
+ <picture>
64
+ <source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=Stoupy51/stouputils&type=Date&theme=dark" />
65
+ <source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=Stoupy51/stouputils&type=Date" />
66
+ <img alt="Star History Chart" src="https://api.star-history.com/svg?repos=Stoupy51/stouputils&type=Date" />
67
+ </picture>
68
+ </a>
69
+ </html>
70
+
@@ -0,0 +1,51 @@
1
+
2
+ # 🛠️ Project Badges
3
+ [![GitHub](https://img.shields.io/github/v/release/Stoupy51/stouputils?logo=github&label=GitHub)](https://github.com/Stoupy51/stouputils/releases/latest)
4
+ [![PyPI - Downloads](https://img.shields.io/pypi/dm/stouputils?logo=python&label=PyPI%20downloads)](https://pypi.org/project/stouputils/)
5
+ [![Documentation](https://img.shields.io/github/v/release/Stoupy51/stouputils?logo=sphinx&label=Documentation&color=purple)](https://stoupy51.github.io/stouputils/latest/)
6
+
7
+
8
+ # 📚 Project Overview
9
+ Stouputils is a collection of utility modules designed to simplify and enhance the development process.<br>
10
+ It includes a range of tools for tasks such as execution of doctests, display utilities, decorators, as well as context managers.
11
+
12
+
13
+ # 🚀 Project File Tree
14
+ ```bash
15
+ stouputils/
16
+ ├── applications/
17
+ │ ├── automatic_docs.py # 📚 Documentation generation utilities (used to create this documentation)
18
+ │ └── ...
19
+
20
+ ├── continuous_delivery/
21
+ │ ├── cd_utils.py # 🔧 Common utilities for continuous delivery
22
+ │ ├── github.py # 📦 GitHub utilities (upload_to_github)
23
+ │ ├── pypi.py # 📦 PyPI utilities (pypi_full_routine)
24
+ │ ├── pyproject.py # 📝 Pyproject.toml utilities
25
+ │ └── ...
26
+
27
+ ├── print.py # 🖨️ Display utilities (info, debug, warning, error)
28
+ ├── io.py # 💻 I/O utilities (file management, json)
29
+ ├── decorators.py # 🎯 Decorators (silent, measure_time, error_handler, simple_cache)
30
+ ├── ctx.py # 🚫 Context managers (Muffle, LogToFile)
31
+ ├── archive.py # 📦 Archive utilities (zip, repair_zip)
32
+ ├── parallel.py # 🧑‍🤝‍🧑 Parallel processing (multiprocessing, multithreading)
33
+ ├── collections.py # 🧰 Collection utilities (unique_list)
34
+ ├── all_doctests.py # ✅ Execution of all doctests for a given path
35
+ ├── backup.py # 📦 Backup utilities (delta backup, consolidate)
36
+ └── ...
37
+ ```
38
+
39
+
40
+ ## ⭐ Star History
41
+
42
+ <html>
43
+ <a href="https://star-history.com/#Stoupy51/stouputils&Date">
44
+ <picture>
45
+ <source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=Stoupy51/stouputils&type=Date&theme=dark" />
46
+ <source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=Stoupy51/stouputils&type=Date" />
47
+ <img alt="Star History Chart" src="https://api.star-history.com/svg?repos=Stoupy51/stouputils&type=Date" />
48
+ </picture>
49
+ </a>
50
+ </html>
51
+
@@ -5,7 +5,7 @@ build-backend = "hatchling.build"
5
5
 
6
6
  [project]
7
7
  name = "stouputils"
8
- version = "1.1.7"
8
+ version = "1.2.1"
9
9
  description = "Stouputils is a collection of utility modules designed to simplify and enhance the development process. It includes a range of tools for tasks such as execution of doctests, display utilities, decorators, as well as context managers, and many more."
10
10
  readme = "README.md"
11
11
  requires-python = ">=3.10"
@@ -19,6 +19,7 @@ dependencies = [
19
19
  "requests>=2.30.0",
20
20
  "pyyaml>=6.0.0",
21
21
  "toml>=0.10.0",
22
+ "m2r2>=0.3.3.post2",
22
23
  ]
23
24
  [[project.authors]]
24
25
  name = "Stoupy51"
@@ -0,0 +1,31 @@
1
+ """ A collection of utility modules designed to simplify and enhance the development process.
2
+
3
+ This package provides various tools and utilities for common development tasks including:
4
+
5
+ Key Features:
6
+ - Continuous delivery utilities (GitHub, PyPI)
7
+ - Display and logging utilities (print)
8
+ - File and I/O management (io)
9
+ - Decorators for common patterns
10
+ - Context managers
11
+ - Archive and backup tools
12
+ - Parallel processing helpers
13
+ - Collection utilities
14
+ - Doctests utilities
15
+
16
+ """
17
+
18
+ # Imports
19
+ from .print import *
20
+ from .archive import *
21
+ from .io import *
22
+ from .decorators import *
23
+ from .ctx import *
24
+ from .parallel import *
25
+ from .all_doctests import *
26
+ from .collections import *
27
+ from .backup import *
28
+
29
+ # Folders
30
+ from .continuous_delivery import *
31
+
@@ -0,0 +1,15 @@
1
+ """ Application-specific utilities and tools.
2
+
3
+ This module provides higher-level utilities for specific application needs:
4
+
5
+ Key Features:
6
+ - Automatic documentation generation with Sphinx: `update_documentation(...)`
7
+ - Support for multi-version documentation
8
+ - GitHub Pages integration
9
+ - Markdown to RST conversion
10
+
11
+ """
12
+
13
+ # Imports
14
+ from .automatic_docs import *
15
+
@@ -0,0 +1,507 @@
1
+ """ Sphinx documentation generation utilities.
2
+
3
+ This module provides a comprehensive set of utilities for automatically generating
4
+ and managing Sphinx documentation for Python projects. It handles the creation
5
+ of configuration files, index pages, version management, and HTML generation.
6
+
7
+ Example of usage:
8
+
9
+ .. code-block:: python
10
+
11
+ import stouputils as stp
12
+ from stouputils.applications import automatic_docs
13
+
14
+ if __name__ == "__main__":
15
+ automatic_docs.update_documentation(
16
+ root_path=stp.get_root_path(__file__, go_up=1),
17
+ project="stouputils",
18
+ author="Stoupy",
19
+ copyright="2025, Stoupy",
20
+ html_logo="https://avatars.githubusercontent.com/u/35665974",
21
+ html_favicon="https://avatars.githubusercontent.com/u/35665974",
22
+ github_user="Stoupy51",
23
+ github_repo="stouputils",
24
+ version="1.2.0",
25
+ skip_undocumented=True,
26
+ )
27
+
28
+ .. image:: https://raw.githubusercontent.com/Stoupy51/stouputils/refs/heads/main/assets/applications/automatic_docs.gif
29
+ :alt: stouputils automatic_docs examples
30
+
31
+ Note:
32
+ This module requires Sphinx and its dependencies to be installed.
33
+ It also requires the 'm2r2' package for Markdown to RST conversion.
34
+
35
+ Example of GitHub Actions workflow:
36
+
37
+ .. code-block:: yaml
38
+
39
+ name: documentation
40
+
41
+ on:
42
+ push:
43
+ branches:
44
+ - main
45
+ tags:
46
+ - 'v*'
47
+ pull_request:
48
+ workflow_dispatch:
49
+
50
+ permissions:
51
+ contents: write
52
+
53
+ jobs:
54
+ docs:
55
+ runs-on: ubuntu-latest
56
+ steps:
57
+ - uses: actions/checkout@v4
58
+ - uses: actions/setup-python@v5
59
+ - name: Install dependencies
60
+ run: |
61
+ pip install hatch stouputils sphinx sphinx_rtd_theme myst_parser furo m2r2
62
+ hatch build
63
+ - name: Build latest docs
64
+ if: github.ref == 'refs/heads/main'
65
+ run: |
66
+ python scripts/create_docs.py
67
+ - name: Build version docs
68
+ if: startsWith(github.ref, 'refs/tags/v')
69
+ run: |
70
+ python scripts/create_docs.py ${GITHUB_REF#refs/tags/v}
71
+ - name: Deploy to GitHub Pages
72
+ uses: peaceiris/actions-gh-pages@v3
73
+ if: ${{ (github.event_name == 'push' && github.ref == 'refs/heads/main') || startsWith(github.ref, 'refs/tags/v') }}
74
+ with:
75
+ publish_branch: gh-pages
76
+ github_token: ${{ secrets.GITHUB_TOKEN }}
77
+ publish_dir: docs/build/html
78
+ keep_files: true
79
+ force_orphan: false
80
+ """
81
+ # Imports
82
+ import os
83
+ import shutil
84
+ import subprocess
85
+ import sys
86
+ from typing import Any, Callable
87
+
88
+ from ..io import clean_path, super_open, super_json_dump
89
+ from ..decorators import handle_error, simple_cache
90
+ from ..continuous_delivery import version_to_float
91
+ from ..print import info
92
+
93
+
94
+ def get_sphinx_conf_content(
95
+ project: str,
96
+ author: str,
97
+ current_version: str,
98
+ copyright: str,
99
+ html_logo: str,
100
+ html_favicon: str,
101
+ github_user: str,
102
+ github_repo: str,
103
+ version_list: list[str] | None = None,
104
+ skip_undocumented: bool = True,
105
+ ) -> str:
106
+ """ Get the content of the Sphinx configuration file.
107
+
108
+ Args:
109
+ project (str): Name of the project
110
+ author (str): Author of the project
111
+ current_version (str): Current version
112
+ copyright (str): Copyright information
113
+ html_logo (str): URL to the logo
114
+ html_favicon (str): URL to the favicon
115
+ github_user (str): GitHub username
116
+ github_repo (str): GitHub repository name
117
+ version_list (list[str] | None): List of versions. Defaults to None
118
+ skip_undocumented (bool): Whether to skip undocumented members. Defaults to True
119
+
120
+ Returns:
121
+ str: Content of the Sphinx configuration file
122
+ """
123
+ conf_content: str = f"""
124
+ # Imports
125
+ import os
126
+ import sys
127
+ from typing import Any
128
+
129
+ # Project information
130
+ project: str = "{project}"
131
+ copyright: str = "{copyright}"
132
+ author: str = "{author}"
133
+ release: str = "{current_version}"
134
+
135
+ # General configuration
136
+ extensions: list[str] = [
137
+ "sphinx.ext.autodoc",
138
+ "sphinx.ext.napoleon",
139
+ "sphinx.ext.viewcode",
140
+ "sphinx.ext.githubpages",
141
+ "sphinx.ext.intersphinx",
142
+ "furo.sphinxext",
143
+ "m2r2",
144
+ ]
145
+
146
+ templates_path: list[str] = ["_templates"]
147
+ exclude_patterns: list[str] = []
148
+
149
+ # HTML output options
150
+ html_theme: str = "furo"
151
+ html_static_path: list[str] = ["_static"]
152
+ html_logo: str = "{html_logo}"
153
+ html_title: str = "{project}"
154
+ html_favicon: str = "{html_favicon}"
155
+
156
+ # Theme options
157
+ html_theme_options: dict[str, Any] = {{
158
+ "light_css_variables": {{
159
+ "color-brand-primary": "#2980B9",
160
+ "color-brand-content": "#2980B9",
161
+ "color-admonition-background": "#E8F0F8",
162
+ }},
163
+ "dark_css_variables": {{
164
+ "color-brand-primary": "#56B4E9",
165
+ "color-brand-content": "#56B4E9",
166
+ "color-admonition-background": "#1F262B",
167
+ }},
168
+ "sidebar_hide_name": False,
169
+ "navigation_with_keys": True,
170
+ "announcement": "This is the latest documentation of {project}",
171
+ "footer_icons": [
172
+ {{
173
+ "name": "GitHub",
174
+ "url": "https://github.com/{github_user}/{github_repo}",
175
+ "html": "<i class='fab fa-github-square'></i>",
176
+ "class": "",
177
+ }},
178
+ ],
179
+ }}
180
+ """
181
+ # Create base html_context dictionary
182
+ html_context: dict[str, Any] = {
183
+ "display_github": True,
184
+ "github_user": github_user,
185
+ "github_repo": github_repo,
186
+ "github_version": "main",
187
+ "conf_py_path": "/docs/source/",
188
+ "source_suffix": [".rst", ".md"],
189
+ "default_mode": "dark",
190
+ }
191
+
192
+ # Add version selector if versions are provided
193
+ if version_list and current_version:
194
+ html_context.update({
195
+ "versions": version_list,
196
+ "current_version": current_version,
197
+ })
198
+ html_context_str: str = super_json_dump(html_context, max_level=1).replace("true", "True").replace("false", "False")
199
+
200
+ conf_content += f"""
201
+ html_context = {html_context_str}
202
+
203
+ # Autodoc settings
204
+ autodoc_default_options: dict[str, bool | str] = {{
205
+ "members": True,
206
+ "member-order": "bysource",
207
+ "special-members": False,
208
+ "undoc-members": False,
209
+ "private-members": False,
210
+ "show-inheritance": True,
211
+ "ignore-module-all": True,
212
+ "exclude-members": "__weakref__",
213
+ }}
214
+
215
+ # Tell autodoc to prefer source code over installed package
216
+ autodoc_mock_imports = []
217
+ always_document_param_types = True
218
+ add_module_names = False
219
+ """
220
+
221
+ if skip_undocumented:
222
+ conf_content += """
223
+ # Only document items with docstrings
224
+ def skip_undocumented(app: Any, what: str, name: str, obj: Any, skip: bool, *args: Any, **kwargs: Any) -> bool:
225
+ if not obj.__doc__:
226
+ return True
227
+ return skip
228
+
229
+ def setup(app: Any) -> None:
230
+ app.connect("autodoc-skip-member", skip_undocumented)
231
+ """
232
+ return conf_content
233
+
234
+ @simple_cache()
235
+ def get_versions_from_github(github_user: str, github_repo: str) -> list[str]:
236
+ """ Get list of versions from GitHub gh-pages branch.
237
+
238
+ Args:
239
+ github_user (str): GitHub username
240
+ github_repo (str): GitHub repository name
241
+
242
+ Returns:
243
+ list[str]: List of versions, with 'latest' as first element
244
+ """
245
+ import requests
246
+ version_list: list[str] = []
247
+ try:
248
+ response = requests.get(f"https://api.github.com/repos/{github_user}/{github_repo}/contents?ref=gh-pages")
249
+ if response.status_code == 200:
250
+ contents = response.json()
251
+ version_list = ["latest"] + sorted(
252
+ [d["name"].replace("v", "") for d in contents
253
+ if d["type"] == "dir" and d["name"].startswith("v")],
254
+ key=version_to_float,
255
+ reverse=True
256
+ )
257
+ except Exception as e:
258
+ info(f"Failed to get versions from GitHub: {e}")
259
+ version_list = ["latest"]
260
+ return version_list
261
+
262
+ def markdown_to_rst(markdown_content: str) -> str:
263
+ """ Convert markdown content to RST format.
264
+
265
+ Args:
266
+ markdown_content (str): Markdown content
267
+
268
+ Returns:
269
+ str: RST content
270
+ """
271
+ if not markdown_content:
272
+ return ""
273
+
274
+ # Convert markdown to RST and return it
275
+ import m2r2 # type: ignore
276
+ return m2r2.convert(markdown_content) # type: ignore
277
+
278
+ def generate_index_rst(
279
+ readme_path: str,
280
+ index_path: str,
281
+ project: str,
282
+ github_user: str,
283
+ github_repo: str,
284
+ get_versions_function: Callable[[str, str], list[str]] = get_versions_from_github,
285
+ ) -> None:
286
+ """ Generate index.rst from README.md content.
287
+
288
+ Args:
289
+ readme_path (str): Path to the README.md file
290
+ index_path (str): Path where index.rst should be created
291
+ project (str): Name of the project
292
+ github_user (str): GitHub username
293
+ github_repo (str): GitHub repository name
294
+ get_versions_function (Callable[[str, str], list[str]]): Function to get versions from GitHub
295
+ """
296
+ # Read README content
297
+ with open(readme_path, "r", encoding="utf-8") as f:
298
+ readme_content: str = f.read()
299
+
300
+ # Generate version selector
301
+ version_selector: str = "\n\n**Versions**: "
302
+
303
+ # Get versions from GitHub
304
+ version_list: list[str] = get_versions_function(github_user, github_repo)
305
+
306
+ # Create version links
307
+ version_links: list[str] = []
308
+ for version in version_list:
309
+ if version == "latest":
310
+ version_links.append("`latest <../latest/index.html>`_")
311
+ else:
312
+ version_links.append(f"`v{version} <../v{version}/index.html>`_")
313
+ version_selector += ", ".join(version_links)
314
+
315
+ # Generate module documentation section
316
+ module_docs: str = f"""
317
+ .. toctree::
318
+ :maxdepth: 10
319
+
320
+ modules/{project}
321
+ """
322
+
323
+ # Convert markdown to RST
324
+ rst_content: str = f"""
325
+ 🛠️ Welcome to {project.capitalize()} Documentation
326
+ {'=' * 100}
327
+ {version_selector}
328
+
329
+ {markdown_to_rst(readme_content)}
330
+
331
+ 📖 Module Documentation
332
+ {'-' * 100}
333
+ {module_docs}
334
+ """
335
+
336
+ # Write the RST file
337
+ with open(index_path, "w", encoding="utf-8") as f:
338
+ f.write(rst_content)
339
+
340
+ def generate_documentation(
341
+ source_dir: str,
342
+ modules_dir: str,
343
+ project_dir: str,
344
+ build_dir: str,
345
+ ) -> None:
346
+ """ Generate documentation using Sphinx.
347
+
348
+ Args:
349
+ source_dir (str): Source directory
350
+ modules_dir (str): Modules directory
351
+ project_dir (str): Project directory
352
+ build_dir (str): Build directory
353
+ """
354
+ # Generate module documentation using sphinx-apidoc
355
+ subprocess.run([
356
+ sys.executable,
357
+ "-m", "sphinx.ext.apidoc",
358
+ "-o", modules_dir,
359
+ "-f", "-e", "-M",
360
+ "--no-toc",
361
+ "-P",
362
+ "--implicit-namespaces",
363
+ "--module-first",
364
+ project_dir,
365
+ ], check=True)
366
+
367
+ # Build HTML documentation
368
+ subprocess.run([
369
+ sys.executable,
370
+ "-m", "sphinx",
371
+ "-b", "html",
372
+ "-a",
373
+ source_dir,
374
+ build_dir,
375
+ ], check=True)
376
+
377
+ def generate_redirect_html(filepath: str) -> None:
378
+ """ Generate HTML content for redirect page.
379
+
380
+ Args:
381
+ filepath (str): Path to the file where the HTML content should be written
382
+ """
383
+ with super_open(filepath, "w", encoding="utf-8") as f:
384
+ f.write("""<!DOCTYPE html>
385
+ <html lang="en">
386
+ <head>
387
+ <meta charset="UTF-8">
388
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
389
+ <meta http-equiv="refresh" content="0;url=./latest/">
390
+ <title>Redirecting...</title>
391
+ </head>
392
+ <body>
393
+ <p>If you are not redirected automatically, <a href="./latest/">click here</a>.</p>
394
+ </body>
395
+ </html>
396
+ """)
397
+
398
+ @handle_error()
399
+ def update_documentation(
400
+ root_path: str,
401
+ project: str,
402
+ author: str = "Author",
403
+ copyright: str = "2025, Author",
404
+ html_logo: str = "",
405
+ html_favicon: str = "",
406
+ github_user: str = "",
407
+ github_repo: str = "",
408
+ version: str | None = None,
409
+ skip_undocumented: bool = True,
410
+
411
+ get_versions_function: Callable[[str, str], list[str]] = get_versions_from_github,
412
+ generate_index_function: Callable[..., None] = generate_index_rst,
413
+ generate_docs_function: Callable[..., None] = generate_documentation,
414
+ generate_redirect_function: Callable[[str], None] = generate_redirect_html,
415
+ get_conf_content_function: Callable[..., str] = get_sphinx_conf_content
416
+ ) -> None:
417
+ """ Update the Sphinx documentation.
418
+
419
+ Args:
420
+ root_path (str): Root path of the project
421
+ project (str): Name of the project
422
+ author (str): Author of the project
423
+ copyright (str): Copyright information
424
+ html_logo (str): URL to the logo
425
+ html_favicon (str): URL to the favicon
426
+ github_user (str): GitHub username
427
+ github_repo (str): GitHub repository name
428
+ version (str | None): Version to build documentation for (e.g. "1.0.0", defaults to "latest")
429
+ skip_undocumented (bool): Whether to skip undocumented members. Defaults to True
430
+
431
+ get_versions_function (Callable[[str, str], list[str]]): Function to get versions from GitHub
432
+ generate_index_function (Callable[..., None]): Function to generate index.rst
433
+ generate_docs_function (Callable[..., None]): Function to generate documentation
434
+ generate_redirect_function (Callable[[str], None]): Function to create redirect file
435
+ get_conf_content_function (Callable[..., str]): Function to get Sphinx conf.py content
436
+ """
437
+ # Setup paths
438
+ root_path = clean_path(root_path)
439
+ docs_dir: str = f"{root_path}/docs"
440
+ source_dir: str = f"{docs_dir}/source"
441
+ modules_dir: str = f"{source_dir}/modules"
442
+ static_dir: str = f"{source_dir}/_static"
443
+ templates_dir: str = f"{source_dir}/_templates"
444
+ html_dir: str = f"{docs_dir}/build/html"
445
+
446
+ # Remove "v" from version if it is a string (just in case)
447
+ version = version.replace("v", "") if isinstance(version, str) else version
448
+
449
+ # Modify build directory if version is specified
450
+ build_dir: str = f"{html_dir}/latest" if not version else f"{html_dir}/v{version}"
451
+
452
+ # Create directories if they don't exist
453
+ for dir in [modules_dir, static_dir, templates_dir]:
454
+ os.makedirs(dir, exist_ok=True)
455
+
456
+ # Generate index.rst from README.md
457
+ readme_path: str = f"{root_path}/README.md"
458
+ index_path: str = f"{source_dir}/index.rst"
459
+ generate_index_function(
460
+ readme_path=readme_path,
461
+ index_path=index_path,
462
+ project=project,
463
+ github_user=github_user,
464
+ github_repo=github_repo,
465
+ get_versions_function=get_versions_function,
466
+ )
467
+
468
+ # Clean up old module documentation
469
+ if os.path.exists(modules_dir):
470
+ shutil.rmtree(modules_dir)
471
+ os.makedirs(modules_dir)
472
+
473
+ # Get versions and current version for conf.py
474
+ version_list: list[str] = get_versions_function(github_user, github_repo)
475
+ current_version: str = version if version else "latest"
476
+
477
+ # Generate conf.py
478
+ conf_path: str = f"{source_dir}/conf.py"
479
+ conf_content: str = get_conf_content_function(
480
+ project=project,
481
+ author=author,
482
+ current_version=current_version,
483
+ copyright=copyright,
484
+ html_logo=html_logo,
485
+ html_favicon=html_favicon,
486
+ github_user=github_user,
487
+ github_repo=github_repo,
488
+ version_list=version_list,
489
+ skip_undocumented=skip_undocumented,
490
+ )
491
+ with open(conf_path, "w", encoding="utf-8") as f:
492
+ f.write(conf_content)
493
+
494
+ # Generate documentation
495
+ generate_docs_function(
496
+ source_dir=source_dir,
497
+ modules_dir=modules_dir,
498
+ project_dir=f"{root_path}/{project}",
499
+ build_dir=build_dir,
500
+ )
501
+
502
+ # Add index.html to the build directory that redirects to the latest version
503
+ generate_redirect_function(f"{html_dir}/index.html")
504
+
505
+ info(f"Documentation updated successfully!")
506
+ info(f"You can view the documentation by opening {build_dir}/index.html")
507
+
@@ -0,0 +1,24 @@
1
+ """ Continuous delivery and deployment utilities.
2
+
3
+ This module provides tools for automating software delivery and deployment:
4
+
5
+ Key Features:
6
+ - GitHub release management and uploads
7
+ - PyPI package publishing utilities
8
+ - pyproject.toml file management
9
+ - Common CD/CI utilities
10
+
11
+ Components:
12
+ - cd_utils: Common utilities for continuous delivery
13
+ - github: GitHub-specific utilities (upload_to_github)
14
+ - pypi: PyPI publishing tools (pypi_full_routine)
15
+ - pyproject: pyproject.toml file management
16
+
17
+ """
18
+
19
+ # Imports
20
+ from .cd_utils import *
21
+ from .github import *
22
+ from .pypi import *
23
+ from .pyproject import *
24
+
@@ -78,3 +78,58 @@ def handle_response(response: requests.Response, error_message: str) -> None:
78
78
  except requests.exceptions.JSONDecodeError:
79
79
  raise ValueError(f"{error_message}, response code {response.status_code} with response {response.text}")
80
80
 
81
+ # Clean a version string
82
+ def clean_version(version: str, keep: str = "") -> str:
83
+ """ Clean a version string
84
+
85
+ Args:
86
+ version (str): The version string to clean
87
+ keep (str): The characters to keep in the version string
88
+ Returns:
89
+ str: The cleaned version string
90
+
91
+ >>> clean_version("v1.e0.zfezf0.1.2.3zefz")
92
+ '1.0.0.1.2.3'
93
+ >>> clean_version("v1.e0.zfezf0.1.2.3zefz", keep="v")
94
+ 'v1.0.0.1.2.3'
95
+ >>> clean_version("v1.2.3b", keep="ab")
96
+ '1.2.3b'
97
+ """
98
+ return "".join(c for c in version if c in "0123456789." + keep)
99
+
100
+ # Convert a version string to a float
101
+ def version_to_float(version: str) -> float:
102
+ """ Converts a version string into a float for comparison purposes.
103
+ The version string is expected to follow the format of major.minor.patch.something_else....,
104
+ where each part is separated by a dot and can be extended indefinitely.
105
+
106
+ Args:
107
+ version (str): The version string to convert. (e.g. "v1.0.0.1.2.3")
108
+ Returns:
109
+ float: The float representation of the version. (e.g. 0)
110
+
111
+ >>> version_to_float("v1.0.0")
112
+ 1.0
113
+ >>> version_to_float("v1.0.0.1")
114
+ 1.000000001
115
+ >>> version_to_float("v2.3.7")
116
+ 2.003007
117
+ >>> version_to_float("v1.0.0.1.2.3")
118
+ 1.0000000010020031
119
+ >>> version_to_float("v2.0") > version_to_float("v1.0.0.1")
120
+ True
121
+ """
122
+ # Clean the version string by keeping only the numbers and dots
123
+ version = clean_version(version)
124
+
125
+ # Split the version string into parts
126
+ version_parts: list[str] = version.split(".")
127
+ total: float = 0.0
128
+ multiplier: float = 1.0
129
+
130
+ # Iterate over the parts and add lesser and lesser weight to each part
131
+ for part in version_parts:
132
+ total += int(part) * multiplier
133
+ multiplier /= 1_000
134
+ return total
135
+
@@ -10,7 +10,7 @@
10
10
  from ..print import info, warning, progress
11
11
  from ..decorators import measure_time, handle_error
12
12
  from ..io import clean_path
13
- from .cd_utils import handle_response
13
+ from .cd_utils import handle_response, version_to_float, clean_version
14
14
  from typing import Any
15
15
  import requests
16
16
  import os
@@ -140,59 +140,6 @@ def delete_existing_tag(tag_url: str, headers: dict[str, str]) -> None:
140
140
  handle_response(delete_response, "Failed to delete existing tag")
141
141
  info("Deleted existing tag")
142
142
 
143
- def clean_version(version: str, keep: str = "") -> str:
144
- """ Clean a version string
145
-
146
- Args:
147
- version (str): The version string to clean
148
- keep (str): The characters to keep in the version string
149
- Returns:
150
- str: The cleaned version string
151
-
152
- >>> clean_version("v1.e0.zfezf0.1.2.3zefz")
153
- '1.0.0.1.2.3'
154
- >>> clean_version("v1.e0.zfezf0.1.2.3zefz", keep="v")
155
- 'v1.0.0.1.2.3'
156
- >>> clean_version("v1.2.3b", keep="ab")
157
- '1.2.3b'
158
- """
159
- return "".join(c for c in version if c in "0123456789." + keep)
160
-
161
- def version_to_float(version: str) -> float:
162
- """ Converts a version string into a float for comparison purposes.
163
- The version string is expected to follow the format of major.minor.patch.something_else....,
164
- where each part is separated by a dot and can be extended indefinitely.
165
-
166
- Args:
167
- version (str): The version string to convert. (e.g. "v1.0.0.1.2.3")
168
- Returns:
169
- float: The float representation of the version. (e.g. 0)
170
-
171
- >>> version_to_float("v1.0.0")
172
- 1.0
173
- >>> version_to_float("v1.0.0.1")
174
- 1.000000001
175
- >>> version_to_float("v2.3.7")
176
- 2.003007
177
- >>> version_to_float("v1.0.0.1.2.3")
178
- 1.0000000010020031
179
- >>> version_to_float("v2.0") > version_to_float("v1.0.0.1")
180
- True
181
- """
182
- # Clean the version string by keeping only the numbers and dots
183
- version = clean_version(version)
184
-
185
- # Split the version string into parts
186
- version_parts: list[str] = version.split(".")
187
- total: float = 0.0
188
- multiplier: float = 1.0
189
-
190
- # Iterate over the parts and add lesser and lesser weight to each part
191
- for part in version_parts:
192
- total += int(part) * multiplier
193
- multiplier /= 1_000
194
- return total
195
-
196
143
  def get_latest_tag(owner: str, project_name: str, version: str, headers: dict[str, str]) -> tuple[str, str] | tuple[None, None]:
197
144
  """ Get latest tag information
198
145
 
stouputils-1.1.7/PKG-INFO DELETED
@@ -1,60 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: stouputils
3
- Version: 1.1.7
4
- Summary: Stouputils is a collection of utility modules designed to simplify and enhance the development process. It includes a range of tools for tasks such as execution of doctests, display utilities, decorators, as well as context managers, and many more.
5
- Project-URL: Homepage, https://github.com/Stoupy51/stouputils
6
- Project-URL: Issues, https://github.com/Stoupy51/stouputils/issues
7
- Author-email: Stoupy51 <stoupy51@gmail.com>
8
- License-File: LICENSE
9
- Classifier: License :: OSI Approved :: MIT License
10
- Classifier: Operating System :: OS Independent
11
- Classifier: Programming Language :: Python :: 3
12
- Requires-Python: >=3.10
13
- Requires-Dist: pyyaml>=6.0.0
14
- Requires-Dist: requests>=2.30.0
15
- Requires-Dist: toml>=0.10.0
16
- Requires-Dist: tqdm>=4.66.0
17
- Description-Content-Type: text/markdown
18
-
19
-
20
- # 🛠️ Project Badges
21
- [![GitHub](https://img.shields.io/github/v/release/Stoupy51/stouputils?logo=github&label=GitHub)](https://github.com/Stoupy51/stouputils/releases/latest)
22
- [![PyPI - Downloads](https://img.shields.io/pypi/dm/stouputils?logo=python&label=PyPI%20downloads)](https://pypi.org/project/stouputils/)
23
- [![Documentation](https://img.shields.io/badge/documentation-purple?logo=sphinx)](https://stoupy51.github.io/stouputils/latest/)
24
-
25
-
26
- # 📚 Project Overview
27
- Stouputils is a collection of utility modules designed to simplify and enhance the development process.<br>
28
- It includes a range of tools for tasks such as execution of doctests, display utilities, decorators, as well as context managers.
29
-
30
-
31
- # 🚀 Project File Tree
32
- ```bash
33
- stouputils/
34
- ├── continuous_delivery/
35
- │ ├── github.py # 📦 GitHub utilities that are very specific (upload_to_github)
36
- │ └── ...
37
-
38
- ├── print.py # 🖨️ Display utilities
39
- ├── io.py # 💻 I/O utilities (for file management, json, etc.)
40
- ├── decorators.py # 🎯 Decorators (silent, measure_time, error_handler, simple_cache, deprecated)
41
- ├── ctx.py # 🚫 Context managers (Muffle)
42
- ├── archive.py # 📦 Archive utilities (zip, unzip)
43
- ├── parallel.py # 🧑‍🤝‍🧑 Parallel processing (multiprocessing, multithreading)
44
- ├── collections.py # 🧰 Collection utilities (unique_list)
45
- ├── all_doctests.py # ✅ Execution of all doctests of all modules for a given path
46
- ├── backup.py # 📦 Backup utilities (create_delta_backup, consolidate_backups, backup_cli)
47
- └── ...
48
- ```
49
-
50
-
51
- ## ⭐ Star History
52
-
53
- <a href="https://star-history.com/#Stoupy51/stouputils&Date">
54
- <picture>
55
- <source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=Stoupy51/stouputils&type=Date&theme=dark" />
56
- <source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=Stoupy51/stouputils&type=Date" />
57
- <img alt="Star History Chart" src="https://api.star-history.com/svg?repos=Stoupy51/stouputils&type=Date" />
58
- </picture>
59
- </a>
60
-
@@ -1,42 +0,0 @@
1
-
2
- # 🛠️ Project Badges
3
- [![GitHub](https://img.shields.io/github/v/release/Stoupy51/stouputils?logo=github&label=GitHub)](https://github.com/Stoupy51/stouputils/releases/latest)
4
- [![PyPI - Downloads](https://img.shields.io/pypi/dm/stouputils?logo=python&label=PyPI%20downloads)](https://pypi.org/project/stouputils/)
5
- [![Documentation](https://img.shields.io/badge/documentation-purple?logo=sphinx)](https://stoupy51.github.io/stouputils/latest/)
6
-
7
-
8
- # 📚 Project Overview
9
- Stouputils is a collection of utility modules designed to simplify and enhance the development process.<br>
10
- It includes a range of tools for tasks such as execution of doctests, display utilities, decorators, as well as context managers.
11
-
12
-
13
- # 🚀 Project File Tree
14
- ```bash
15
- stouputils/
16
- ├── continuous_delivery/
17
- │ ├── github.py # 📦 GitHub utilities that are very specific (upload_to_github)
18
- │ └── ...
19
-
20
- ├── print.py # 🖨️ Display utilities
21
- ├── io.py # 💻 I/O utilities (for file management, json, etc.)
22
- ├── decorators.py # 🎯 Decorators (silent, measure_time, error_handler, simple_cache, deprecated)
23
- ├── ctx.py # 🚫 Context managers (Muffle)
24
- ├── archive.py # 📦 Archive utilities (zip, unzip)
25
- ├── parallel.py # 🧑‍🤝‍🧑 Parallel processing (multiprocessing, multithreading)
26
- ├── collections.py # 🧰 Collection utilities (unique_list)
27
- ├── all_doctests.py # ✅ Execution of all doctests of all modules for a given path
28
- ├── backup.py # 📦 Backup utilities (create_delta_backup, consolidate_backups, backup_cli)
29
- └── ...
30
- ```
31
-
32
-
33
- ## ⭐ Star History
34
-
35
- <a href="https://star-history.com/#Stoupy51/stouputils&Date">
36
- <picture>
37
- <source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=Stoupy51/stouputils&type=Date&theme=dark" />
38
- <source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=Stoupy51/stouputils&type=Date" />
39
- <img alt="Star History Chart" src="https://api.star-history.com/svg?repos=Stoupy51/stouputils&type=Date" />
40
- </picture>
41
- </a>
42
-
@@ -1,15 +0,0 @@
1
-
2
- # Imports
3
- from .print import *
4
- from .archive import *
5
- from .io import *
6
- from .decorators import *
7
- from .ctx import *
8
- from .parallel import *
9
- from .all_doctests import *
10
- from .collections import *
11
- from .backup import *
12
-
13
- # Folders
14
- from .continuous_delivery import *
15
-
@@ -1,7 +0,0 @@
1
-
2
- # Imports
3
- from .cd_utils import *
4
- from .github import *
5
- from .pypi import *
6
- from .pyproject import *
7
-
File without changes
File without changes
File without changes
File without changes