2 Copyright 2018 The Kubernetes Authors.
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
8 http://www.apache.org/licenses/LICENSE-2.0
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.
29 // isGoFile filters files from parsing.
30 func isGoFile(f os.FileInfo) bool {
31 // ignore non-Go or Go test files
34 !strings.HasPrefix(name, ".") &&
35 !strings.HasSuffix(name, "_test.go") &&
36 strings.HasSuffix(name, ".go")
39 // GetAnnotation extracts the annotation from comment text.
40 // It will return "foo" for comment "+kubebuilder:webhook:foo" .
41 func GetAnnotation(c, name string) string {
42 prefix := fmt.Sprintf("+%s:", name)
43 if strings.HasPrefix(c, prefix) {
44 return strings.TrimPrefix(c, prefix)
49 // ParseKV parses key-value string formatted as "foo=bar" and returns key and value.
50 func ParseKV(s string) (key, value string, err error) {
51 kv := strings.Split(s, "=")
53 err = fmt.Errorf("invalid key value pair")
54 return key, value, err
56 key, value = kv[0], kv[1]
57 if strings.HasPrefix(value, "\"") && strings.HasSuffix(value, "\"") {
58 value = value[1 : len(value)-1]
60 return key, value, err
63 // ParseDir parses the Go files under given directory and parses the annotation by
64 // invoking the parseFn function on each comment group (multi-lines comments).
65 // TODO(droot): extend it to multiple dirs
66 func ParseDir(dir string, parseFn func(string) error) error {
67 fset := token.NewFileSet()
69 err := filepath.Walk(dir,
70 func(path string, info os.FileInfo, _ error) error {
72 // TODO(droot): enable this output based on verbose flag
73 // fmt.Println("skipping non-go file", path)
76 return ParseFile(fset, path, nil, parseFn)
81 // ParseFile parses given filename or content src and parses annotations by
82 // invoking the parseFn function on each comment group (multi-lines comments).
83 func ParseFile(fset *token.FileSet, filename string, src interface{}, parseFn func(string) error) error {
84 f, err := parser.ParseFile(fset, filename, src, parser.ParseComments)
86 fmt.Printf("error from parse.ParseFile: %v", err)
90 // using commentMaps here because it sanitizes the comment text by removing
91 // comment markers, compresses newlines etc.
92 cmap := ast.NewCommentMap(fset, f, f.Comments)
94 for _, commentGroup := range cmap.Comments() {
95 err = parseFn(commentGroup.Text())
97 fmt.Print("error when parsing annotation")