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