[Differential] [Request, 82 lines] D76: contrib: add a codemod script to rewrite nested with
quark (Jun Wu)
phabricator at mercurial-scm.org
Fri Jul 14 01:35:30 UTC 2017
quark created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.
REVISION SUMMARY
The codemod script rewrites nested with with a single with if the code could
be put in one line (80 chars).
REPOSITORY
rHG Mercurial
REVISION DETAIL
https://phab.mercurial-scm.org/D76
AFFECTED FILES
contrib/codemod/codemod_nestedwith.py
CHANGE DETAILS
Index: contrib/codemod/codemod_nestedwith.py
===================================================================
--- /dev/null
+++ contrib/codemod/codemod_nestedwith.py
@@ -0,0 +1,82 @@
+#!/usr/bin/env python
+# codemod_nestedwith.py - codemod tool to rewrite nested with
+#
+# Copyright 2017 Facebook, Inc.
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2 or any later version.
+from __future__ import absolute_import, print_function
+
+import sys
+
+import redbaron
+
+def readpath(path):
+ with open(path) as f:
+ return f.read()
+
+def writepath(path, content):
+ with open(path, 'w') as f:
+ f.write(content)
+
+def extractstring(rnode):
+ """get the string from a RedBaron string or call_argument node"""
+ while rnode.type != 'string':
+ rnode = rnode.value
+ return rnode.value[1:-1] # unquote, "'str'" -> "str"
+
+def nestedwithitems(red):
+ """match nested withs, yield (node, innernode, level)"""
+ visited = set()
+ for node in red.find_all('with'):
+ if node in visited:
+ continue
+ entry = None
+ level = 0
+ cur = node
+ try:
+ while True:
+ if cur.type == 'with':
+ visited.add(cur)
+ level += 1
+ cur = cur[0]
+ else:
+ break
+ if level > 1:
+ entry = (node, level)
+ except Exception:
+ raise
+ #pass
+ else:
+ if entry:
+ yield entry
+
+def main(argv):
+ if not argv:
+ print('Usage: codemod_nestedwith.py FILES\n')
+
+ # first loop: scan all files before taking any action
+ for i, path in enumerate(argv):
+ print('(%d/%d) scanning %s' % (i + 1, len(argv), path))
+ changed = False
+ red = redbaron.RedBaron(readpath(path))
+
+ for node, level in nestedwithitems(red):
+ while level > 1:
+ # estimate line length after merging two "with"s
+ new = '%swith %s:' % (node.indentation, node.contexts.dumps())
+ new += ', %s' % node[0].contexts.dumps()
+ # only do the rewrite if the end result is within 80 chars
+ if len(new) > 80:
+ break
+ node.contexts.append(node[0].contexts)
+ node.value = node[0].value
+ node.value.decrease_indentation(4)
+ level -= 1
+ changed = True
+ if changed:
+ print('updating %s' % path)
+ writepath(path, red.dumps())
+
+if __name__ == "__main__":
+ sys.exit(main(sys.argv[1:]))
EMAIL PREFERENCES
https://phab.mercurial-scm.org/settings/panel/emailpreferences/
To: quark, #hg-reviewers
Cc: mercurial-devel, indygreg
More information about the Mercurial-devel
mailing list