| 1 | |
|---|
| 2 | |
|---|
| 3 | |
|---|
| 4 | |
|---|
| 5 | |
|---|
| 6 | |
|---|
| 7 | """\ |
|---|
| 8 | This script scans a directory tree for files which contain code which |
|---|
| 9 | is deprecated in ftputil %s and above (and even much longer). The |
|---|
| 10 | script uses simple heuristics, so it may miss occurences of deprecated |
|---|
| 11 | usage or print some inappropriate lines of your files. |
|---|
| 12 | |
|---|
| 13 | Usage: %s start_dir |
|---|
| 14 | |
|---|
| 15 | where start_dir is the starting directory which will be scanned |
|---|
| 16 | recursively for offending code. |
|---|
| 17 | |
|---|
| 18 | Currently, these deprecated features are examined: |
|---|
| 19 | |
|---|
| 20 | - You should no longer use the exceptions via the ftputil module but |
|---|
| 21 | via the ftp_error module. So, for example, instead of |
|---|
| 22 | ftputil.PermanentError write ftp_error.PermanentError. |
|---|
| 23 | |
|---|
| 24 | - Don't use the xreadlines method of FTP file objects (as returned by |
|---|
| 25 | FTPHost.file = FTPHost.open). Instead use |
|---|
| 26 | |
|---|
| 27 | for line in ftp_host.open(path): |
|---|
| 28 | ... |
|---|
| 29 | """ |
|---|
| 30 | |
|---|
| 31 | import ftputil_version |
|---|
| 32 | |
|---|
| 33 | import os |
|---|
| 34 | import re |
|---|
| 35 | import sys |
|---|
| 36 | |
|---|
| 37 | __doc__ = __doc__ % (ftputil_version.__version__, os.path.basename(sys.argv[0])) |
|---|
| 38 | |
|---|
| 39 | deprecated_features = [ |
|---|
| 40 | ("Possible use(s) of FTP exceptions via ftputil module", |
|---|
| 41 | re.compile(r"\bftputil\s*?\.\s*?[A-Za-z]+Error\b"), {}), |
|---|
| 42 | ("Possible use(s) of xreadline method of FTP file objects", |
|---|
| 43 | re.compile(r"\.\s*?xreadlines\b"), {}), |
|---|
| 44 | ] |
|---|
| 45 | |
|---|
| 46 | def scan_file(file_name): |
|---|
| 47 | """ |
|---|
| 48 | Scan a file with name `file_name` for code deprecated in |
|---|
| 49 | ftputil usage and collect the offending data in the data |
|---|
| 50 | structure `deprecated_features`. |
|---|
| 51 | """ |
|---|
| 52 | fobj = open(file_name) |
|---|
| 53 | try: |
|---|
| 54 | for index, line in enumerate(fobj): |
|---|
| 55 | |
|---|
| 56 | |
|---|
| 57 | for title, regex, positions in deprecated_features: |
|---|
| 58 | if regex.search(line): |
|---|
| 59 | positions.setdefault(file_name, []) |
|---|
| 60 | positions[file_name].append((index+1, line.rstrip())) |
|---|
| 61 | finally: |
|---|
| 62 | fobj.close() |
|---|
| 63 | |
|---|
| 64 | def print_results(): |
|---|
| 65 | """ |
|---|
| 66 | Print statistics of deprecated code after the directory has been |
|---|
| 67 | scanned. |
|---|
| 68 | """ |
|---|
| 69 | last_title = "" |
|---|
| 70 | |
|---|
| 71 | |
|---|
| 72 | for title, regex, positions in deprecated_features: |
|---|
| 73 | if title != last_title: |
|---|
| 74 | print |
|---|
| 75 | print title, "..." |
|---|
| 76 | print |
|---|
| 77 | last_title = title |
|---|
| 78 | if not positions: |
|---|
| 79 | print " no deprecated code found" |
|---|
| 80 | continue |
|---|
| 81 | file_names = positions.keys() |
|---|
| 82 | file_names.sort() |
|---|
| 83 | for file_name in file_names: |
|---|
| 84 | print file_name |
|---|
| 85 | for line_number, line in positions[file_name]: |
|---|
| 86 | print "%5d: %s" % (line_number, line) |
|---|
| 87 | print |
|---|
| 88 | print "If possible, check your code also by other means." |
|---|
| 89 | |
|---|
| 90 | def main(start_dir): |
|---|
| 91 | """ |
|---|
| 92 | Scan a directory tree starting at `start_dir` and print uses |
|---|
| 93 | of deprecated features, if any were found. |
|---|
| 94 | """ |
|---|
| 95 | |
|---|
| 96 | |
|---|
| 97 | for dir_path, dir_names, file_names in os.walk(start_dir): |
|---|
| 98 | for file_name in file_names: |
|---|
| 99 | abs_name = os.path.abspath(os.path.join(dir_path, file_name)) |
|---|
| 100 | if file_name.endswith(".py"): |
|---|
| 101 | scan_file(abs_name) |
|---|
| 102 | print_results() |
|---|
| 103 | |
|---|
| 104 | |
|---|
| 105 | if __name__ == '__main__': |
|---|
| 106 | if len(sys.argv) == 2: |
|---|
| 107 | if sys.argv[1] in ("-h", "--help"): |
|---|
| 108 | print __doc__ |
|---|
| 109 | sys.exit(0) |
|---|
| 110 | start_dir = sys.argv[1] |
|---|
| 111 | if not os.path.isdir(start_dir): |
|---|
| 112 | print >> sys.stderr, "Directory %s not found." % start_dir |
|---|
| 113 | sys.exit() |
|---|
| 114 | else: |
|---|
| 115 | print >> sys.stderr, "Usage: %s start_dir" % sys.argv[0] |
|---|
| 116 | sys.exit() |
|---|
| 117 | main(start_dir) |
|---|