Add tests
This commit is contained in:
parent
f3375f168e
commit
eab658607d
4
Makefile
4
Makefile
|
@ -13,3 +13,7 @@ gen-doc:
|
|||
|
||||
gen-docs:
|
||||
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
|
||||
|
||||
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
|
||||
wg-*/README.md
|
||||
sig-list.md
|
||||
./sig-<sig-name>/README.md
|
||||
./wg-<working-group-name>/README.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
|
||||
|
||||
|
|
|
@ -31,11 +31,10 @@ import (
|
|||
|
||||
var (
|
||||
sigsYamlFile = "sigs.yaml"
|
||||
templateDir = "generator"
|
||||
sigIndexTemplate = filepath.Join(templateDir, "sig_index.tmpl")
|
||||
wgIndexTemplate = filepath.Join(templateDir, "wg_index.tmpl")
|
||||
listTemplate = filepath.Join(templateDir, "sig_list.tmpl")
|
||||
headerTemplate = filepath.Join(templateDir, "header.tmpl")
|
||||
sigIndexTemplate = "sig_index.tmpl"
|
||||
wgIndexTemplate = "wg_index.tmpl"
|
||||
listTemplate = "sig_list.tmpl"
|
||||
headerTemplate = "header.tmpl"
|
||||
sigListOutput = "sig-list.md"
|
||||
sigIndexOutput = "README.md"
|
||||
githubTeamNames = []string{"misc", "test-failures", "bugs", "feature-requests", "proposals", "pr-reviews", "api-reviews"}
|
||||
|
@ -95,34 +94,10 @@ type SigEntries struct {
|
|||
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 {
|
||||
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 {
|
||||
_, err := os.Stat(path)
|
||||
return err == nil
|
||||
|
@ -162,7 +137,13 @@ func getExistingContent(path string) (string, error) {
|
|||
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
|
||||
t, err := template.ParseFiles(templatePath, headerTemplate)
|
||||
if err != nil {
|
||||
|
@ -242,6 +223,7 @@ func createReadmeFiles(ctx Context) error {
|
|||
return err
|
||||
}
|
||||
}
|
||||
|
||||
var selectedWg *string
|
||||
if wg, ok := os.LookupEnv("WG"); ok {
|
||||
selectedWg = &wg
|
||||
|
@ -289,12 +271,14 @@ func main() {
|
|||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
sigEntries := SigEntries{ctx.Sigs}
|
||||
sort.Sort(sigEntries)
|
||||
ctx.Sigs = sigEntries.Sigs
|
||||
wgEntries := WgEntries{ctx.WorkingGroups}
|
||||
sort.Sort(wgEntries)
|
||||
ctx.WorkingGroups = wgEntries.WorkingGroups
|
||||
|
||||
sort.Slice(ctx.Sigs, func(i, j int) bool {
|
||||
return ctx.Sigs[i].Name >= ctx.Sigs[j].Name
|
||||
})
|
||||
|
||||
sort.Slice(ctx.WorkingGroups, func(i, j int) bool {
|
||||
return ctx.WorkingGroups[i].Name >= ctx.WorkingGroups[j].Name
|
||||
})
|
||||
|
||||
err = createReadmeFiles(ctx)
|
||||
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