tophat / codewatch

[deprecated] Monitor and manage deeply customizable metrics about your python code using ASTs
https://codewatch.io
Apache License 2.0
38 stars 3 forks source link

add proof of concept #1

Closed lime-green closed 5 years ago

lime-green commented 5 years ago

TODO:

Proof of concept code, this should help form the beginning of this project

The usage is as such:

codewatch codewatch_config_module

The codewatch_config_module should contain the following two methods:

# visit all directories
def directory_filter(_dir_name):
    return True

# visit all files
def file_filter(file_name):
    return True

Tune these filters to suit your needs.

Then, you should add visitor classes that subclass from codewatch.NodeVisitor. It follows the same API as ast.NodeVisitor:

from codewatch import NodeVisitor

class CountImportsVisitor(NodeVisitor):
    def _count_import(self):
        self.stats.increment('total_imports_num')

    def visit_Import(self, node):
        self._count_import()

    def visit_ImportFrom(self, node):
        self._count_import()

This will build a stats dictionary that contains something like the following:

{
    'total_imports_num': 763
}

Then, once again in the codewatch_config_module you can add assertions against this stat dictionary. The class should inherit from codewatch.Assertion:

from codewatch import Assertion

class CountImportsAssertion(Assertion):
    def assert_number_of_imports_not_too_high(self):
        threshold = 700
        newStat = self.stats.get('total_imports_num')
        err = 'There were {} total imports detected which exceeds threshold of {}'.format(newStat, threshold)
        return newStat <= threshold, err

In this case, the assertion would fail since 763 is the newStat and the message:

There were 763 total imports detected which exceeds threshold of 700

would be printed

cabiad commented 5 years ago

I snagged this description and used it as our initial README.md! :)

francoiscampbell commented 5 years ago

just a random comment: what about exploring a redux-style reducer approach for stats, where a visitor would receive the node and the top-level stats tree as arguments and return a new stats object?

codecov[bot] commented 5 years ago

Codecov Report

Merging #1 into master will decrease coverage by 0.48%. The diff coverage is 99.51%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master       #1      +/-   ##
==========================================
- Coverage     100%   99.51%   -0.49%     
==========================================
  Files           1        7       +6     
  Lines           3      206     +203     
  Branches        0       26      +26     
==========================================
+ Hits            3      205     +202     
- Misses          0        1       +1
Flag Coverage Δ
#py27 99.51% <99.51%> (-0.49%) :arrow_down:
#py36 99.51% <99.51%> (-0.49%) :arrow_down:
Impacted Files Coverage Δ
codewatch/__init__.py 100% <100%> (ø) :arrow_up:
codewatch/stats.py 100% <100%> (ø)
codewatch/assertion.py 100% <100%> (ø)
codewatch/loader.py 100% <100%> (ø)
codewatch/run.py 100% <100%> (ø)
codewatch/file_walker.py 100% <100%> (ø)
codewatch/node_visitor.py 96.87% <96.87%> (ø)
... and 3 more

Continue to review full report at Codecov.

Legend - Click here to learn more Δ = absolute <relative> (impact), ø = not affected, ? = missing data Powered by Codecov. Last update 0a41753...a37715d. Read the comment docs.

lime-green commented 5 years ago

just a random comment: what about exploring a redux-style reducer approach for stats, where a visitor would receive the node and the top-level stats tree as arguments and return a new stats object?

@francoiscampbell yeah I like the redux idea. Although this breaks the ast.NodeVisitor api compatibility. I'm not sure how much we desire this compatibility as a feature though

cabiad commented 5 years ago

@francoiscampbell

just a random comment: what about exploring a redux-style reducer approach for stats, where a visitor would receive the node and the top-level stats tree as arguments and return a new stats object?

Filed as #10