<div style="padding: 20px; background: #333333; margin-bottom: 20px;">
❗ **Important Note:**
All credit of this code goes to the original creator which can be found at https://github.com/scottrogowski/code2flow
I have made a small change which includes the Graphviz libraries in the package so as to not rely on having Graphviz installed.
The version of Graphviz is the latest at the time of this commit. The files downloaded can be found at https://graphviz.org/download/
The downloaded files are stored in the code2flowdiagram/graphviz folder.
In order to publish the package on PyPi I have renamed the package to code2flowdiagram.
</div>
![Version 2.5.1](https://img.shields.io/badge/version-2.5.1-brightgreen) ![Build passing](https://img.shields.io/badge/build-passing-brightgreen) ![Coverage 100%](https://img.shields.io/badge/coverage-100%25-brightgreen) ![License MIT](https://img.shields.io/badge/license-MIT-green])
code2flowdiagram generates [call graphs](https://en.wikipedia.org/wiki/Call_graph) for dynamic programming language. code2flowdiagram supports Python, JavaScript, Ruby, and PHP.
The basic algorithm is simple:
1. Translate your source files into ASTs.
1. Find all function definitions.
1. Determine where those functions are called.
1. Connect the dots.
code2flowdiagram is useful for:
- Untangling spaghetti code.
- Identifying orphaned functions.
- Getting new developers up to speed.
code2flowdiagram provides a _pretty good estimate_ of your project's structure. No algorithm can generate a perfect call graph for a [dynamic language](https://en.wikipedia.org/wiki/Dynamic_programming_language) – even less so if that language is [duck-typed](https://en.wikipedia.org/wiki/Duck_typing). See the known limitations in the section below.
_(Below: code2flowdiagram running against a subset of itself `code2flowdiagram code2flowdiagram/engine.py code2flowdiagram/python.py --target-function=code2flowdiagram --downstream-depth=3`)_
## Installation
```bash
pip3 install code2flowdiagram
```
If you don't have it already, you will also need to install graphviz. Installation instructions can be found [here](https://graphviz.org/download/).
Additionally, depending on the language you want to parse, you may need to install additional dependencies:
- JavaScript: [Acorn](https://www.npmjs.com/package/acorn)
- Ruby: [Parser](https://github.com/whitequark/parser)
- PHP: [PHP-Parser](https://github.com/nikic/PHP-Parser)
- Python: No extra dependencies needed
## Usage
To generate a DOT file, run something like:
```bash
code2flowdiagram mypythonfile.py
```
Or, for Javascript:
```bash
code2flowdiagram myjavascriptfile.js
```
You can specify multiple files or import directories:
```bash
code2flowdiagram project/directory/source_a.js project/directory/source_b.js
```
```bash
code2flowdiagram project/directory/*.js
```
```bash
code2flowdiagram project/directory --language js
```
To pull out a subset of the graph, try something like:
```bash
code2flowdiagram mypythonfile.py --target-function my_func --upstream-depth=1 --downstream-depth=1
```
There are a ton of command line options, to see them all, run:
```bash
code2flowdiagram --help
```
## How code2flowdiagram works
code2flowdiagram approximates the structure of projects in dynamic languages. It is _not possible_ to generate a perfect callgraph for a dynamic language.
Detailed algorithm:
1. Generate an AST of the source code
2. Recursively separate groups and nodes. Groups are files, modules, or classes. More precisely, groups are namespaces where functions live. Nodes are the functions themselves.
3. For all nodes, identify function calls in those nodes.
4. For all nodes, identify in-scope variables. Attempt to connect those variables to specific nodes and groups. This is where there is some ambiguity in the algorithm because it is impossible to know the types of variables in dynamic languages. So, instead, heuristics must be used.
5. For all calls in all nodes, attempt to find a match from the in-scope variables. This will be an edge.
6. If a definitive match from in-scope variables cannot be found, attempt to find a single match from all other groups and nodes.
7. Trim orphaned nodes and groups.
8. Output results.
## Why is it impossible to generate a perfect call graph?
Consider this toy example in Python
```python
def func_factory(param):
if param < .5:
return func_a
else:
return func_b
func = func_factory(important_variable)
func()
```
We have no way of knowing whether `func` will point to `func_a` or `func_b` until runtime. In practice, ambiguity like this is common and is present in most non-trivial applications.
## Known limitations
code2flowdiagram is internally powered by ASTs. Most limitations stem from a token not being named what code2flowdiagram expects it to be named.
- All functions without definitions are skipped. This most often happens when a file is not included.
- Functions with identical names in different namespaces are (loudly) skipped. E.g. If you have two classes with identically named methods, code2flowdiagram cannot distinguish between these and skips them.
- Imported functions from outside your project directory (including from standard libraries) which share names with your defined functions may not be handled correctly. Instead, when you call the imported function, code2flowdiagram will link to your local functions. For example, if you have a function `search()` and call, `import searcher; searcher.search()`, code2flowdiagram may link (incorrectly) to your defined function.
- Anonymous or generated functions are skipped. This includes lambdas and factories.
- If a function is renamed, either explicitly or by being passed around as a parameter, it will be skipped.
## As an imported library
You can work with code2flowdiagram as an imported Python library in much the same way as you work with it
from the CLI.
```python
import code2flowdiagram
code2flowdiagram.code2flowdiagram(['path/to/filea', 'path/to/fileb'], 'path/to/outputfile')
```
The keyword arguments to `code2flowdiagram.code2flowdiagram` are roughly the same as the CLI
parameters. To see all available parameters, refer to the code2flowdiagram function in [engine.py](https://github.com/scottrogowski/code2flowdiagram/blob/master/code2flowdiagram/engine.py).
## How to contribute
1. **Open an issue**: code2flowdiagram is not perfect and there is a lot that can be improved. If you find a problem parsing your source that you can identify with a simplified example, please open an issue.
2. **Create a PR**: Even better, if you have a fix for the issue you identified that passes unit tests, please open a PR.
3. **Add a language**: While dense, each language implementation is between 250-400 lines of code including comments. If you want to implement another language, the existing implementations can be your guide.
## Unit tests
Test coverage is 100%. To run:
```bash
pip install -r requirements_dev.txt
make test
```
## License
code2flowdiagram is licensed under the MIT license.
Prior to the rewrite in April 2021, code2flowdiagram was licensed under LGPL. The last commit under that license was 24b2cb854c6a872ba6e17409fbddb6659bf64d4c.
The April 2021 rewrite was substantial, so it's probably reasonable to treat code2flowdiagram as completely MIT-licensed.
## Feedback / Issues / Contact
If you have an issue using code2flowdiagram or a feature request, please post it in the issues tab.
Raw data
{
"_id": null,
"home_page": "https://github.com/KeilanEvans/code2flowdiagram",
"name": "code2flowdiagram",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.6",
"maintainer_email": null,
"keywords": null,
"author": "Keilan Evans",
"author_email": null,
"download_url": "https://files.pythonhosted.org/packages/f6/67/18a897945739c69e47065fe1c6cc983a87f4e14455744b73ea761228d606/code2flowdiagram-1.0.2.tar.gz",
"platform": null,
"description": "<div style=\"padding: 20px; background: #333333; margin-bottom: 20px;\">\n\n\u2757 **Important Note:**\n\nAll credit of this code goes to the original creator which can be found at https://github.com/scottrogowski/code2flow\n\nI have made a small change which includes the Graphviz libraries in the package so as to not rely on having Graphviz installed.\n\nThe version of Graphviz is the latest at the time of this commit. The files downloaded can be found at https://graphviz.org/download/\n\nThe downloaded files are stored in the code2flowdiagram/graphviz folder.\n\nIn order to publish the package on PyPi I have renamed the package to code2flowdiagram.\n\n</div>\n\n![Version 2.5.1](https://img.shields.io/badge/version-2.5.1-brightgreen) ![Build passing](https://img.shields.io/badge/build-passing-brightgreen) ![Coverage 100%](https://img.shields.io/badge/coverage-100%25-brightgreen) ![License MIT](https://img.shields.io/badge/license-MIT-green])\n\ncode2flowdiagram generates [call graphs](https://en.wikipedia.org/wiki/Call_graph) for dynamic programming language. code2flowdiagram supports Python, JavaScript, Ruby, and PHP.\n\nThe basic algorithm is simple:\n\n1. Translate your source files into ASTs.\n1. Find all function definitions.\n1. Determine where those functions are called.\n1. Connect the dots.\n\ncode2flowdiagram is useful for:\n\n- Untangling spaghetti code.\n- Identifying orphaned functions.\n- Getting new developers up to speed.\n\ncode2flowdiagram provides a _pretty good estimate_ of your project's structure. No algorithm can generate a perfect call graph for a [dynamic language](https://en.wikipedia.org/wiki/Dynamic_programming_language) \u2013 even less so if that language is [duck-typed](https://en.wikipedia.org/wiki/Duck_typing). See the known limitations in the section below.\n\n_(Below: code2flowdiagram running against a subset of itself `code2flowdiagram code2flowdiagram/engine.py code2flowdiagram/python.py --target-function=code2flowdiagram --downstream-depth=3`)_\n\n## Installation\n\n```bash\npip3 install code2flowdiagram\n```\n\nIf you don't have it already, you will also need to install graphviz. Installation instructions can be found [here](https://graphviz.org/download/).\n\nAdditionally, depending on the language you want to parse, you may need to install additional dependencies:\n\n- JavaScript: [Acorn](https://www.npmjs.com/package/acorn)\n- Ruby: [Parser](https://github.com/whitequark/parser)\n- PHP: [PHP-Parser](https://github.com/nikic/PHP-Parser)\n- Python: No extra dependencies needed\n\n## Usage\n\nTo generate a DOT file, run something like:\n\n```bash\ncode2flowdiagram mypythonfile.py\n```\n\nOr, for Javascript:\n\n```bash\ncode2flowdiagram myjavascriptfile.js\n```\n\nYou can specify multiple files or import directories:\n\n```bash\ncode2flowdiagram project/directory/source_a.js project/directory/source_b.js\n```\n\n```bash\ncode2flowdiagram project/directory/*.js\n```\n\n```bash\ncode2flowdiagram project/directory --language js\n```\n\nTo pull out a subset of the graph, try something like:\n\n```bash\ncode2flowdiagram mypythonfile.py --target-function my_func --upstream-depth=1 --downstream-depth=1\n```\n\nThere are a ton of command line options, to see them all, run:\n\n```bash\ncode2flowdiagram --help\n```\n\n## How code2flowdiagram works\n\ncode2flowdiagram approximates the structure of projects in dynamic languages. It is _not possible_ to generate a perfect callgraph for a dynamic language.\n\nDetailed algorithm:\n\n1. Generate an AST of the source code\n2. Recursively separate groups and nodes. Groups are files, modules, or classes. More precisely, groups are namespaces where functions live. Nodes are the functions themselves.\n3. For all nodes, identify function calls in those nodes.\n4. For all nodes, identify in-scope variables. Attempt to connect those variables to specific nodes and groups. This is where there is some ambiguity in the algorithm because it is impossible to know the types of variables in dynamic languages. So, instead, heuristics must be used.\n5. For all calls in all nodes, attempt to find a match from the in-scope variables. This will be an edge.\n6. If a definitive match from in-scope variables cannot be found, attempt to find a single match from all other groups and nodes.\n7. Trim orphaned nodes and groups.\n8. Output results.\n\n## Why is it impossible to generate a perfect call graph?\n\nConsider this toy example in Python\n\n```python\ndef func_factory(param):\n if param < .5:\n return func_a\n else:\n return func_b\n\nfunc = func_factory(important_variable)\nfunc()\n```\n\nWe have no way of knowing whether `func` will point to `func_a` or `func_b` until runtime. In practice, ambiguity like this is common and is present in most non-trivial applications.\n\n## Known limitations\n\ncode2flowdiagram is internally powered by ASTs. Most limitations stem from a token not being named what code2flowdiagram expects it to be named.\n\n- All functions without definitions are skipped. This most often happens when a file is not included.\n- Functions with identical names in different namespaces are (loudly) skipped. E.g. If you have two classes with identically named methods, code2flowdiagram cannot distinguish between these and skips them.\n- Imported functions from outside your project directory (including from standard libraries) which share names with your defined functions may not be handled correctly. Instead, when you call the imported function, code2flowdiagram will link to your local functions. For example, if you have a function `search()` and call, `import searcher; searcher.search()`, code2flowdiagram may link (incorrectly) to your defined function.\n- Anonymous or generated functions are skipped. This includes lambdas and factories.\n- If a function is renamed, either explicitly or by being passed around as a parameter, it will be skipped.\n\n## As an imported library\n\nYou can work with code2flowdiagram as an imported Python library in much the same way as you work with it\nfrom the CLI.\n\n```python\nimport code2flowdiagram\ncode2flowdiagram.code2flowdiagram(['path/to/filea', 'path/to/fileb'], 'path/to/outputfile')\n```\n\nThe keyword arguments to `code2flowdiagram.code2flowdiagram` are roughly the same as the CLI\nparameters. To see all available parameters, refer to the code2flowdiagram function in [engine.py](https://github.com/scottrogowski/code2flowdiagram/blob/master/code2flowdiagram/engine.py).\n\n## How to contribute\n\n1. **Open an issue**: code2flowdiagram is not perfect and there is a lot that can be improved. If you find a problem parsing your source that you can identify with a simplified example, please open an issue.\n2. **Create a PR**: Even better, if you have a fix for the issue you identified that passes unit tests, please open a PR.\n3. **Add a language**: While dense, each language implementation is between 250-400 lines of code including comments. If you want to implement another language, the existing implementations can be your guide.\n\n## Unit tests\n\nTest coverage is 100%. To run:\n\n```bash\n pip install -r requirements_dev.txt\n make test\n```\n\n## License\n\ncode2flowdiagram is licensed under the MIT license.\nPrior to the rewrite in April 2021, code2flowdiagram was licensed under LGPL. The last commit under that license was 24b2cb854c6a872ba6e17409fbddb6659bf64d4c.\nThe April 2021 rewrite was substantial, so it's probably reasonable to treat code2flowdiagram as completely MIT-licensed.\n\n## Feedback / Issues / Contact\n\nIf you have an issue using code2flowdiagram or a feature request, please post it in the issues tab.\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Visualize your source code as DOT flowcharts",
"version": "1.0.2",
"project_urls": {
"Download": "https://github.com/KeilanEvans/code2flowdiagram/releases",
"Homepage": "https://github.com/KeilanEvans/code2flowdiagram"
},
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "4b03bcfc4a607b1b929cf3b78c02abed76fcc240facc837d917485bcb695f64a",
"md5": "e949896202e1fda1b622d3e8dd89064e",
"sha256": "ea4c97650e1f488dd68fbf34608a4c269d8a2c58ac85ca50a826000b5cd95ee8"
},
"downloads": -1,
"filename": "code2flowdiagram-1.0.2-py3-none-any.whl",
"has_sig": false,
"md5_digest": "e949896202e1fda1b622d3e8dd89064e",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.6",
"size": 9460791,
"upload_time": "2024-10-31T08:20:09",
"upload_time_iso_8601": "2024-10-31T08:20:09.546839Z",
"url": "https://files.pythonhosted.org/packages/4b/03/bcfc4a607b1b929cf3b78c02abed76fcc240facc837d917485bcb695f64a/code2flowdiagram-1.0.2-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "f66718a897945739c69e47065fe1c6cc983a87f4e14455744b73ea761228d606",
"md5": "207fb0e9a32b9e22131ef72a87a12bcc",
"sha256": "1789c47e0a1226f12d199f9562814dbd273dd0bb337b99f060b66a47bfbff7e8"
},
"downloads": -1,
"filename": "code2flowdiagram-1.0.2.tar.gz",
"has_sig": false,
"md5_digest": "207fb0e9a32b9e22131ef72a87a12bcc",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.6",
"size": 9373301,
"upload_time": "2024-10-31T08:20:12",
"upload_time_iso_8601": "2024-10-31T08:20:12.374183Z",
"url": "https://files.pythonhosted.org/packages/f6/67/18a897945739c69e47065fe1c6cc983a87f4e14455744b73ea761228d606/code2flowdiagram-1.0.2.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-10-31 08:20:12",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "KeilanEvans",
"github_project": "code2flowdiagram",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "code2flowdiagram"
}