Propose patches to autofix simple linting errors
Propose patches to autofix simple linting errors

Summary:
`arc lint` has this really nice functionality that allows linting errors to
specify an 'original' and 'replacement' text which can be used to fix a linting
error.

We use the script and regex linting engine to convert from our linting errors to
arc's format, so we output our "original" and "replacement" texts delimited by
null characters.

This also has an associated update to the arcanist repo updating our default
`~/.arcrc`.

Test Plan:
Patch this diff into `~/khan/devtools/khan-linter` and update your `~/.arcrc`
with these keys:

    "linter.scriptandregex.regex"  : "\/^((?P<file>[^:]*):(?P<line>\\d+):((?P<char>\\d+):)? (?P<name>((?P<error>E)|(?P<warning>W))\\S+) (?P<message>[^\\x00]*)(\\x00(?P<original>[^\\x00]*)\\x00(?P<replacement>[^\\x00]*)\\x00)?)|(?P<ignore>SKIPPING.*)$\/m",
    "linter.scriptandregex.script" : "~\/khan\/devtools\/khan-linter\/runlint.py --always-exit-0 --blacklist=yes --propose-arc-fixes"

Next, introduce the following lint errors into webapp.

- 1 blank line between top level declarations instead of 2 in a python file
- an unused import in a python file
- a missing semicolon in a .js file
- a missing semicolon in a .jsx file

Now run `arc lint`. It should propose a fix for each one of these errors. For
each of them, hit 'y' to accept the change. Afterwards, run `arc lint` again,
and you should see no more lint errors.

The output will look something like this after you've accepted all the diffs:

    >>> Lint for javascript/react-package/checkbox.jsx:

    Warning  (S&RX) W033
        Missing semicolon.

                40             {this.props.children}
                41         </span>;
                42     }
        >>> -     43 })
            +        });
                44
                45 module.exports = CheckBox;
    --- /Users/jlfwong/khan/webapp/javascript/react-package/checkbox.jsx    2014-07-31 12:53:19.000000000 -0400
    +++ /private/var/folders/3m/6pycd7zx12n4_8fqw3l_mf9h0000gn/T/5t38ybr65n4so4c4/91920-tH9rUK      2014-07-31 12:53:47.000000000 -0400
    @@ -40,6 +40,6 @@
                {this.props.children}
            </span>;
        }
    -})
    +});

    module.exports = CheckBox;

        Apply this patch to javascript/react-package/checkbox.jsx? [y/N] y

    >>> Lint for javascript/shared-package/visit-tracking.js:

    Warning  (S&RX) W033
        Missing semicolon.

                6 var _ = require("underscore");
                7
                8 var BigBingo = require("./bigbingo.js");
        >>> -      9 var Cookies = require("./cookies.js")
            +        var Cookies = require("./cookies.js");
                10
                11 // TODO(stephanie): do this in a more appropriate common library
                12 var getSeconds = function(dateString) {
    --- /Users/jlfwong/khan/webapp/javascript/shared-package/visit-tracking.js      2014-07-31 12:53:26.000000000 -0400
    +++ /private/var/folders/3m/6pycd7zx12n4_8fqw3l_mf9h0000gn/T/1hiii19nmmboc08s/91920-dioGq6      2014-07-31 12:53:50.000000000 -0400
    @@ -6,7 +6,7 @@
    var _ = require("underscore");

    var BigBingo = require("./bigbingo.js");
    -var Cookies = require("./cookies.js")
    +var Cookies = require("./cookies.js");

    // TODO(stephanie): do this in a more appropriate common library
    var getSeconds = function(dateString) {

        Apply this patch to javascript/shared-package/visit-tracking.js? [y/N] y

    >>> Lint for kake/compile_js_bundles.py:

    Error  (S&RX) E=pyflakes=
        'sys' imported but unused

                28 import glob
                29 import os
                30 import re
        >>> -     31 import sys
            -     32
            +
                33 import js_css_packages.util
                34 from js_css_packages import third_party_js
                35 import ka_root

    Error  (S&RX) E302
        expected 2 blank lines, found 1

                51     }
                52     return computed_js_inputs.included_files(filename, context)
                53
            +
                54 def _before_first_dot_match(filename, name):
                55     """Return true if the part of filename before the first dot matches name.
                56
    --- /Users/jlfwong/khan/webapp/kake/compile_js_bundles.py       2014-07-31 12:53:38.000000000 -0400
    +++ /private/var/folders/3m/6pycd7zx12n4_8fqw3l_mf9h0000gn/T/eupmpvubplskw0kk/91920-guugVp      2014-07-31 12:53:54.000000000 -0400
    @@ -28,7 +28,6 @@
    import glob
    import os
    import re
    -import sys

    import js_css_packages.util
    from js_css_packages import third_party_js
    @@ -51,6 +50,7 @@
        }
        return computed_js_inputs.included_files(filename, context)

    +
    def _before_first_dot_match(filename, name):
        """Return true if the part of filename before the first dot matches name.

        Apply this patch to kake/compile_js_bundles.py? [y/N] y

    OKAY  No lint warnings.

Reviewers: alpert, csilvers

Reviewed By: csilvers

Subscribers: chris

Differential Revision: http://phabricator.khanacademy.org/D11806

Khan/khan-linter,Khan/khan-linter,Khan/khan-linter,Khan/khan-linter