| 1 | #! /usr/bin/env python
|
|---|
| 2 |
|
|---|
| 3 | # Released to the public domain, by Tim Peters, 03 October 2000.
|
|---|
| 4 |
|
|---|
| 5 | """reindent [-d][-r][-v] [ path ... ]
|
|---|
| 6 |
|
|---|
| 7 | -d (--dryrun) Dry run. Analyze, but don't make any changes to, files.
|
|---|
| 8 | -r (--recurse) Recurse. Search for all .py files in subdirectories too.
|
|---|
| 9 | -v (--verbose) Verbose. Print informative msgs; else no output.
|
|---|
| 10 | -h (--help) Help. Print this usage information and exit.
|
|---|
| 11 |
|
|---|
| 12 | Change Python (.py) files to use 4-space indents and no hard tab characters.
|
|---|
| 13 | Also trim excess spaces and tabs from ends of lines, and remove empty lines
|
|---|
| 14 | at the end of files. Also ensure the last line ends with a newline.
|
|---|
| 15 |
|
|---|
| 16 | If no paths are given on the command line, reindent operates as a filter,
|
|---|
| 17 | reading a single source file from standard input and writing the transformed
|
|---|
| 18 | source to standard output. In this case, the -d, -r and -v flags are
|
|---|
| 19 | ignored.
|
|---|
| 20 |
|
|---|
| 21 | You can pass one or more file and/or directory paths. When a directory
|
|---|
| 22 | path, all .py files within the directory will be examined, and, if the -r
|
|---|
| 23 | option is given, likewise recursively for subdirectories.
|
|---|
| 24 |
|
|---|
| 25 | If output is not to standard output, reindent overwrites files in place,
|
|---|
| 26 | renaming the originals with a .bak extension. If it finds nothing to
|
|---|
| 27 | change, the file is left alone. If reindent does change a file, the changed
|
|---|
| 28 | file is a fixed-point for future runs (i.e., running reindent on the
|
|---|
| 29 | resulting .py file won't change it again).
|
|---|
| 30 |
|
|---|
| 31 | The hard part of reindenting is figuring out what to do with comment
|
|---|
| 32 | lines. So long as the input files get a clean bill of health from
|
|---|
| 33 | tabnanny.py, reindent should do a good job.
|
|---|
| 34 | """
|
|---|
| 35 |
|
|---|
| 36 | __version__ = "1"
|
|---|
| 37 |
|
|---|
| 38 | import tokenize
|
|---|
| 39 | import os
|
|---|
| 40 | import sys
|
|---|
| 41 |
|
|---|
| 42 | verbose = 0
|
|---|
| 43 | recurse = 0
|
|---|
| 44 | dryrun = 0
|
|---|
| 45 |
|
|---|
| 46 | def usage(msg=None):
|
|---|
| 47 | if msg is not None:
|
|---|
| 48 | print >> sys.stderr, msg
|
|---|
| 49 | print >> sys.stderr, __doc__
|
|---|
| 50 |
|
|---|
| 51 | def errprint(*args):
|
|---|
| 52 | sep = ""
|
|---|
| 53 | for arg in args:
|
|---|
| 54 | sys.stderr.write(sep + str(arg))
|
|---|
| 55 | sep = " "
|
|---|
| 56 | sys.stderr.write("\n")
|
|---|
| 57 |
|
|---|
| 58 | def main():
|
|---|
| 59 | import getopt
|
|---|
| 60 | global verbose, recurse, dryrun
|
|---|
| 61 | try:
|
|---|
| 62 | opts, args = getopt.getopt(sys.argv[1:], "drvh",
|
|---|
| 63 | ["dryrun", "recurse", "verbose", "help"])
|
|---|
| 64 | except getopt.error, msg:
|
|---|
| 65 | usage(msg)
|
|---|
| 66 | return
|
|---|
| 67 | for o, a in opts:
|
|---|
| 68 | if o in ('-d', '--dryrun'):
|
|---|
| 69 | dryrun += 1
|
|---|
| 70 | elif o in ('-r', '--recurse'):
|
|---|
| 71 | recurse += 1
|
|---|
| 72 | elif o in ('-v', '--verbose'):
|
|---|
| 73 | verbose += 1
|
|---|
| 74 | elif o in ('-h', '--help'):
|
|---|
| 75 | usage()
|
|---|
| 76 | return
|
|---|
| 77 | if not args:
|
|---|
| 78 | r = Reindenter(sys.stdin)
|
|---|
| 79 | r.run()
|
|---|
| 80 | r.write(sys.stdout)
|
|---|
| 81 | return
|
|---|
| 82 | for arg in args:
|
|---|
| 83 | check(arg)
|
|---|
| 84 |
|
|---|
| 85 | def check(file):
|
|---|
| 86 | if os.path.isdir(file) and not os.path.islink(file):
|
|---|
| 87 | if verbose:
|
|---|
| 88 | print "listing directory", file
|
|---|
| 89 | names = os.listdir(file)
|
|---|
| 90 | for name in names:
|
|---|
| 91 | fullname = os.path.join(file, name)
|
|---|
| 92 | if ((recurse and os.path.isdir(fullname) and
|
|---|
| 93 | not os.path.islink(fullname))
|
|---|
| 94 | or name.lower().endswith(".py")):
|
|---|
| 95 | check(fullname)
|
|---|
| 96 | return
|
|---|
| 97 |
|
|---|
| 98 | if verbose:
|
|---|
| 99 | print "checking", file, "...",
|
|---|
| 100 | try:
|
|---|
| 101 | f = open(file)
|
|---|
| 102 | except IOError, msg:
|
|---|
| 103 | errprint("%s: I/O Error: %s" % (file, str(msg)))
|
|---|
| 104 | return
|
|---|
| 105 |
|
|---|
| 106 | r = Reindenter(f)
|
|---|
| 107 | f.close()
|
|---|
| 108 | if r.run():
|
|---|
| 109 | if verbose:
|
|---|
| 110 | print "changed."
|
|---|
| 111 | if dryrun:
|
|---|
| 112 | print "But this is a dry run, so leaving it alone."
|
|---|
| 113 | if not dryrun:
|
|---|
| 114 | bak = file + ".bak"
|
|---|
| 115 | if os.path.exists(bak):
|
|---|
|
|---|