forked from kubernetes/enhancements
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: chuckha <ha.chuck@gmail.com>
- Loading branch information
Showing
10 changed files
with
680 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
/* | ||
Copyright 2019 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 | ||
|
||
import ( | ||
"flag" | ||
"fmt" | ||
"os" | ||
|
||
"k8s.io/enhancements/pkg/kepval/keps" | ||
) | ||
|
||
func main() { | ||
list := flag.NewFlagSet("list", flag.ExitOnError) | ||
list.Parse(os.Args[1:]) | ||
|
||
parser := &keps.Parser{} | ||
exit := 0 | ||
for _, filename := range list.Args() { | ||
file, err := os.Open(filename) | ||
if err != nil { | ||
fmt.Printf("could not open file: %v", err) | ||
os.Exit(1) | ||
} | ||
defer file.Close() | ||
kep := parser.Parse(file) | ||
// if error is nil we can move on | ||
if kep.Error == nil { | ||
continue | ||
} | ||
|
||
fmt.Printf("%v has an error: %q\n", filename, kep.Error.Error()) | ||
exit = 1 | ||
} | ||
|
||
if exit == 0 { | ||
fmt.Println("No validation errors") | ||
} | ||
os.Exit(exit) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
/* | ||
Copyright 2019 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 | ||
|
||
import ( | ||
"fmt" | ||
"io/ioutil" | ||
"os" | ||
"os/exec" | ||
"path/filepath" | ||
"strings" | ||
"testing" | ||
|
||
"github.com/pkg/errors" | ||
) | ||
|
||
func TestIntegration(t *testing.T) { | ||
tempDir, err := ioutil.TempDir(".", "test") | ||
if err != nil { | ||
t.Fatalf("%+v", errors.WithStack(err)) | ||
} | ||
defer os.RemoveAll(tempDir) | ||
fmt.Println("Cloning...") | ||
cmd := exec.Command("git", "clone", "https://github.com/kubernetes/enhancements") | ||
cmd.Dir = tempDir | ||
out, err := cmd.CombinedOutput() | ||
if err != nil { | ||
fmt.Println(string(out)) | ||
t.Fatalf("%+v", errors.WithStack(err)) | ||
} | ||
fmt.Println("Building...") | ||
cmd = exec.Command("go", "build", "-o", filepath.Join(tempDir, "kepval"), ".") | ||
if out, err := cmd.CombinedOutput(); err != nil { | ||
fmt.Println(string(out)) | ||
t.Fatal(err) | ||
} | ||
fmt.Println("Walking...") | ||
if filepath.Walk( | ||
filepath.Join(tempDir, "enhancements", "keps"), | ||
func(path string, info os.FileInfo, err error) error { | ||
if info.IsDir() { | ||
return nil | ||
} | ||
if err != nil { | ||
t.Fatalf("%+v", err) | ||
} | ||
if ignore(info.Name()) { | ||
return nil | ||
} | ||
cmd = exec.Command(filepath.Join(tempDir, "kepval"), path) | ||
if out, err := cmd.CombinedOutput(); err != nil { | ||
fmt.Println(string(out)) | ||
t.Fatal(err) | ||
} | ||
return nil | ||
}, | ||
) != nil { | ||
t.Fatal(err) | ||
} | ||
} | ||
|
||
func ignore(name string) bool { | ||
if !strings.HasSuffix(name, "md") { | ||
return true | ||
} | ||
if name == "0023-documentation-for-images.md" { | ||
return true | ||
} | ||
return false | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
# kepval | ||
|
||
`kepval` is a tool that checks the YAML metadata in a KEP (Kubernetes | ||
Enhancement Proposal) is valid. | ||
|
||
## Getting started | ||
|
||
1. Install `kepval`: `GO111MODULE=on go get k8s.io/enhancements/cmd/kepval` | ||
2. [optional] clone the enhancements for test data `git clone https://github.com/kubernetes/enhancements.git` | ||
3. Run `kepval <path to kep.md>` | ||
|
||
## Development | ||
|
||
1. Run the tests with `go test -cover ./...` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
module k8s.io/enhancements | ||
|
||
go 1.12 | ||
|
||
require ( | ||
github.com/pkg/errors v0.8.1 | ||
gopkg.in/yaml.v2 v2.2.2 | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= | ||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= | ||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= | ||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= | ||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
/* | ||
Copyright 2019 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 keps | ||
|
||
import ( | ||
"bufio" | ||
"bytes" | ||
"io" | ||
"strings" | ||
|
||
"github.com/pkg/errors" | ||
"gopkg.in/yaml.v2" | ||
"k8s.io/enhancements/pkg/kepval/keps/validations" | ||
) | ||
|
||
type Proposals []*Proposal | ||
|
||
func (p *Proposals) AddProposal(proposal *Proposal) { | ||
*p = append(*p, proposal) | ||
} | ||
|
||
type Proposal struct { | ||
Title string `yaml:"title"` | ||
Authors []string `yaml:,flow` | ||
OwningSIG string `yaml:"owning-sig"` | ||
ParticipatingSIGs []string `yaml:"participating-sigs",flow,omitempty` | ||
Reviewers []string `yaml:,flow` | ||
Approvers []string `yaml:,flow` | ||
Editor string `yaml:"editor,omitempty"` | ||
CreationDate string `yaml:"creation-date"` | ||
LastUpdated string `yaml:"last-updated"` | ||
Status string `yaml:"status"` | ||
SeeAlso []string `yaml:"see-also,omitempty"` | ||
Replaces []string `yaml:"replaces,omitempty"` | ||
SupersededBy []string `yaml:"superseded-by,omitempty"` | ||
|
||
Filename string `yaml:"-"` | ||
Error error `yaml:"-"` | ||
Contents string `yaml:"-"` | ||
} | ||
|
||
type Parser struct{} | ||
|
||
func (p *Parser) Parse(in io.Reader) *Proposal { | ||
scanner := bufio.NewScanner(in) | ||
count := 0 | ||
metadata := []byte{} | ||
var body bytes.Buffer | ||
for scanner.Scan() { | ||
line := scanner.Text() + "\n" | ||
body.WriteString(line) | ||
if count == 2 { | ||
continue | ||
} | ||
if strings.Contains(line, "---") { | ||
count++ | ||
continue | ||
} | ||
if count == 1 { | ||
metadata = append(metadata, []byte(line)...) | ||
} | ||
} | ||
proposal := &Proposal{ | ||
Contents: body.String(), | ||
} | ||
if err := scanner.Err(); err != nil { | ||
proposal.Error = errors.Wrap(err, "error reading file") | ||
return proposal | ||
} | ||
|
||
// First do structural checks | ||
test := map[interface{}]interface{}{} | ||
if err := yaml.Unmarshal(metadata, test); err != nil { | ||
proposal.Error = errors.Wrap(err, "error unmarshaling YAML") | ||
return proposal | ||
} | ||
if err := validations.ValidateStructure(test); err != nil { | ||
proposal.Error = errors.Wrap(err, "error validating KEP metadata") | ||
return proposal | ||
} | ||
|
||
proposal.Error = yaml.Unmarshal(metadata, proposal) | ||
return proposal | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
/* | ||
Copyright 2019 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 keps_test | ||
|
||
import ( | ||
"strings" | ||
"testing" | ||
|
||
"k8s.io/enhancements/pkg/kepval/keps" | ||
) | ||
|
||
func TestValidParsing(t *testing.T) { | ||
testcases := []struct { | ||
name string | ||
fileContents string | ||
}{ | ||
{ | ||
"simple test", | ||
`--- | ||
title: test | ||
authors: | ||
- "@jpbetz" | ||
- "@roycaihw" | ||
- "@sttts" | ||
owning-sig: sig-api-machinery | ||
participating-sigs: | ||
- sig-api-machinery | ||
- sig-architecture | ||
reviewers: | ||
- "@deads2k" | ||
- "@lavalamp" | ||
- "@liggitt" | ||
- "@mbohlool" | ||
- "@sttts" | ||
approvers: | ||
- "@deads2k" | ||
- "@lavalamp" | ||
creation-date: 2018-04-15 | ||
last-updated: 2018-04-24 | ||
status: provisional | ||
---`, | ||
}, | ||
} | ||
for _, tc := range testcases { | ||
t.Run(tc.name, func(t *testing.T) { | ||
p := &keps.Parser{} | ||
contents := strings.NewReader(tc.fileContents) | ||
out := p.Parse(contents) | ||
if out.Error != nil { | ||
t.Fatalf("expected no error but got one: %v", out.Error) | ||
} | ||
if out == nil { | ||
t.Fatal("out should not be nil") | ||
} | ||
}) | ||
} | ||
} |
Oops, something went wrong.