Pawel Wodnicki | 723c394 | 2012-11-17 06:35:19 +0000 | [diff] [blame] | 1 | #!/usr/bin/env python |
Pawel Wodnicki | 7e2db21 | 2012-11-17 06:24:37 +0000 | [diff] [blame] | 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 | |
Serge Guelton | 60ccceb | 2019-01-03 14:11:33 +0000 | [diff] [blame] | 23 | from __future__ import print_function |
Pawel Wodnicki | 7e2db21 | 2012-11-17 06:24:37 +0000 | [diff] [blame] | 24 | import os |
| 25 | |
| 26 | code_owners = {} |
| 27 | |
| 28 | def process_files_and_folders(owner): |
| 29 | filesfolders = owner['filesfolders'] |
| 30 | # paths must be in ( ... ) so strip them |
| 31 | lpar = filesfolders.find('(') |
| 32 | rpar = filesfolders.rfind(')') |
| 33 | if rpar <= lpar: |
| 34 | # give up |
| 35 | return |
| 36 | paths = filesfolders[lpar+1:rpar] |
| 37 | # split paths |
| 38 | owner['paths'] = [] |
| 39 | for path in paths.split(): |
| 40 | owner['paths'].append(path) |
| 41 | |
| 42 | def process_code_owner(owner): |
| 43 | if 'filesfolders' in owner: |
| 44 | filesfolders = owner['filesfolders'] |
| 45 | else: |
| 46 | # print "F: field missing, using D: field" |
| 47 | owner['filesfolders'] = owner['description'] |
| 48 | process_files_and_folders(owner) |
| 49 | code_owners[owner['name']] = owner |
| 50 | |
| 51 | # process CODE_OWNERS.TXT first |
| 52 | code_owners_file = open("CODE_OWNERS.TXT", "r").readlines() |
| 53 | code_owner = {} |
| 54 | for line in code_owners_file: |
| 55 | for word in line.split(): |
| 56 | if word == "N:": |
| 57 | name = line[2:].strip() |
| 58 | if code_owner: |
| 59 | process_code_owner(code_owner) |
| 60 | code_owner = {} |
| 61 | # reset the values |
| 62 | code_owner['name'] = name |
| 63 | if word == "E:": |
| 64 | email = line[2:].strip() |
| 65 | code_owner['email'] = email |
| 66 | if word == "D:": |
| 67 | description = line[2:].strip() |
| 68 | code_owner['description'] = description |
| 69 | if word == "F:": |
| 70 | filesfolders = line[2:].strip() |
| 71 | code_owner['filesfolders'].append(filesfolders) |
| 72 | |
| 73 | def find_owners(fpath): |
| 74 | onames = [] |
| 75 | lmatch = -1 |
| 76 | # very simplistic way of findning the best match |
| 77 | for name in code_owners: |
| 78 | owner = code_owners[name] |
| 79 | if 'paths' in owner: |
| 80 | for path in owner['paths']: |
| 81 | # print "searching (" + path + ")" |
| 82 | # try exact match |
| 83 | if fpath == path: |
| 84 | return name |
| 85 | # see if path ends with a * |
| 86 | rstar = path.rfind('*') |
| 87 | if rstar>0: |
| 88 | # try the longest match, |
| 89 | rpos = -1 |
| 90 | if len(fpath) < len(path): |
| 91 | rpos = path.find(fpath) |
| 92 | if rpos == 0: |
| 93 | onames.append(name) |
| 94 | onames.append('Chris Lattner') |
| 95 | return onames |
| 96 | |
| 97 | # now lest try to find the owner of the file or folder |
| 98 | import sys |
| 99 | |
| 100 | if len(sys.argv) < 2: |
Serge Guelton | 60ccceb | 2019-01-03 14:11:33 +0000 | [diff] [blame] | 101 | print("usage " + sys.argv[0] + " file_or_folder") |
Pawel Wodnicki | 7e2db21 | 2012-11-17 06:24:37 +0000 | [diff] [blame] | 102 | exit(-1) |
| 103 | |
| 104 | # the path we are checking |
| 105 | path = str(sys.argv[1]) |
| 106 | |
| 107 | # check if this is real path |
| 108 | if not os.path.exists(path): |
Serge Guelton | 60ccceb | 2019-01-03 14:11:33 +0000 | [diff] [blame] | 109 | print("path (" + path + ") does not exist") |
Pawel Wodnicki | 7e2db21 | 2012-11-17 06:24:37 +0000 | [diff] [blame] | 110 | exit(-1) |
| 111 | |
| 112 | owners_name = find_owners(path) |
| 113 | |
Alp Toker | ae43cab6 | 2014-01-24 17:20:08 +0000 | [diff] [blame] | 114 | # be grammatically correct |
Serge Guelton | 60ccceb | 2019-01-03 14:11:33 +0000 | [diff] [blame] | 115 | print("The owner(s) of the (" + path + ") is(are) : " + str(owners_name)) |
Pawel Wodnicki | 7e2db21 | 2012-11-17 06:24:37 +0000 | [diff] [blame] | 116 | |
| 117 | exit(0) |
| 118 | |
| 119 | # bottom up walk of the current . |
| 120 | # not yet used |
| 121 | root = "." |
| 122 | for dir,subdirList,fileList in os.walk( root , topdown=False ) : |
Serge Guelton | 60ccceb | 2019-01-03 14:11:33 +0000 | [diff] [blame] | 123 | print("dir :" , dir) |
Pawel Wodnicki | 7e2db21 | 2012-11-17 06:24:37 +0000 | [diff] [blame] | 124 | for fname in fileList : |
Serge Guelton | 60ccceb | 2019-01-03 14:11:33 +0000 | [diff] [blame] | 125 | print("-" , fname) |
| 126 | print() |