Skip to content

Commit 1b16b39

Browse files
committed
hack: include verify scripts for golint, gofmt, govet etc
These scripts are copied from the cluster-api-provider-docker repository.
1 parent 3c6ef16 commit 1b16b39

16 files changed

+837
-0
lines changed

hack/update-all.sh

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#!/usr/bin/env bash
2+
# Copyright 2019 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+
set -o errexit
17+
set -o nounset
18+
set -o pipefail
19+
20+
# shellcheck source=/dev/null
21+
source "$(dirname "$0")/utils.sh"
22+
REPO_PATH=$(get_root_path)
23+
24+
"${REPO_PATH}"/hack/update-deps.sh
25+
"${REPO_PATH}"/hack/update-gofmt.sh

hack/update-deps.sh

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#!/usr/bin/env bash
2+
# Copyright 2019 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+
17+
set -o nounset
18+
set -o errexit
19+
set -o pipefail
20+
21+
# shellcheck source=/dev/null
22+
source "$(dirname "$0")/utils.sh"
23+
# cd to the root path
24+
cd_root_path
25+
26+
export GO111MODULE="on"
27+
go mod tidy

hack/update-gofmt.sh

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#!/usr/bin/env bash
2+
# Copyright 2019 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+
# script to run gofmt over our code (not vendor)
17+
set -o errexit
18+
set -o nounset
19+
set -o pipefail
20+
21+
# shellcheck source=/dev/null
22+
source "$(dirname "$0")/utils.sh"
23+
# cd to the root path
24+
cd_root_path
25+
26+
# update go fmt
27+
go fmt ./...

hack/utils.sh

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#!/usr/bin/env bash
2+
# Copyright 2019 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+
# get_root_path returns the root path of the project source tree
17+
get_root_path() {
18+
echo "$(git rev-parse --show-toplevel)"
19+
}
20+
21+
# cd_root_path cds to the root path of the project source tree
22+
cd_root_path() {
23+
cd "$(get_root_path)" || exit
24+
}

hack/verify-all.sh

+94
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
#!/usr/bin/env bash
2+
# Copyright 2019 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+
set -o errexit
17+
set -o nounset
18+
set -o pipefail
19+
20+
# shellcheck source=/dev/null
21+
source "$(dirname "$0")/utils.sh"
22+
23+
# set REPO_PATH
24+
REPO_PATH=$(get_root_path)
25+
cd "${REPO_PATH}"
26+
27+
# exit code, if a script fails we'll set this to 1
28+
res=0
29+
30+
# run all verify scripts, optionally skipping any of them
31+
32+
if [[ "${VERIFY_WHITESPACE:-true}" == "true" ]]; then
33+
echo "[*] Verifying whitespace..."
34+
hack/verify-whitespace.sh || res=1
35+
cd "${REPO_PATH}"
36+
fi
37+
38+
if [[ "${VERIFY_SPELLING:-true}" == "true" ]]; then
39+
echo "[*] Verifying spelling..."
40+
hack/verify-spelling.sh || res=1
41+
cd "${REPO_PATH}"
42+
fi
43+
44+
if [[ "${VERIFY_BOILERPLATE:-true}" == "true" ]]; then
45+
echo "[*] Verifying boilerplate..."
46+
hack/verify-boilerplate.sh || res=1
47+
cd "${REPO_PATH}"
48+
fi
49+
50+
if [[ "${VERIFY_GOFMT:-true}" == "true" ]]; then
51+
echo "[*] Verifying gofmt..."
52+
hack/verify-gofmt.sh || res=1
53+
cd "${REPO_PATH}"
54+
fi
55+
56+
if [[ "${VERIFY_GOLINT:-true}" == "true" ]]; then
57+
echo "[*] Verifying golint..."
58+
hack/verify-golint.sh || res=1
59+
cd "${REPO_PATH}"
60+
fi
61+
62+
if [[ "${VERIFY_GOVET:-true}" == "true" ]]; then
63+
echo "[*] Verifying govet..."
64+
hack/verify-govet.sh || res=1
65+
cd "${REPO_PATH}"
66+
fi
67+
68+
if [[ "${VERIFY_DEPS:-true}" == "true" ]]; then
69+
echo "[*] Verifying deps..."
70+
hack/verify-deps.sh || res=1
71+
cd "${REPO_PATH}"
72+
fi
73+
74+
if [[ "${VERIFY_GOTEST:-true}" == "true" ]]; then
75+
echo "[*] Verifying gotest..."
76+
hack/verify-gotest.sh || res=1
77+
cd "${REPO_PATH}"
78+
fi
79+
80+
if [[ "${VERIFY_BUILD:-true}" == "true" ]]; then
81+
echo "[*] Verifying build..."
82+
hack/verify-build.sh || res=1
83+
cd "${REPO_PATH}"
84+
fi
85+
86+
# exit based on verify scripts
87+
if [[ "${res}" = 0 ]]; then
88+
echo ""
89+
echo "All verify checks passed, congrats!"
90+
else
91+
echo ""
92+
echo "One or more verify checks failed! See output above..."
93+
fi
94+
exit "${res}"

hack/verify-boilerplate.go

+174
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
/*
2+
Copyright 2019 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+
17+
package main
18+
19+
import (
20+
"errors"
21+
"fmt"
22+
"io/ioutil"
23+
"os"
24+
"regexp"
25+
"strings"
26+
)
27+
28+
const (
29+
yearPlaceholder = "YEAR"
30+
boilerPlateStart = "Copyright "
31+
boilerPlateEnd = "limitations under the License."
32+
)
33+
34+
var (
35+
supportedExt = []string{".go", ".py", ".sh"}
36+
yearRegexp = regexp.MustCompile("(20)[0-9][0-9]")
37+
boilerPlate = []string{
38+
boilerPlateStart + yearPlaceholder + " The Kubernetes Authors.",
39+
"",
40+
`Licensed under the Apache License, Version 2.0 (the "License");`,
41+
"you may not use this file except in compliance with the License.",
42+
"You may obtain a copy of the License at",
43+
"",
44+
" http://www.apache.org/licenses/LICENSE-2.0",
45+
"",
46+
"Unless required by applicable law or agreed to in writing, software",
47+
`distributed under the License is distributed on an "AS IS" BASIS,`,
48+
"WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.",
49+
"See the License for the specific language governing permissions and",
50+
boilerPlateEnd,
51+
}
52+
)
53+
54+
// trimLeadingComment strips a single line comment characters such as # or //
55+
// at the exact beginning of a line, but also the first possible space character after it.
56+
func trimLeadingComment(line, c string) string {
57+
if strings.Index(line, c) == 0 {
58+
x := len(c)
59+
if len(line) == x {
60+
return ""
61+
}
62+
if line[x] == byte(' ') {
63+
return line[x+1:]
64+
}
65+
return line[x:]
66+
}
67+
return line
68+
}
69+
70+
// verifyFileExtension verifies if the file extensions is supported
71+
func isSupportedFileExtension(filePath string) bool {
72+
// check if the file has an extension
73+
idx := strings.LastIndex(filePath, ".")
74+
if idx == -1 {
75+
return false
76+
}
77+
78+
// check if the file has a supported extension
79+
ext := filePath[idx : idx+len(filePath)-idx]
80+
for _, e := range supportedExt {
81+
if e == ext {
82+
return true
83+
}
84+
}
85+
return false
86+
}
87+
88+
// verifyBoilerplate verifies if a string contains the boilerplate
89+
func verifyBoilerplate(contents string) error {
90+
idx := 0
91+
foundBoilerplateStart := false
92+
lines := strings.Split(contents, "\n")
93+
for _, line := range lines {
94+
// handle leading comments
95+
line = trimLeadingComment(line, "//")
96+
line = trimLeadingComment(line, "#")
97+
98+
// find the start of the boilerplate
99+
bpLine := boilerPlate[idx]
100+
if strings.Contains(line, boilerPlateStart) {
101+
foundBoilerplateStart = true
102+
103+
// validate the year of the copyright
104+
yearWords := strings.Split(line, " ")
105+
expectedLen := len(strings.Split(boilerPlate[0], " "))
106+
if len(yearWords) != expectedLen {
107+
return fmt.Errorf("copyright line should contain exactly %d words", expectedLen)
108+
}
109+
if !yearRegexp.MatchString(yearWords[1]) {
110+
return fmt.Errorf("cannot parse the year in the copyright line")
111+
}
112+
bpLine = strings.ReplaceAll(bpLine, yearPlaceholder, yearWords[1])
113+
}
114+
115+
// match line by line
116+
if foundBoilerplateStart {
117+
if line != bpLine {
118+
return fmt.Errorf("boilerplate line %d does not match\nexpected: %q\ngot: %q", idx+1, bpLine, line)
119+
}
120+
idx++
121+
// exit after the last line is found
122+
if strings.Index(line, boilerPlateEnd) == 0 {
123+
break
124+
}
125+
}
126+
}
127+
128+
if !foundBoilerplateStart {
129+
return fmt.Errorf("the file is missing a boilerplate")
130+
}
131+
if idx < len(boilerPlate) {
132+
return errors.New("boilerplate has missing lines")
133+
}
134+
return nil
135+
}
136+
137+
// verifyFile verifies if a file contains the boilerplate
138+
func verifyFile(filePath string) error {
139+
if len(filePath) == 0 {
140+
return errors.New("empty file name")
141+
}
142+
143+
if !isSupportedFileExtension(filePath) {
144+
fmt.Printf("skipping %q: unsupported file type\n", filePath)
145+
return nil
146+
}
147+
148+
// read the file
149+
b, err := ioutil.ReadFile(filePath)
150+
if err != nil {
151+
return err
152+
}
153+
154+
return verifyBoilerplate(string(b))
155+
}
156+
157+
func main() {
158+
if len(os.Args) < 2 {
159+
fmt.Println("usage: " +
160+
"go run verify-boilerplate.go <path-to-file> <path-to-file> ...")
161+
os.Exit(1)
162+
}
163+
164+
hasErr := false
165+
for _, filePath := range os.Args[1:] {
166+
if err := verifyFile(filePath); err != nil {
167+
fmt.Printf("error validating %q: %v\n", filePath, err)
168+
hasErr = true
169+
}
170+
}
171+
if hasErr {
172+
os.Exit(1)
173+
}
174+
}

0 commit comments

Comments
 (0)