diff --git a/.bazelrc b/.bazelrc new file mode 100644 index 0000000000..32715c4a20 --- /dev/null +++ b/.bazelrc @@ -0,0 +1,2 @@ +test --test_output=errors + diff --git a/.kazelcfg.json b/.kazelcfg.json new file mode 100644 index 0000000000..3f3d7d632e --- /dev/null +++ b/.kazelcfg.json @@ -0,0 +1,4 @@ +{ + "GoPrefix": "k8s.io/org", + "AddSourcesRules": true +} diff --git a/BUILD.bazel b/BUILD.bazel new file mode 100644 index 0000000000..44fb88931a --- /dev/null +++ b/BUILD.bazel @@ -0,0 +1,68 @@ +load("@io_kubernetes_build//defs:run_in_workspace.bzl", "workspace_binary") + +workspace_binary( + name = "dep", + cmd = "//vendor/github.com/golang/dep/cmd/dep", +) + +workspace_binary( + name = "golint", + cmd = "//vendor/github.com/golang/lint/golint", +) + +load("@bazel_gazelle//:def.bzl", "gazelle") + +# gazelle:prefix k8s.io/org +# gazelle:proto disable_global + +gazelle( + name = "gazelle", + command = "fix", + external = "vendored", +) + +gazelle( + name = "gazelle-diff", + command = "fix", + external = "vendored", + mode = "diff", +) + +workspace_binary( + name = "kazel", + cmd = "//vendor/k8s.io/repo-infra/kazel", +) + +workspace_binary( + name = "kazel-diff", + args = [ + "--dry-run", + "--print-diff", + ], + cmd = "//vendor/k8s.io/repo-infra/kazel", +) + +filegroup( + name = "package-srcs", + srcs = glob( + ["**"], + exclude = [ + "bazel-*/**", + ".git/**", + ], + ), + visibility = ["//visibility:private"], +) + +filegroup( + name = "all-srcs", + srcs = [ + ":package-srcs", + "//admin:all-srcs", + "//cmd/merge:all-srcs", + "//config:all-srcs", + "//vendor:all-srcs", + ], + tags = ["automanaged"], + visibility = ["//visibility:public"], +) diff --git a/WORKSPACE b/WORKSPACE new file mode 100644 index 0000000000..5164bbf5d2 --- /dev/null +++ b/WORKSPACE @@ -0,0 +1,77 @@ +git_repository( + name = "bazel_skylib", + commit = "2169ae1c374aab4a09aa90e65efe1a3aad4e279b", + remote = "https://github.com/bazelbuild/bazel-skylib.git", +) + +load("@bazel_skylib//:lib.bzl", "versions") + +versions.check(minimum_bazel_version = "0.14.0") + +http_archive( + name = "io_bazel_rules_go", + urls = ["https://github.com/bazelbuild/rules_go/releases/download/0.14.0/rules_go-0.14.0.tar.gz"], + sha256 = "5756a4ad75b3703eb68249d50e23f5d64eaf1593e886b9aa931aa6e938c4e301", +) + +http_archive( + name = "bazel_gazelle", + urls = ["https://github.com/bazelbuild/bazel-gazelle/releases/download/0.14.0/bazel-gazelle-0.14.0.tar.gz"], + sha256 = "c0a5739d12c6d05b6c1ad56f2200cb0b57c5a70e03ebd2f7b87ce88cabf09c7b", +) + +load("@io_bazel_rules_go//go:def.bzl", "go_rules_dependencies", "go_register_toolchains") + +go_rules_dependencies() + +go_register_toolchains(go_version = "1.10.2") + +load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies") + +http_archive( + name = "io_bazel_rules_docker", + sha256 = "cef4e7adfc1df999891e086bf42bed9092cfdf374adb902f18de2c1d6e1e0197", + strip_prefix = "rules_docker-198367210c55fba5dded22274adde1a289801dc4", + urls = ["https://github.com/bazelbuild/rules_docker/archive/198367210c55fba5dded22274adde1a289801dc4.tar.gz"], +) + +git_repository( + name = "io_kubernetes_build", + commit = "4ce715fbe67d8fbed05ec2bb47a148e754100a4b", + remote = "https://github.com/kubernetes/repo-infra.git", +) + +load("@io_bazel_rules_docker//docker:docker.bzl", "docker_repositories", "docker_pull") + +docker_repositories() + +docker_pull( + name = "distroless-base", + # latest circa 2017/11/29 + digest = "sha256:bef8d030c7f36dfb73a8c76137616faeea73ac5a8495d535f27c911d0db77af3", + registry = "gcr.io", + repository = "distroless/base", +) + +load( + "@io_bazel_rules_docker//go:image.bzl", + _go_repositories = "repositories", +) + +_go_repositories() + +docker_pull( + name = "alpine-base", + # 0.1 as of 2017/11/29 + digest = "sha256:317d39ece9dd09992fa81236964be3f3919b940f42e3143379dd66e4af930f3a", + registry = "gcr.io", + repository = "k8s-prow/alpine", +) + +docker_pull( + name = "git-base", + # 0.2 as of 2018/05/10 + digest = "sha256:3eaeff9a2c35a50c3a0af7ef7cf26ea73e6fd966f54ef3dfe79d4ffb45805112", + registry = "gcr.io", + repository = "k8s-prow/git", +) diff --git a/hack/boilerplate/boilerplate.Dockerfile.txt b/hack/boilerplate/boilerplate.Dockerfile.txt new file mode 100644 index 0000000000..384f325abf --- /dev/null +++ b/hack/boilerplate/boilerplate.Dockerfile.txt @@ -0,0 +1,14 @@ +# Copyright YEAR 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. + diff --git a/hack/boilerplate/boilerplate.Makefile.txt b/hack/boilerplate/boilerplate.Makefile.txt new file mode 100644 index 0000000000..384f325abf --- /dev/null +++ b/hack/boilerplate/boilerplate.Makefile.txt @@ -0,0 +1,14 @@ +# Copyright YEAR 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. + diff --git a/hack/boilerplate/boilerplate.bzl.txt b/hack/boilerplate/boilerplate.bzl.txt new file mode 100644 index 0000000000..384f325abf --- /dev/null +++ b/hack/boilerplate/boilerplate.bzl.txt @@ -0,0 +1,14 @@ +# Copyright YEAR 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. + diff --git a/hack/boilerplate/boilerplate.go.txt b/hack/boilerplate/boilerplate.go.txt new file mode 100644 index 0000000000..59e740c1ee --- /dev/null +++ b/hack/boilerplate/boilerplate.go.txt @@ -0,0 +1,16 @@ +/* +Copyright YEAR 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. +*/ + diff --git a/hack/boilerplate/boilerplate.py.txt b/hack/boilerplate/boilerplate.py.txt new file mode 100644 index 0000000000..384f325abf --- /dev/null +++ b/hack/boilerplate/boilerplate.py.txt @@ -0,0 +1,14 @@ +# Copyright YEAR 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. + diff --git a/hack/boilerplate/boilerplate.sh.txt b/hack/boilerplate/boilerplate.sh.txt new file mode 100644 index 0000000000..384f325abf --- /dev/null +++ b/hack/boilerplate/boilerplate.sh.txt @@ -0,0 +1,14 @@ +# Copyright YEAR 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. + diff --git a/hack/update-all.sh b/hack/update-all.sh new file mode 100644 index 0000000000..f3fc1ccabe --- /dev/null +++ b/hack/update-all.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash +# Copyright 2017 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. + +set -o errexit +set -o nounset +set -o pipefail +set -o xtrace + +cd "$(git rev-parse --show-toplevel)" +for sh in $(ls hack/update* | grep -v update-all); do + "./$sh" && echo "PASS: $sh" && continue + echo "FAIL: $sh" + exit 1 +done diff --git a/hack/update-bazel.sh b/hack/update-bazel.sh new file mode 100755 index 0000000000..08c61402fc --- /dev/null +++ b/hack/update-bazel.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash +# Copyright 2018 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. + +set -o errexit +set -o nounset +set -o pipefail + +cd "$(git rev-parse --show-toplevel)" +mkdir -p ./vendor +touch ./vendor/BUILD.bazel +bazel run //:gazelle +bazel run //:kazel diff --git a/hack/update-deps.sh b/hack/update-deps.sh new file mode 100755 index 0000000000..4a231ea834 --- /dev/null +++ b/hack/update-deps.sh @@ -0,0 +1,48 @@ +#!/bin/bash +# Copyright 2018 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. + + +# Run dep ensure and generate bazel rules. +# +# Usage: +# update-deps.sh +# +# The args are sent to dep ensure -v + +set -o nounset +set -o errexit +set -o pipefail +set -o xtrace + +cd "$(git rev-parse --show-toplevel)" +trap 'echo "FAILED" >&2' ERR + +# dep itself has a problematic testdata directory with infinite symlinks which +# makes bazel sad: https://github.com/golang/dep/pull/1412 +# dep should probably be removing it, but it doesn't: +# https://github.com/golang/dep/issues/1580 +rm -rf vendor/github.com/golang/dep/internal/fs/testdata +# go-bindata does too, and is not maintained ... +rm -rf vendor/github.com/jteeuwen/go-bindata/testdata +# docker has a contrib dir with nothing we use in it, dep will retain the licenses +# which includes some GPL, so we manually prune this. +# See https://github.com/kubernetes/steering/issues/57 +rm -rf vendor/github.com/docker/docker/contrib +bazel run //:dep -- ensure -v "$@" +rm -rf vendor/github.com/golang/dep/internal/fs/testdata +rm -rf vendor/github.com/jteeuwen/go-bindata/testdata +rm -rf vendor/github.com/docker/docker/contrib +hack/update-bazel.sh +echo SUCCESS diff --git a/hack/update-gofmt.sh b/hack/update-gofmt.sh new file mode 100755 index 0000000000..a14aecbbd2 --- /dev/null +++ b/hack/update-gofmt.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +# Copyright 2017 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. + +set -o errexit +set -o nounset +set -o pipefail + +find . -name "*.go" | grep -v "\/vendor\/" | xargs gofmt -s -w diff --git a/hack/verify-all.sh b/hack/verify-all.sh new file mode 100755 index 0000000000..93ccaa6c58 --- /dev/null +++ b/hack/verify-all.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash +# Copyright 2017 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. + +set -o errexit +set -o nounset +set -o pipefail +set -o xtrace + +cd "$(git rev-parse --show-toplevel)" +err=0 +for sh in $(ls hack/verify* | grep -v verify-all); do + "./$sh" && echo "PASS: $sh" && continue + err=1 + echo "FAIL: $sh" +done +exit $err diff --git a/hack/verify-bazel.sh b/hack/verify-bazel.sh new file mode 100755 index 0000000000..a48d21bbfd --- /dev/null +++ b/hack/verify-bazel.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash +# 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. + +set -o errexit +set -o nounset +set -o pipefail + +cd "$(git rev-parse --show-toplevel)" +ls ./vendor/BUILD.bazel >/dev/null +gazelle_diff=$(bazel run //:gazelle-diff) +kazel_diff=$(bazel run //:kazel-diff) + +if [[ -n "${gazelle_diff}" ]]; then + echo "Gazelle diff:" + echo "${gazelle_diff}" +fi + +if [[ -n "${kazel_diff}" ]]; then + echo "Kazel diff:" + echo "${kazel_diff}" +fi + +if [[ -n "${gazelle_diff}${kazel_diff}" ]]; then + echo "FAIL: invalid BUILD.bazel files. Fix with ./hack/update-bazel.sh" + exit 1 +fi diff --git a/hack/verify-deps.sh b/hack/verify-deps.sh new file mode 100755 index 0000000000..8c9add1874 --- /dev/null +++ b/hack/verify-deps.sh @@ -0,0 +1,53 @@ +#!/bin/bash +# Copyright 2018 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. + +set -o nounset +set -o errexit +set -o pipefail +set -o xtrace + +prefix="k8s.io/org" +repo_root="$(git rev-parse --show-toplevel)" +cd "${repo_root}" + +_tmpdir="$(mktemp -d -t verify-deps.XXXXXX)" +cd "${_tmpdir}" +_tmpdir="$(realpath pwd)" + +trap "rm -rf ${_tmpdir}" EXIT + +_tmp_gopath="${_tmpdir}/go" +_tmp_repo_root="${_tmp_gopath}/src/${prefix}" +mkdir -p "${_tmp_repo_root}/.." +cp -a "${repo_root}" "${_tmp_repo_root}/.." + +cd "${_tmp_repo_root}" +export GOPATH="${_tmp_gopath}" +export PATH="${_tmp_gopath}/bin:${PATH}" +echo $GOPATH +./hack/update-deps.sh + +diff=$(diff -Nupr \ + -x ".git" \ + -x "bazel-*" \ + -x "_output" \ + "${repo_root}" "${_tmp_repo_root}" 2>/dev/null || true) + +if [[ -n "${diff}" ]]; then + echo "${diff}" >&2 + echo >&2 + echo "ERROR: bad deps. Run ./hack/update-deps.sh" >&2 + exit 1 +fi diff --git a/hack/verify-gofmt.sh b/hack/verify-gofmt.sh new file mode 100755 index 0000000000..0332f335d5 --- /dev/null +++ b/hack/verify-gofmt.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash +# Copyright 2017 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. + +set -o errexit +set -o nounset +set -o pipefail + +diff=$(find . -name "*.go" | grep -v "\/vendor\/" | xargs gofmt -s -d 2>&1) +if [[ -n "${diff}" ]]; then + echo "${diff}" + echo + echo "FAIL: bad gofmt. Please run hack/update-gofmt.sh" + exit 1 +fi diff --git a/hack/verify_boilerplate.py b/hack/verify_boilerplate.py new file mode 100755 index 0000000000..ad2f94809b --- /dev/null +++ b/hack/verify_boilerplate.py @@ -0,0 +1,209 @@ +#!/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. + +# Verifies that all source files contain the necessary copyright boilerplate +# snippet. + +from __future__ import print_function + +import argparse +import glob +import os +import re +import sys + + +def get_args(): + parser = argparse.ArgumentParser() + parser.add_argument( + "filenames", help="list of files to check, all files if unspecified", nargs='*') + + rootdir = os.path.dirname(__file__) + "/../" + rootdir = os.path.abspath(rootdir) + parser.add_argument("--rootdir", default=rootdir, + help="root directory to examine") + + default_boilerplate_dir = os.path.join(rootdir, "hack/boilerplate") + parser.add_argument("--boilerplate-dir", default=default_boilerplate_dir) + return parser.parse_args() + + +def get_refs(): + refs = {} + + for path in glob.glob(os.path.join(ARGS.boilerplate_dir, "boilerplate.*.txt")): + extension = os.path.basename(path).split(".")[1] + + ref_file = open(path, 'r') + ref = ref_file.read().splitlines() + ref_file.close() + refs[extension] = ref + + return refs + + +def file_passes(filename, refs, regexs): # pylint: disable=too-many-locals + try: + with open(filename, 'r') as fp: + data = fp.read() + except IOError: + return False + + basename = os.path.basename(filename) + extension = file_extension(filename) + if extension != "": + ref = refs[extension] + else: + ref = refs[basename] + + # remove build tags from the top of Go files + if extension == "go": + con = regexs["go_build_constraints"] + (data, found) = con.subn("", data, 1) + + # remove shebang from the top of shell files + if extension == "sh" or extension == "py": + she = regexs["shebang"] + (data, found) = she.subn("", data, 1) + + data = data.splitlines() + + # if our test file is smaller than the reference it surely fails! + if len(ref) > len(data): + return False + + # trim our file to the same number of lines as the reference file + data = data[:len(ref)] + + year = regexs["year"] + for datum in data: + if year.search(datum): + return False + + # Replace all occurrences of the regex "2017|2016|2015|2014" with "YEAR" + when = regexs["date"] + for idx, datum in enumerate(data): + (data[idx], found) = when.subn('YEAR', datum) + if found != 0: + break + + # if we don't match the reference at this point, fail + if ref != data: + return False + + return True + + +def file_extension(filename): + return os.path.splitext(filename)[1].split(".")[-1].lower() + + +SKIPPED_DIRS = [ + 'Godeps', 'third_party', '_gopath', '_output', + '.git', 'vendor', '__init__.py', 'node_modules' +] + +# even when generated by bazel we will complain about some generated files +# not having the headers. since they're just generated, ignore them +IGNORE_HEADERS = [ + '// Code generated by go-bindata.' +] + + +def has_ignored_header(pathname): + with open(pathname, 'r') as myfile: + data = myfile.read() + for header in IGNORE_HEADERS: + if data.startswith(header): + return True + return False + + +def normalize_files(files): + newfiles = [] + for pathname in files: + if any(x in pathname for x in SKIPPED_DIRS): + continue + newfiles.append(pathname) + for idx, pathname in enumerate(newfiles): + if not os.path.isabs(pathname): + newfiles[idx] = os.path.join(ARGS.rootdir, pathname) + return newfiles + + +def get_files(extensions): + files = [] + if ARGS.filenames: + files = ARGS.filenames + else: + for root, dirs, walkfiles in os.walk(ARGS.rootdir): + # don't visit certain dirs. This is just a performance improvement + # as we would prune these later in normalize_files(). But doing it + # cuts down the amount of filesystem walking we do and cuts down + # the size of the file list + for dpath in SKIPPED_DIRS: + if dpath in dirs: + dirs.remove(dpath) + + for name in walkfiles: + pathname = os.path.join(root, name) + files.append(pathname) + + files = normalize_files(files) + outfiles = [] + for pathname in files: + basename = os.path.basename(pathname) + extension = file_extension(pathname) + if extension in extensions or basename in extensions: + if not has_ignored_header(pathname): + outfiles.append(pathname) + return outfiles + + +def get_regexs(): + regexs = {} + # Search for "YEAR" which exists in the boilerplate, but shouldn't in the real thing + regexs["year"] = re.compile('YEAR') + # dates can be 2014, 2015, 2016 or 2017, company holder names can be anything + regexs["date"] = re.compile('(2014|2015|2016|2017|2018)') + # strip // +build \n\n build constraints + regexs["go_build_constraints"] = re.compile( + r"^(// \+build.*\n)+\n", re.MULTILINE) + # strip #!.* from shell/python scripts + regexs["shebang"] = re.compile(r"^(#!.*\n)\n*", re.MULTILINE) + return regexs + + +def main(): + regexs = get_regexs() + refs = get_refs() + filenames = get_files(refs.keys()) + nonconforming_files = [] + for filename in filenames: + if not file_passes(filename, refs, regexs): + nonconforming_files.append(filename) + + if nonconforming_files: + print('%d files have incorrect boilerplate headers:' % + len(nonconforming_files)) + for filename in sorted(nonconforming_files): + print(os.path.relpath(filename, ARGS.rootdir)) + sys.exit(1) + + +if __name__ == "__main__": + ARGS = get_args() + main()