k8s.io/kubernetes@v1.31.0-alpha.0.0.20240520171757-56147500dadc/hack/verify-flags-underscore.py (about) 1 #!/usr/bin/env python3 2 3 # Copyright 2015 The Kubernetes Authors. 4 # 5 # Licensed under the Apache License, Version 2.0 (the "License"); 6 # you may not use this file except in compliance with the License. 7 # You may obtain a copy of the License at 8 # 9 # http://www.apache.org/licenses/LICENSE-2.0 10 # 11 # Unless required by applicable law or agreed to in writing, software 12 # distributed under the License is distributed on an "AS IS" BASIS, 13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 # See the License for the specific language governing permissions and 15 # limitations under the License. 16 17 import argparse 18 import os 19 import re 20 import sys 21 22 parser = argparse.ArgumentParser() 23 parser.add_argument("filenames", help="list of files to check, all files if unspecified", nargs='*') 24 args = parser.parse_args() 25 26 # Cargo culted from http://stackoverflow.com/questions/898669/how-can-i-detect-if-a-file-is-binary-non-text-in-python 27 def is_binary(pathname): 28 """Return true if the given filename is binary. 29 @raise EnvironmentError: if the file does not exist or cannot be accessed. 30 @attention: found @ http://bytes.com/topic/python/answers/21222-determine-file-type-binary-text on 6/08/2010 31 @author: Trent Mick <TrentM@ActiveState.com> 32 @author: Jorge Orpinel <jorge@orpinel.com>""" 33 try: 34 with open(pathname, 'r') as f: 35 CHUNKSIZE = 1024 36 while True: 37 chunk = f.read(CHUNKSIZE) 38 if '\0' in chunk: # found null byte 39 return True 40 if len(chunk) < CHUNKSIZE: 41 break # done 42 except: 43 return True 44 45 return False 46 47 def get_all_files(rootdir): 48 all_files = [] 49 for root, dirs, files in os.walk(rootdir): 50 # don't visit certain dirs 51 if 'vendor' in dirs: 52 dirs.remove('vendor') 53 if 'staging' in dirs: 54 dirs.remove('staging') 55 if '_output' in dirs: 56 dirs.remove('_output') 57 if 'third_party' in dirs: 58 dirs.remove('third_party') 59 if '.git' in dirs: 60 dirs.remove('.git') 61 62 for name in files: 63 pathname = os.path.join(root, name) 64 if not is_binary(pathname): 65 all_files.append(pathname) 66 return all_files 67 68 # Collects all the flags used in golang files and verifies the flags do 69 # not contain underscore. If any flag needs to be excluded from this check, 70 # need to add that flag in hack/verify-flags/excluded-flags.txt. 71 def check_underscore_in_flags(rootdir, files): 72 # preload the 'known' flags which don't follow the - standard 73 pathname = os.path.join(rootdir, "hack/verify-flags/excluded-flags.txt") 74 f = open(pathname, 'r') 75 excluded_flags = set(f.read().splitlines()) 76 f.close() 77 78 regexs = [ re.compile('Var[P]?\([^,]*, "([^"]*)"'), 79 re.compile('.String[P]?\("([^"]*)",[^,]+,[^)]+\)'), 80 re.compile('.Int[P]?\("([^"]*)",[^,]+,[^)]+\)'), 81 re.compile('.Bool[P]?\("([^"]*)",[^,]+,[^)]+\)'), 82 re.compile('.Duration[P]?\("([^"]*)",[^,]+,[^)]+\)'), 83 re.compile('.StringSlice[P]?\("([^"]*)",[^,]+,[^)]+\)') ] 84 85 new_excluded_flags = set() 86 # walk all the files looking for any flags being declared 87 for pathname in files: 88 if not pathname.endswith(".go"): 89 continue 90 f = open(pathname, 'r') 91 data = f.read() 92 f.close() 93 matches = [] 94 for regex in regexs: 95 matches = matches + regex.findall(data) 96 for flag in matches: 97 if any(x in flag for x in excluded_flags): 98 continue 99 if "_" in flag: 100 new_excluded_flags.add(flag) 101 if len(new_excluded_flags) != 0: 102 print("Found a flag declared with an _ but which is not explicitly listed as a valid flag name in hack/verify-flags/excluded-flags.txt") 103 print("Are you certain this flag should not have been declared with an - instead?") 104 l = list(new_excluded_flags) 105 l.sort() 106 print(("%s" % "\n".join(l))) 107 sys.exit(1) 108 109 def main(): 110 rootdir = os.path.dirname(__file__) + "/../" 111 rootdir = os.path.abspath(rootdir) 112 113 if len(args.filenames) > 0: 114 files = args.filenames 115 else: 116 files = get_all_files(rootdir) 117 118 check_underscore_in_flags(rootdir, files) 119 120 if __name__ == "__main__": 121 sys.exit(main())