PageRenderTime 518ms CodeModel.GetById 134ms app.highlight 151ms RepoModel.GetById 152ms app.codeStats 15ms

/Lib/lib2to3/main.py

http://unladen-swallow.googlecode.com/
Python | 133 lines | 95 code | 15 blank | 23 comment | 33 complexity | 85da2f9b910a7b8af322a872949da4e1 MD5 | raw file
  1"""
  2Main program for 2to3.
  3"""
  4
  5import sys
  6import os
  7import logging
  8import shutil
  9import optparse
 10
 11from . import refactor
 12
 13
 14class StdoutRefactoringTool(refactor.RefactoringTool):
 15    """
 16    Prints output to stdout.
 17    """
 18
 19    def __init__(self, fixers, options, explicit, nobackups):
 20        self.nobackups = nobackups
 21        super(StdoutRefactoringTool, self).__init__(fixers, options, explicit)
 22
 23    def log_error(self, msg, *args, **kwargs):
 24        self.errors.append((msg, args, kwargs))
 25        self.logger.error(msg, *args, **kwargs)
 26
 27    def write_file(self, new_text, filename, old_text):
 28        if not self.nobackups:
 29            # Make backup
 30            backup = filename + ".bak"
 31            if os.path.lexists(backup):
 32                try:
 33                    os.remove(backup)
 34                except os.error, err:
 35                    self.log_message("Can't remove backup %s", backup)
 36            try:
 37                os.rename(filename, backup)
 38            except os.error, err:
 39                self.log_message("Can't rename %s to %s", filename, backup)
 40        # Actually write the new file
 41        super(StdoutRefactoringTool, self).write_file(new_text,
 42                                                      filename, old_text)
 43        if not self.nobackups:
 44            shutil.copymode(backup, filename)
 45
 46    def print_output(self, lines):
 47        for line in lines:
 48            print line
 49
 50
 51def main(fixer_pkg, args=None):
 52    """Main program.
 53
 54    Args:
 55        fixer_pkg: the name of a package where the fixers are located.
 56        args: optional; a list of command line arguments. If omitted,
 57              sys.argv[1:] is used.
 58
 59    Returns a suggested exit status (0, 1, 2).
 60    """
 61    # Set up option parser
 62    parser = optparse.OptionParser(usage="2to3 [options] file|dir ...")
 63    parser.add_option("-d", "--doctests_only", action="store_true",
 64                      help="Fix up doctests only")
 65    parser.add_option("-f", "--fix", action="append", default=[],
 66                      help="Each FIX specifies a transformation; default: all")
 67    parser.add_option("-x", "--nofix", action="append", default=[],
 68                      help="Prevent a fixer from being run.")
 69    parser.add_option("-l", "--list-fixes", action="store_true",
 70                      help="List available transformations (fixes/fix_*.py)")
 71    parser.add_option("-p", "--print-function", action="store_true",
 72                      help="Modify the grammar so that print() is a function")
 73    parser.add_option("-v", "--verbose", action="store_true",
 74                      help="More verbose logging")
 75    parser.add_option("-w", "--write", action="store_true",
 76                      help="Write back modified files")
 77    parser.add_option("-n", "--nobackups", action="store_true", default=False,
 78                      help="Don't write backups for modified files.")
 79
 80    # Parse command line arguments
 81    refactor_stdin = False
 82    options, args = parser.parse_args(args)
 83    if not options.write and options.nobackups:
 84        parser.error("Can't use -n without -w")
 85    if options.list_fixes:
 86        print "Available transformations for the -f/--fix option:"
 87        for fixname in refactor.get_all_fix_names(fixer_pkg):
 88            print fixname
 89        if not args:
 90            return 0
 91    if not args:
 92        print >>sys.stderr, "At least one file or directory argument required."
 93        print >>sys.stderr, "Use --help to show usage."
 94        return 2
 95    if "-" in args:
 96        refactor_stdin = True
 97        if options.write:
 98            print >>sys.stderr, "Can't write to stdin."
 99            return 2
100
101    # Set up logging handler
102    level = logging.DEBUG if options.verbose else logging.INFO
103    logging.basicConfig(format='%(name)s: %(message)s', level=level)
104
105    # Initialize the refactoring tool
106    rt_opts = {"print_function" : options.print_function}
107    avail_fixes = set(refactor.get_fixers_from_package(fixer_pkg))
108    unwanted_fixes = set(fixer_pkg + ".fix_" + fix for fix in options.nofix)
109    explicit = set()
110    if options.fix:
111        all_present = False
112        for fix in options.fix:
113            if fix == "all":
114                all_present = True
115            else:
116                explicit.add(fixer_pkg + ".fix_" + fix)
117        requested = avail_fixes.union(explicit) if all_present else explicit
118    else:
119        requested = avail_fixes.union(explicit)
120    fixer_names = requested.difference(unwanted_fixes)
121    rt = StdoutRefactoringTool(sorted(fixer_names), rt_opts, sorted(explicit),
122                               options.nobackups)
123
124    # Refactor all files and directories passed as arguments
125    if not rt.errors:
126        if refactor_stdin:
127            rt.refactor_stdin()
128        else:
129            rt.refactor(args, options.write, options.doctests_only)
130        rt.summarize()
131
132    # Return error status (0 if rt.errors is zero)
133    return int(bool(rt.errors))