mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 19:56:01 +00:00
Add verbose mode to boilerplate
hack/verify-boilerplate.sh -v will now print out why the file does not match along with a diff if possible. Note: boilerplate.py now has a unit test that is run along with hack/verify-boilerplate.sh.
This commit is contained in:
parent
373be74d75
commit
a6550b332e
1
.gitignore
vendored
1
.gitignore
vendored
@ -117,3 +117,4 @@ kubernetes.tar.gz
|
|||||||
!\.drone\.sec
|
!\.drone\.sec
|
||||||
|
|
||||||
/bazel-*
|
/bazel-*
|
||||||
|
*.pyc
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
|
import difflib
|
||||||
import glob
|
import glob
|
||||||
import json
|
import json
|
||||||
import mmap
|
import mmap
|
||||||
@ -25,16 +26,28 @@ import re
|
|||||||
import sys
|
import sys
|
||||||
|
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument("filenames", help="list of files to check, all files if unspecified", nargs='*')
|
parser.add_argument(
|
||||||
|
"filenames",
|
||||||
|
help="list of files to check, all files if unspecified",
|
||||||
|
nargs='*')
|
||||||
|
|
||||||
rootdir = os.path.dirname(__file__) + "/../../"
|
rootdir = os.path.dirname(__file__) + "/../../"
|
||||||
rootdir = os.path.abspath(rootdir)
|
rootdir = os.path.abspath(rootdir)
|
||||||
parser.add_argument("--rootdir", default=rootdir, help="root directory to examine")
|
parser.add_argument(
|
||||||
|
"--rootdir", default=rootdir, help="root directory to examine")
|
||||||
|
|
||||||
default_boilerplate_dir = os.path.join(rootdir, "hack/boilerplate")
|
default_boilerplate_dir = os.path.join(rootdir, "hack/boilerplate")
|
||||||
parser.add_argument("--boilerplate-dir", default=default_boilerplate_dir)
|
parser.add_argument(
|
||||||
|
"--boilerplate-dir", default=default_boilerplate_dir)
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
"-v", "--verbose",
|
||||||
|
help="give verbose output regarding why a file does not pass",
|
||||||
|
action="store_true")
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
verbose_out = sys.stderr if args.verbose else open("/dev/null", "w")
|
||||||
|
|
||||||
def get_refs():
|
def get_refs():
|
||||||
refs = {}
|
refs = {}
|
||||||
@ -52,7 +65,8 @@ def get_refs():
|
|||||||
def file_passes(filename, refs, regexs):
|
def file_passes(filename, refs, regexs):
|
||||||
try:
|
try:
|
||||||
f = open(filename, 'r')
|
f = open(filename, 'r')
|
||||||
except:
|
except Exception as exc:
|
||||||
|
print("Unable to open %s: %s" % (filename, exc), file=verbose_out)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
data = f.read()
|
data = f.read()
|
||||||
@ -79,6 +93,9 @@ def file_passes(filename, refs, regexs):
|
|||||||
|
|
||||||
# if our test file is smaller than the reference it surely fails!
|
# if our test file is smaller than the reference it surely fails!
|
||||||
if len(ref) > len(data):
|
if len(ref) > len(data):
|
||||||
|
print('File %s smaller than reference (%d < %d)' %
|
||||||
|
(filename, len(data), len(ref)),
|
||||||
|
file=verbose_out)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# trim our file to the same number of lines as the reference file
|
# trim our file to the same number of lines as the reference file
|
||||||
@ -87,6 +104,7 @@ def file_passes(filename, refs, regexs):
|
|||||||
p = regexs["year"]
|
p = regexs["year"]
|
||||||
for d in data:
|
for d in data:
|
||||||
if p.search(d):
|
if p.search(d):
|
||||||
|
print('File %s is missing the year' % filename, file=verbose_out)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# Replace all occurrences of the regex "2016|2015|2014" with "YEAR"
|
# Replace all occurrences of the regex "2016|2015|2014" with "YEAR"
|
||||||
@ -98,6 +116,12 @@ def file_passes(filename, refs, regexs):
|
|||||||
|
|
||||||
# if we don't match the reference at this point, fail
|
# if we don't match the reference at this point, fail
|
||||||
if ref != data:
|
if ref != data:
|
||||||
|
print("Header in %s does not match reference, diff:" % filename, file=verbose_out)
|
||||||
|
if args.verbose:
|
||||||
|
print(file=verbose_out)
|
||||||
|
for line in difflib.unified_diff(ref, data, 'reference', filename, lineterm=''):
|
||||||
|
print(line, file=verbose_out)
|
||||||
|
print(file=verbose_out)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return True
|
return True
|
||||||
@ -105,7 +129,8 @@ def file_passes(filename, refs, regexs):
|
|||||||
def file_extension(filename):
|
def file_extension(filename):
|
||||||
return os.path.splitext(filename)[1].split(".")[-1].lower()
|
return os.path.splitext(filename)[1].split(".")[-1].lower()
|
||||||
|
|
||||||
skipped_dirs = ['Godeps', 'third_party', '_gopath', '_output', '.git', 'cluster/env.sh', "vendor", "test/e2e/generated/bindata.go"]
|
skipped_dirs = ['Godeps', 'third_party', '_gopath', '_output', '.git', 'cluster/env.sh',
|
||||||
|
"vendor", "test/e2e/generated/bindata.go", "hack/boilerplate/test"]
|
||||||
|
|
||||||
def normalize_files(files):
|
def normalize_files(files):
|
||||||
newfiles = []
|
newfiles = []
|
||||||
@ -166,5 +191,7 @@ def main():
|
|||||||
if not file_passes(filename, refs, regexs):
|
if not file_passes(filename, refs, regexs):
|
||||||
print(filename, file=sys.stdout)
|
print(filename, file=sys.stdout)
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
sys.exit(main())
|
sys.exit(main())
|
||||||
|
52
hack/boilerplate/boilerplate_test.py
Normal file
52
hack/boilerplate/boilerplate_test.py
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
# Copyright 2016 The Kubernetes Authors.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
import boilerplate
|
||||||
|
import unittest
|
||||||
|
import StringIO
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
class TestBoilerplate(unittest.TestCase):
|
||||||
|
"""
|
||||||
|
Note: run this test from the hack/boilerplate directory.
|
||||||
|
|
||||||
|
$ python -m unittest boilerplate_test
|
||||||
|
"""
|
||||||
|
|
||||||
|
def test_boilerplate(self):
|
||||||
|
os.chdir("test/")
|
||||||
|
|
||||||
|
class Args(object):
|
||||||
|
def __init__(self):
|
||||||
|
self.filenames = []
|
||||||
|
self.rootdir = "."
|
||||||
|
self.boilerplate_dir = "../"
|
||||||
|
self.verbose = True
|
||||||
|
|
||||||
|
# capture stdout
|
||||||
|
old_stdout = sys.stdout
|
||||||
|
sys.stdout = StringIO.StringIO()
|
||||||
|
|
||||||
|
boilerplate.args = Args()
|
||||||
|
ret = boilerplate.main()
|
||||||
|
|
||||||
|
output = sorted(sys.stdout.getvalue().split())
|
||||||
|
|
||||||
|
sys.stdout = old_stdout
|
||||||
|
|
||||||
|
self.assertEquals(
|
||||||
|
output, ['././fail.go', '././fail.py'])
|
19
hack/boilerplate/test/fail.go
Normal file
19
hack/boilerplate/test/fail.go
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2014 The Kubernetes Authors.
|
||||||
|
|
||||||
|
fail
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package main
|
17
hack/boilerplate/test/fail.py
Normal file
17
hack/boilerplate/test/fail.py
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
# Copyright 2015 The Kubernetes Authors.
|
||||||
|
#
|
||||||
|
# failed
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
17
hack/boilerplate/test/pass.go
Normal file
17
hack/boilerplate/test/pass.go
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2014 The Kubernetes Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package main
|
17
hack/boilerplate/test/pass.py
Normal file
17
hack/boilerplate/test/pass.py
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
# Copyright 2015 The Kubernetes Authors.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
True
|
@ -19,10 +19,29 @@ set -o nounset
|
|||||||
set -o pipefail
|
set -o pipefail
|
||||||
|
|
||||||
KUBE_ROOT=$(dirname "${BASH_SOURCE}")/..
|
KUBE_ROOT=$(dirname "${BASH_SOURCE}")/..
|
||||||
boiler="${KUBE_ROOT}/hack/boilerplate/boilerplate.py"
|
|
||||||
|
boilerDir="${KUBE_ROOT}/hack/boilerplate"
|
||||||
|
boiler="${boilerDir}/boilerplate.py"
|
||||||
|
|
||||||
files_need_boilerplate=($(${boiler} "$@"))
|
files_need_boilerplate=($(${boiler} "$@"))
|
||||||
|
|
||||||
|
# Run boilerplate.py unit tests
|
||||||
|
unitTestOut="$(mktemp)"
|
||||||
|
trap cleanup EXIT
|
||||||
|
cleanup() {
|
||||||
|
rm "${unitTestOut}"
|
||||||
|
}
|
||||||
|
|
||||||
|
pushd "${boilerDir}" >/dev/null
|
||||||
|
if ! python -m unittest boilerplate_test 2>"${unitTestOut}"; then
|
||||||
|
echo "boilerplate_test.py failed"
|
||||||
|
echo
|
||||||
|
cat "${unitTestOut}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
popd >/dev/null
|
||||||
|
|
||||||
|
# Run boilerplate check
|
||||||
if [[ ${#files_need_boilerplate[@]} -gt 0 ]]; then
|
if [[ ${#files_need_boilerplate[@]} -gt 0 ]]; then
|
||||||
for file in "${files_need_boilerplate[@]}"; do
|
for file in "${files_need_boilerplate[@]}"; do
|
||||||
echo "Boilerplate header is wrong for: ${file}"
|
echo "Boilerplate header is wrong for: ${file}"
|
||||||
|
Loading…
Reference in New Issue
Block a user