Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature: new params for graphviz + solves #70 #74

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -162,3 +162,8 @@ htmlcov
.idea/
.history/
.vscode/

# our vis. of architecture
architecture.dot
architecture.html
architecture.svg
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,19 +48,19 @@ See `pyan3 --help`.

Example:

`pyan *.py --uses --no-defines --colored --grouped --annotated --dot >myuses.dot`
`pyan3 *.py --uses --no-defines --colored --grouped --annotated --dot >myuses.dot`

Then render using your favorite GraphViz filter, mainly `dot` or `fdp`:

`dot -Tsvg myuses.dot >myuses.svg`

Or use directly

`pyan *.py --uses --no-defines --colored --grouped --annotated --svg >myuses.svg`
`pyan3 *.py --uses --no-defines --colored --grouped --annotated --svg >myuses.svg`

You can also export as an interactive HTML

`pyan *.py --uses --no-defines --colored --grouped --annotated --html > myuses.html`
`pyan3 *.py --uses --no-defines --colored --grouped --annotated --html > myuses.html`

Alternatively, you can call `pyan` from a script

Expand Down
55 changes: 51 additions & 4 deletions pyan/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,31 @@ def main(cli_args=None):
),
)

parser.add_argument(
"--dot-ranksep",
default="0.5",
dest="ranksep",
help=(
"specifies the dot graph 'ranksep' property for "
"controlling desired rank separation, in inches. "
"Allowed values: [0.02 .. 1000.0]. "
"[dot only]"
),
)

parser.add_argument(
"--graphviz-layout",
default="dot",
dest="layout",
help=(
"specifies the graphviz 'layout' property for "
"the name of the layout algorithm to use. "
"Allowed values: ['dot', 'neato', 'fdp', 'sfdp', 'twopi', 'circo']. "
"Recommended values: ['dot', 'fdp']. "
"[graphviz only]"
),
)

parser.add_argument(
"-a",
"--annotated",
Expand All @@ -159,7 +184,12 @@ def main(cli_args=None):

known_args, unknown_args = parser.parse_known_args(cli_args)

filenames = [fn2 for fn in unknown_args for fn2 in glob(fn, recursive=True)]

filenames = []
for fn in unknown_args:
for fn2 in glob(fn, recursive=True):
abs_fn2 = os.path.abspath(fn2)
filenames.append(abs_fn2)

# determine root
if known_args.root is not None:
Expand Down Expand Up @@ -203,6 +233,11 @@ def main(cli_args=None):
handler = logging.FileHandler(known_args.logname)
logger.addHandler(handler)

logger.debug(f"[files] {unknown_args}")

if root:
root = os.path.abspath(root)

v = CallGraphVisitor(filenames, logger=logger, root=root)

if known_args.function or known_args.namespace:
Expand All @@ -222,13 +257,25 @@ def main(cli_args=None):
writer = None

if known_args.dot:
writer = DotWriter(graph, options=["rankdir=" + known_args.rankdir], output=known_args.filename, logger=logger)
writer = DotWriter(graph, options=[
"rankdir=" + known_args.rankdir,
"ranksep=" + known_args.ranksep,
"layout=" + known_args.layout,
], output=known_args.filename, logger=logger)

if known_args.html:
writer = HTMLWriter(graph, options=["rankdir=" + known_args.rankdir], output=known_args.filename, logger=logger)
writer = HTMLWriter(graph, options=[
"rankdir=" + known_args.rankdir,
"ranksep=" + known_args.ranksep,
"layout=" + known_args.layout,
], output=known_args.filename, logger=logger)

if known_args.svg:
writer = SVGWriter(graph, options=["rankdir=" + known_args.rankdir], output=known_args.filename, logger=logger)
writer = SVGWriter(graph, options=[
"rankdir=" + known_args.rankdir,
"ranksep=" + known_args.ranksep,
"layout=" + known_args.layout,
], output=known_args.filename, logger=logger)

if known_args.tgf:
writer = TgfWriter(graph, output=known_args.filename, logger=logger)
Expand Down
5 changes: 5 additions & 0 deletions visualize_pyan_architecture.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,8 @@
echo -ne "Pyan architecture: generating architecture.{dot,svg}\n"
python3 -m pyan pyan/*.py --no-defines --uses --colored --annotate --dot -V >architecture.dot 2>architecture.log
dot -Tsvg architecture.dot >architecture.svg
echo -ne "Pyan architecture: generating architecture.{html,graphviz=fdp}\n"
python3 -m pyan pyan/*.py --no-defines --uses \
--grouped --nested-groups \
--graphviz-layout fdp \
--colored --html > architecture.html