Andrew Bartholomew | 2639c50 | 2014-05-10 10:58:07 -0400 | [diff] [blame] | 1 | #!/usr/bin/env python -E |
The Android Open Source Project | 88b6079 | 2009-03-03 19:28:42 -0800 | [diff] [blame] | 2 | |
Anthony King | 91a1c64 | 2015-10-31 14:04:43 -0400 | [diff] [blame] | 3 | from __future__ import print_function |
| 4 | |
The Android Open Source Project | 88b6079 | 2009-03-03 19:28:42 -0800 | [diff] [blame] | 5 | import sys, os, re |
| 6 | |
| 7 | excludes = [r'.*?/\.obj.*?', |
| 8 | r'.*?~', |
| 9 | r'.*?\/.DS_Store', |
| 10 | r'.*?\/.gdb_history', |
| 11 | r'.*?\/buildspec.mk', |
| 12 | r'.*?/\..*?\.swp', |
| 13 | r'.*?/out/.*?', |
| 14 | r'.*?/install/.*?'] |
| 15 | |
Anthony King | 91a1c64 | 2015-10-31 14:04:43 -0400 | [diff] [blame] | 16 | excludes_compiled = list(map(re.compile, excludes)) |
The Android Open Source Project | 88b6079 | 2009-03-03 19:28:42 -0800 | [diff] [blame] | 17 | |
| 18 | def filter_excludes(str): |
| 19 | for e in excludes_compiled: |
| 20 | if e.match(str): |
| 21 | return False |
| 22 | return True |
| 23 | |
| 24 | def split_perforce_parts(s): |
| 25 | spaces = ((s.count(" ") + 1) / 3) * 2 |
| 26 | pos = 0 |
| 27 | while spaces > 0: |
| 28 | pos = s.find(" ", pos) + 1 |
| 29 | spaces = spaces - 1 |
| 30 | return s[pos:] |
| 31 | |
| 32 | def quotate(s): |
| 33 | return '"' + s + '"' |
| 34 | |
| 35 | class PerforceError(Exception): |
| 36 | def __init__(self,value): |
| 37 | self.value = value |
| 38 | def __str__(self): |
| 39 | return repr(self.value) |
| 40 | |
| 41 | |
| 42 | def run(command, regex, filt): |
| 43 | def matchit(s): |
| 44 | m = regex_compiled.match(s) |
| 45 | if m: |
| 46 | return m.group(1) |
| 47 | else: |
| 48 | return "" |
| 49 | def filterit(s): |
| 50 | if filt_compiled.match(s): |
| 51 | return True |
| 52 | else: |
| 53 | return False |
| 54 | |
| 55 | fd = os.popen(command); |
| 56 | lines = fd.readlines() |
| 57 | status = fd.close() |
| 58 | if status: |
| 59 | raise PerforceError("error calling " + command) |
| 60 | |
| 61 | regex_compiled = re.compile(regex) |
| 62 | filt_compiled = re.compile(filt) |
| 63 | |
| 64 | if len(lines) >= 1: |
Anthony King | 91a1c64 | 2015-10-31 14:04:43 -0400 | [diff] [blame] | 65 | lines = list(filter(filterit, lines)) |
The Android Open Source Project | 88b6079 | 2009-03-03 19:28:42 -0800 | [diff] [blame] | 66 | if len(lines) >= 1: |
Anthony King | 91a1c64 | 2015-10-31 14:04:43 -0400 | [diff] [blame] | 67 | return list(map(matchit, lines)) |
The Android Open Source Project | 88b6079 | 2009-03-03 19:28:42 -0800 | [diff] [blame] | 68 | return None |
| 69 | |
| 70 | try: |
| 71 | if len(sys.argv) == 1: |
| 72 | do_exclude = True |
| 73 | elif len(sys.argv) == 2 and sys.argv[1] == "-a": |
| 74 | do_exclude = False |
| 75 | else: |
Anthony King | 91a1c64 | 2015-10-31 14:04:43 -0400 | [diff] [blame] | 76 | print("usage: checktree [-a]") |
| 77 | print(" -a don't filter common crud in the tree") |
The Android Open Source Project | 88b6079 | 2009-03-03 19:28:42 -0800 | [diff] [blame] | 78 | sys.exit(1) |
| 79 | |
| 80 | have = run("p4 have ...", r'[^#]+#[0-9]+ - (.*)', r'.*') |
| 81 | |
| 82 | cwd = os.getcwd() |
| 83 | files = run("find . -not -type d", r'.(.*)', r'.*') |
Anthony King | 91a1c64 | 2015-10-31 14:04:43 -0400 | [diff] [blame] | 84 | files = [cwd+s for s in files] |
The Android Open Source Project | 88b6079 | 2009-03-03 19:28:42 -0800 | [diff] [blame] | 85 | |
| 86 | added_depot_path = run("p4 opened ...", r'([^#]+)#.*', r'.*?#[0-9]+ - add .*'); |
| 87 | added = [] |
| 88 | if added_depot_path: |
Anthony King | 91a1c64 | 2015-10-31 14:04:43 -0400 | [diff] [blame] | 89 | added_depot_path = list(map(quotate, added_depot_path)) |
The Android Open Source Project | 88b6079 | 2009-03-03 19:28:42 -0800 | [diff] [blame] | 90 | |
| 91 | where = "p4 where " + " ".join(added_depot_path) |
| 92 | added = run(where, r'(.*)', r'.*') |
Anthony King | 91a1c64 | 2015-10-31 14:04:43 -0400 | [diff] [blame] | 93 | added = list(map(split_perforce_parts, added)) |
The Android Open Source Project | 88b6079 | 2009-03-03 19:28:42 -0800 | [diff] [blame] | 94 | |
| 95 | extras = [] |
| 96 | |
| 97 | # Python 2.3 -- still default on Mac OS X -- does not have set() |
| 98 | # Make dict's here to support the "in" operations below |
| 99 | have = dict().fromkeys(have, 1) |
| 100 | added = dict().fromkeys(added, 1) |
| 101 | |
| 102 | for file in files: |
| 103 | if not file in have: |
| 104 | if not file in added: |
| 105 | extras.append(file) |
| 106 | |
| 107 | if do_exclude: |
| 108 | extras = filter(filter_excludes, extras) |
| 109 | |
| 110 | for s in extras: |
Anthony King | 91a1c64 | 2015-10-31 14:04:43 -0400 | [diff] [blame] | 111 | print(s.replace(" ", "\\ ")) |
The Android Open Source Project | 88b6079 | 2009-03-03 19:28:42 -0800 | [diff] [blame] | 112 | |
Anthony King | 91a1c64 | 2015-10-31 14:04:43 -0400 | [diff] [blame] | 113 | except PerforceError as e: |
The Android Open Source Project | 88b6079 | 2009-03-03 19:28:42 -0800 | [diff] [blame] | 114 | sys.exit(2) |
| 115 | |