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

Multi-line rules #29

Closed
langston-barrett opened this issue Jul 28, 2020 · 2 comments
Closed

Multi-line rules #29

langston-barrett opened this issue Jul 28, 2020 · 2 comments

Comments

@langston-barrett
Copy link

Bellybutton doesn't like this:

  filter_by:
    description: Use SQLAlchemy's filter_by for concision
    # Find calls to "filter" that:
    # 
    # - are chained after a call to "query" with one argument,
    # - have one argument,
    # - which is an equality comparison
    #   * which has a LHS which is an attribute access on a name
    expr: >
      //Call[ ./func/Attribute[ @attr='filter'
                                and ./value/Call[./func/Attribute[@attr='query']
                                and ./args[count(child::*) = 1]]
                              ]
             and ./args[count(child::*) = 1]
             and ./args/Compare[ ./ops/Eq
                                 and ./left/Attribute[ @attr != 'attributes'
                                                       and ./value/Name
                                                     ]
                               ]
            ]
    example: |
      session.query(Model).filter(Model.attr == baz)
    instead: |
      session.query(Model).filter_by(attr = baz)
    settings: *all_files

it says:

ERROR: /x/frontend/.bellybutton.yml, rule `filter_by`: 'str' object has no attribute 'match'

It works fine if you inline expr, but this is a pain because expr is huge:

    expr: //Call[./func/Attribute[ @attr='filter' and ./value/Call[./func/Attribute[@attr='query'] and ./args[count(child::*) = 1]]] and ./args[count(child::*) = 1] and ./args/Compare[ ./ops/Eq and ./left/Attribute[ @attr != 'attributes' and ./value/Name]]]

This is version 0.3.0.

@hchasestevens
Copy link
Owner

Hi @langston-barrett ,

Thanks for raising! bellybutton relies on the first characters of the expr being //, to know to parse the value as an XPath expression. I will not close this ticket, since you (rightly) point out the annoyance of not being able to use the standard YAML multi-line syntax, however, I think you should be able to instead do:

  filter_by:
    description: Use SQLAlchemy's filter_by for concision
    expr:
      //Call[ ./func/Attribute[ @attr='filter'
                                and ./value/Call[./func/Attribute[@attr='query']
                                and ./args[count(child::*) = 1]]
                              ]
             and ./args[count(child::*) = 1]
             and ./args/Compare[ ./ops/Eq
                                 and ./left/Attribute[ @attr != 'attributes'
                                                       and ./value/Name
                                                     ]
                               ]
            ]
    example: |
      session.query(Model).filter(Model.attr == baz)
    instead: |
      session.query(Model).filter_by(attr = baz)
    settings: *all_files

and have it work (or, at least, this is how I typically format my .bellybutton.yml files). Please let me know if this helps!

  • Chase

@langston-barrett
Copy link
Author

@hchasestevens Thanks for the quick reply! That works perfectly. Feel free to keep open if you feel like supporting YAML multi-line string syntax, but I'm satisfied as long as I can write the rules readably.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants