summaryrefslogtreecommitdiffstats
path: root/tools/git
diff options
context:
space:
mode:
authorblundell@chromium.org <blundell@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-06-21 18:22:58 +0000
committerblundell@chromium.org <blundell@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-06-21 18:22:58 +0000
commit8ad7fba0ab635297bfe08edb9da7b3d58351b2fc (patch)
tree8eff747947c051756745f3d0ff7f29623d764eab /tools/git
parent1046739ad1c13c48e7fd156afd409e932e203d5b (diff)
downloadchromium_src-8ad7fba0ab635297bfe08edb9da7b3d58351b2fc.zip
chromium_src-8ad7fba0ab635297bfe08edb9da7b3d58351b2fc.tar.gz
chromium_src-8ad7fba0ab635297bfe08edb9da7b3d58351b2fc.tar.bz2
Augment mffr.py to be able to take arguments from a file.
Example use case is iterating on follow-up changes to a file changing namespaces, impacting all the symbols within that file. R=joi Review URL: https://chromiumcodereview.appspot.com/17527004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@207883 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'tools/git')
-rwxr-xr-xtools/git/mffr.py101
1 files changed, 77 insertions, 24 deletions
diff --git a/tools/git/mffr.py b/tools/git/mffr.py
index 7f791d0..d5b67c8 100755
--- a/tools/git/mffr.py
+++ b/tools/git/mffr.py
@@ -17,6 +17,7 @@ REGEXP uses full Python regexp syntax. REPLACEMENT can use
back-references.
"""
+import optparse
import re
import subprocess
import sys
@@ -73,25 +74,57 @@ def MultiFileFindReplace(original, replacement, file_globs):
def main():
- file_globs = []
- force_unsafe_run = False
- args = sys.argv[1:]
- while args and args[0].startswith('-'):
- if args[0] == '-d':
- file_globs = ['*.cc', '*.h', '*.m', '*.mm']
- args = args[1:]
- elif args[0] == '-g':
- file_globs.append(args[1])
- args = args[2:]
- elif args[0] == '-f':
- force_unsafe_run = True
- args = args[1:]
- if not file_globs:
- file_globs = ['*.*']
- if not args:
- print globals()['__doc__']
+ parser = optparse.OptionParser(usage='''
+(1) %prog <options> REGEXP REPLACEMENT
+REGEXP uses full Python regexp syntax. REPLACEMENT can use back-references.
+
+(2) %prog <options> -i <file>
+<file> should contain a list (in Python syntax) of
+[REGEXP, REPLACEMENT, [GLOBS]] lists, e.g.:
+[
+ [r"(foo|bar)", r"\1baz", ["*.cc", "*.h"]],
+ ["54", "42"],
+]
+As shown above, [GLOBS] can be omitted for a given search-replace list, in which
+case the corresponding search-replace will use the globs specified on the
+command line.''')
+ parser.add_option('-d', action='store_true',
+ dest='use_default_glob',
+ help='Perform the change on C++ and Objective-C(++) source '
+ 'and header files.')
+ parser.add_option('-f', action='store_true',
+ dest='force_unsafe_run',
+ help='Perform the run even if there are uncommitted local '
+ 'changes.')
+ parser.add_option('-g', action='append',
+ type='string',
+ default=[],
+ metavar="<glob>",
+ dest='user_supplied_globs',
+ help='Perform the change on the specified glob. Can be '
+ 'specified multiple times, in which case the globs are '
+ 'unioned.')
+ parser.add_option('-i', "--input_file",
+ type='string',
+ action='store',
+ default='',
+ metavar="<file>",
+ dest='input_filename',
+ help='Read arguments from <file> rather than the command '
+ 'line. NOTE: To be sure of regular expressions being '
+ 'interpreted correctly, use raw strings.')
+ opts, args = parser.parse_args()
+ if opts.use_default_glob and opts.user_supplied_globs:
+ print '"-d" and "-g" cannot be used together'
+ parser.print_help()
return 1
- if not force_unsafe_run:
+
+ from_file = opts.input_filename != ""
+ if (from_file and len(args) != 0) or (not from_file and len(args) != 2):
+ parser.print_help()
+ return 1
+
+ if not opts.force_unsafe_run:
out, err = subprocess.Popen(['git', 'status', '--porcelain'],
stdout=subprocess.PIPE,
shell=_USE_SHELL).communicate()
@@ -103,12 +136,32 @@ def main():
print ''
print 'To override this safeguard, pass the -f flag.'
return 1
- original = args[0]
- replacement = args[1]
- print 'File globs: %s' % file_globs
- print 'Original: %s' % original
- print 'Replacement: %s' % replacement
- MultiFileFindReplace(original, replacement, file_globs)
+
+ global_file_globs = ['*.*']
+ if opts.use_default_glob:
+ global_file_globs = ['*.cc', '*.h', '*.m', '*.mm']
+ elif opts.user_supplied_globs:
+ global_file_globs = opts.user_supplied_globs
+
+ # Construct list of search-replace tasks.
+ search_replace_tasks = []
+ if opts.input_filename == '':
+ original = args[0]
+ replacement = args[1]
+ search_replace_tasks.append([original, replacement, global_file_globs])
+ else:
+ f = open(opts.input_filename)
+ search_replace_tasks = eval("".join(f.readlines()))
+ for task in search_replace_tasks:
+ if len(task) == 2:
+ task.append(global_file_globs)
+ f.close()
+
+ for (original, replacement, file_globs) in search_replace_tasks:
+ print 'File globs: %s' % file_globs
+ print 'Original: %s' % original
+ print 'Replacement: %s' % replacement
+ MultiFileFindReplace(original, replacement, file_globs)
return 0