11
12
from . import refactor
14
class StdoutRefactoringTool(refactor.RefactoringTool):
15
def diff_texts(a, b, filename):
16
"""Return a unified diff of two strings."""
19
return difflib.unified_diff(a, b, filename, filename,
20
"(original)", "(refactored)",
24
class StdoutRefactoringTool(refactor.MultiprocessRefactoringTool):
16
26
Prints output to stdout.
19
def __init__(self, fixers, options, explicit, nobackups):
29
def __init__(self, fixers, options, explicit, nobackups, show_diffs):
20
30
self.nobackups = nobackups
31
self.show_diffs = show_diffs
21
32
super(StdoutRefactoringTool, self).__init__(fixers, options, explicit)
23
34
def log_error(self, msg, *args, **kwargs):
24
35
self.errors.append((msg, args, kwargs))
25
36
self.logger.error(msg, *args, **kwargs)
27
def write_file(self, new_text, filename, old_text):
38
def write_file(self, new_text, filename, old_text, encoding):
28
39
if not self.nobackups:
30
41
backup = filename + ".bak"
38
49
except os.error, err:
39
50
self.log_message("Can't rename %s to %s", filename, backup)
40
51
# Actually write the new file
41
super(StdoutRefactoringTool, self).write_file(new_text,
52
write = super(StdoutRefactoringTool, self).write_file
53
write(new_text, filename, old_text, encoding)
43
54
if not self.nobackups:
44
55
shutil.copymode(backup, filename)
46
def print_output(self, lines):
57
def print_output(self, old, new, filename, equal):
59
self.log_message("No changes to %s", filename)
61
self.log_message("Refactored %s", filename)
63
diff_lines = diff_texts(old, new, filename)
65
for line in diff_lines:
67
except UnicodeEncodeError:
68
warn("couldn't encode %s's diff for your terminal" %
74
print >> sys.stderr, "WARNING: %s" % (msg,)
51
77
def main(fixer_pkg, args=None):
64
90
help="Fix up doctests only")
65
91
parser.add_option("-f", "--fix", action="append", default=[],
66
92
help="Each FIX specifies a transformation; default: all")
93
parser.add_option("-j", "--processes", action="store", default=1,
94
type="int", help="Run 2to3 concurrently")
67
95
parser.add_option("-x", "--nofix", action="append", default=[],
68
96
help="Prevent a fixer from being run.")
69
97
parser.add_option("-l", "--list-fixes", action="store_true",
72
100
help="Modify the grammar so that print() is a function")
73
101
parser.add_option("-v", "--verbose", action="store_true",
74
102
help="More verbose logging")
103
parser.add_option("--no-diffs", action="store_true",
104
help="Don't show diffs of the refactoring")
75
105
parser.add_option("-w", "--write", action="store_true",
76
106
help="Write back modified files")
77
107
parser.add_option("-n", "--nobackups", action="store_true", default=False,
80
110
# Parse command line arguments
81
111
refactor_stdin = False
82
113
options, args = parser.parse_args(args)
114
if not options.write and options.no_diffs:
115
warn("not writing files and not printing diffs; that's not very useful")
83
116
if not options.write and options.nobackups:
84
117
parser.error("Can't use -n without -w")
85
118
if options.list_fixes:
92
print >>sys.stderr, "At least one file or directory argument required."
93
print >>sys.stderr, "Use --help to show usage."
125
print >> sys.stderr, "At least one file or directory argument required."
126
print >> sys.stderr, "Use --help to show usage."
96
129
refactor_stdin = True
98
print >>sys.stderr, "Can't write to stdin."
131
print >> sys.stderr, "Can't write to stdin."
133
if options.print_function:
134
flags["print_function"] = True
101
136
# Set up logging handler
102
137
level = logging.DEBUG if options.verbose else logging.INFO
103
138
logging.basicConfig(format='%(name)s: %(message)s', level=level)
105
140
# Initialize the refactoring tool
106
rt_opts = {"print_function" : options.print_function}
107
141
avail_fixes = set(refactor.get_fixers_from_package(fixer_pkg))
108
142
unwanted_fixes = set(fixer_pkg + ".fix_" + fix for fix in options.nofix)
119
153
requested = avail_fixes.union(explicit)
120
154
fixer_names = requested.difference(unwanted_fixes)
121
rt = StdoutRefactoringTool(sorted(fixer_names), rt_opts, sorted(explicit),
155
rt = StdoutRefactoringTool(sorted(fixer_names), flags, sorted(explicit),
156
options.nobackups, not options.no_diffs)
124
158
# Refactor all files and directories passed as arguments
125
159
if not rt.errors:
126
160
if refactor_stdin:
127
161
rt.refactor_stdin()
129
rt.refactor(args, options.write, options.doctests_only)
164
rt.refactor(args, options.write, options.doctests_only,
166
except refactor.MultiprocessingUnsupported:
167
assert options.processes > 1
168
print >> sys.stderr, "Sorry, -j isn't " \
169
"supported on this platform."
132
173
# Return error status (0 if rt.errors is zero)