]>
Commit | Line | Data |
---|---|---|
970d7e83 LB |
1 | #!/usr/bin/env python |
2 | ||
3 | """ | |
4 | wciia - Whose Code Is It Anyway | |
5 | ||
6 | Determines code owner of the file/folder relative to the llvm source root. | |
7 | Code owner is determined from the content of the CODE_OWNERS.TXT | |
8 | by parsing the D: field | |
9 | ||
10 | usage: | |
11 | ||
12 | utils/wciia.py path | |
13 | ||
14 | limitations: | |
15 | - must be run from llvm source root | |
16 | - very simplistic algorithm | |
17 | - only handles * as a wildcard | |
18 | - not very user friendly | |
19 | - does not handle the proposed F: field | |
20 | ||
21 | """ | |
22 | ||
23 | import os | |
24 | ||
25 | code_owners = {} | |
26 | ||
27 | def process_files_and_folders(owner): | |
28 | filesfolders = owner['filesfolders'] | |
29 | # paths must be in ( ... ) so strip them | |
30 | lpar = filesfolders.find('(') | |
31 | rpar = filesfolders.rfind(')') | |
32 | if rpar <= lpar: | |
33 | # give up | |
34 | return | |
35 | paths = filesfolders[lpar+1:rpar] | |
36 | # split paths | |
37 | owner['paths'] = [] | |
38 | for path in paths.split(): | |
39 | owner['paths'].append(path) | |
40 | ||
41 | def process_code_owner(owner): | |
42 | if 'filesfolders' in owner: | |
43 | filesfolders = owner['filesfolders'] | |
44 | else: | |
45 | # print "F: field missing, using D: field" | |
46 | owner['filesfolders'] = owner['description'] | |
47 | process_files_and_folders(owner) | |
48 | code_owners[owner['name']] = owner | |
49 | ||
50 | # process CODE_OWNERS.TXT first | |
51 | code_owners_file = open("CODE_OWNERS.TXT", "r").readlines() | |
52 | code_owner = {} | |
53 | for line in code_owners_file: | |
54 | for word in line.split(): | |
55 | if word == "N:": | |
56 | name = line[2:].strip() | |
57 | if code_owner: | |
58 | process_code_owner(code_owner) | |
59 | code_owner = {} | |
60 | # reset the values | |
61 | code_owner['name'] = name | |
62 | if word == "E:": | |
63 | email = line[2:].strip() | |
64 | code_owner['email'] = email | |
65 | if word == "D:": | |
66 | description = line[2:].strip() | |
67 | code_owner['description'] = description | |
68 | if word == "F:": | |
69 | filesfolders = line[2:].strip() | |
70 | code_owner['filesfolders'].append(filesfolders) | |
71 | ||
72 | def find_owners(fpath): | |
73 | onames = [] | |
74 | lmatch = -1 | |
75 | # very simplistic way of findning the best match | |
76 | for name in code_owners: | |
77 | owner = code_owners[name] | |
78 | if 'paths' in owner: | |
79 | for path in owner['paths']: | |
80 | # print "searching (" + path + ")" | |
81 | # try exact match | |
82 | if fpath == path: | |
83 | return name | |
84 | # see if path ends with a * | |
85 | rstar = path.rfind('*') | |
86 | if rstar>0: | |
87 | # try the longest match, | |
88 | rpos = -1 | |
89 | if len(fpath) < len(path): | |
90 | rpos = path.find(fpath) | |
91 | if rpos == 0: | |
92 | onames.append(name) | |
93 | onames.append('Chris Lattner') | |
94 | return onames | |
95 | ||
96 | # now lest try to find the owner of the file or folder | |
97 | import sys | |
98 | ||
99 | if len(sys.argv) < 2: | |
100 | print "usage " + sys.argv[0] + " file_or_folder" | |
101 | exit(-1) | |
102 | ||
103 | # the path we are checking | |
104 | path = str(sys.argv[1]) | |
105 | ||
106 | # check if this is real path | |
107 | if not os.path.exists(path): | |
108 | print "path (" + path + ") does not exist" | |
109 | exit(-1) | |
110 | ||
111 | owners_name = find_owners(path) | |
112 | ||
1a4d82fc | 113 | # be grammatically correct |
970d7e83 LB |
114 | print "The owner(s) of the (" + path + ") is(are) : " + str(owners_name) |
115 | ||
116 | exit(0) | |
117 | ||
118 | # bottom up walk of the current . | |
119 | # not yet used | |
120 | root = "." | |
121 | for dir,subdirList,fileList in os.walk( root , topdown=False ) : | |
122 | print "dir :" , dir | |
123 | for fname in fileList : | |
124 | print "-" , fname | |
125 |