Skip to content

Commit

Permalink
refactor(puml): remove nesting and grouping of namespaces, use "!prag…
Browse files Browse the repository at this point in the history
…ma useIntermediatePackages false" instead (#64)
  • Loading branch information
lucsorel authored Oct 15, 2023
1 parent a9da0ab commit 34bfc95
Show file tree
Hide file tree
Showing 15 changed files with 72 additions and 326 deletions.
22 changes: 6 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
<img width="350px" alt="Python logo"
src="https://www.python.org/static/community_logos/python-logo-generic.svg" />
</a>
<a href="http://plantuml.com/" target="_blank">
<img width="116px" height="112px" alt="PlantUML logo" src="http://s.plantuml.com/logoc.png" style="margin-bottom: 40px" vspace="40px" />
<a href="https://plantuml.com/" target="_blank">
<img width="116px" height="112px" alt="PlantUML logo" src="https://s.plantuml.com/logoc.png" style="margin-bottom: 40px" vspace="40px" />
</a>
<h1>Python to PlantUML</h1>
</div>
Expand Down Expand Up @@ -94,18 +94,8 @@ This outputs the following PlantUML content:

```plantuml
@startuml py2puml.domain
namespace py2puml.domain {
namespace package {}
namespace umlclass {}
namespace umlitem {}
namespace umlenum {}
namespace umlrelation {}
}
class py2puml.domain.package.Package {
name: str
children: List[Package]
items_number: int
}
!pragma useIntermediatePackages false
class py2puml.domain.umlclass.UmlAttribute {
name: str
type: str
Expand Down Expand Up @@ -135,7 +125,6 @@ class py2puml.domain.umlrelation.UmlRelation {
target_fqn: str
type: RelType
}
py2puml.domain.package.Package *-- py2puml.domain.package.Package
py2puml.domain.umlclass.UmlClass *-- py2puml.domain.umlclass.UmlAttribute
py2puml.domain.umlitem.UmlItem <|-- py2puml.domain.umlclass.UmlClass
py2puml.domain.umlenum.UmlEnum *-- py2puml.domain.umlenum.Member
Expand All @@ -147,7 +136,7 @@ footer Generated by //py2puml//

Using PlantUML, this content is rendered as in this diagram:

![py2puml domain UML Diagram](https://www.plantuml.com/plantuml/png/ZPD1Yzim48Nl-XLpNbWRUZHxs2M4rj1DbZGzbIN8zcmgAikkD2wO9F-zigqWEw1L3i6HPgJlFUdfsH3NrDKIslvBQxz9rTHSAAPuZQRb9TuKuCG0PaLU_k5776S1IicDkLcGk9RaRT4wRPA18Ut6vMyXAuqgW-_2q2_N_kwgWh0s1zNL1UeCXA9n_iAcdnTamQEApnHTUvAVjNmXqgBeAAoB-dOnDiH9b1aKJIETYBj8gvai07xb6kTtfiMRDWTUM38loV62feVpYNWUMWOXkVq6tNxyLMuO8g7g8gIn9Nd5uQw2e7zSTZX7HJUqqjUU3L2FWElvJRZti6wDafDeb5i_shWb-QvaXtBVjpuMg-ths_P7li-tcmmUu3J5uEAg-URRUfVlNpQhTGPFPr-EUlD4ws-tr0XWcawNU5ZS2W1nVKJoi_EWEjspSxYmo8jyU7oCF5eMoxNV8_BCM2INJsUxKOp68WdnOWAfl5j56CBkl4cd9H8pzj4qX1g-eaBD2IieUaXJjp1DsJEgolvZ_m40)
![py2puml domain UML Diagram](https://www.plantuml.com/plantuml/png/ZPBFwzf04CNl-rTChu89z1WyA29jeFx0sbCHcIIZBDtTfBkJWgZ_UyUeuSitO7BQnwxpUSzvcGP6pxKrK9s_Ld96HMbHE_MbydYo27MWr35vIuL6fWtcV_140Ove0YcL6mpXqsmaihcFVbapO_OwgvdWeW0SMaeWi1VDvwhLae9rda1MbaRT-gdpksY8-EA717xemBy_UkuLW0u7pCG5S-xbQoPxnwToTl8U_xf6lfadLzjeIJOZtnd_XwQcGG09i92p8TW6zlfl3_HU07J_GNVUaq7MfOksP7QotuOnNoytwv_fBbsl4XZ1vR7icxoag--BRRgRhUQB12RNzgcRiEiWARTFtRY4ilOv7Tej0J3w4t5xqrR-p2OclGsFnkD17vVgwN9o5L2Vc-hfGyAyxtneYZScQk369Sk0-jMnB9ayV2D77faAoCuGny_1E5PJSeMe_m00)

For a full overview of the CLI, run:

Expand Down Expand Up @@ -213,6 +202,7 @@ poetry run pytest -v --cov=py2puml --cov-branch --cov-report term-missing --cov-

# Changelog

* `0.8.1`: delegated the grouping of nested namespaces (see `0.7.0`) to the PlantUML binary, which handles it natively
* `0.8.0`: added support for union types, and github actions (pre-commit hooks + automated tests)
* `0.7.2`: added the current working directory to the import path to make py2puml work in any directory or in native virtual environment (not handled by poetry)
* `0.7.1`: removed obsolete part of documentation: deeply compound types are now well handled (by version `0.7.0`)
Expand Down
21 changes: 17 additions & 4 deletions py2puml/asserts.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,29 @@ def assert_py2puml_is_file_content(domain_path: str, domain_module: str, diagram
assert_py2puml_is_stringio(domain_path, domain_module, expected_puml_file)


def normalize_lines_with_returns(lines_with_returns: Iterable[str]) -> List[str]:
'''
When comparing contents, each piece of contents can either be:
- a formatted string block output by the py2puml command containg line returns
- a single line of contents read from a file, each line ending with a line return
This function normalizes each sequence of contents as a list of string lines,
each one finishing without a line return to ease comparison.
'''
return ''.join(lines_with_returns).split('\n')


def assert_py2puml_is_stringio(domain_path: str, domain_module: str, expected_content_stream: StringIO):
# generates the PlantUML documentation
puml_content = list(py2puml(domain_path, domain_module))
puml_content_lines = normalize_lines_with_returns(py2puml(domain_path, domain_module))
expected_content_lines = normalize_lines_with_returns(expected_content_stream)

assert_multilines(puml_content, expected_content_stream)
assert_multilines(puml_content_lines, expected_content_lines)


def assert_multilines(actual_multilines: List[str], expected_multilines: Iterable[str]):
def assert_multilines(actual_multilines: List[str], expected_multilines: List[str]):
line_index = 0
for line_index, (actual_line, expected_line) in enumerate(zip(actual_multilines, expected_multilines)):
# print(f'{actual_line=}\n{expected_line=}')
assert actual_line == expected_line, f'actual and expected contents have changed at line {line_index + 1}: {actual_line=}, {expected_line=}'

assert line_index + 1 == len(actual_multilines), f'actual and expected diagrams have {line_index + 1} lines'
2 changes: 1 addition & 1 deletion py2puml/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def run():

argparser = ArgumentParser(description='Generate PlantUML class diagrams to document your Python application.')

argparser.add_argument('-v', '--version', action='version', version='py2puml 0.8.0')
argparser.add_argument('-v', '--version', action='version', version='py2puml 0.8.1')
argparser.add_argument('path', metavar='path', type=str, help='the filepath to the domain')
argparser.add_argument('module', metavar='module', type=str, help='the module name of the domain', default=None)

Expand Down
10 changes: 0 additions & 10 deletions py2puml/domain/package.py

This file was deleted.

98 changes: 0 additions & 98 deletions py2puml/export/namespace.py

This file was deleted.

28 changes: 16 additions & 12 deletions py2puml/export/puml.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,23 @@
from py2puml.domain.umlenum import UmlEnum
from py2puml.domain.umlitem import UmlItem
from py2puml.domain.umlrelation import UmlRelation
from py2puml.export.namespace import puml_namespace_content

PUML_FILE_START = '@startuml {diagram_name}\n'
PUML_FILE_FOOTER = 'footer Generated by //py2puml//\n'
PUML_FILE_END = '@enduml\n'
PUML_ITEM_START_TPL = '{item_type} {item_fqn} {{\n'
PUML_ATTR_TPL = ' {attr_name}: {attr_type}{staticity}\n'
PUML_ITEM_END = '}\n'
PUML_RELATION_TPL = '{source_fqn} {rel_type}-- {target_fqn}\n'
PUML_FILE_START = '''@startuml {diagram_name}
!pragma useIntermediatePackages false
'''
PUML_FILE_FOOTER = '''footer Generated by //py2puml//
'''
PUML_FILE_END = '''@enduml
'''
PUML_ITEM_START_TPL = '''{item_type} {item_fqn} {{
'''
PUML_ATTR_TPL = ''' {attr_name}: {attr_type}{staticity}
'''
PUML_ITEM_END = '''}
'''
PUML_RELATION_TPL = '''{source_fqn} {rel_type}-- {target_fqn}
'''

FEATURE_STATIC = ' {static}'
FEATURE_INSTANCE = ''
Expand All @@ -21,10 +29,6 @@
def to_puml_content(diagram_name: str, uml_items: List[UmlItem], uml_relations: List[UmlRelation]) -> Iterable[str]:
yield PUML_FILE_START.format(diagram_name=diagram_name)

# exports the namespaces
for namespace_line in puml_namespace_content(uml_items):
yield namespace_line

# exports the domain classes and enums
for uml_item in uml_items:
if isinstance(uml_item, UmlEnum):
Expand Down
15 changes: 2 additions & 13 deletions py2puml/py2puml.domain.puml
Original file line number Diff line number Diff line change
@@ -1,16 +1,6 @@
@startuml py2puml.domain
namespace py2puml.domain {
namespace package {}
namespace umlclass {}
namespace umlitem {}
namespace umlenum {}
namespace umlrelation {}
}
class py2puml.domain.package.Package {
name: str
children: List[Package]
items_number: int
}
!pragma useIntermediatePackages false

class py2puml.domain.umlclass.UmlAttribute {
name: str
type: str
Expand Down Expand Up @@ -40,7 +30,6 @@ class py2puml.domain.umlrelation.UmlRelation {
target_fqn: str
type: RelType
}
py2puml.domain.package.Package *-- py2puml.domain.package.Package
py2puml.domain.umlclass.UmlClass *-- py2puml.domain.umlclass.UmlAttribute
py2puml.domain.umlitem.UmlItem <|-- py2puml.domain.umlclass.UmlClass
py2puml.domain.umlenum.UmlEnum *-- py2puml.domain.umlenum.Member
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "py2puml"
version = "0.8.0"
version = "0.8.1"
description = "Generate PlantUML class diagrams to document your Python application."
keywords = ["class diagram", "PlantUML", "documentation", "inspection", "AST"]
readme = "README.md"
Expand Down
9 changes: 0 additions & 9 deletions tests/modules/withnestednamespace/plantuml_namespace.txt

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@
@startuml tests.modules.withnestednamespace
namespace tests.modules.withnestednamespace {
namespace nomoduleroot.modulechild.leaf {}
namespace tree {}
namespace branches.branch {}
namespace withonlyonesubpackage.underground {
namespace roots.roots {}
}
namespace trunks.trunk {}
}
!pragma useIntermediatePackages false

class tests.modules.withnestednamespace.nomoduleroot.modulechild.leaf.CommownLeaf {
color: int
area: float
Expand Down
6 changes: 2 additions & 4 deletions tests/puml_files/withrootnotincwd.puml
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
@startuml withrootnotincwd
namespace withrootnotincwd {
namespace point {}
namespace segment {}
}
!pragma useIntermediatePackages false

class withrootnotincwd.point.Point {
x: float
y: float
Expand Down
Loading

0 comments on commit 34bfc95

Please sign in to comment.