Skip to content

Commit 9ee1336

Browse files
authored
Merge pull request kubernetes#1467 from dims/kepify-to-generate-json-for-netlify
kepify: New command to generate KEP json for Netlify
2 parents 490d72c + fd11ef6 commit 9ee1336

File tree

2 files changed

+191
-4
lines changed

2 files changed

+191
-4
lines changed

cmd/kepify/main.go

Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
/*
2+
Copyright 2020 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+
"crypto/md5"
21+
"encoding/json"
22+
"flag"
23+
"fmt"
24+
"os"
25+
"path/filepath"
26+
"strings"
27+
28+
"k8s.io/enhancements/pkg/kepval/keps"
29+
)
30+
31+
func Usage() {
32+
fmt.Fprintf(os.Stderr, `
33+
Usage: %s [-dir <kep-directory>] [-output <path-to-json-file>]
34+
Command line flags override config values.
35+
`, os.Args[0])
36+
flag.PrintDefaults()
37+
}
38+
39+
func main() {
40+
dirPath := flag.String("dir", "keps", "root directory for the KEPs")
41+
filePath := flag.String("output", "keps.json", "output json file")
42+
43+
flag.Usage = Usage
44+
flag.Parse()
45+
46+
if len(*dirPath) == 0 {
47+
fmt.Fprintf(os.Stderr, "please specify the root directory for KEPs using '--dir'\n")
48+
os.Exit(1)
49+
}
50+
if _, err := os.Stat(*dirPath); os.IsNotExist(err) {
51+
fmt.Printf("directory does not exist : %s", *dirPath)
52+
os.Exit(1)
53+
}
54+
55+
if len(*filePath) == 0 {
56+
fmt.Fprintf(os.Stderr, "please specify the file path for the output json using '--output'\n")
57+
os.Exit(1)
58+
}
59+
60+
// Find all the keps
61+
files, err := findMarkdownFiles(dirPath)
62+
if err != nil {
63+
fmt.Fprintf(os.Stderr, "unable to find markdown files: %v\n", err)
64+
os.Exit(1)
65+
}
66+
if len(files) == 0 {
67+
fmt.Fprintf(os.Stderr, "did not find any KEPs\n")
68+
os.Exit(1)
69+
}
70+
71+
// Parse the files
72+
proposals, err := parseFiles(files)
73+
if err != nil {
74+
fmt.Fprintf(os.Stderr, "error parsing files: %q\n", err)
75+
os.Exit(1)
76+
}
77+
78+
// Generate the json output
79+
err = printJSONOutput(*filePath, proposals)
80+
if err != nil {
81+
fmt.Fprintf(os.Stderr, "could not open file: %v\n", err)
82+
os.Exit(1)
83+
}
84+
}
85+
86+
func findMarkdownFiles(dirPath *string) ([]string, error) {
87+
files := []string{}
88+
err := filepath.Walk(
89+
*dirPath,
90+
func(path string, info os.FileInfo, err error) error {
91+
if err != nil {
92+
return err
93+
}
94+
if info.IsDir() {
95+
return nil
96+
}
97+
if ignore(info.Name()) {
98+
return nil
99+
}
100+
files = append(files, path)
101+
return nil
102+
},
103+
)
104+
return files, err
105+
}
106+
107+
func parseFiles(files []string) (keps.Proposals, error) {
108+
var proposals keps.Proposals
109+
for _, filename := range files {
110+
parser := &keps.Parser{}
111+
file, err := os.Open(filename)
112+
if err != nil {
113+
return nil, fmt.Errorf("could not open file: %v\n", err)
114+
}
115+
defer file.Close()
116+
kep := parser.Parse(file)
117+
// if error is nil we can move on
118+
if kep.Error != nil {
119+
return nil, fmt.Errorf("%v has an error: %q\n", filename, kep.Error.Error())
120+
}
121+
fmt.Printf(">>>> parsed file successfully: %s\n", filename)
122+
proposals.AddProposal(kep)
123+
}
124+
return proposals, nil
125+
}
126+
127+
func printJSONOutput(filePath string, proposals keps.Proposals) error {
128+
fmt.Printf("Output file: %s\n", filePath)
129+
file, err := os.Create(filePath)
130+
if err != nil {
131+
return err
132+
}
133+
defer file.Close()
134+
135+
total := len(proposals)
136+
fmt.Printf("Total KEPs: %d\n", total)
137+
138+
fmt.Fprintln(file, "{")
139+
for i, kep := range proposals {
140+
fmt.Fprintf(file, "\t\"%s\": {\n", hash(kep.OwningSIG+":"+kep.Title))
141+
fmt.Fprintf(file, "\t\t\"%s\": \"%s\",\n", "title", kep.Title)
142+
fmt.Fprintf(file, "\t\t\"%s\": \"%s\",\n", "owning-sig", kep.OwningSIG)
143+
fmt.Fprintf(file, "\t\t\"%s\": %s,\n", "participating-sigs", marshal(kep.ParticipatingSIGs))
144+
fmt.Fprintf(file, "\t\t\"%s\": %s,\n", "reviewers", marshal(kep.Reviewers))
145+
fmt.Fprintf(file, "\t\t\"%s\": %s,\n", "authors", marshal(kep.Authors))
146+
fmt.Fprintf(file, "\t\t\"%s\": \"%s\",\n", "editor", kep.Editor)
147+
fmt.Fprintf(file, "\t\t\"%s\": \"%s\",\n", "creation-date", kep.CreationDate)
148+
fmt.Fprintf(file, "\t\t\"%s\": \"%s\",\n", "last-updated", kep.LastUpdated)
149+
fmt.Fprintf(file, "\t\t\"%s\": \"%s\",\n", "status", kep.Status)
150+
fmt.Fprintf(file, "\t\t\"%s\": %s,\n", "see-also", marshal(kep.SeeAlso))
151+
fmt.Fprintf(file, "\t\t\"%s\": %s,\n", "replaces", marshal(kep.Replaces))
152+
fmt.Fprintf(file, "\t\t\"%s\": %s,\n", "superseded-by", marshal(kep.SupersededBy))
153+
contents, _ := json.Marshal(kep.Contents)
154+
fmt.Fprintf(file, "\t\t\"%s\": %s\n", "markdown", contents)
155+
if i < total-1 {
156+
fmt.Fprintln(file, "\t},")
157+
} else {
158+
fmt.Fprintln(file, "\t}")
159+
}
160+
}
161+
fmt.Fprintln(file, "}")
162+
return nil
163+
}
164+
165+
func marshal(array []string) string {
166+
contents, _ := json.Marshal(array)
167+
return string(contents)
168+
}
169+
170+
func hash(s string) string {
171+
return fmt.Sprintf("%x", md5.Sum([]byte(s)))
172+
}
173+
174+
/// ignore certain files in the keps/ subdirectory
175+
func ignore(name string) bool {
176+
if !strings.HasSuffix(name, "md") {
177+
return true
178+
}
179+
if name == "0023-documentation-for-images.md" ||
180+
name == "0004-cloud-provider-template.md" ||
181+
name == "0001a-meta-kep-implementation.md" ||
182+
name == "0001-kubernetes-enhancement-proposal-process.md" ||
183+
name == "YYYYMMDD-kep-template.md" ||
184+
name == "README.md" ||
185+
name == "kep-faq.md" {
186+
return true
187+
}
188+
return false
189+
}

pkg/kepval/keps/proposals.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,16 +62,14 @@ func (p *Parser) Parse(in io.Reader) *Proposal {
6262
var body bytes.Buffer
6363
for scanner.Scan() {
6464
line := scanner.Text() + "\n"
65-
body.WriteString(line)
66-
if count == 2 {
67-
continue
68-
}
6965
if strings.Contains(line, "---") {
7066
count++
7167
continue
7268
}
7369
if count == 1 {
7470
metadata = append(metadata, []byte(line)...)
71+
} else {
72+
body.WriteString(line)
7573
}
7674
}
7775
proposal := &Proposal{

0 commit comments

Comments
 (0)