Adding JSLint to ReviewBot
Review Request #3435 — Created Oct. 21, 2012 and discarded
Information | |
---|---|
Allyshia | |
ReviewBot | |
Reviewers | |
reviewbot | |
Implementation of the JSLint tool for ReviewBot. Parses all uploaded files to a review request and outputs descriptive comments on the relevant .js source files on lines where style errors are found. Options for this tool can be configured in the tool's admin panel. This addition to ReviewBot requires that SpiderMonkey be installed (other engines might also be suitable but have not been tested) to enable the running of the jslint.js linting tool.
manual testing: - tested jslint on the spidermonkey commandline to make sure that the script itself was working as expected locally. - tested what error output the jslint.com website provides for a given file and tested ReviewBot on local dev server tool by posting a review with same file and ensuring output is the same with the same options ticked (seeing that file with errors was being commented by ReviewBot). - started by importing all of the dependencies used by the jslint.com website and removed all which were not necessary to the standalone jslint tool, testing that it yielded the same results. Those other dependencies were only necessary for web purposes, even if Doug Crockford suggests they be bundled with jslint itself and minified. - tested changing options in the option panel, and making sure they affect the output of the static analysis tool in locally published reviews. Included print statements in py and js scripts to make sure the correct options were being passed into jslint.
Description | From | Last Updated |
---|---|---|
This should probably be renamed. JSLint is more than a style checker. |
SM smacleod | |
This should probably be adjusted like 'name'. It might be a good idea to include the version number of JSLint … |
SM smacleod | |
This should probably be changed to be case insensitive. I've seen some use '.JS' I really would like to add … |
SM smacleod | |
This appears to still be just copied from the pep8 tool, but you'll need to change this parsing code to … |
SM smacleod | |
let's put these in alphabetical order. |
SM smacleod | |
As Aamir pointed out, 'import os' should be coming first. Imports should be ordered like this: Standard Library imports (e.g. … |
SM smacleod | |
If this is enabled, I think you should definitely indicate in the review body_top, or body_bottom that the scan was … |
SM smacleod | |
This should probably be done only once per request, instead of every time handle_file is called (Once per file). You'll … |
SM smacleod | |
I don't think this is quite correct. The package key should probably be 'reviewbot', or 'reviewbot.tools'. I'm fine with lib … |
SM smacleod | |
Let's rename jsLint.py to jslint.py. So, this should be changed to 'jslint = reviewbot.tools.jslint:JSLintTool', |
SM smacleod | |
I believe, generally, we prefer the higher level imports to go above the more granular ones, so line 3 and … |
|
|
Evil? Or Eval? Or Evil-Eval? Not sure if this is being cheeky, or just a typo. :) |
|
|
Isn't 80 the traditional character limit? Or is something here 0-indexed? Or have I just been lied to all my … |
|
|
PACKAGE_ROOT is in all caps, and lib_path is not. Why? |
|
|
Can you not simply pass the actual True and False literals to the script? Will the JS engine accept something … |
|
|
Might not be necessary to sent the lowercase form of the strings. runJSLint is checking the content of the string … |
AL Allyshia | |
Yeah, maybe this is overkill then. |
|
|
This line will need to be indented two more spaces, since it's still inside the dicts parens. |
|
|
Is there a reason this is not called *before* we do all of JSLineTool's specialized stuff? |
|
|
Let's put a newline after the if-block. |
|
|
I don't think the string representation of dict for the things you're passing is going to change anytime soon, so … |
|
|
self.jsLintOptions is a dict. wondering if we should depend on auto-formatting of dict to string used here or whether we … |
AL Allyshia | |
Yeah, a little less silent-fail would probably be good here. |
|
|
This function should be documented. Also, as a general rule, we tend to use 4-space indentation for Javascript. |
|
|
var options |
|
|
Should be formatted like: if (custom_options) { ... } |
|
|
for (var op in custom_options) { |
|
|
var custom |
|
|
See comment on line 127 of jslint.py. Originally this check did not exist, and we passed the straight string value … |
AL Allyshia | |
It'd be nice if the caller could just pass in things typed as one would expect, without having to jump … |
|
|
It'd be awesome to have the tool return an all-clear. Maybe even a ship-it, if the tool is configured for … |
|
|
} else { |
|
|
Spaces on either side of the =, space before the { |
|
|
Space after the if and before the { |
|
|
Spaces on either side of the +'s, and line up line 33 so that it's still contained (vertically) within the … |
|
|
2 Blank lines here. |
SM smacleod | |
> 79 characters |
SM smacleod | |
Can we break this out one per line, 4 space indented. |
SM smacleod | |
I'm curious why you're having to call int(...) here. The values of self.settings *should* be the proper type, is this … |
SM smacleod | |
Could we change the formatting here a bit (Also note the trailling comma): "load('%s'); runJSLint('%s', read('%s'), %s);" % ( self.runJSLint_path, … |
SM smacleod |
Change Summary:
small fix to setup.py to match entry_point name to class name defined in jsLint.py
Diff: |
Revision 2 (+6531) |
---|
-
-
bot/reviewbot/tools/jsLint.py (Diff revision 2) This should probably be renamed. JSLint is more than a style checker.
-
bot/reviewbot/tools/jsLint.py (Diff revision 2) This should probably be adjusted like 'name'. It might be a good idea to include the version number of JSLint (Not the self.version, but the actual JSLint projects version) in the description here.
-
bot/reviewbot/tools/jsLint.py (Diff revision 2) This should probably be changed to be case insensitive. I've seen some use '.JS' I really would like to add better support for file matching to review bot in general, and make it so tool devs don't have to worry about this. I haven't thought of a good solution yet though.
-
bot/reviewbot/tools/jsLint.py (Diff revision 2) This appears to still be just copied from the pep8 tool, but you'll need to change this parsing code to match the output from your javscript.
-
bot/reviewbot/tools/runJSLint.js (Diff revision 2) It's probably worth figuring out a way to pass these options in from the python code. If you can't pass arguments into the JS, you could probably generate 'options' in the python, and pass it as a string as part of the call to execute. Once you solve that problem, they can be added to the admin panel like the pep8 tool's 'max_line_length'.
-
Status: Re-opened
Description: |
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Testing Done: |
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Diff: |
Revision 3 (+13111) |
-
-
-
bot/reviewbot/tools/jsLint.py (Diff revision 3) Add an extra line before the class declaration (should be a total of 2 blank lines)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
bot/reviewbot/tools/jsLint.py (Diff revision 3) I think this can be DRYed up a bit. Maybe we can do something like this: settings_keys = ['debug', 'devel', 'es5', 'evil', 'passfail', 'sloppy', 'white'] jsLintOptions = dict((s, str(self.settings[s]).lower()) for s in settings_keys) jsLintOptions['maxlen'] = int(self.settings['maxlen'])
-
-
bot/reviewbot/tools/jsLint.py (Diff revision 3) As Aamir pointed out, 'import os' should be coming first. Imports should be ordered like this: Standard Library imports (e.g. os, sys, etc.) ===BLANK LINE=== Third Party imports ===BLANK LINE=== Local Imports (e.g. 'reviewbot...') Also, imports should be ordered alphabetically within the three categories.
-
bot/reviewbot/tools/jsLint.py (Diff revision 3) If this is enabled, I think you should definitely indicate in the review body_top, or body_bottom that the scan was stopped after a single error. Maybe even print PASSED, or FAILED etc. In most cases we'll probably want to find all errors and print them, so I think you should probably default this to False. I think you were probably emulating the defaults from JSLint itself, but False seems more natural in our setting. Also, this reminds me, does JSLint stop on certain errors, and refuse to continue scanning until they are fixed? If this is the case, is there a way we can detect this, and indicate to the user that scanning stopped after that point?
-
bot/reviewbot/tools/jsLint.py (Diff revision 3) This should probably be done only once per request, instead of every time handle_file is called (Once per file). You'll probably want to override handle_files, or execute, and take care of this stuff there. Make sure to call the base class' method from your overridden method.
-
bot/reviewbot/tools/jsLint.py (Diff revision 3) What exactly does JSLint output which causes the failure? I'm wondering if it's something that should be displayed in the review another way?
-
bot/reviewbot/tools/jslint.js (Diff revision 3) Quite the opinionated option, with quite a useless description. Not sure what this does, but it gives me the vibe it could be a hot button issue. Do you think this is an option we should include? I'd say we should at least figure out what it does.
-
bot/setup.py (Diff revision 3) I don't think this is quite correct. The package key should probably be 'reviewbot', or 'reviewbot.tools'. I'm fine with lib being inside the tools folder, but I think the JSLint specific stuff needs to be put in a sub folder as well (We may end up expanding with other things in here, and I'd like to have it organized). So, you'll have something like: package_data={ 'reviewbot.tools': [ 'lib/jslint/*.js', ] }
-
bot/setup.py (Diff revision 3) Let's rename jsLint.py to jslint.py. So, this should be changed to 'jslint = reviewbot.tools.jslint:JSLintTool',
Change Summary:
- Addressed previous comments, including style changes and changes to lib structure. - Modified the way JSLINT accepts and handles options (in both py and js scrpts). Managed to fix the issue whereby scan was stopping short of full completion when run as a ReviewBot tool, though this still requires a bit of testing to ensure that it is performing optimally. It seems that running jsling directly from the spidermonkey commandline actually scans up to 91% of the file, whereas the maximum hit for running via the python tool for the same file was 75%. Not sure if there is a difference in the way options are passed that is making that difference, and more testing should be done to ensure that that difference still holds. Managed to match the scanning level (75%) as seen on the jslint.com website, which is expected performance. -POSSIBLE IMPROVEMENTS: have a pass/fail notice written at the top-of-file comment section, notify the user whether premature stopping was due to pass/fail option being set to true in user options?
Testing Done: |
|
||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Diff: |
Revision 4 (+6666) |
-
Somme comments to guide reviewers and sollicit feedback.
-
bot/reviewbot/tools/jslint.py (Diff revision 4) Might not be necessary to sent the lowercase form of the strings. runJSLint is checking the content of the string anyway, it could check for upper case "True" and "False".
-
bot/reviewbot/tools/jslint.py (Diff revision 4) self.jsLintOptions is a dict. wondering if we should depend on auto-formatting of dict to string used here or whether we should use an explicit json.dumps() type conversion to string. Thoughts on why that might be advantageous?
-
bot/reviewbot/tools/lib/jslint/runJSLint.js (Diff revision 4) See comment on line 127 of jslint.py. Originally this check did not exist, and we passed the straight string value to jslint as an option. Since conversion to boolean value, kept on accepting lower case string since it best mimics the js boolean values (you could argue in the interest of modularity, if another program were to use this js script, they might not send in uppercase 'True' and 'False', so we are picking a standard).
-
Just a few comments from reading over the code
-
-
bot/reviewbot/tools/jslint.py (Diff revision 4) Maybe you could add a comment about which file caused the failure?
-
-
bot/reviewbot/tools/jslint.py (Diff revision 4) I believe, generally, we prefer the higher level imports to go above the more granular ones, so line 3 and 4 should be swapped.
-
bot/reviewbot/tools/jslint.py (Diff revision 4) Evil? Or Eval? Or Evil-Eval? Not sure if this is being cheeky, or just a typo. :)
-
bot/reviewbot/tools/jslint.py (Diff revision 4) Isn't 80 the traditional character limit? Or is something here 0-indexed? Or have I just been lied to all my life?
-
bot/reviewbot/tools/jslint.py (Diff revision 4) PACKAGE_ROOT is in all caps, and lib_path is not. Why?
-
bot/reviewbot/tools/jslint.py (Diff revision 4) Can you not simply pass the actual True and False literals to the script? Will the JS engine accept something like: js -e "load('foo'); runJSLint('bar', read('baz'), {someOption: false, otherOption: true}" ?
-
-
bot/reviewbot/tools/jslint.py (Diff revision 4) This line will need to be indented two more spaces, since it's still inside the dicts parens.
-
bot/reviewbot/tools/jslint.py (Diff revision 4) Is there a reason this is not called *before* we do all of JSLineTool's specialized stuff?
-
-
bot/reviewbot/tools/jslint.py (Diff revision 4) I don't think the string representation of dict for the things you're passing is going to change anytime soon, so I'm not too worried, personally. This line needs to have two spaces removed from its indentation.
-
bot/reviewbot/tools/jslint.py (Diff revision 4) Yeah, a little less silent-fail would probably be good here.
-
bot/reviewbot/tools/lib/jslint/runJSLint.js (Diff revision 4) This function should be documented. Also, as a general rule, we tend to use 4-space indentation for Javascript.
-
-
bot/reviewbot/tools/lib/jslint/runJSLint.js (Diff revision 4) Should be formatted like: if (custom_options) { ... }
-
-
-
bot/reviewbot/tools/lib/jslint/runJSLint.js (Diff revision 4) It'd be nice if the caller could just pass in things typed as one would expect, without having to jump through type conversion hoops...see my question above about passing boolean literals.
-
bot/reviewbot/tools/lib/jslint/runJSLint.js (Diff revision 4) It'd be awesome to have the tool return an all-clear. Maybe even a ship-it, if the tool is configured for it. (The ship-it thing might be out of scope, and a nice-to-have...but I think hearing about a no-error run would be a good thing).
-
-
bot/reviewbot/tools/lib/jslint/runJSLint.js (Diff revision 4) Spaces on either side of the =, space before the {
-
-
bot/reviewbot/tools/lib/jslint/runJSLint.js (Diff revision 4) Spaces on either side of the +'s, and line up line 33 so that it's still contained (vertically) within the parentheses of the above line.
Change Summary:
taking out of WIP status addressed latest comments: - made style/formatting changes to both .py and .js source, added documentation - used json.dumps() instead of stringified dictionary for passing custom options to runJSLint.js so that conversion from string to boolean is not necessary on JS side and we don't have to pass lowercase string values of booleans True and False on the py side. - added TODOs for implementing proper failure/success messages to the user -- support for this section in a review should be added. - cleaned up error handling to return False (ignore file) on ValueError in jslint.py TESTED that behaviour of jslint was maintained after these changes and that changes to the option (admin) panel were picked up on new reviews.
Diff: |
Revision 5 (+44 -40) |
---|
Change Summary:
Condensed description.
Description: |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Testing Done: |
|
-
The latest diff seems to have been uploaded strangely, only showing part of the change. Could you please update this again with the full patch?
-
Allyshia, this is looking really good. I pulled the patch down, and ran Review Bot locally against it with PEP8 and JSLint :D We are going to have to update this to be a separate package before it can be committed though (The JSLint Licensing issues :/). We can discuss that in IRC.
-
-
-
bot/reviewbot/tools/jslint.py (Diff revision 6) Can we break this out one per line, 4 space indented.
-
bot/reviewbot/tools/jslint.py (Diff revision 6) I'm curious why you're having to call int(...) here. The values of self.settings *should* be the proper type, is this not the case?
-
bot/reviewbot/tools/jslint.py (Diff revision 6) Could we change the formatting here a bit (Also note the trailling comma): "load('%s'); runJSLint('%s', read('%s'), %s);" % ( self.runJSLint_path, self.jsLint_path, path, json.dumps(self.jsLintOptions)),
Change Summary:
- addressing formatting issues brought up in last review - this review request will continue as a new request on a new repo as JSLint is being moved out of Review Bot.
Diff: |
Revision 7 (+6683) |
---|