13 Commits
Author SHA1 Message Date
jakob.scheid b2a8e54766 Merge pull request 'Chore: prepare release 0.2.0' (#49) from chore/prepare-0-2-0 into main
Release package / Build package (release) Successful in 24s
Release package / Prepare release asset upload (release) Successful in 14s
Release package / Publish package to package registry (release) Successful in 16s
Release package / Upload release asset (${{ fromJSON(needs.prepare_upload_release_asset.outputs.files) }}) (release) Successful in 23s
Reviewed-on: #49
2026-09-28 00:40:29 +02:00
jakob.scheid 773294f3d9 docs(changelog): move unreleased section to 0.2.0 2026-09-28 00:35:43 +02:00
jakob.scheid 200221e324 chore: update version in pyproject.toml to 0.2.0 2026-09-28 00:34:39 +02:00
jakob.scheid e8bcf4feb1 Merge pull request 'Fix(ci): spelling error in API reference workflow' (#48) from fix/fix-api-reference-spelling into main
Reviewed-on: #48
2026-09-28 00:31:45 +02:00
jakob.scheid ff3bddd366 fix(ci): fix spelling in API reference workflow
Replaced '--chached' with '--cached' and replaced '--quit' with
'--quiet'.
2026-09-28 00:29:11 +02:00
jakob.scheid e94365faf8 Merge pull request 'Chore(ci): adapt API reference workflow to the new API' (#45) from feature/adapt-api-reference-workflow-to-new-cli into main
Reviewed-on: #45
2026-09-28 00:22:39 +02:00
jakob.scheid 95da53898c chore(ci): adapt API reference workflow to new API
Adapted the API reference generation workflow to the new API, which no
longer requires the src/ structure.
2026-09-28 00:18:44 +02:00
jakob.scheid 4d2e63d560 refactor(ci): use force overwriting feature 2026-09-28 00:17:30 +02:00
jakob.scheid 2187590468 Merge pull request 'Refactor: lint code' (#43) from refactor/lint into main
Reviewed-on: #43
2026-09-28 00:08:30 +02:00
jakob.scheid 37308227d9 chore: add noqa comments to wildcard imports
Added noqa comments to suppress linting warnings for wildcard imports.
2026-09-28 00:04:53 +02:00
jakob.scheid f796263c0e fix: fix syntax errors (target version)
Fixed all lines which were syntax errors in the target version (only
multi-line f-strings).
2026-09-28 00:04:53 +02:00
jakob.scheid 896bfcc2dd style: use target version practices 2026-09-28 00:04:53 +02:00
jakob.scheid b2a7c9a0e3 style: fix lines which exceed the line length limit 2026-09-28 00:04:44 +02:00
13 changed files with 66 additions and 62 deletions

No files matched your search

+2 -3
View File
@@ -39,8 +39,7 @@ jobs:
- name: Generate documentation - name: Generate documentation
run: | run: |
rm -rf docs/reference jcloud-docsgen python -T -f -o docs/reference ./src
jcloud-docsgen python -T -o docs/reference .
- name: Commit and push - name: Commit and push
run: | run: |
@@ -49,7 +48,7 @@ jobs:
git add docs/reference git add docs/reference
if git diff --chached --quit; then if git diff --cached --quiet; then
echo "No changes" echo "No changes"
exit 0 exit 0
fi fi
+1 -1
View File
@@ -1,6 +1,6 @@
# Changelog # Changelog
## [Unreleased] ## [0.2.0] - 2026-09-28
### Added ### Added
+1 -1
View File
@@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"
[project] [project]
name = "jcloud-docsgen" name = "jcloud-docsgen"
version = "0.1.0" version = "0.2.0"
description = "A tool that generates Markdown documentation for software project source code" description = "A tool that generates Markdown documentation for software project source code"
dependencies = ["docstring-parser"] dependencies = ["docstring-parser"]
requires-python = ">=3.10" requires-python = ">=3.10"
+1 -1
View File
@@ -13,7 +13,7 @@
# limitations under the License. # limitations under the License.
from . import cli from . import cli
from .core import * from .core import * # noqa: F403
from .core import __all__ as _core__all__ from .core import __all__ as _core__all__
__all__ = [ __all__ = [
+1 -1
View File
@@ -13,7 +13,7 @@
# limitations under the License. # limitations under the License.
from . import namespaces from . import namespaces
from ._core import * from ._core import * # noqa: F403
from ._core import __all__ as _core__all__ from ._core import __all__ as _core__all__
__all__ = [ __all__ = [
+8 -11
View File
@@ -249,9 +249,8 @@ def _markdown_table(
if len(row) != header_len: if len(row) != header_len:
if force_row_lengths: if force_row_lengths:
raise ValueError( raise ValueError(
f'expected {header_len} value{ f'expected {header_len} value'
"s" if header_len > 1 else "" f'{"s" if header_len > 1 else ""}, got {len(row)}'
}, got {len(row)}',
) )
else: else:
row = _fit_row_length(header_len, row) row = _fit_row_length(header_len, row)
@@ -277,9 +276,8 @@ def _markdown_table(
if len(row) != header_len: if len(row) != header_len:
if force_row_lengths: if force_row_lengths:
raise ValueError( raise ValueError(
f'expected {header_len} value{ f'expected {header_len} value'
"s" if header_len > 1 else "" f'{"s" if header_len > 1 else ""}, got {len(row)}'
}, got {len(row)}',
) )
else: else:
row = _fit_row_length(header_len, row) row = _fit_row_length(header_len, row)
@@ -601,11 +599,10 @@ class PythonDefinitionDocumentationGenerator:
if _is_docstring(self.definition.doc) or not self.skip_empty_sections: if _is_docstring(self.definition.doc) or not self.skip_empty_sections:
if self.allow_html: if self.allow_html:
md += f'<details><summary><h{ md += (
str(self.level + 1) f'<details><summary><h{str(self.level + 1)} style="displa'
} style="display:inline">Docstring</h{ f'y:inline">Docstring</h{str(self.level + 1)}></summary>'
str(self.level + 1) )
}></summary>'
else: else:
md += self.level * '#' + '# Docstring\n\n' md += self.level * '#' + '# Docstring\n\n'
+20 -12
View File
@@ -28,9 +28,11 @@ class NamespaceError(ValueError):
if not self.args: if not self.args:
return '' return ''
else: else:
return f'{self.args[0]}{ return (
": " if self.namespace_identifier and self.args[0] else "" self.args[0]
}{self.namespace_identifier if self.args[0] else ""}' + (': ' if self.namespace_identifier and self.args[0] else '')
+ (self.namespace_identifier if self.args[0] else '')
)
class InvalidNamespaceError(NamespaceError): ... class InvalidNamespaceError(NamespaceError): ...
@@ -55,9 +57,11 @@ class PythonIdentifierError(ValueError):
if not self.args: if not self.args:
return '' return ''
else: else:
return f'{self.args[0]}{ return (
": " if self.identifier and self.args[0] else "" self.args[0]
}{self.identifier if self.args[0] else ""}' + (': ' if self.identifier and self.args[0] else '')
+ (self.identifier if self.args[0] else '')
)
class InvalidPythonIdentifierError(PythonIdentifierError): ... class InvalidPythonIdentifierError(PythonIdentifierError): ...
@@ -76,9 +80,11 @@ class PythonAnnotationError(ValueError):
if not self.args: if not self.args:
return '' return ''
else: else:
return f'{self.args[0]}{ return (
": " if self.annotation and self.args[0] else "" self.args[0]
}{self.annotation if self.args[0] else ""}' + (': ' if self.annotation and self.args[0] else '')
+ (self.annotation if self.args[0] else '')
)
class InvalidPythonAnnotationError(PythonAnnotationError): ... class InvalidPythonAnnotationError(PythonAnnotationError): ...
@@ -97,9 +103,11 @@ class PythonDefinitionError(ValueError):
if not self.args: if not self.args:
return '' return ''
else: else:
return f'{self.args[0]}{ return (
": " if self.definition and self.args[0] else "" self.args[0]
}{self.definition if self.args[0] else ""}' + (': ' if self.definition and self.args[0] else '')
+ (self.definition if self.args[0] else '')
)
class PythonArgumentStructureError(PythonDefinitionError): ... class PythonArgumentStructureError(PythonDefinitionError): ...
+5 -7
View File
@@ -20,7 +20,6 @@ import errno
import os import os
import pathlib import pathlib
import types import types
from typing import Union
try: try:
from warnings import deprecated from warnings import deprecated
@@ -154,10 +153,10 @@ def assert_that_is_instance(
obj: object, obj: object,
class_or_tuple: type | types.UnionType | tuple[type, ...], class_or_tuple: type | types.UnionType | tuple[type, ...],
) -> None: ) -> None:
if not isinstance(class_or_tuple, Union[type, types.UnionType, tuple]): if not isinstance(class_or_tuple, (type, types.UnionType, tuple)):
raise TypeError( raise TypeError(
f"class_or_tuple: expected 'Union[type, types.UnionType, " f"class_or_tuple: expected 'type | types.UnionType, tupl"
f"tuple[type, ...]]', 'got {type(class_or_tuple).__name__}'", f"e[type, ...]', 'got {type(class_or_tuple).__name__}'",
) )
if not isinstance(obj, class_or_tuple): if not isinstance(obj, class_or_tuple):
if isinstance(class_or_tuple, (tuple, types.UnionType)): if isinstance(class_or_tuple, (tuple, types.UnionType)):
@@ -175,9 +174,8 @@ def assert_that_is_instance(
else: else:
exception_message_expected = "'" + class_or_tuple.__name__ + "'" exception_message_expected = "'" + class_or_tuple.__name__ + "'"
raise TypeError( raise TypeError(
f"expected {exception_message_expected}, got '{ f'expected {exception_message_expected}'
type(obj).__name__ f", got '{type(obj).__name__}'"
}'",
) )
@@ -85,7 +85,9 @@ def test_PythonDocumentationGenerator_collect_modules(
python_documentation_generator: PythonDocumentationGenerator, python_documentation_generator: PythonDocumentationGenerator,
expected, expected,
): ):
assert python_documentation_generator.namespace().sub_namespaces == expected assert (
python_documentation_generator.namespace().sub_namespaces
) == expected
@pytest.mark.parametrize( @pytest.mark.parametrize(
@@ -125,12 +125,12 @@ Returns all users.
##### Method signature ##### Method signature
```python ```python
list_all(self) -> List[User] list_all(self) -> list[User]
``` ```
##### Returns ##### Returns
Return type: `List[User]` Return type: `list[User]`
##### Parameters ##### Parameters
@@ -1,5 +1,4 @@
from dataclasses import dataclass from dataclasses import dataclass
from typing import Optional
@dataclass @dataclass
@@ -11,4 +10,4 @@ class User:
id: str id: str
name: str name: str
email: str email: str
age: Optional[int] = None age: int | None = None
@@ -1,5 +1,3 @@
from typing import Dict, List
from .models import User from .models import User
@@ -10,7 +8,7 @@ class InMemoryUserStorage:
""" """
def __init__(self): def __init__(self):
self._users: Dict[str, User] = {} self._users: dict[str, User] = {}
def add(self, user: User) -> None: def add(self, user: User) -> None:
"""Adds a user.""" """Adds a user."""
@@ -24,6 +22,6 @@ class InMemoryUserStorage:
"""Deletes a user.""" """Deletes a user."""
del self._users[user_id] del self._users[user_id]
def list_all(self) -> List[User]: def list_all(self) -> list[User]:
"""Returns all users.""" """Returns all users."""
return list(self._users.values()) return list(self._users.values())
@@ -292,22 +292,25 @@ def test_PythonDocumentationGenerator_collect_modules(
None, None,
[ [
( (
"""pytest.mark.parametrize('python_documentation_gener""" "pytest.mark.parametrize('python_documentatio"
"""ator,expected', [(PythonDocumentationGenerator(path""" "n_generator,expected', [(PythonDocumentation"
"""lib.Path('tests/unit/core/python/_core/test_project""" "Generator(pathlib.Path('tests/unit/core/pyth"
"""_dirs/pdir_1'), pathlib.Path('tests/unit/core/pytho""" "on/_core/test_project_dirs/pdir_1'), pathlib"
"""n/_core/test_project_dirs/pdir_1/docs')), []), (Pyt""" ".Path('tests/unit/core/python/_core/test_pro"
"""honDocumentationGenerator(pathlib.Path('tests/unit/""" "ject_dirs/pdir_1/docs')), []), (PythonDocume"
"""core/python/_core/test_project_dirs/pdir_2'), pathl""" "ntationGenerator(pathlib.Path('tests/unit/co"
"""ib.Path('tests/unit/core/python/_core/test_project_""" "re/python/_core/test_project_dirs/pdir_2'), "
"""dirs/pdir_2/docs')), [PythonPackageNamespace('pkg',""" "pathlib.Path('tests/unit/core/python/_core/t"
""" [PythonModuleNamespace('module')])]), (PythonDocum""" "est_project_dirs/pdir_2/docs')), [PythonPack"
"""entationGenerator(pathlib.Path('tests/unit/core/pyt""" "ageNamespace('pkg', [PythonModuleNamespace('"
"""hon/_core/test_project_dirs/pdir_3'), pathlib.Path(""" "module')])]), (PythonDocumentationGenerator("
"""'tests/unit/core/python/_core/test_project_dirs/pdi""" "pathlib.Path('tests/unit/core/python/_core/t"
"""r_3/docs')), [PythonPackageNamespace('pkg', [Python""" "est_project_dirs/pdir_3'), pathlib.Path('tes"
"""ModuleNamespace(\'module'), PythonPackageNamespace(""" 'ts/unit/core/python/_core/test_project_dirs/'
"""\'pkg\', [PythonModuleNamespace(\'module2')])])])])""" "pdir_3/docs')), [PythonPackageNamespace('pkg"
"', [PythonModuleNamespace('module'), Python"
"PackageNamespace('pkg', [PythonModuleNames"
"pace('module2')])])])])"
) )
], ],
), ),