Add tests
This commit is contained in:
parent
f3375f168e
commit
eab658607d
4
Makefile
4
Makefile
|
@ -13,3 +13,7 @@ gen-doc:
|
||||||
|
|
||||||
gen-docs:
|
gen-docs:
|
||||||
docker run -v $(shell pwd):/go/src/app sigdocs
|
docker run -v $(shell pwd):/go/src/app sigdocs
|
||||||
|
|
||||||
|
test:
|
||||||
|
docker build -t sigdocs-test -f generator/Dockerfile.test generator
|
||||||
|
docker run sigdocs-test
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
FROM golang:1.6-onbuild
|
FROM golang:1.8-onbuild
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
FROM golang:1.8
|
||||||
|
|
||||||
|
WORKDIR /go/src/app
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
RUN go-wrapper download
|
||||||
|
|
||||||
|
CMD ["go", "test", "./..."]
|
|
@ -1,14 +1,26 @@
|
||||||
# SIG Doc builder
|
# SIG Doc builder
|
||||||
|
|
||||||
This script will generate the following documentation files:
|
This folder contains scripts to automatically generate documentation about the
|
||||||
|
different Special Interest Groups (SIGs) of Kubernetes. The authoritative
|
||||||
|
source for SIG information is the `sigs.yaml` file in the project root. All
|
||||||
|
updates must be done there.
|
||||||
|
|
||||||
|
When an update happens to the this file, the next step is generate the
|
||||||
|
accompanying documentation. This takes the format of two types of doc file:
|
||||||
|
|
||||||
```
|
```
|
||||||
sig-*/README.md
|
./sig-<sig-name>/README.md
|
||||||
wg-*/README.md
|
./wg-<working-group-name>/README.md
|
||||||
sig-list.md
|
./sig-list.md
|
||||||
```
|
```
|
||||||
|
|
||||||
Based off the `sigs.yaml` metadata file.
|
For example, if a contributor has updated `sig-cluster-lifecycle`, the
|
||||||
|
following files will be generated:
|
||||||
|
|
||||||
|
```
|
||||||
|
./sig-cluster-lifecycle/README.md
|
||||||
|
./sig-list.md
|
||||||
|
```
|
||||||
|
|
||||||
## How to use
|
## How to use
|
||||||
|
|
||||||
|
|
|
@ -31,11 +31,10 @@ import (
|
||||||
|
|
||||||
var (
|
var (
|
||||||
sigsYamlFile = "sigs.yaml"
|
sigsYamlFile = "sigs.yaml"
|
||||||
templateDir = "generator"
|
sigIndexTemplate = "sig_index.tmpl"
|
||||||
sigIndexTemplate = filepath.Join(templateDir, "sig_index.tmpl")
|
wgIndexTemplate = "wg_index.tmpl"
|
||||||
wgIndexTemplate = filepath.Join(templateDir, "wg_index.tmpl")
|
listTemplate = "sig_list.tmpl"
|
||||||
listTemplate = filepath.Join(templateDir, "sig_list.tmpl")
|
headerTemplate = "header.tmpl"
|
||||||
headerTemplate = filepath.Join(templateDir, "header.tmpl")
|
|
||||||
sigListOutput = "sig-list.md"
|
sigListOutput = "sig-list.md"
|
||||||
sigIndexOutput = "README.md"
|
sigIndexOutput = "README.md"
|
||||||
githubTeamNames = []string{"misc", "test-failures", "bugs", "feature-requests", "proposals", "pr-reviews", "api-reviews"}
|
githubTeamNames = []string{"misc", "test-failures", "bugs", "feature-requests", "proposals", "pr-reviews", "api-reviews"}
|
||||||
|
@ -95,34 +94,10 @@ type SigEntries struct {
|
||||||
Sigs []Sig
|
Sigs []Sig
|
||||||
}
|
}
|
||||||
|
|
||||||
func (slice SigEntries) Len() int {
|
|
||||||
return len(slice.Sigs)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (slice SigEntries) Less(i, j int) bool {
|
|
||||||
return slice.Sigs[i].Name < slice.Sigs[j].Name
|
|
||||||
}
|
|
||||||
|
|
||||||
func (slice SigEntries) Swap(i, j int) {
|
|
||||||
slice.Sigs[i], slice.Sigs[j] = slice.Sigs[j], slice.Sigs[i]
|
|
||||||
}
|
|
||||||
|
|
||||||
type WgEntries struct {
|
type WgEntries struct {
|
||||||
WorkingGroups []Wg
|
WorkingGroups []Wg
|
||||||
}
|
}
|
||||||
|
|
||||||
func (slice WgEntries) Len() int {
|
|
||||||
return len(slice.WorkingGroups)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (slice WgEntries) Less(i, j int) bool {
|
|
||||||
return slice.WorkingGroups[i].Name < slice.WorkingGroups[j].Name
|
|
||||||
}
|
|
||||||
|
|
||||||
func (slice WgEntries) Swap(i, j int) {
|
|
||||||
slice.WorkingGroups[i], slice.WorkingGroups[j] = slice.WorkingGroups[j], slice.WorkingGroups[i]
|
|
||||||
}
|
|
||||||
|
|
||||||
func pathExists(path string) bool {
|
func pathExists(path string) bool {
|
||||||
_, err := os.Stat(path)
|
_, err := os.Stat(path)
|
||||||
return err == nil
|
return err == nil
|
||||||
|
@ -162,7 +137,13 @@ func getExistingContent(path string) (string, error) {
|
||||||
return strings.Join(captured, "\n"), nil
|
return strings.Join(captured, "\n"), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeTemplate(templatePath, outputPath string, data interface{}) error {
|
func writeTemplate(templateFilePath, outputPath string, data interface{}) error {
|
||||||
|
wd, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
templatePath := filepath.Join(wd, templateFilePath)
|
||||||
|
|
||||||
// set up template
|
// set up template
|
||||||
t, err := template.ParseFiles(templatePath, headerTemplate)
|
t, err := template.ParseFiles(templatePath, headerTemplate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -242,6 +223,7 @@ func createReadmeFiles(ctx Context) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var selectedWg *string
|
var selectedWg *string
|
||||||
if wg, ok := os.LookupEnv("WG"); ok {
|
if wg, ok := os.LookupEnv("WG"); ok {
|
||||||
selectedWg = &wg
|
selectedWg = &wg
|
||||||
|
@ -289,12 +271,14 @@ func main() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
sigEntries := SigEntries{ctx.Sigs}
|
|
||||||
sort.Sort(sigEntries)
|
sort.Slice(ctx.Sigs, func(i, j int) bool {
|
||||||
ctx.Sigs = sigEntries.Sigs
|
return ctx.Sigs[i].Name >= ctx.Sigs[j].Name
|
||||||
wgEntries := WgEntries{ctx.WorkingGroups}
|
})
|
||||||
sort.Sort(wgEntries)
|
|
||||||
ctx.WorkingGroups = wgEntries.WorkingGroups
|
sort.Slice(ctx.WorkingGroups, func(i, j int) bool {
|
||||||
|
return ctx.WorkingGroups[i].Name >= ctx.WorkingGroups[j].Name
|
||||||
|
})
|
||||||
|
|
||||||
err = createReadmeFiles(ctx)
|
err = createReadmeFiles(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -0,0 +1,136 @@
|
||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestNonExistantDirIsCreated(t *testing.T) {
|
||||||
|
dir := "/tmp/nonexistent"
|
||||||
|
err := createDirIfNotExists(dir)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Received error creating dir: %v", err)
|
||||||
|
}
|
||||||
|
if !pathExists(dir) {
|
||||||
|
t.Fatalf("%s should exist", dir)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetExistingData(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
path string
|
||||||
|
expected string
|
||||||
|
expectErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
path: "./testdata/custom_content.md",
|
||||||
|
expected: "FOO BAR BAZ",
|
||||||
|
expectErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "./testdata/no_custom_content.md",
|
||||||
|
expected: "",
|
||||||
|
expectErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "./testdata/foo.md",
|
||||||
|
expected: "",
|
||||||
|
expectErr: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range cases {
|
||||||
|
content, err := getExistingContent(c.path)
|
||||||
|
if err != nil && c.expectErr == false {
|
||||||
|
t.Fatalf("Received unexpected error for %s: %v", c.path, err)
|
||||||
|
}
|
||||||
|
if err == nil && c.expectErr == true {
|
||||||
|
t.Fatalf("Expected error for %s but received none", c.path)
|
||||||
|
}
|
||||||
|
if content != c.expected {
|
||||||
|
t.Fatalf("Expected %s but received %s", c.expected, content)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWriteTemplate(t *testing.T) {
|
||||||
|
customContent := `
|
||||||
|
<!-- BEGIN CUSTOM CONTENT -->
|
||||||
|
Example
|
||||||
|
custom
|
||||||
|
content!
|
||||||
|
|
||||||
|
<!-- END CUSTOM CONTENT -->
|
||||||
|
`
|
||||||
|
|
||||||
|
cases := []struct {
|
||||||
|
templatePath string
|
||||||
|
outputPath string
|
||||||
|
data map[string]string
|
||||||
|
expectErr bool
|
||||||
|
expected string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
templatePath: "./testdata/non_existent_template.tmpl",
|
||||||
|
expectErr: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
templatePath: "./testdata/example.tmpl",
|
||||||
|
outputPath: "/tmp/non_existing_path.md",
|
||||||
|
expectErr: false,
|
||||||
|
data: map[string]string{"Message": "Hello!"},
|
||||||
|
expected: "Hello!",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
templatePath: "./testdata/example.tmpl",
|
||||||
|
outputPath: "./testdata/example.md",
|
||||||
|
expectErr: false,
|
||||||
|
data: map[string]string{"Message": "Hello!"},
|
||||||
|
expected: customContent,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
templatePath: "./testdata/example.tmpl",
|
||||||
|
outputPath: "/tmp/non_existing_path.md",
|
||||||
|
expectErr: false,
|
||||||
|
data: map[string]string{"Message": "Hello!"},
|
||||||
|
expected: "Last generated: ",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range cases {
|
||||||
|
err := writeTemplate(c.templatePath, c.outputPath, c.data)
|
||||||
|
if err != nil && c.expectErr == false {
|
||||||
|
t.Fatalf("Received unexpected error for %s: %v", c.templatePath, err)
|
||||||
|
}
|
||||||
|
if c.expectErr {
|
||||||
|
if err == nil {
|
||||||
|
t.Fatalf("Expected error for %s but received none", c.templatePath)
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
content, err := ioutil.ReadFile(c.outputPath)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("%s should exist", c.outputPath)
|
||||||
|
}
|
||||||
|
if strings.Contains(string(content), c.expected) == false {
|
||||||
|
t.Fatalf("%s was not found in %s", c.expected, c.outputPath)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
<!---
|
||||||
|
This is an autogenerated file!
|
||||||
|
|
||||||
|
Please do not edit this file directly, but instead make changes to the
|
||||||
|
sigs.yaml file in the project root.
|
||||||
|
|
||||||
|
To understand how this file is generated, see generator/README.md.
|
||||||
|
-->
|
||||||
|
# Auth SIG
|
||||||
|
|
||||||
|
Covers improvements to Kubernetes authorization, authentication, and cluster security policy.
|
||||||
|
|
||||||
|
## Meetings
|
||||||
|
* [Wednesdays at 18:00 UTC](https://zoom.us/my/k8s.sig.auth) (biweekly). [Convert to your timezone](http://www.thetimezoneconverter.com/?t=18:00&tz=UTC).
|
||||||
|
|
||||||
|
Meeting notes and Agenda can be found [here](https://docs.google.com/document/d/1woLGRoONE3EBVx-wTb4pvp4CI7tmLZ6lS26VTbosLKM/edit#).
|
||||||
|
|
||||||
|
## Leads
|
||||||
|
* [Eric Chiang](https://github.com/ericchiang), CoreOS
|
||||||
|
* [Jordan Liggitt](https://github.com/liggitt), Red Hat
|
||||||
|
* [David Eads](https://github.com/deads2k), Red Hat
|
||||||
|
|
||||||
|
## Contact
|
||||||
|
* [Slack](https://kubernetes.slack.com/messages/sig-auth)
|
||||||
|
* [Mailing list](https://groups.google.com/forum/#!forum/kubernetes-sig-auth)
|
||||||
|
|
||||||
|
<!-- BEGIN CUSTOM CONTENT -->
|
||||||
|
FOO BAR BAZ
|
||||||
|
<!-- END CUSTOM CONTENT -->
|
||||||
|
|
||||||
|
Last generated: Wed Jun 7 2017 14:27:56
|
|
@ -0,0 +1,9 @@
|
||||||
|
Hello!
|
||||||
|
<!-- BEGIN CUSTOM CONTENT -->
|
||||||
|
Example
|
||||||
|
custom
|
||||||
|
content!
|
||||||
|
|
||||||
|
<!-- END CUSTOM CONTENT -->
|
||||||
|
|
||||||
|
Last generated: Thu Jun 15 2017 15:20:28
|
|
@ -0,0 +1 @@
|
||||||
|
{{.Message}}
|
|
@ -0,0 +1,31 @@
|
||||||
|
<!---
|
||||||
|
This is an autogenerated file!
|
||||||
|
|
||||||
|
Please do not edit this file directly, but instead make changes to the
|
||||||
|
sigs.yaml file in the project root.
|
||||||
|
|
||||||
|
To understand how this file is generated, see generator/README.md.
|
||||||
|
-->
|
||||||
|
# Auth SIG
|
||||||
|
|
||||||
|
Covers improvements to Kubernetes authorization, authentication, and cluster security policy.
|
||||||
|
|
||||||
|
## Meetings
|
||||||
|
* [Wednesdays at 18:00 UTC](https://zoom.us/my/k8s.sig.auth) (biweekly). [Convert to your timezone](http://www.thetimezoneconverter.com/?t=18:00&tz=UTC).
|
||||||
|
|
||||||
|
Meeting notes and Agenda can be found [here](https://docs.google.com/document/d/1woLGRoONE3EBVx-wTb4pvp4CI7tmLZ6lS26VTbosLKM/edit#).
|
||||||
|
|
||||||
|
## Leads
|
||||||
|
* [Eric Chiang](https://github.com/ericchiang), CoreOS
|
||||||
|
* [Jordan Liggitt](https://github.com/liggitt), Red Hat
|
||||||
|
* [David Eads](https://github.com/deads2k), Red Hat
|
||||||
|
|
||||||
|
## Contact
|
||||||
|
* [Slack](https://kubernetes.slack.com/messages/sig-auth)
|
||||||
|
* [Mailing list](https://groups.google.com/forum/#!forum/kubernetes-sig-auth)
|
||||||
|
|
||||||
|
<!-- BEGIN CUSTOM CONTENT -->
|
||||||
|
|
||||||
|
<!-- END CUSTOM CONTENT -->
|
||||||
|
|
||||||
|
Last generated: Wed Jun 7 2017 14:27:56
|
Loading…
Reference in New Issue