Pawel Wodnicki | 7e2db21 | 2012-11-17 06:24:37 +0000 | [diff] [blame^] | 1 | #! 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 | |
| 113 | # be gramatically correct |
| 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 | print |