scripts/munge.py
changeset 506 deaf548efde3
parent 480 9b07ddeb1412
child 511 52557918ec8f
equal deleted inserted replaced
505:4f0b8d80e99a 506:deaf548efde3
   262 
   262 
   263 def applyActionToFiles(action, action_args,
   263 def applyActionToFiles(action, action_args,
   264                        start_path='', abs_path=False, files_pattern='',
   264                        start_path='', abs_path=False, files_pattern='',
   265                        recurse_dirs=False, dirs_pattern='',
   265                        recurse_dirs=False, dirs_pattern='',
   266                        follow_symlinks=False, quiet_output=False,
   266                        follow_symlinks=False, quiet_output=False,
   267                        hide_paths=False, **action_options):
   267                        hide_paths=False, hide_text=False, **action_options):
   268   """Applies a callable action to files, based on options and arguments.
   268   """Applies a callable action to files, based on options and arguments.
   269   
   269   
   270   Args:
   270   Args:
   271     action: callable that expects a file path argument, positional arguments
   271     action: callable that expects a file path argument, positional arguments
   272       (action_args), and keyword options from the command-line options dict;
   272       (action_args), and keyword options from the command-line options dict;
   281     dirs_pattern: Python regex (object or pattern) which selects which
   281     dirs_pattern: Python regex (object or pattern) which selects which
   282       subdirectories to traverse if recurse_dirs is True
   282       subdirectories to traverse if recurse_dirs is True
   283     follow_symlinks: boolean indicating if symlinks should be traversed
   283     follow_symlinks: boolean indicating if symlinks should be traversed
   284     quiet_output: optional boolean indicating if output should be suppressed
   284     quiet_output: optional boolean indicating if output should be suppressed
   285     hide_paths: optional boolean indicating to omit file paths from output
   285     hide_paths: optional boolean indicating to omit file paths from output
       
   286     hide_text: optional boolean indicating to omit find/replace text from
       
   287       output
   286     **action_options: remaining keyword arguments that are passed unchanged
   288     **action_options: remaining keyword arguments that are passed unchanged
   287       to the action callable
   289       to the action callable
   288 
   290 
   289   Returns:
   291   Returns:
   290     two-tuple containing an exit code and a (possibly empty) list of
   292     two-tuple containing an exit code and a (possibly empty) list of
   332           if recurse_dirs:
   334           if recurse_dirs:
   333             if dirs_regex.match(item):
   335             if dirs_regex.match(item):
   334               sub_paths.append(item_path)
   336               sub_paths.append(item_path)
   335           continue
   337           continue
   336       
   338       
   337         if files_regex.match(item):
   339         if os.path.isfile(item_path) and files_regex.match(item):
   338           try:
   340           try:
   339             matched, found_output = action(item_path, *action_args,
   341             matched, found_output = action(item_path, *action_args,
   340                                            **action_options)
   342                                            **action_options)
   341           except (IOError, OSError), error:
   343           except (IOError, OSError), error:
   342             raise Error(error.args[0], '%s: %s' % (
   344             raise Error(error.args[0], '%s: %s' % (
   346             exit_code = 0  # at least one matched file has now been found
   348             exit_code = 0  # at least one matched file has now been found
   347 
   349 
   348             if (not quiet_output) and (not hide_paths):
   350             if (not quiet_output) and (not hide_paths):
   349               output.append(item_path)
   351               output.append(item_path)
   350 
   352 
   351           if not quiet_output:
   353           if (not quiet_output) and (not hide_text):
   352             output.extend(found_output)
   354             output.extend(found_output)
   353 
   355 
   354     paths = sub_paths
   356     paths = sub_paths
   355   
   357   
   356   return exit_code, output
   358   return exit_code, output
   418     '-a', '--abspath', dest='abs_path', default=False, action='store_true',
   420     '-a', '--abspath', dest='abs_path', default=False, action='store_true',
   419     help=('output absolute paths instead of relative paths'
   421     help=('output absolute paths instead of relative paths'
   420           ' [default: %default]'))
   422           ' [default: %default]'))
   421 
   423 
   422   output_group.add_option(
   424   output_group.add_option(
   423     '-p', '--nopaths', dest='hide_paths', default=False, action='store_true',
   425     '', '--nopaths', dest='hide_paths', default=False, action='store_true',
   424     help=('suppress printing of file path names for successfully matched'
   426     help=('suppress printing of file path names for successfully matched'
   425           ' files to stdout [default: %default]'))
   427           ' files to stdout [default: %default]'))
       
   428 
       
   429   output_group.add_option(
       
   430     '', '--notext', dest='hide_text', default=False, action='store_true',
       
   431     help=('suppress find/replace text output to stdout (but still print'
       
   432           ' paths if not --nopath, and still perform replacements if'
       
   433           ' specified) [default: %default]'))
   426 
   434 
   427   output_group.add_option(
   435   output_group.add_option(
   428     '-q', '--quiet', dest='quiet_output', default=False, action='store_true',
   436     '-q', '--quiet', dest='quiet_output', default=False, action='store_true',
   429     help=('suppress *all* printed output to stdout (but still perform'
   437     help=('suppress *all* printed output to stdout (but still perform'
   430           ' replacements if specified) [default: %default]'))
   438           ' replacements if specified) [default: %default]'))
   509       
   517       
   510   Returns:
   518   Returns:
   511     exit code suitable for sys.exit()
   519     exit code suitable for sys.exit()
   512   """
   520   """
   513   options = {}  # empty options, used if _parseArgs() fails
   521   options = {}  # empty options, used if _parseArgs() fails
       
   522   parser = None
   514 
   523 
   515   try:
   524   try:
   516     action, options, args, parser = _parseArgs(argv[1:])
   525     action, options, args, parser = _parseArgs(argv[1:])
   517     exit_code, output = applyActionToFiles(action, args, **options)
   526     exit_code, output = applyActionToFiles(action, args, **options)
   518 
   527 
   520 
   529 
   521   except Error, error:
   530   except Error, error:
   522     if not options.get('quiet_output'):
   531     if not options.get('quiet_output'):
   523       print >>sys.stderr, '\nERROR: (%s: %s) %s\n' % (
   532       print >>sys.stderr, '\nERROR: (%s: %s) %s\n' % (
   524         error.args[0], os.strerror(error.args[0]), error.args[1])
   533         error.args[0], os.strerror(error.args[0]), error.args[1])
   525       print >>sys.stderr, parser.get_usage()
   534 
       
   535       if parser:
       
   536         print >>sys.stderr, parser.get_usage()
   526 
   537 
   527     exit_code = error.args[0]
   538     exit_code = error.args[0]
   528 
   539 
   529   return exit_code
   540   return exit_code
   530 
   541