Commit 497bf8b9 authored by dpranke@chromium.org's avatar dpranke@chromium.org

Rework format-webkitpy to use single-quoting for chromium, add more args.

In addition to changing the default for the chromium coding style to
use single-quoted string literals instead of double, this reworks the
structure of the program to be a bit clearer, and adds command line
args to toggle on and off the autopep8 reformatting and the string literal
reformatting.

TBR=eseidel@chromium.org

Review URL: https://codereview.chromium.org/555283006

git-svn-id: svn://svn.chromium.org/blink/trunk@181767 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 701d4208
...@@ -12,72 +12,92 @@ from webkitpy.thirdparty import autopep8 ...@@ -12,72 +12,92 @@ from webkitpy.thirdparty import autopep8
def parse_args(args=None): def parse_args(args=None):
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument('--chromium', action='store_const', dest='style', const='chromium', default='blink', parser.add_argument('--chromium', action='store_const', dest='style', const='chromium', default='blink',
help="format according to Chromium's Python coding styles instead of Blink's") help="Format according to Chromium's Python coding styles instead of Blink's.")
parser.add_argument('--no-backups', action='store_false', default=True, dest='backup', parser.add_argument('--no-backups', action='store_false', default=True, dest='backup',
help='do not back up files before overwriting them') help='Do not back up files before overwriting them.')
parser.add_argument('-j', '--jobs', metavar='n', type=int, default=0, parser.add_argument('-j', '--jobs', metavar='n', type=int, default=0,
help='number of parallel jobs; match CPU count if less than 1') help='Number of parallel jobs; match CPU count if less than 1.')
parser.add_argument('files', nargs='*', default=['-'], parser.add_argument('files', nargs='*', default=['-'],
help="files to format or '-' for standard in") help="files to format or '-' for standard in")
parser.add_argument('--double-quote-strings', action='store_const', dest='quoting', const='double', default='single',
help='Rewrite string literals to use double quotes instead of single quotes.')
parser.add_argument('--no-autopep8', action='store_true',
help='Skip the autopep8 code-formatting step.')
parser.add_argument('--leave-strings-alone', action='store_true',
help='Do not reformat string literals to use a consistent quote style.')
return parser.parse_args(args=args) return parser.parse_args(args=args)
def main(host=None, args=None): def main(host=None, args=None):
options = parse_args(args) options = parse_args(args)
if options.no_autopep8:
options.style = None
if options.leave_strings_alone:
options.quoting = None
autopep8_options = _autopep8_options_for_style(options.style)
fixers = _fixers_for_quoting(options.quoting)
if options.files == ['-']: if options.files == ['-']:
host = host or SystemHost() host = host or SystemHost()
host.print_(reformat_source(host.stdin.read(), options.style, '<stdin>'), end='') host.print_(reformat_source(host.stdin.read(), autopep8_options, fixers, '<stdin>'), end='')
return return
# We create the arglist before checking if we need to create a Host, because a # We create the arglist before checking if we need to create a Host, because a
# real host is non-picklable and can't be passed to host.executive.map(). # real host is non-picklable and can't be passed to host.executive.map().
arglist = [(host, name, options.style, options.backup) for name in options.files]
arglist = [(host, name, autopep8_options, fixers, options.backup) for name in options.files]
host = host or SystemHost() host = host or SystemHost()
host.executive.map(_reformat_thunk, arglist, processes=options.jobs) host.executive.map(_reformat_thunk, arglist, processes=options.jobs)
def _autopep8_options_for_style(style):
return {
None: [],
'blink': autopep8.parse_args(['--aggressive',
'--max-line-length', '132',
'--indent-size', '4',
'']),
'chromium': autopep8.parse_args(['--aggressive',
'--max-line-length', '80',
'--indent-size', '2',
'']),
}.get(style)
def _fixers_for_quoting(quoting):
return {
None: [],
'double': ['webkitpy.formatter.fix_double_quote_strings'],
'single': ['webkitpy.formatter.fix_single_quote_strings'],
}.get(quoting)
def _reformat_thunk(args): def _reformat_thunk(args):
reformat_file(*args) reformat_file(*args)
def reformat_file(host, name, style, should_backup_file): def reformat_file(host, name, autopep8_options, fixers, should_backup_file):
host = host or SystemHost() host = host or SystemHost()
source = host.filesystem.read_text_file(name) source = host.filesystem.read_text_file(name)
dest = reformat_source(source, style, name) dest = reformat_source(source, autopep8_options, fixers, name)
if dest != source: if dest != source:
if should_backup_file: if should_backup_file:
host.filesystem.write_text_file(name + '.bak', source) host.filesystem.write_text_file(name + '.bak', source)
host.filesystem.write_text_file(name, dest) host.filesystem.write_text_file(name, dest)
def reformat_source(source, style, name): def reformat_source(source, autopep8_options, fixers, name):
options = _autopep8_options_for_style(style) tmp_str = source
tmp_str = autopep8.fix_code(source, options)
if autopep8_options:
tmp_str = autopep8.fix_code(tmp_str, autopep8_options)
fixers = _fixers_for_style(style) if fixers:
tool = lib2to3.refactor.RefactoringTool(fixer_names=fixers, tool = lib2to3.refactor.RefactoringTool(fixer_names=fixers,
explicit=fixers) explicit=fixers)
return unicode(tool.refactor_string(tmp_str, name=name)) tmp_str = unicode(tool.refactor_string(tmp_str, name=name))
return tmp_str
def _autopep8_options_for_style(style):
if style == 'chromium':
max_line_length = 80
indent_size = 2
else:
max_line_length = 132
indent_size = 4
return autopep8.parse_args(['--aggressive',
'--max-line-length', str(max_line_length),
'--indent-size', str(indent_size),
''])
def _fixers_for_style(style):
if style == 'chromium':
return ['webkitpy.formatter.fix_double_quote_strings']
else:
return ['webkitpy.formatter.fix_single_quote_strings']
...@@ -40,34 +40,33 @@ EXPECTED_CHROMIUM_OUTPUT = ''' ...@@ -40,34 +40,33 @@ EXPECTED_CHROMIUM_OUTPUT = '''
def foo(): def foo():
"""triple-quoted docstring""" """triple-quoted docstring"""
try: try:
bar = "bar" bar = 'bar'
long_list = [ long_list = [
"this is a list of strings that should be wrapped", 'this is a list of strings that should be wrapped',
"and consistently quoted"] 'and consistently quoted']
longer_list = [ longer_list = [
"this is a list of strings that should be wrapped", 'this is a list of strings that should be wrapped',
"and consistently quoted", 'and consistently quoted',
"because it's important to test quoting"] "because it's important to test quoting"]
except Exception as e: except Exception as e:
pass pass
''' '''
EXPECTED_ONLY_DOUBLE_QUOTED_OUTPUT = '''
def foo():
"""triple-quoted docstring"""
try:
bar = "bar"
long_list = ["this is a list of strings that should be wrapped", "and consistently quoted"]
longer_list = ["this is a list of strings that should be wrapped", "and consistently quoted", "because it's important to test quoting"]
except Exception, e:
pass
'''
class TestMain(unittest.TestCase): class TestMain(unittest.TestCase):
maxDiff = 4096 maxDiff = 4096
def test_stdin_blink(self):
host = MockSystemHost()
host.stdin = StringIO.StringIO(ACTUAL_INPUT)
main(host, ['-'])
self.assertMultiLineEqual(host.stdout.getvalue(), EXPECTED_BLINK_OUTPUT)
def test_stdin_chromium(self):
host = MockSystemHost()
host.stdin = StringIO.StringIO(ACTUAL_INPUT)
main(host, ['--chromium', '-'])
self.assertMultiLineEqual(host.stdout.getvalue(), EXPECTED_CHROMIUM_OUTPUT)
def test_files_blink(self): def test_files_blink(self):
host = MockSystemHost() host = MockSystemHost()
host.filesystem.files = { host.filesystem.files = {
...@@ -84,3 +83,27 @@ class TestMain(unittest.TestCase): ...@@ -84,3 +83,27 @@ class TestMain(unittest.TestCase):
main(host, ['--no-backups', 'test.py']) main(host, ['--no-backups', 'test.py'])
self.assertEqual(host.filesystem.files, { self.assertEqual(host.filesystem.files, {
'test.py': EXPECTED_BLINK_OUTPUT}) 'test.py': EXPECTED_BLINK_OUTPUT})
def test_stdin_blink(self):
host = MockSystemHost()
host.stdin = StringIO.StringIO(ACTUAL_INPUT)
main(host, ['-'])
self.assertMultiLineEqual(host.stdout.getvalue(), EXPECTED_BLINK_OUTPUT)
def test_stdin_chromium(self):
host = MockSystemHost()
host.stdin = StringIO.StringIO(ACTUAL_INPUT)
main(host, ['--chromium', '-'])
self.assertMultiLineEqual(host.stdout.getvalue(), EXPECTED_CHROMIUM_OUTPUT)
def test_stdin_no_changes(self):
host = MockSystemHost()
host.stdin = StringIO.StringIO(ACTUAL_INPUT)
main(host, ['--no-autopep8', '--leave-strings-alone', '-'])
self.assertMultiLineEqual(host.stdout.getvalue(), ACTUAL_INPUT)
def test_stdin_only_double_quoting(self):
host = MockSystemHost()
host.stdin = StringIO.StringIO(ACTUAL_INPUT)
main(host, ['--no-autopep8', '--double-quote-strings', '-'])
self.assertMultiLineEqual(host.stdout.getvalue(), EXPECTED_ONLY_DOUBLE_QUOTED_OUTPUT)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment