[Differential] [Updated, 124 lines] D76: contrib: add a codemod script to rewrite nested with

quark (Jun Wu) phabricator at mercurial-scm.org
Thu Jul 13 23:41:17 EDT 2017


quark updated this revision to Diff 127.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D76?vs=124&id=127

REVISION DETAIL
  https://phab.mercurial-scm.org/D76

AFFECTED FILES
  contrib/codemod/codemod_nestedwith.py
  tests/hghave.py
  tests/test-codemod-nestedwith.t

CHANGE DETAILS

Index: tests/test-codemod-nestedwith.t
===================================================================
--- /dev/null
+++ tests/test-codemod-nestedwith.t
@@ -0,0 +1,59 @@
+#require redbaron
+
+  $ cat > a.py <<EOF
+  > with a() as b, c as d:
+  >     with e.f, g.h.i[3].j() as k:
+  >         with l:
+  >             with m():
+  >                 with superlongmethodsocannotbeinasamelinewith80charlimit:
+  >                     # do something
+  >                     result = foo.bar()
+  >                     if result:
+  >                         return 0
+  >                     raise RuntimeError('unexpected')
+  > 
+  > with a:
+  >     with b:
+  >         with c, d:
+  >             with e, f:
+  >                 with g:
+  >                     foo(2)
+  >                 with h:
+  >                     with i:
+  >                         foo(3)
+  >         bar(1)
+  > 
+  > with supersupersupersupersuperlongmethod() as supersupersuperlongx:
+  >     with a as somethinglong:
+  >         with b as something:
+  >             with supersupersuperlongmethod() as supersupersuperlongy:
+  >                 with c:
+  >                     with d:
+  >                         baz(3)
+  > EOF
+
+  $ $TESTDIR/../contrib/codemod/codemod_nestedwith.py a.py
+  (1/1) scanning a.py
+  updating a.py
+
+  $ cat a.py
+  with a() as b, c as d, e.f, g.h.i[3].j() as k, l, m():
+      with superlongmethodsocannotbeinasamelinewith80charlimit:
+          # do something
+          result = foo.bar()
+          if result:
+              return 0
+          raise RuntimeError('unexpected')
+  
+  with a, b:
+      with c, d, e, f:
+          with g:
+              foo(2)
+          with h, i:
+              foo(3)
+      bar(1)
+  
+  with supersupersupersupersuperlongmethod() as supersupersuperlongx:
+      with a as somethinglong, b as something:
+          with supersupersuperlongmethod() as supersupersuperlongy, c, d:
+              baz(3)
Index: tests/hghave.py
===================================================================
--- tests/hghave.py
+++ tests/hghave.py
@@ -448,6 +448,15 @@
     except ImportError:
         return False
 
+ at check("redbaron", "RedBaron python refactoring library")
+def has_redbaron():
+    try:
+        import redbaron
+        redbaron.RedBaron('1+1') # silence unused import warning
+        return True
+    except ImportError:
+        return False
+
 @check("outer-repo", "outer repo")
 def has_outer_repo():
     # failing for other reasons than 'no repo' imply that there is a repo
Index: contrib/codemod/codemod_nestedwith.py
===================================================================
--- /dev/null
+++ contrib/codemod/codemod_nestedwith.py
@@ -0,0 +1,56 @@
+#!/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 main(argv):
+    if not argv:
+        print('Usage: codemod_nestedwith.py FILES')
+
+    for i, path in enumerate(argv):
+        print('(%d/%d) scanning %s' % (i + 1, len(argv), path))
+        changed = False
+        red = redbaron.RedBaron(readpath(path))
+        processed = set()
+        for node in red.find_all('with'):
+            if node in processed or node.type != 'with':
+                continue
+            top = node
+            child = top[0]
+            while True:
+                if len(top) > 1 or child.type != 'with':
+                    break
+                # estimate line length after merging two "with"s
+                new = '%swith %s:' % (top.indentation, top.contexts.dumps())
+                new += ', %s' % child.contexts.dumps()
+                # only do the rewrite if the end result is within 80 chars
+                if len(new) > 80:
+                    break
+                processed.add(child)
+                top.contexts.extend(child.contexts)
+                top.value = child.value
+                top.value.decrease_indentation(4)
+                child = child[0]
+                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