Created a new script for generating scaffolding for new extensions.

Review Request #2822 — Created Jan. 23, 2012 and discarded

ammok
RBTools
rbtools, reviewboard
Created a new script for generating scaffolding for new extensions.
I added some unit tests for naming convention testing and conversion, but otherwise all testing has been manual on Linux 3.1.8-1.
I have tried creating new extensions with each option, and installing the egg using easy_install name develop on a local environment.
Description From Last Updated

The convention is to have imports in alphabetical order.

ME medanat

this could be: return response[0].lower() == 'y'

ME medanat

This could be: return bool(re.match(self.REGEX, string))

ME medanat

You can use the bool() function here again.

ME medanat

This could be: return re.match(r'^[a-z]', string) != None

ME medanat

This may not be very readable. Consider breaking it into multiple lines.

ME medanat

This could be: if string: Since None and the empty string have the same boolean value of False in Python.

ME medanat

This could be: (I'm not 100% sure on this one) if not options.description:

ME medanat

Leave a space between imports and code body.

ME medanat

Again, if dashboard_link Also, why are you prefixing the tags with hyphens?

ME medanat

Again, if dashboard_link

ME medanat

This would be: URLHook(extension, pattern)

ME medanat

Same init issue: Class(arg1, ...)

ME medanat

init issue again.

ME medanat

I'm not sure what's going on here with the template tags: {{'{%'}} Is there a reason you're doing it this ...

ME medanat

Place this in a trans block.

ME medanat

Place "To do..." in trans block.

ME medanat

These could be on the same line. Also, it seems that there's an extra single space before "To do..." "To ...

ME medanat

Not sure if this applies in template pages, but this could be: {% if dashboard_link %}

ME medanat

Consider adding the an all caps case?

ME medanat

Isn't the comma at the end of this string a syntax error?

ME medanat

We'll want some documentation for this function, and the various classes / functions below.

mike_conleymike_conley

I wonder if it'd be clearer if the flow for the unrecognized input case was as follows: 1) Ask the ...

mike_conleymike_conley

Possibly place this variable within __init__

ME medanat

Same thing, place within __init__

ME medanat

Same thing, place within __init__

ME medanat

--dashboard-link is optional - we should mention that in its help information.

mike_conleymike_conley

Newlines above and below this for block.

mike_conleymike_conley

This template is missing from your patch.

mike_conleymike_conley

Nitpicking here: {%- if dashboard_link is not none%} Add a single space after none

ME medanat

All this could be wrapped within the same: {%- if dashboard_link is not none %} {%- endif %}

ME medanat

Wrap within same if statement.

ME medanat

jinja2 is a third-party module, and belongs in a group after the built-in Python modules.

chipx86chipx86

Same.

chipx86chipx86

Two blank lines here.

chipx86chipx86

No need for the parens around question.

chipx86chipx86

No need for the len() check, I don't think.

chipx86chipx86

Blank line between these.

chipx86chipx86

Classes should always at least inherit from 'object'): class NamingConvention(object):

chipx86chipx86

Should use re.compile().

chipx86chipx86

The regex should be pulled out into a compiled regex in the class.

chipx86chipx86

This can be one statement.

chipx86chipx86

Make this part of the class, and compile it.

chipx86chipx86

One statement.

chipx86chipx86

This can be simplified to: if string: string = ... elif case.formatted(string): return

chipx86chipx86

Blank line between these.

chipx86chipx86

Blank line between these.

chipx86chipx86

Blank line between these. Basically: Blank line before/after a block of code.

chipx86chipx86

Inherit from object.

chipx86chipx86

Should use the os.path stuff to parse the path.

chipx86chipx86

Use os.path.join instead.

chipx86chipx86

No need for parens when it's just one thing in the format arguments.

chipx86chipx86

Blank line.

chipx86chipx86

Use 'f', not 'FILE'. No uppercase unless it's a constant.

chipx86chipx86

Blank line.

chipx86chipx86

Blank line.

chipx86chipx86

Blank line.

chipx86chipx86

Two blank lines.

chipx86chipx86

Should use Django's url() stuff.

chipx86chipx86

Two blank lines.

chipx86chipx86

__init__ should take *args, **kwargs, and the super() should pass it. That allows us to expand down the road without ...

chipx86chipx86

The URLs should be indented only 4 spaces, and use the url() stuff. Also, two blank lines above this.

chipx86chipx86

Two blank lines.

chipx86chipx86

If we're not providing any sort of default arguments, no need for the {} param to RequestContext.

chipx86chipx86

Should only be indented 4 spaces.

chipx86chipx86

Two blank lines.

chipx86chipx86

Single quotes are fine.

chipx86chipx86

Either one line, or indent the value by 4 spaces.

chipx86chipx86
AM
ME
  1. Well done, that's a large chunk of code. Good hustle!
    
    I pointed out a number of issues (mostly style), be sure to verify each one and double check the correctness of the code afterwards. 
    
    I would also suggest running a PEP8 guide checker on your code:
    
    PEP8: http://www.python.org/dev/peps/pep-0008/
    PEP8 guide checker: http://pypi.python.org/pypi/pep8
    
    Thanks!
    
    -Yazan 
  2. rbtools/rb_extgen.py (Diff revision 2)
     
     
     
     
     
     
     
     
     
     
    The convention is to have imports in alphabetical order.
  3. rbtools/rb_extgen.py (Diff revision 2)
     
     
    this could be: 
    
    return response[0].lower() == 'y' 
  4. rbtools/rb_extgen.py (Diff revision 2)
     
     
    This could be:
    
    return bool(re.match(self.REGEX, string))
  5. rbtools/rb_extgen.py (Diff revision 2)
     
     
    I'm not a huge fan of this approach to looping.
    
    Maybe use an iterator here?
    
    iterator = (word.capitalize() for word in string.split(" "))
    
    and then get words using iterator.next()
    
    This is simply an opinion, and not a correctness issue.
    
    
  6. rbtools/rb_extgen.py (Diff revision 2)
     
     
    You can use the bool() function here again.
  7. rbtools/rb_extgen.py (Diff revision 2)
     
     
     
    This could be:
    
    return re.match(r'^[a-z]', string) != None
    1. Better yet, use the bool() function here again.
  8. rbtools/rb_extgen.py (Diff revision 2)
     
     
    This may not be very readable. Consider breaking it into multiple lines.
  9. rbtools/rb_extgen.py (Diff revision 2)
     
     
    This could be:
    
    if string:
    
    Since None and the empty string have the same boolean value of False in Python.
  10. rbtools/rb_extgen.py (Diff revision 2)
     
     
    This could be: (I'm not 100% sure on this one)
    
    if not options.description:
    1. You're right Yazan - this should be replaced with:
      
      if not options.description
  11. Leave a space between imports and code body.
  12. Again,
    
    if dashboard_link
    
    Also, why are you prefixing the tags with hyphens?
  13. Again, if dashboard_link
  14. This would be:
    
    URLHook(extension, pattern)
  15. Same init issue:
    
    Class(arg1, ...)
  16. init issue again.
  17. I'm not sure what's going on here with the template tags:
    
    {{'{%'}}
    
    Is there a reason you're doing it this way rather than {% statement %}?
  18. Place "To do..." in trans block.
  19. These could be on the same line.
    Also, it seems that there's an extra single space before "To do..."
    
    "To do..." can also be placed in a trans block.
  20. Not sure if this applies in template pages, but this could be:
    
    {% if dashboard_link %}
  21. rbtools/tests.py (Diff revision 2)
     
     
    Consider adding the an all caps case?
    1. Review review (so meta):
      
      Grammar: "Consider adding an all caps case?"
  22. setup.py (Diff revision 2)
     
     
    Isn't the comma at the end of this string a syntax error? 
    1. I saw this multiple times across your code. It is not a syntax error, but the last comma in dict/list data types is not required. I would suggest removing it.
    2. I'm actually fine with the trailing comma - and I've seen multiple places throughout the Review Board codebase where we use it.
      
      I think the idea is:  this is a list of items, and sometime down the line, we might add something to this list.  The most likely point of error injection is the fact that we'll forget the comma on the preceding line.  So this pre-empts it a little bit.
      
      Note that I don't believe we can do this in Javascript.  IE fails out when it finds a trailing comma with nothing after it.
  23. 
      
AM
AM
  1. 
      
  2. rbtools/rb_extgen.py (Diff revision 2)
     
     
    PEP 8 seems to recommend that we explicitly check to see if it "is None".
  3. It might be a bit unclear (should I add a '.template' suffix to these files?), but this uses Jinja. The dashes suppress whitespace.
  4. It seems the suggested idiom for calling a superconstructor is to use something like super(ExtensionURLHook, self).__init__(arg1) (it's also used a few times in the reviewboard code)
  5. Yes. This is because otherwise Jinja will interpret it as Jinja templating rather than raw text: http://jinja.pocoo.org/docs/templates/#escaping
  6. The indentation for plain text in the HTML templates seems to be either one space or 2 spaces.
  7. setup.py (Diff revision 2)
     
     
    The line above it already ended with a comma. It always looked like an error to me but I can see the sense in keeping it as it allows you to easily add and remove individual lines anywhere in the list without worrying about commas.
  8. 
      
AM
mike_conley
  1. Anthony:
    
    This is looking really good!  Just a few issues below.
    
    Thanks for your work,
    
    -Mike
  2. rbtools/rb_extgen.py (Diff revision 3)
     
     
    We'll want some documentation for this function, and the various classes / functions below.
  3. rbtools/rb_extgen.py (Diff revision 3)
     
     
    I wonder if it'd be clearer if the flow for the unrecognized input case was as follows:
    
    1) Ask the user the question
    2) User answers with something invalid
    3) Tell the user that their input was unrecognized
    4) Go to (1)
    
    This way, it's clearer what question the user is being asked to answer.
  4. rbtools/rb_extgen.py (Diff revision 3)
     
     
    --dashboard-link is optional - we should mention that in its help information.
  5. rbtools/rb_extgen.py (Diff revision 3)
     
     
     
    If I supply no arguments, I get:
    
    incorrect number of arguments
    Traceback (most recent call last):
      File "/usr/local/bin/rb_extgen", line 9, in <module>
        load_entry_point('RBTools==0.4alpha0.dev', 'console_scripts', 'rb_extgen')()
      File "/media/Projects/rbtools/rbtools/rb_extgen.py", line 157, in main
        parse_options()
      File "/media/Projects/rbtools/rbtools/rb_extgen.py", line 101, in parse_options
        options.extension_name = args[0]
    IndexError: list index out of range
    
    
    We should probably do something more helpful here, like display the help.
  6. rbtools/rb_extgen.py (Diff revision 3)
     
     
     
     
    Newlines above and below this for block.
  7. rbtools/rb_extgen.py (Diff revision 3)
     
     
     
    This template is missing from your patch.
  8. rbtools/tests.py (Diff revision 3)
     
     
    Nice tests!
  9. 
      
ME
  1. Looking good! As Mike has noted, some documentation/comments would go a long way.
    
    Good job!
  2. rbtools/rb_extgen.py (Diff revision 3)
     
     
    Possibly place this variable within __init__
    1. This variable feels like it would make more sense as a class variable, however I've rolled the other two into __init__.
  3. rbtools/rb_extgen.py (Diff revision 3)
     
     
    Same thing, place within __init__
  4. rbtools/rb_extgen.py (Diff revision 3)
     
     
    Same thing, place within __init__
  5. Nitpicking here:
    
    {%- if dashboard_link is not none%}
    
    Add a single space after none
  6. rbtools/templates/extensions/extension/extension.py (Diff revision 3)
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    All this could be wrapped within the same:
    
    {%- if dashboard_link is not none %}
    
    {%- endif %}
    1. I originally did this because I wanted to keep them separate as there could be other options that would need to expose the URL hook.
      However, it would make sense to split them up as the use case comes up.
  7. rbtools/templates/extensions/extension/extension.py (Diff revision 3)
     
     
     
     
     
     
     
    Wrap within same if statement.
  8. 
      
AM
chipx86
  1. This doesn't belong in RBTools. RBTools is meant to be used to talk to a Review Board server, but not for developing. This might be better suited as something in reviewboard/contrib/. We could probably build a package out of it later, or move it out to its own module.
    1. Should I open up a new review request, or am I able to submit a revision that spans multiple repositories?
  2. 
      
chipx86
  1. A bit of stuff here. Mostly style-related, which you'll get the hang of. Also some pythonisms.
  2. rbtools/rb_extgen.py (Diff revision 4)
     
     
    jinja2 is a third-party module, and belongs in a group after the built-in Python modules.
  3. rbtools/rb_extgen.py (Diff revision 4)
     
     
  4. rbtools/rb_extgen.py (Diff revision 4)
     
     
     
     
    Two blank lines here.
  5. rbtools/rb_extgen.py (Diff revision 4)
     
     
    No need for the parens around question.
  6. rbtools/rb_extgen.py (Diff revision 4)
     
     
    No need for the len() check, I don't think.
  7. rbtools/rb_extgen.py (Diff revision 4)
     
     
     
    Blank line between these.
  8. rbtools/rb_extgen.py (Diff revision 4)
     
     
    Classes should always at least inherit from 'object'):
    
    class NamingConvention(object):
  9. rbtools/rb_extgen.py (Diff revision 4)
     
     
    Should use re.compile().
  10. rbtools/rb_extgen.py (Diff revision 4)
     
     
    The regex should be pulled out into a compiled regex in the class.
  11. rbtools/rb_extgen.py (Diff revision 4)
     
     
     
    This can be one statement.
  12. rbtools/rb_extgen.py (Diff revision 4)
     
     
    Make this part of the class, and compile it.
  13. rbtools/rb_extgen.py (Diff revision 4)
     
     
     
    One statement.
  14. rbtools/rb_extgen.py (Diff revision 4)
     
     
     
     
     
    This can be simplified to:
    
    if string:
        string = ...
    elif case.formatted(string):
        return
  15. rbtools/rb_extgen.py (Diff revision 4)
     
     
     
    Blank line between these.
  16. rbtools/rb_extgen.py (Diff revision 4)
     
     
     
    Blank line between these.
  17. rbtools/rb_extgen.py (Diff revision 4)
     
     
     
    Blank line between these.
    
    Basically: Blank line before/after a block of code.
  18. rbtools/rb_extgen.py (Diff revision 4)
     
     
    Inherit from object.
  19. rbtools/rb_extgen.py (Diff revision 4)
     
     
    Should use the os.path stuff to parse the path.
  20. rbtools/rb_extgen.py (Diff revision 4)
     
     
    Use os.path.join instead.
  21. rbtools/rb_extgen.py (Diff revision 4)
     
     
    No need for parens when it's just one thing in the format arguments.
  22. rbtools/rb_extgen.py (Diff revision 4)
     
     
     
    Blank line.
  23. rbtools/rb_extgen.py (Diff revision 4)
     
     
    Use 'f', not 'FILE'. No uppercase unless it's a constant.
  24. rbtools/rb_extgen.py (Diff revision 4)
     
     
     
    Blank line.
  25. rbtools/rb_extgen.py (Diff revision 4)
     
     
     
    Blank line.
  26. rbtools/rb_extgen.py (Diff revision 4)
     
     
     
    Blank line.
  27. Two blank lines.
  28. Should use Django's url() stuff.
  29. Two blank lines.
  30. __init__ should take *args, **kwargs, and the super() should pass it. That allows us to expand down the road without breaking things.
  31. rbtools/templates/extensions/extension/urls.py (Diff revision 4)
     
     
     
     
    The URLs should be indented only 4 spaces, and use the url() stuff.
    
    Also, two blank lines above this.
  32. rbtools/templates/extensions/extension/views.py (Diff revision 4)
     
     
     
     
     
    Two blank lines.
  33. If we're not providing any sort of default arguments, no need for the {} param to RequestContext.
  34. Should only be indented 4 spaces.
  35. rbtools/templates/extensions/setup.py (Diff revision 4)
     
     
     
     
    Two blank lines.
  36. rbtools/templates/extensions/setup.py (Diff revision 4)
     
     
    Single quotes are fine.
  37. rbtools/templates/extensions/setup.py (Diff revision 4)
     
     
     
    Either one line, or indent the value by 4 spaces.
  38. 
      
AM
Review request changed

Status: Discarded

Change Summary:

The patch for this review request was moved to another repository - see http://reviews.reviewboard.org/r/2830/
Loading...