github.com/GoogleContainerTools/kaniko@v1.23.0/hack/boilerplate/boilerplate.py (about) 1 #!/usr/bin/env python3 2 3 # Copyright 2018 Google LLC 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 from __future__ import print_function 18 19 import argparse 20 import glob 21 import os 22 import re 23 import sys 24 25 26 SKIPPED_DIRS = ["Godeps", "third_party", ".git", "vendor", "examples", "testdata"] 27 SKIPPED_FILES = ["install_golint.sh"] 28 29 parser = argparse.ArgumentParser() 30 parser.add_argument("filenames", help="list of files to check, all files if unspecified", nargs='*') 31 32 rootdir = os.path.dirname(__file__) + "/../" 33 rootdir = os.path.abspath(rootdir) 34 parser.add_argument("--rootdir", default=rootdir, help="root directory to examine") 35 36 default_boilerplate_dir = os.path.join(rootdir, "/boilerplate") 37 parser.add_argument("--boilerplate-dir", default=default_boilerplate_dir) 38 args = parser.parse_args() 39 40 41 def get_refs(): 42 refs = {} 43 44 for path in glob.glob(os.path.join(args.boilerplate_dir, "boilerplate.*.txt")): 45 extension = os.path.basename(path).split(".")[1] 46 47 ref_file = open(path, 'r') 48 ref = ref_file.read().splitlines() 49 ref_file.close() 50 refs[extension] = ref 51 52 return refs 53 54 def file_passes(filename, refs, regexs): 55 try: 56 f = open(filename, 'r') 57 except: 58 return False 59 60 data = f.read() 61 f.close() 62 63 basename = os.path.basename(filename) 64 extension = file_extension(filename) 65 if extension != "": 66 ref = refs[extension] 67 else: 68 ref = refs[basename] 69 70 # remove build tags from the top of Go files 71 if extension == "go": 72 p = regexs["go_build_constraints_go"] 73 (data, found) = p.subn("", data, 1) 74 75 if extension == "go": 76 p = regexs["go_build_constraints"] 77 (data, found) = p.subn("", data, 1) 78 79 # remove shebang from the top of shell files 80 elif extension == "sh": 81 p = regexs["shebang"] 82 (data, found) = p.subn("", data, 1) 83 84 data = data.splitlines() 85 86 # if our test file is smaller than the reference it surely fails! 87 if len(ref) > len(data): 88 return False 89 90 # trim our file to the same number of lines as the reference file 91 data = data[:len(ref)] 92 93 p = regexs["year"] 94 for d in data: 95 if p.search(d): 96 return False 97 98 # Replace all occurrences of the date regex with "YEAR" 99 p = regexs["date"] 100 for i, d in enumerate(data): 101 (data[i], found) = p.subn('YEAR', d) 102 if found != 0: 103 break 104 105 # if we don't match the reference at this point, fail 106 if ref != data: 107 return False 108 109 return True 110 111 def file_extension(filename): 112 return os.path.splitext(filename)[1].split(".")[-1].lower() 113 114 def normalize_files(files): 115 newfiles = [] 116 for i, pathname in enumerate(files): 117 if not os.path.isabs(pathname): 118 newfiles.append(os.path.join(args.rootdir, pathname)) 119 return newfiles 120 121 def get_files(extensions): 122 files = [] 123 if len(args.filenames) > 0: 124 files = args.filenames 125 else: 126 for root, dirs, walkfiles in os.walk(args.rootdir): 127 for d in SKIPPED_DIRS: 128 if d in dirs: 129 dirs.remove(d) 130 131 for name in walkfiles: 132 if name not in SKIPPED_FILES: 133 pathname = os.path.join(root, name) 134 files.append(pathname) 135 136 files = normalize_files(files) 137 outfiles = [] 138 for pathname in files: 139 basename = os.path.basename(pathname) 140 extension = file_extension(pathname) 141 if extension in extensions or basename in extensions: 142 outfiles.append(pathname) 143 return outfiles 144 145 def get_regexs(): 146 regexs = {} 147 # Search for "YEAR" which exists in the boilerplate, but shouldn't in the real thing 148 regexs["year"] = re.compile( 'YEAR' ) 149 # dates can be any year [2000-2099] company holder names can be anything 150 regexs["date"] = re.compile( '(20\d\d)' ) 151 # strip // go:build \n\n build constraints 152 regexs["go_build_constraints_go"] = re.compile(r"^(//go\:build.*)+\n", re.MULTILINE) 153 # strip // +build \n\n build constraints 154 regexs["go_build_constraints"] = re.compile(r"^(// \+build.*\n)+\n", re.MULTILINE) 155 # strip #!.* from shell scripts 156 regexs["shebang"] = re.compile(r"^(#!.*\n)\n*", re.MULTILINE) 157 return regexs 158 159 def main(): 160 regexs = get_regexs() 161 refs = get_refs() 162 filenames = get_files(refs.keys()) 163 164 for filename in filenames: 165 if not file_passes(filename, refs, regexs): 166 print(filename, file=sys.stdout) 167 168 if __name__ == "__main__": 169 sys.exit(main())