generated from jCloud/repository-template
Merge pull request 'Chore: prepare release 0.1.0' (#4) from chore/prepare-0-1-0 into main
Release package / Build package (release) Failing after 20s
Release package / Publish package to package registry (release) Skipped
Release package / Prepare release asset upload (release) Failing after 13s
Release package / Upload release asset (${{ fromJSON(needs.prepare_upload_release_asset.outputs.files) }}) (release) Skipped
Release package / Build package (release) Failing after 20s
Release package / Publish package to package registry (release) Skipped
Release package / Prepare release asset upload (release) Failing after 13s
Release package / Upload release asset (${{ fromJSON(needs.prepare_upload_release_asset.outputs.files) }}) (release) Skipped
Reviewed-on: #4
This commit was merged in pull request #4.
This commit is contained in:
48 files changed
+57
-72
No files matched your search
+1
-1
@@ -2,4 +2,4 @@ dist/
|
||||
src/*.egg-info/
|
||||
.vscode/
|
||||
.pytest_cache/
|
||||
__pycache__/
|
||||
__pycache__/
|
||||
@@ -19,4 +19,4 @@ API reference and generated documentation can be found in [docs/reference](docs/
|
||||
|
||||
## Notice
|
||||
|
||||
This project is under active development. The documentation will be expanded over time.
|
||||
This project is under active development. The documentation will be expanded over time.
|
||||
+9
-24
@@ -1,29 +1,14 @@
|
||||
# Changelog
|
||||
|
||||
## [Unreleased]
|
||||
## [0.1.0] - 2026-09-01
|
||||
|
||||
### Added
|
||||
|
||||
- Add class for existing directories
|
||||
- Add function to format a list human-readable
|
||||
- Add function to assert that an object is an instance of a specific type
|
||||
- Add Python project documentation generator class
|
||||
- Add Python namespaces classes
|
||||
- Add type checking for the `name` attribute at the constructor of `core.python.namespaces.PythonNamespace`
|
||||
- Add check whether sub-namespaces are not empty in `core.python.namespaces.PythonPackageNamespace.namespace`
|
||||
- Add feature to get the names of all sub-namespaces of a `core.python.namespaces.PythonPackageNamespace`
|
||||
- Add feature to compare `core.python.namespaces.PythonPackageNamespace` instances or `core.python.namespaces.PythonModuleNamespace` instances
|
||||
- Add string representation for Python namespace objects
|
||||
- Add `PythonDocumentationGenerator` method to collect all namespaces
|
||||
- Add class for existing files
|
||||
- Add classes for Python function arguments
|
||||
- Add classes for Python definitions
|
||||
- Add class for Python modules
|
||||
- Add feature to get the signature representation of a Python function argument
|
||||
- Add class for Python docstrings
|
||||
- Add feature to parse Python docstrings
|
||||
- Add function to ensure a non-empty string.
|
||||
- Add Python definition documentation generator
|
||||
- Add function to get the path segments of a path relative to another
|
||||
- Add Python module documentation generator
|
||||
- Add Python project documentation generator
|
||||
- utility class for existing directories
|
||||
- utility class for existing files
|
||||
- Python project documentation generator
|
||||
- Python definition documentation generator
|
||||
- Python module documentation generator
|
||||
- Python namespaces
|
||||
- signature representation of a Python function argument
|
||||
- Python docstrings
|
||||
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
SOFTWARE.
|
||||
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
SOFTWARE.
|
||||
@@ -174,4 +174,4 @@
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
END OF TERMS AND CONDITIONS
|
||||
+1
-1
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
SOFTWARE.
|
||||
@@ -22,4 +22,4 @@ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
@@ -16,4 +16,4 @@ INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PA
|
||||
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
+1
-1
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
SOFTWARE.
|
||||
+2
-2
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "jcloud-docsgen"
|
||||
version = "1.0.0"
|
||||
version = "0.1.0"
|
||||
description = "A tool that generates Markdown documentation for software project source code"
|
||||
dependencies = ["docstring-parser"]
|
||||
license = "Apache-2.0"
|
||||
@@ -13,4 +13,4 @@ license = "Apache-2.0"
|
||||
package-dir = {"" = "src"}
|
||||
|
||||
[tool.setuptools.packages.find]
|
||||
where = ["src"]
|
||||
where = ["src"]
|
||||
@@ -19,4 +19,4 @@ from .core import __all__ as _core__all__
|
||||
__all__ = [
|
||||
'cli',
|
||||
*_core__all__
|
||||
]
|
||||
]
|
||||
@@ -34,4 +34,4 @@ def main() -> int:
|
||||
argument_parser = argparse.ArgumentParser()
|
||||
argument_parser.add_argument('project_directory', type = existing_directory, default = pathlib.Path('.'), help = 'The directory of the project')
|
||||
args = argument_parser.parse_args()
|
||||
return 0
|
||||
return 0
|
||||
@@ -16,4 +16,4 @@ from . import python
|
||||
|
||||
__all__ = [
|
||||
'python'
|
||||
]
|
||||
]
|
||||
@@ -19,4 +19,4 @@ from . import namespaces
|
||||
__all__ = [
|
||||
*_core__all__,
|
||||
'namespaces'
|
||||
]
|
||||
]
|
||||
@@ -951,4 +951,4 @@ class PythonDocumentationGenerator:
|
||||
self.project_directory / 'src',
|
||||
self.include_sections,
|
||||
self.kwargs
|
||||
)
|
||||
)
|
||||
@@ -170,4 +170,4 @@ class PythonASTArgumentsListParser:
|
||||
else:
|
||||
arguments.append(PythonFunctionArgument(self.ast_arguments_list.kwarg.arg, PythonArgumentKind.KWARGS, None, ast.unparse(self.ast_arguments_list.kwarg.annotation)))
|
||||
|
||||
return arguments
|
||||
return arguments
|
||||
@@ -229,4 +229,4 @@ class PythonClassDefinition(PythonDefinition):
|
||||
for expr in node.body
|
||||
if isinstance(expr, (ast.FunctionDef, ast.AsyncFunctionDef, ast.ClassDef))
|
||||
]
|
||||
)
|
||||
)
|
||||
@@ -46,4 +46,4 @@ class PythonDocstring:
|
||||
:rtype: docstring_parser.Docstring
|
||||
'''
|
||||
|
||||
return docstring_parser.parse(self.docstring)
|
||||
return docstring_parser.parse(self.docstring)
|
||||
@@ -186,4 +186,4 @@ class PythonModuleNamespace(PythonNamespace):
|
||||
super().__init__(name)
|
||||
|
||||
def __eq__(self, value: PythonModuleNamespace) -> bool:
|
||||
return self.name == value.name
|
||||
return self.name == value.name
|
||||
@@ -76,4 +76,4 @@ class PythonDefinitionError(ValueError):
|
||||
else:
|
||||
return f'{self.args[0]}{": " if self.definition and self.args[0] else ""}{self.definition if self.args[0] else ""}'
|
||||
|
||||
class PythonArgumentStructureError(PythonDefinitionError): ...
|
||||
class PythonArgumentStructureError(PythonDefinitionError): ...
|
||||
@@ -172,4 +172,4 @@ def get_relative_path_segments(path: pathlib.Path, root: pathlib.Path) -> list[s
|
||||
root.resolve()
|
||||
)
|
||||
.parts
|
||||
)
|
||||
)
|
||||
@@ -1410,4 +1410,4 @@ Examples
|
||||
>>> A()''')
|
||||
])
|
||||
def test_PythonDefinitionDocumentationGenerator_generate_documentation(definition_documentation_generator, expected):
|
||||
assert definition_documentation_generator.generate_documentation() == expected
|
||||
assert definition_documentation_generator.generate_documentation() == expected
|
||||
@@ -59,4 +59,4 @@ def test_generate_documentation(dir, expectdir):
|
||||
allow_tables = True,
|
||||
allow_html = False
|
||||
).generate_documentation(
|
||||
) # simplify the tests
|
||||
) # simplify the tests
|
||||
+1
-1
@@ -1 +1 @@
|
||||
def func(): ...
|
||||
def func(): ...
|
||||
@@ -961,4 +961,4 @@ Barks.
|
||||
A dog.'''),
|
||||
])
|
||||
def test_PythonModuleDocumentationGenerator_exceptions(module_documentation_generator, expected):
|
||||
assert module_documentation_generator.generate_documentation() == expected
|
||||
assert module_documentation_generator.generate_documentation() == expected
|
||||
@@ -24,4 +24,4 @@ import pytest
|
||||
(PythonArgumentKind.KWARGS, 'kwargs'),
|
||||
])
|
||||
def test__argument_kind_human_readable(argument_kind, expected):
|
||||
assert _argument_kind_human_readable(argument_kind) == expected
|
||||
assert _argument_kind_human_readable(argument_kind) == expected
|
||||
@@ -136,4 +136,4 @@ def test_PythonDocumentationGenerator_collect_modules(python_documentation_gener
|
||||
])
|
||||
])
|
||||
def test___collect_definitions(module, expected):
|
||||
assert list(_collect_definitions(module)) == expected
|
||||
assert list(_collect_definitions(module)) == expected
|
||||
@@ -53,4 +53,4 @@ def test__fit_row_length(expected_length, row, expected):
|
||||
def test__fit_row_length_exceptions(expected_length, row, expected_exception):
|
||||
with pytest.raises(expected_exception) as exc_info:
|
||||
_fit_row_length(expected_length, row)
|
||||
assert str(exc_info.value) == 'expected must be larger than or equal 0.'
|
||||
assert str(exc_info.value) == 'expected must be larger than or equal 0.'
|
||||
@@ -101,4 +101,4 @@ def docstring_args_list(docstring: str) -> list[docstring_parser.DocstringParam]
|
||||
([], '', {}),
|
||||
])
|
||||
def test__function_params_types(arg_list, docstring, expected):
|
||||
assert _function_params_info(arg_list, docstring_args_list(docstring)) == expected
|
||||
assert _function_params_info(arg_list, docstring_args_list(docstring)) == expected
|
||||
@@ -90,4 +90,4 @@ def test__markdown_table(header, body, allow_markdown_table, force_row_lengths,
|
||||
def test__markdown_table_exceptions(header, body, allow_markdown_table, force_row_lengths, one_line_values, missing_value, expected_exception, expected_exception_msg):
|
||||
with pytest.raises(expected_exception) as exc_info:
|
||||
_markdown_table(header, body, allow_markdown_table = allow_markdown_table, force_row_lengths = force_row_lengths, one_line_values = one_line_values, missing_value = missing_value)
|
||||
assert str(exc_info.value) == expected_exception_msg
|
||||
assert str(exc_info.value) == expected_exception_msg
|
||||
@@ -94,4 +94,4 @@ import pytest
|
||||
], ['a: int = 1']),
|
||||
])
|
||||
def test__signature_argument_list(argument_list, expected):
|
||||
assert _signature_argument_list(argument_list) == expected
|
||||
assert _signature_argument_list(argument_list) == expected
|
||||
@@ -47,4 +47,4 @@ class Dog(Animal):
|
||||
Barks.
|
||||
'''
|
||||
|
||||
print('Woof!')
|
||||
print('Woof!')
|
||||
@@ -212,4 +212,4 @@ def argument_list(argument_list: str) -> ast.arguments:
|
||||
]),
|
||||
])
|
||||
def test_PythonASTArgumentsListParser_to_argument_list(ast_arguments_list, expected):
|
||||
assert PythonASTArgumentsListParser(ast_arguments_list).to_argument_list() == expected
|
||||
assert PythonASTArgumentsListParser(ast_arguments_list).to_argument_list() == expected
|
||||
@@ -154,4 +154,4 @@ def test_PythonFunctionArgument_asterik(name, kind, annotation):
|
||||
(PythonFunctionArgument('a', PythonArgumentKind.KWARGS, None, 'int'), '**a: int'),
|
||||
])
|
||||
def test_PythonFunctionArgument_signature_repr(argument, expected):
|
||||
assert argument.signature_repr() == expected
|
||||
assert argument.signature_repr() == expected
|
||||
@@ -94,4 +94,4 @@ def test_PythonFunctionDefinition_exceptions(name, args, returns, doc, decorator
|
||||
])),
|
||||
])
|
||||
def test_PythonDefinition_from_node(node, expected):
|
||||
assert PythonClassDefinition.from_node(node) == expected
|
||||
assert PythonClassDefinition.from_node(node) == expected
|
||||
@@ -81,4 +81,4 @@ def test_PythonDefinition_exceptions(name, doc, decorators, expected_exception,
|
||||
])
|
||||
def test_PythonDefinition___eq__(definition1, definition2, expected):
|
||||
assert (definition1 == definition2) == expected
|
||||
assert (definition2 == definition1) == expected
|
||||
assert (definition2 == definition1) == expected
|
||||
@@ -84,4 +84,4 @@ def test_PythonFunctionDefinition_exceptions(name, args, returns, doc, decorator
|
||||
(ast_node('@decorator\ndef func(): ...'), PythonFunctionDefinition('func', [], None, None, ['decorator'])),
|
||||
])
|
||||
def test_PythonDefinition_from_node(node, expected):
|
||||
assert PythonFunctionDefinition.from_node(node) == expected
|
||||
assert PythonFunctionDefinition.from_node(node) == expected
|
||||
@@ -44,4 +44,4 @@ def test_PythonModuleNamespace___eq__(namespace1, namespace2, expected):
|
||||
(PythonModuleNamespace(StrSubclass('a')), 'PythonModuleNamespace(\'a\')'),
|
||||
])
|
||||
def test_PythonModuleNamespace_string_representation(namespace, expected):
|
||||
assert repr(namespace) == expected
|
||||
assert repr(namespace) == expected
|
||||
@@ -31,4 +31,4 @@ def test_PythonNamespace_name_attribute(namespace, expected_name):
|
||||
(PythonNamespace(StrSubclass('a')), 'PythonNamespace(\'a\')'),
|
||||
])
|
||||
def test_PythonNamespace_string_representation(namespace, expected):
|
||||
assert repr(namespace) == expected
|
||||
assert repr(namespace) == expected
|
||||
@@ -105,4 +105,4 @@ def test_PythonPackageNamespace_string_representation(namespace, expected):
|
||||
])
|
||||
def test_PythonPackageNamespace___getitem__(namespace, new_namespace, expected):
|
||||
namespace.add(new_namespace)
|
||||
assert namespace == expected
|
||||
assert namespace == expected
|
||||
@@ -39,4 +39,4 @@ def test_ExistingDirectory(path, expected):
|
||||
def test_ExistingDirectory_exceptions(path, expected_exception, expected_exception_message):
|
||||
with pytest.raises(expected_exception) as exc_info:
|
||||
ExistingDirectory(path)
|
||||
assert str(exc_info.value) == expected_exception_message
|
||||
assert str(exc_info.value) == expected_exception_message
|
||||
@@ -32,4 +32,4 @@ def test_ExistingDirectory(path, expected):
|
||||
def test_ExistingDirectory_exceptions(path, expected_exception, expected_exception_message):
|
||||
with pytest.raises(expected_exception) as exc_info:
|
||||
ExistingFile(path)
|
||||
assert str(exc_info.value) == expected_exception_message
|
||||
assert str(exc_info.value) == expected_exception_message
|
||||
@@ -40,4 +40,4 @@ def test_assert_that_is_instance(obj, class_or_tuple):
|
||||
def test_assert_that_is_instance_exceptions(obj, class_or_tuple, expected_exception_msg):
|
||||
with pytest.raises(TypeError) as exc_info:
|
||||
assert_that_is_instance(obj, class_or_tuple)
|
||||
assert str(exc_info.value) == expected_exception_msg
|
||||
assert str(exc_info.value) == expected_exception_msg
|
||||
@@ -73,4 +73,4 @@ import pathlib
|
||||
|
||||
])
|
||||
def test_get_relative_path_segments(path, root, expected):
|
||||
assert get_relative_path_segments(path, root) == expected
|
||||
assert get_relative_path_segments(path, root) == expected
|
||||
@@ -51,4 +51,4 @@ import pytest
|
||||
([1, 2, 3, 42, 'a', 23], 'and', '\'', '\'1\', \'2\', \'3\', \'42\', \'a\' and \'23\''),
|
||||
])
|
||||
def test_human_readable_list(ls, final_separator, quotation_mark, expected):
|
||||
assert human_readable_list(ls, final_separator, quotation_mark) == expected
|
||||
assert human_readable_list(ls, final_separator, quotation_mark) == expected
|
||||
@@ -27,4 +27,4 @@ import pytest
|
||||
('a', 'a'),
|
||||
])
|
||||
def test_non_empty_str(value, expected):
|
||||
assert non_empty_str(value) == expected
|
||||
assert non_empty_str(value) == expected
|
||||
@@ -33,4 +33,4 @@ def ast_node(statement: str) -> Union[ast.stmt, None]:
|
||||
body = ast.parse(statement).body
|
||||
if not body:
|
||||
return None
|
||||
return body[0]
|
||||
return body[0]
|
||||
Reference in new issue
Block a user