Skip to content

Commit 16e6d68

Browse files
authored
Add hack scripts (#353)
1 parent 9ce12de commit 16e6d68

38 files changed

+3596
-4
lines changed

hack/boilerplate.go.txt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
2+
Copyright The Kubernetes Authors.
33

44
Licensed under the Apache License, Version 2.0 (the "License");
55
you may not use this file except in compliance with the License.
@@ -12,4 +12,5 @@ distributed under the License is distributed on an "AS IS" BASIS,
1212
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1313
See the License for the specific language governing permissions and
1414
limitations under the License.
15-
*/
15+
*/
16+
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# syntax=docker/dockerfile:1.1-experimental
2+
3+
# Copyright YEAR 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+
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Copyright YEAR The Kubernetes Authors.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+

hack/boilerplate/boilerplate.bzl.txt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Copyright YEAR The Kubernetes Authors.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Copyright The Kubernetes Authors.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/*
2+
Copyright The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+

hack/boilerplate/boilerplate.go.txt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/*
2+
Copyright YEAR The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/

hack/boilerplate/boilerplate.py

Lines changed: 232 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,232 @@
1+
#!/usr/bin/env python
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+
from __future__ import print_function
18+
19+
import argparse
20+
import datetime
21+
import difflib
22+
import glob
23+
import os
24+
import re
25+
import sys
26+
27+
parser = argparse.ArgumentParser()
28+
parser.add_argument(
29+
"filenames",
30+
help="list of files to check, all files if unspecified",
31+
nargs='*')
32+
33+
rootdir = os.path.dirname(__file__) + "/../../"
34+
rootdir = os.path.abspath(rootdir)
35+
parser.add_argument(
36+
"--rootdir", default=rootdir, help="root directory to examine")
37+
38+
default_boilerplate_dir = os.path.join(rootdir, "hack/boilerplate")
39+
parser.add_argument(
40+
"--boilerplate-dir", default=default_boilerplate_dir)
41+
42+
parser.add_argument(
43+
"-v", "--verbose",
44+
help="give verbose output regarding why a file does not pass",
45+
action="store_true")
46+
47+
args = parser.parse_args()
48+
49+
verbose_out = sys.stderr if args.verbose else open("/dev/null", "w")
50+
51+
def get_refs():
52+
refs = {}
53+
54+
for path in glob.glob(os.path.join(args.boilerplate_dir, "boilerplate.*.txt")):
55+
extension = os.path.basename(path).split(".")[1]
56+
57+
ref_file = open(path, 'r')
58+
ref = ref_file.read().splitlines()
59+
ref_file.close()
60+
refs[extension] = ref
61+
62+
return refs
63+
64+
def is_generated_file(filename, data, regexs):
65+
for d in generated_files:
66+
if d in filename:
67+
return True
68+
69+
for d in skipped_ungenerated_files:
70+
if d in filename:
71+
return False
72+
73+
p = regexs["generated"]
74+
return p.search(data)
75+
76+
def file_passes(filename, refs, regexs):
77+
try:
78+
f = open(filename, 'r')
79+
except Exception as exc:
80+
print("Unable to open %s: %s" % (filename, exc), file=verbose_out)
81+
return False
82+
83+
data = f.read()
84+
f.close()
85+
86+
# determine if the file is automatically generated
87+
generated = is_generated_file(filename, data, regexs)
88+
89+
basename = os.path.basename(filename)
90+
extension = file_extension(filename)
91+
if generated:
92+
if extension == "go":
93+
extension = "generatego"
94+
elif extension == "bzl":
95+
extension = "generatebzl"
96+
97+
if extension != "":
98+
ref = refs[extension]
99+
else:
100+
ref = refs[basename]
101+
102+
# remove extra content from the top of files
103+
if extension == "go" or extension == "generatego":
104+
p = regexs["go_build_constraints"]
105+
(data, found) = p.subn("", data, 1)
106+
elif extension == "sh":
107+
p = regexs["shebang"]
108+
(data, found) = p.subn("", data, 1)
109+
110+
data = data.splitlines()
111+
112+
# if our test file is smaller than the reference it surely fails!
113+
if len(ref) > len(data):
114+
print('File %s smaller than reference (%d < %d)' %
115+
(filename, len(data), len(ref)),
116+
file=verbose_out)
117+
return False
118+
119+
# trim our file to the same number of lines as the reference file
120+
data = data[:len(ref)]
121+
122+
p = regexs["year"]
123+
for d in data:
124+
if p.search(d):
125+
if generated:
126+
print('File %s has the YEAR field, but it should not be in generated file' % filename, file=verbose_out)
127+
else:
128+
print('File %s has the YEAR field, but missing the year of date' % filename, file=verbose_out)
129+
return False
130+
131+
if not generated:
132+
# Replace all occurrences of the regex "2014|2015|2016|2017|2018" with "YEAR"
133+
p = regexs["date"]
134+
for i, d in enumerate(data):
135+
(data[i], found) = p.subn('YEAR', d)
136+
if found != 0:
137+
break
138+
139+
# if we don't match the reference at this point, fail
140+
if ref != data:
141+
print("Header in %s does not match reference, diff:" % filename, file=verbose_out)
142+
if args.verbose:
143+
print(file=verbose_out)
144+
for line in difflib.unified_diff(ref, data, 'reference', filename, lineterm=''):
145+
print(line, file=verbose_out)
146+
print(file=verbose_out)
147+
return False
148+
149+
return True
150+
151+
def file_extension(filename):
152+
return os.path.splitext(filename)[1].split(".")[-1].lower()
153+
154+
skipped_dirs = ['Godeps', 'third_party', '_gopath', '_output', '.git', 'cluster/env.sh',
155+
"vendor", "hack/boilerplate/test", "tilt_modules"]
156+
157+
# list all the files contain 'DO NOT EDIT', but are not generated
158+
skipped_ungenerated_files = ['hack/lib/swagger.sh', 'hack/boilerplate/boilerplate.py']
159+
160+
# list all the files that does not contain 'DO NOT EDIT', but are generated
161+
generated_files = []
162+
163+
def normalize_files(files):
164+
newfiles = []
165+
for pathname in files:
166+
if any(x in pathname for x in skipped_dirs):
167+
continue
168+
newfiles.append(pathname)
169+
for i, pathname in enumerate(newfiles):
170+
if not os.path.isabs(pathname):
171+
newfiles[i] = os.path.join(args.rootdir, pathname)
172+
return newfiles
173+
174+
def get_files(extensions):
175+
files = []
176+
if len(args.filenames) > 0:
177+
files = args.filenames
178+
else:
179+
for root, dirs, walkfiles in os.walk(args.rootdir):
180+
# don't visit certain dirs. This is just a performance improvement
181+
# as we would prune these later in normalize_files(). But doing it
182+
# cuts down the amount of filesystem walking we do and cuts down
183+
# the size of the file list
184+
for d in skipped_dirs:
185+
if d in dirs:
186+
dirs.remove(d)
187+
188+
for name in walkfiles:
189+
pathname = os.path.join(root, name)
190+
files.append(pathname)
191+
192+
files = normalize_files(files)
193+
outfiles = []
194+
for pathname in files:
195+
basename = os.path.basename(pathname)
196+
extension = file_extension(pathname)
197+
if extension in extensions or basename in extensions:
198+
outfiles.append(pathname)
199+
return outfiles
200+
201+
def get_dates():
202+
years = datetime.datetime.now().year
203+
return '(%s)' % '|'.join((str(year) for year in range(2014, years+1)))
204+
205+
def get_regexs():
206+
regexs = {}
207+
# Search for "YEAR" which exists in the boilerplate, but shouldn't in the real thing
208+
regexs["year"] = re.compile( 'YEAR' )
209+
# get_dates return 2014, 2015, 2016, 2017, or 2018 until the current year as a regex like: "(2014|2015|2016|2017|2018)";
210+
# company holder names can be anything
211+
regexs["date"] = re.compile(get_dates())
212+
# strip // +build \n\n build constraints
213+
regexs["go_build_constraints"] = re.compile(r"^(// \+build.*\n)+\n", re.MULTILINE)
214+
# strip #!.* from shell scripts
215+
regexs["shebang"] = re.compile(r"^(#!.*\n)\n*", re.MULTILINE)
216+
# Search for generated files
217+
regexs["generated"] = re.compile( 'DO NOT EDIT' )
218+
return regexs
219+
220+
def main():
221+
regexs = get_regexs()
222+
refs = get_refs()
223+
filenames = get_files(refs.keys())
224+
225+
for filename in filenames:
226+
if not file_passes(filename, refs, regexs):
227+
print(filename, file=sys.stdout)
228+
229+
return 0
230+
231+
if __name__ == "__main__":
232+
sys.exit(main())

hack/boilerplate/boilerplate.py.txt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#!/usr/bin/env python
2+
3+
# Copyright YEAR 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+

hack/boilerplate/boilerplate.sh.txt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Copyright YEAR The Kubernetes Authors.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+

0 commit comments

Comments
 (0)