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

Generate JSON output #194

Open
wants to merge 31 commits into
base: master
Choose a base branch
from
Open

Conversation

devdanzin
Copy link
Collaborator

@devdanzin devdanzin commented Jul 9, 2023

This proof of concept adds a --json option to diff, index, rank and report, allowing to generate output in JSON format.

Example output (excerpt from wily report -n 11 --json src\wily\commands\report.py):

[
 {
    "Revision": "f1e8225",
    "Author": "Anthony Shaw",
    "Date": "2023-03-12",
    "Cyclomatic Complexity": "24 (0)",
    "Unique Operands": "8 (0)",
    "Maintainability Index": "56.8982 (0.0)",
    "Lines of Code": "206 (0)"
  },
  {
    "Revision": "e9921dd",
    "Author": "Christian Clauss",
    "Date": "2023-03-11",
    "Cyclomatic Complexity": "24 (0)",
    "Unique Operands": "8 (0)",
    "Maintainability Index": "56.8982 (0)",
    "Lines of Code": "206 (0)"
  }
]

Pasting this here I just realized it might be a good idea to add file name to each JSON entry. Oh well, back to the drawing board.

Still needs tests and docstring updates.

Fixes part of #92.

@devdanzin
Copy link
Collaborator Author

The CI failures could be fixed by extracting a function from the kinda duplicated code that prints the table or JSON, something like below:

def print_result(as_json, console_format, data, headers, path):
    if as_json:
        json_data = [{headers[x]: d[x] for x in range(len(headers))} for d in data]
        for entry in json_data:
            entry["Filename"] = path
        print(json.dumps(json_data, indent=2))
    else:
        print(
            tabulate.tabulate(
                headers=headers, tabular_data=data, tablefmt=console_format
            )
        )

However, it's not clear to me where such a function should live. Maybe in a new module in wily.helper?

@codecov-commenter
Copy link

codecov-commenter commented Jul 9, 2023

Codecov Report

Attention: 2 lines in your changes are missing coverage. Please review.

Comparison is base (2590691) 95.86% compared to head (74d2813) 95.83%.

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #194      +/-   ##
==========================================
- Coverage   95.86%   95.83%   -0.03%     
==========================================
  Files          25       26       +1     
  Lines        1403     1442      +39     
  Branches      296      315      +19     
==========================================
+ Hits         1345     1382      +37     
- Misses         33       34       +1     
- Partials       25       26       +1     
Files Coverage Δ
src/wily/__main__.py 94.92% <100.00%> (+0.10%) ⬆️
src/wily/commands/index.py 100.00% <100.00%> (ø)
src/wily/commands/rank.py 96.82% <100.00%> (+0.15%) ⬆️
src/wily/commands/report.py 97.45% <100.00%> (+0.20%) ⬆️
src/wily/helper/output.py 100.00% <100.00%> (ø)
src/wily/commands/diff.py 88.77% <88.88%> (-0.76%) ⬇️

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@sorasful
Copy link

This feature could be really useful, do you need help on something ?

@devdanzin
Copy link
Collaborator Author

Yes, thank you, I'd love to get some validation on the chosen output format/entries. I'll update this PR this week and show what the output currently looks like.

@devdanzin devdanzin changed the title WIP: generate JSON output Generate JSON output Oct 29, 2023
@devdanzin
Copy link
Collaborator Author

I've updated the PR and added some tests. I'm open to all suggestions: if you see ways to improve the output or the code, please let me know.

Here's some sample output for report:

[
  {
    "Revision": "d0ad384",
    "Message": "Add some more typing (#221)\n\n* Update typing info ",
    "Author": "devdanzin",
    "Date": "2023-09-22",
    "Cyclomatic Complexity": "23 (0)",
    "Unique Operands": "6 (0)",
    "Maintainability Index": "62.7366 (-0.30257)",
    "Lines of Code": "176 (1)",
    "Filename": "src\\wily\\commands\\graph.py"
  },
  {
    "Revision": "bdc825f",
    "Message": "Standalone plotly.min.js for graph (fix #189) (#20",
    "Author": "devdanzin",
    "Date": "2023-09-22",
    "Cyclomatic Complexity": "23 (0)",
    "Unique Operands": "6 (0)",
    "Maintainability Index": "63.0391 (0.624665)",
    "Lines of Code": "175 (3)",
    "Filename": "src\\wily\\commands\\graph.py"
  },
  {
    "Revision": "6f5cd5d",
    "Message": "Restore displaying graph markers. (#215)\n\n",
    "Author": "devdanzin",
    "Date": "2023-09-04",
    "Cyclomatic Complexity": "23 (0)",
    "Unique Operands": "6 (0)",
    "Maintainability Index": "62.4145 (0.0997117)",
    "Lines of Code": "172 (0)",
    "Filename": "src\\wily\\commands\\graph.py"
  },
  {
    "Revision": "07fc855",
    "Message": "Allow passing multiple file names to graph, to get",
    "Author": "devdanzin",
    "Date": "2023-08-25",
    "Cyclomatic Complexity": "23 (3)",
    "Unique Operands": "6 (1)",
    "Maintainability Index": "62.3148 (-2.57913)",
    "Lines of Code": "172 (15)",
    "Filename": "src\\wily\\commands\\graph.py"
  }
]

Here's sample output for report, diff, rank and index (only the JSON goes to stdout):

Output for wily report --json
wily report src\wily\commands\graph.py -c -m --json
Using default metrics ['raw.loc', 'maintainability.mi', 'halstead.h1', 'cyclomatic.complexity']
-----------History for ['cyclomatic.complexity', 'halstead.h1', 'maintainability.mi', 'raw.loc']------------
[
  {
    "Revision": "d0ad384",
    "Message": "Add some more typing (#221)\n\n* Update typing info ",
    "Author": "devdanzin",
    "Date": "2023-09-22",
    "Cyclomatic Complexity": "23 (0)",
    "Unique Operands": "6 (0)",
    "Maintainability Index": "62.7366 (-0.30257)",
    "Lines of Code": "176 (1)",
    "Filename": "src\\wily\\commands\\graph.py"
  },
  {
    "Revision": "bdc825f",
    "Message": "Standalone plotly.min.js for graph (fix #189) (#20",
    "Author": "devdanzin",
    "Date": "2023-09-22",
    "Cyclomatic Complexity": "23 (0)",
    "Unique Operands": "6 (0)",
    "Maintainability Index": "63.0391 (0.624665)",
    "Lines of Code": "175 (3)",
    "Filename": "src\\wily\\commands\\graph.py"
  },
  {
    "Revision": "6f5cd5d",
    "Message": "Restore displaying graph markers. (#215)\n\n",
    "Author": "devdanzin",
    "Date": "2023-09-04",
    "Cyclomatic Complexity": "23 (0)",
    "Unique Operands": "6 (0)",
    "Maintainability Index": "62.4145 (0.0997117)",
    "Lines of Code": "172 (0)",
    "Filename": "src\\wily\\commands\\graph.py"
  },
  {
    "Revision": "07fc855",
    "Message": "Allow passing multiple file names to graph, to get",
    "Author": "devdanzin",
    "Date": "2023-08-25",
    "Cyclomatic Complexity": "23 (3)",
    "Unique Operands": "6 (1)",
    "Maintainability Index": "62.3148 (-2.57913)",
    "Lines of Code": "172 (15)",
    "Filename": "src\\wily\\commands\\graph.py"
  }
]
Output of wily diff --json
wily diff src\wily\commands\report.py -r bdc825f --json
Using default metrics ['raw.loc', 'maintainability.mi', 'halstead.h1', 'cyclomatic.complexity']
Comparing current with bdc825f by devdanzin on 2023-09-22.
[
  {
    "File": "src\\wily\\commands\\report.py",
    "Lines of Code": "216 -> 222",
    "Maintainability Index": "52.2582 -> 51.1045",
    "Unique Operands": "10 -> 10",
    "Cyclomatic Complexity": "27 -> 29"
  },
  {
    "File": "src\\wily\\commands\\report.py:report",
    "Lines of Code": "-",
    "Maintainability Index": "-",
    "Unique Operands": "10 -> 10",
    "Cyclomatic Complexity": "27 -> 29"
  },
  {
    "File": "src\\wily\\commands\\report.py:report",
    "Lines of Code": "-",
    "Maintainability Index": "-",
    "Unique Operands": "10 -> 10",
    "Cyclomatic Complexity": "27 -> 29"
  }
]
Output for wily rank --json
wily rank --json
-----------Rank for Maintainability Index for f57006e by devdanzin on 2023-10-28.------------
[
  {
    "File": "test\\unit\\test_report_unit.py",
    "Maintainability Index": 32.32190502991561
  },
  {
    "File": "src\\wily\\__main__.py",
    "Maintainability Index": 34.30472174464306
  },
[...]
  {
    "File": "test",
    "Maintainability Index": 53.8019265092112
  },
  {
    "File": "src\\wily\\commands\\diff.py",
    "Maintainability Index": 54.453194689759016
  },
  {
    "File": "test\\unit\\test_cache.py",
    "Maintainability Index": 56.010024060239985
  },
  {
    "File": "test\\integration\\test_archiver.py",
    "Maintainability Index": 56.92174441952554
  },
  {
    "File": "test\\integration",
    "Maintainability Index": 58.06125906375679
  },
  {
    "File": "test\\unit\\test_operators.py",
    "Maintainability Index": 58.341013499953924
  },
  {
    "File": "src\\wily\\operators\\__init__.py",
    "Maintainability Index": 58.88435086943125
  },
  {
    "File": "test\\integration\\test_all_operators.py",
    "Maintainability Index": 60.037337074043776
  },
  {
    "File": "src\\wily\\commands\\build.py",
    "Maintainability Index": 61.21595278201455
  },
  {
    "File": "test\\unit\\test_list_metrics_unit.py",
    "Maintainability Index": 61.88150602294518
  },
  {
    "File": "src\\wily\\cache.py",
    "Maintainability Index": 62.37760644177526
  },
  {
    "File": "src\\wily\\commands\\graph.py",
    "Maintainability Index": 62.736559310518224
  },
  {
    "File": "src\\wily\\state.py",
    "Maintainability Index": 62.91391505052898
  },
  {
    "File": "src\\wily\\archivers\\git.py",
    "Maintainability Index": 64.88920153537751
  },
  {
    "File": "",
    "Maintainability Index": 66.68375918601492
  },
[...]
    "File": "docs",
    "Maintainability Index": 100.0
  },
  {
    "File": "docs\\source",
    "Maintainability Index": 100.0
  },
  {
    "File": "Total",
    "Maintainability Index": 68.52496920011775
  }
]
Output of wily index --json
wily index -m --json
--------Configuration---------
Path: ~\PycharmProjects\wily
Archiver: git
Operators: {'cyclomatic', 'raw', 'maintainability', 'halstead'}

-----------History------------
[
{
"Revision": "f57006e",
"Author": "devdanzin",
"Message": "Increase ruff max branches, statements and complex",
"Date": "2023-10-28"
},
[...]
{
"Revision": "be1fb28",
"Author": "devdanzin",
"Message": "Add as_json to command docstrings, fix docstring p",
"Date": "2023-10-27"
},
{
"Revision": "3ef2985",
"Author": "devdanzin",
"Message": "Make as_json in rank() a keyword argument defaulti",
"Date": "2023-10-27"
},
{
"Revision": "8f17212",
"Author": "devdanzin",
"Message": "Merge master.\n",
"Date": "2023-10-27"
},
{
"Revision": "e4fdec9",
"Author": "devdanzin",
"Message": "Change print_result() into print_json(), restore p",
"Date": "2023-10-27"
},
{
"Revision": "2590691",
"Author": "Anthony Shaw",
"Message": "update gitignore\n",
"Date": "2023-10-11"
},
{
"Revision": "4ac2334",
"Author": "Anthony Shaw",
"Message": "Merge branch 'master' of github.com:tonybaloney/wi",
"Date": "2023-10-11"
},
{
"Revision": "ee7014a",
"Author": "Anthony Shaw",
"Message": "Update version data\n",
"Date": "2023-10-11"
},
{
"Revision": "a79b62e",
"Author": "Anthony Shaw",
"Message": "Test support for Python 3.12 (#224)\n\n* Test suppor",
"Date": "2023-10-11"
},
{
"Revision": "4663329",
"Author": "devdanzin",
"Message": "Fix typing of tests and make pyright check them on",
"Date": "2023-09-25"
},
[...]
{
"Revision": "8eb4416",
"Author": "Anthony Shaw",
"Message": "Annotate core functions and remove sphinx style ar",
"Date": "2023-08-03"
}
]

@devdanzin devdanzin added enhancement New feature or request help wanted Extra attention is needed labels Oct 29, 2023
src/wily/helper/output.py Outdated Show resolved Hide resolved
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants