18951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin Peterson""" 28951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin PetersonMain program for 2to3. 38951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin Peterson""" 48951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin Peterson 52acbae80165390a5be3bb12351147b8026787e13Zachary Warefrom __future__ import with_statement, print_function 68d26b0be6dba383c8aa8c9496da9eccff630238eBenjamin Peterson 78951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin Petersonimport sys 88951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin Petersonimport os 93059b00f65f8b01aa7b214b7030783c748ecc70cBenjamin Petersonimport difflib 108951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin Petersonimport logging 110b24b3d9511f8f838da4dfb9a59255aff5fcf72eBenjamin Petersonimport shutil 128951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin Petersonimport optparse 138951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin Peterson 148951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin Petersonfrom . import refactor 158951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin Peterson 163059b00f65f8b01aa7b214b7030783c748ecc70cBenjamin Peterson 173059b00f65f8b01aa7b214b7030783c748ecc70cBenjamin Petersondef diff_texts(a, b, filename): 183059b00f65f8b01aa7b214b7030783c748ecc70cBenjamin Peterson """Return a unified diff of two strings.""" 193059b00f65f8b01aa7b214b7030783c748ecc70cBenjamin Peterson a = a.splitlines() 203059b00f65f8b01aa7b214b7030783c748ecc70cBenjamin Peterson b = b.splitlines() 213059b00f65f8b01aa7b214b7030783c748ecc70cBenjamin Peterson return difflib.unified_diff(a, b, filename, filename, 223059b00f65f8b01aa7b214b7030783c748ecc70cBenjamin Peterson "(original)", "(refactored)", 233059b00f65f8b01aa7b214b7030783c748ecc70cBenjamin Peterson lineterm="") 243059b00f65f8b01aa7b214b7030783c748ecc70cBenjamin Peterson 253059b00f65f8b01aa7b214b7030783c748ecc70cBenjamin Peterson 26608d8bcdfc1762cde31efdf02a6379a06d7964b1Benjamin Petersonclass StdoutRefactoringTool(refactor.MultiprocessRefactoringTool): 27d61de7f18db0eb9763a046f547053ccc59f2bfc5Benjamin Peterson """ 2858f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith A refactoring tool that can avoid overwriting its input files. 29d61de7f18db0eb9763a046f547053ccc59f2bfc5Benjamin Peterson Prints output to stdout. 3058f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith 3158f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith Output files can optionally be written to a different directory and or 3258f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith have an extra file suffix appended to their name for use in situations 3358f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith where you do not want to replace the input files. 34d61de7f18db0eb9763a046f547053ccc59f2bfc5Benjamin Peterson """ 35d61de7f18db0eb9763a046f547053ccc59f2bfc5Benjamin Peterson 3658f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith def __init__(self, fixers, options, explicit, nobackups, show_diffs, 3758f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith input_base_dir='', output_dir='', append_suffix=''): 3858f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith """ 3958f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith Args: 4058f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith fixers: A list of fixers to import. 4158f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith options: A dict with RefactoringTool configuration. 4258f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith explicit: A list of fixers to run even if they are explicit. 4358f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith nobackups: If true no backup '.bak' files will be created for those 4458f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith files that are being refactored. 4558f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith show_diffs: Should diffs of the refactoring be printed to stdout? 4658f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith input_base_dir: The base directory for all input files. This class 4758f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith will strip this path prefix off of filenames before substituting 4858f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith it with output_dir. Only meaningful if output_dir is supplied. 4958f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith All files processed by refactor() must start with this path. 5058f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith output_dir: If supplied, all converted files will be written into 5158f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith this directory tree instead of input_base_dir. 5258f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith append_suffix: If supplied, all files output by this tool will have 5358f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith this appended to their filename. Useful for changing .py to 5458f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith .py3 for example by passing append_suffix='3'. 5558f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith """ 56206e3074d34aeb5a4d0c1e24d970b6569f7ad702Benjamin Peterson self.nobackups = nobackups 573059b00f65f8b01aa7b214b7030783c748ecc70cBenjamin Peterson self.show_diffs = show_diffs 5858f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith if input_base_dir and not input_base_dir.endswith(os.sep): 5958f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith input_base_dir += os.sep 6058f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith self._input_base_dir = input_base_dir 6158f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith self._output_dir = output_dir 6258f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith self._append_suffix = append_suffix 63206e3074d34aeb5a4d0c1e24d970b6569f7ad702Benjamin Peterson super(StdoutRefactoringTool, self).__init__(fixers, options, explicit) 64206e3074d34aeb5a4d0c1e24d970b6569f7ad702Benjamin Peterson 65d61de7f18db0eb9763a046f547053ccc59f2bfc5Benjamin Peterson def log_error(self, msg, *args, **kwargs): 66d61de7f18db0eb9763a046f547053ccc59f2bfc5Benjamin Peterson self.errors.append((msg, args, kwargs)) 67d61de7f18db0eb9763a046f547053ccc59f2bfc5Benjamin Peterson self.logger.error(msg, *args, **kwargs) 68d61de7f18db0eb9763a046f547053ccc59f2bfc5Benjamin Peterson 69d481e3d7914d20238c62c76991255b3b2b5e4a17Benjamin Peterson def write_file(self, new_text, filename, old_text, encoding): 7058f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith orig_filename = filename 7158f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith if self._output_dir: 7258f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith if filename.startswith(self._input_base_dir): 7358f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith filename = os.path.join(self._output_dir, 7458f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith filename[len(self._input_base_dir):]) 7558f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith else: 7658f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith raise ValueError('filename %s does not start with the ' 7758f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith 'input_base_dir %s' % ( 7858f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith filename, self._input_base_dir)) 7958f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith if self._append_suffix: 8058f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith filename += self._append_suffix 8158f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith if orig_filename != filename: 82efc66f9e365be38ffb3db5252a10170df8a947acGregory P. Smith output_dir = os.path.dirname(filename) 83efc66f9e365be38ffb3db5252a10170df8a947acGregory P. Smith if not os.path.isdir(output_dir): 84efc66f9e365be38ffb3db5252a10170df8a947acGregory P. Smith os.makedirs(output_dir) 85efc66f9e365be38ffb3db5252a10170df8a947acGregory P. Smith self.log_message('Writing converted %s to %s.', orig_filename, 86efc66f9e365be38ffb3db5252a10170df8a947acGregory P. Smith filename) 87206e3074d34aeb5a4d0c1e24d970b6569f7ad702Benjamin Peterson if not self.nobackups: 88206e3074d34aeb5a4d0c1e24d970b6569f7ad702Benjamin Peterson # Make backup 89206e3074d34aeb5a4d0c1e24d970b6569f7ad702Benjamin Peterson backup = filename + ".bak" 90206e3074d34aeb5a4d0c1e24d970b6569f7ad702Benjamin Peterson if os.path.lexists(backup): 91206e3074d34aeb5a4d0c1e24d970b6569f7ad702Benjamin Peterson try: 92206e3074d34aeb5a4d0c1e24d970b6569f7ad702Benjamin Peterson os.remove(backup) 93ad28c7f9dad791567afa0624acfb3ba430851965Andrew Svetlov except OSError as err: 94206e3074d34aeb5a4d0c1e24d970b6569f7ad702Benjamin Peterson self.log_message("Can't remove backup %s", backup) 95206e3074d34aeb5a4d0c1e24d970b6569f7ad702Benjamin Peterson try: 96206e3074d34aeb5a4d0c1e24d970b6569f7ad702Benjamin Peterson os.rename(filename, backup) 97ad28c7f9dad791567afa0624acfb3ba430851965Andrew Svetlov except OSError as err: 98206e3074d34aeb5a4d0c1e24d970b6569f7ad702Benjamin Peterson self.log_message("Can't rename %s to %s", filename, backup) 99206e3074d34aeb5a4d0c1e24d970b6569f7ad702Benjamin Peterson # Actually write the new file 100d481e3d7914d20238c62c76991255b3b2b5e4a17Benjamin Peterson write = super(StdoutRefactoringTool, self).write_file 101d481e3d7914d20238c62c76991255b3b2b5e4a17Benjamin Peterson write(new_text, filename, old_text, encoding) 1029203501bae35a7a6fbec2287324382075177872dBenjamin Peterson if not self.nobackups: 1038bcddcabd770dd424b97d7c667ef8e5337436215Benjamin Peterson shutil.copymode(backup, filename) 10458f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith if orig_filename != filename: 10558f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith # Preserve the file mode in the new output directory. 10658f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith shutil.copymode(orig_filename, filename) 107206e3074d34aeb5a4d0c1e24d970b6569f7ad702Benjamin Peterson 1083059b00f65f8b01aa7b214b7030783c748ecc70cBenjamin Peterson def print_output(self, old, new, filename, equal): 1093059b00f65f8b01aa7b214b7030783c748ecc70cBenjamin Peterson if equal: 1103059b00f65f8b01aa7b214b7030783c748ecc70cBenjamin Peterson self.log_message("No changes to %s", filename) 1113059b00f65f8b01aa7b214b7030783c748ecc70cBenjamin Peterson else: 1123059b00f65f8b01aa7b214b7030783c748ecc70cBenjamin Peterson self.log_message("Refactored %s", filename) 1133059b00f65f8b01aa7b214b7030783c748ecc70cBenjamin Peterson if self.show_diffs: 114ffa94b0f022a697dd491a0c31acd2e3b2629c048Benjamin Peterson diff_lines = diff_texts(old, new, filename) 115ffa94b0f022a697dd491a0c31acd2e3b2629c048Benjamin Peterson try: 1168d26b0be6dba383c8aa8c9496da9eccff630238eBenjamin Peterson if self.output_lock is not None: 1178d26b0be6dba383c8aa8c9496da9eccff630238eBenjamin Peterson with self.output_lock: 1188d26b0be6dba383c8aa8c9496da9eccff630238eBenjamin Peterson for line in diff_lines: 1198d26b0be6dba383c8aa8c9496da9eccff630238eBenjamin Peterson print(line) 1208d26b0be6dba383c8aa8c9496da9eccff630238eBenjamin Peterson sys.stdout.flush() 1218d26b0be6dba383c8aa8c9496da9eccff630238eBenjamin Peterson else: 1228d26b0be6dba383c8aa8c9496da9eccff630238eBenjamin Peterson for line in diff_lines: 1238d26b0be6dba383c8aa8c9496da9eccff630238eBenjamin Peterson print(line) 124ffa94b0f022a697dd491a0c31acd2e3b2629c048Benjamin Peterson except UnicodeEncodeError: 125ffa94b0f022a697dd491a0c31acd2e3b2629c048Benjamin Peterson warn("couldn't encode %s's diff for your terminal" % 126ffa94b0f022a697dd491a0c31acd2e3b2629c048Benjamin Peterson (filename,)) 127ffa94b0f022a697dd491a0c31acd2e3b2629c048Benjamin Peterson return 1283059b00f65f8b01aa7b214b7030783c748ecc70cBenjamin Peterson 1293059b00f65f8b01aa7b214b7030783c748ecc70cBenjamin Petersondef warn(msg): 1308fb00bef2747b832c828981f2b54d2f88495694fBenjamin Peterson print("WARNING: %s" % (msg,), file=sys.stderr) 131d61de7f18db0eb9763a046f547053ccc59f2bfc5Benjamin Peterson 132d61de7f18db0eb9763a046f547053ccc59f2bfc5Benjamin Peterson 1338951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin Petersondef main(fixer_pkg, args=None): 1348951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin Peterson """Main program. 1358951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin Peterson 1368951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin Peterson Args: 1378951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin Peterson fixer_pkg: the name of a package where the fixers are located. 1388951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin Peterson args: optional; a list of command line arguments. If omitted, 1398951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin Peterson sys.argv[1:] is used. 1408951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin Peterson 1418951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin Peterson Returns a suggested exit status (0, 1, 2). 1428951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin Peterson """ 1438951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin Peterson # Set up option parser 1440b24b3d9511f8f838da4dfb9a59255aff5fcf72eBenjamin Peterson parser = optparse.OptionParser(usage="2to3 [options] file|dir ...") 1458951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin Peterson parser.add_option("-d", "--doctests_only", action="store_true", 1468951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin Peterson help="Fix up doctests only") 1478951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin Peterson parser.add_option("-f", "--fix", action="append", default=[], 148206e3074d34aeb5a4d0c1e24d970b6569f7ad702Benjamin Peterson help="Each FIX specifies a transformation; default: all") 149608d8bcdfc1762cde31efdf02a6379a06d7964b1Benjamin Peterson parser.add_option("-j", "--processes", action="store", default=1, 150608d8bcdfc1762cde31efdf02a6379a06d7964b1Benjamin Peterson type="int", help="Run 2to3 concurrently") 151206e3074d34aeb5a4d0c1e24d970b6569f7ad702Benjamin Peterson parser.add_option("-x", "--nofix", action="append", default=[], 152e2bb4eb77b24a1870bd7feb15124b7adf1460efeMartin v. Löwis help="Prevent a transformation from being run") 1538951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin Peterson parser.add_option("-l", "--list-fixes", action="store_true", 1548d26b0be6dba383c8aa8c9496da9eccff630238eBenjamin Peterson help="List available transformations") 1558951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin Peterson parser.add_option("-p", "--print-function", action="store_true", 1562021100d6daec7ed40f9a47c97184d3fe708ed8dBenjamin Peterson help="Modify the grammar so that print() is a function") 1578951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin Peterson parser.add_option("-v", "--verbose", action="store_true", 1588951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin Peterson help="More verbose logging") 1593059b00f65f8b01aa7b214b7030783c748ecc70cBenjamin Peterson parser.add_option("--no-diffs", action="store_true", 1603059b00f65f8b01aa7b214b7030783c748ecc70cBenjamin Peterson help="Don't show diffs of the refactoring") 1618951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin Peterson parser.add_option("-w", "--write", action="store_true", 1628951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin Peterson help="Write back modified files") 163206e3074d34aeb5a4d0c1e24d970b6569f7ad702Benjamin Peterson parser.add_option("-n", "--nobackups", action="store_true", default=False, 164e2bb4eb77b24a1870bd7feb15124b7adf1460efeMartin v. Löwis help="Don't write backups for modified files") 16558f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith parser.add_option("-o", "--output-dir", action="store", type="str", 16658f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith default="", help="Put output files in this directory " 16758f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith "instead of overwriting the input files. Requires -n.") 16858f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith parser.add_option("-W", "--write-unchanged-files", action="store_true", 16958f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith help="Also write files even if no changes were required" 17058f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith " (useful with --output-dir); implies -w.") 17158f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith parser.add_option("--add-suffix", action="store", type="str", default="", 17258f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith help="Append this string to all output filenames." 17358f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith " Requires -n if non-empty. " 17458f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith "ex: --add-suffix='3' will generate .py3 files.") 1758951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin Peterson 1768951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin Peterson # Parse command line arguments 1778951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin Peterson refactor_stdin = False 1782021100d6daec7ed40f9a47c97184d3fe708ed8dBenjamin Peterson flags = {} 1798951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin Peterson options, args = parser.parse_args(args) 18058f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith if options.write_unchanged_files: 18158f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith flags["write_unchanged_files"] = True 18258f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith if not options.write: 18358f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith warn("--write-unchanged-files/-W implies -w.") 18458f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith options.write = True 18558f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith # If we allowed these, the original files would be renamed to backup names 18658f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith # but not replaced. 18758f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith if options.output_dir and not options.nobackups: 18858f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith parser.error("Can't use --output-dir/-o without -n.") 18958f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith if options.add_suffix and not options.nobackups: 19058f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith parser.error("Can't use --add-suffix without -n.") 19158f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith 1923059b00f65f8b01aa7b214b7030783c748ecc70cBenjamin Peterson if not options.write and options.no_diffs: 1933059b00f65f8b01aa7b214b7030783c748ecc70cBenjamin Peterson warn("not writing files and not printing diffs; that's not very useful") 194206e3074d34aeb5a4d0c1e24d970b6569f7ad702Benjamin Peterson if not options.write and options.nobackups: 195206e3074d34aeb5a4d0c1e24d970b6569f7ad702Benjamin Peterson parser.error("Can't use -n without -w") 1968951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin Peterson if options.list_fixes: 197c0a40ab6237ffea6feabb602853ba16aae9471f4Benjamin Peterson print("Available transformations for the -f/--fix option:") 1988951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin Peterson for fixname in refactor.get_all_fix_names(fixer_pkg): 199c0a40ab6237ffea6feabb602853ba16aae9471f4Benjamin Peterson print(fixname) 2008951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin Peterson if not args: 2018951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin Peterson return 0 2028951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin Peterson if not args: 203c0a40ab6237ffea6feabb602853ba16aae9471f4Benjamin Peterson print("At least one file or directory argument required.", file=sys.stderr) 204c0a40ab6237ffea6feabb602853ba16aae9471f4Benjamin Peterson print("Use --help to show usage.", file=sys.stderr) 2058951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin Peterson return 2 2068951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin Peterson if "-" in args: 2078951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin Peterson refactor_stdin = True 2088951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin Peterson if options.write: 209c0a40ab6237ffea6feabb602853ba16aae9471f4Benjamin Peterson print("Can't write to stdin.", file=sys.stderr) 2108951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin Peterson return 2 2112021100d6daec7ed40f9a47c97184d3fe708ed8dBenjamin Peterson if options.print_function: 2122021100d6daec7ed40f9a47c97184d3fe708ed8dBenjamin Peterson flags["print_function"] = True 2138951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin Peterson 2148951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin Peterson # Set up logging handler 2158951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin Peterson level = logging.DEBUG if options.verbose else logging.INFO 2168951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin Peterson logging.basicConfig(format='%(name)s: %(message)s', level=level) 21758f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith logger = logging.getLogger('lib2to3.main') 2188951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin Peterson 2198951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin Peterson # Initialize the refactoring tool 220206e3074d34aeb5a4d0c1e24d970b6569f7ad702Benjamin Peterson avail_fixes = set(refactor.get_fixers_from_package(fixer_pkg)) 221206e3074d34aeb5a4d0c1e24d970b6569f7ad702Benjamin Peterson unwanted_fixes = set(fixer_pkg + ".fix_" + fix for fix in options.nofix) 222206e3074d34aeb5a4d0c1e24d970b6569f7ad702Benjamin Peterson explicit = set() 2238951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin Peterson if options.fix: 224206e3074d34aeb5a4d0c1e24d970b6569f7ad702Benjamin Peterson all_present = False 225206e3074d34aeb5a4d0c1e24d970b6569f7ad702Benjamin Peterson for fix in options.fix: 226206e3074d34aeb5a4d0c1e24d970b6569f7ad702Benjamin Peterson if fix == "all": 227206e3074d34aeb5a4d0c1e24d970b6569f7ad702Benjamin Peterson all_present = True 228206e3074d34aeb5a4d0c1e24d970b6569f7ad702Benjamin Peterson else: 229206e3074d34aeb5a4d0c1e24d970b6569f7ad702Benjamin Peterson explicit.add(fixer_pkg + ".fix_" + fix) 230206e3074d34aeb5a4d0c1e24d970b6569f7ad702Benjamin Peterson requested = avail_fixes.union(explicit) if all_present else explicit 2318951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin Peterson else: 232206e3074d34aeb5a4d0c1e24d970b6569f7ad702Benjamin Peterson requested = avail_fixes.union(explicit) 233206e3074d34aeb5a4d0c1e24d970b6569f7ad702Benjamin Peterson fixer_names = requested.difference(unwanted_fixes) 23458f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith input_base_dir = os.path.commonprefix(args) 23558f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith if (input_base_dir and not input_base_dir.endswith(os.sep) 23658f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith and not os.path.isdir(input_base_dir)): 23758f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith # One or more similar names were passed, their directory is the base. 23858f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith # os.path.commonprefix() is ignorant of path elements, this corrects 23958f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith # for that weird API. 24058f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith input_base_dir = os.path.dirname(input_base_dir) 24158f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith if options.output_dir: 24258f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith input_base_dir = input_base_dir.rstrip(os.sep) 24358f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith logger.info('Output in %r will mirror the input directory %r layout.', 24458f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith options.output_dir, input_base_dir) 24558f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith rt = StdoutRefactoringTool( 24658f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith sorted(fixer_names), flags, sorted(explicit), 24758f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith options.nobackups, not options.no_diffs, 24858f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith input_base_dir=input_base_dir, 24958f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith output_dir=options.output_dir, 25058f23ffb21b0fadb8df91c7c9735401f50b3e844Gregory P. Smith append_suffix=options.add_suffix) 2518951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin Peterson 2528951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin Peterson # Refactor all files and directories passed as arguments 2538951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin Peterson if not rt.errors: 2548951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin Peterson if refactor_stdin: 2558951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin Peterson rt.refactor_stdin() 2568951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin Peterson else: 257608d8bcdfc1762cde31efdf02a6379a06d7964b1Benjamin Peterson try: 258608d8bcdfc1762cde31efdf02a6379a06d7964b1Benjamin Peterson rt.refactor(args, options.write, options.doctests_only, 259608d8bcdfc1762cde31efdf02a6379a06d7964b1Benjamin Peterson options.processes) 260608d8bcdfc1762cde31efdf02a6379a06d7964b1Benjamin Peterson except refactor.MultiprocessingUnsupported: 261608d8bcdfc1762cde31efdf02a6379a06d7964b1Benjamin Peterson assert options.processes > 1 2628fb00bef2747b832c828981f2b54d2f88495694fBenjamin Peterson print("Sorry, -j isn't supported on this platform.", 2638fb00bef2747b832c828981f2b54d2f88495694fBenjamin Peterson file=sys.stderr) 264608d8bcdfc1762cde31efdf02a6379a06d7964b1Benjamin Peterson return 1 2658951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin Peterson rt.summarize() 2668951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin Peterson 2678951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin Peterson # Return error status (0 if rt.errors is zero) 2688951b6172cdfcbc6c14949c4b9fa32908615d49cBenjamin Peterson return int(bool(rt.errors)) 269