11 from . import refactor
14 class StdoutRefactoringTool(refactor
.RefactoringTool
):
16 Prints output to stdout.
19 def __init__(self
, fixers
, options
, explicit
, nobackups
):
20 self
.nobackups
= nobackups
21 super(StdoutRefactoringTool
, self
).__init
__(fixers
, options
, explicit
)
23 def log_error(self
, msg
, *args
, **kwargs
):
24 self
.errors
.append((msg
, args
, kwargs
))
25 self
.logger
.error(msg
, *args
, **kwargs
)
27 def write_file(self
, new_text
, filename
, old_text
):
28 if not self
.nobackups
:
30 backup
= filename
+ ".bak"
31 if os
.path
.lexists(backup
):
35 self
.log_message("Can't remove backup %s", backup
)
37 os
.rename(filename
, backup
)
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
,
43 if not self
.nobackups
:
44 shutil
.copymode(backup
, filename
)
46 def print_output(self
, lines
):
51 def main(fixer_pkg
, args
=None):
55 fixer_pkg: the name of a package where the fixers are located.
56 args: optional; a list of command line arguments. If omitted,
59 Returns a suggested exit status (0, 1, 2).
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.")
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
):
92 print >>sys
.stderr
, "At least one file or directory argument required."
93 print >>sys
.stderr
, "Use --help to show usage."
98 print >>sys
.stderr
, "Can't write to stdin."
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
)
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
)
112 for fix
in options
.fix
:
116 explicit
.add(fixer_pkg
+ ".fix_" + fix
)
117 requested
= avail_fixes
.union(explicit
) if all_present
else explicit
119 requested
= avail_fixes
.union(explicit
)
120 fixer_names
= requested
.difference(unwanted_fixes
)
121 rt
= StdoutRefactoringTool(sorted(fixer_names
), rt_opts
, sorted(explicit
),
124 # Refactor all files and directories passed as arguments
129 rt
.refactor(args
, options
.write
, options
.doctests_only
)
132 # Return error status (0 if rt.errors is zero)
133 return int(bool(rt
.errors
))