Merge pull request #726 from jamiehannaford/add-tests
Add generator tests
This commit is contained in:
commit
789f252a71
|
@ -6,4 +6,5 @@ services:
|
|||
- docker
|
||||
|
||||
script:
|
||||
- make test-unit
|
||||
- bash ./scripts/verify.sh
|
||||
|
|
12
Makefile
12
Makefile
|
@ -1,3 +1,5 @@
|
|||
IMAGE_NAME=kube-communitydocs
|
||||
|
||||
all: \
|
||||
build-image \
|
||||
gen-docs \
|
||||
|
@ -6,10 +8,10 @@ reset-docs:
|
|||
git checkout HEAD -- sig-list.md sig-*
|
||||
|
||||
build-image:
|
||||
docker build -t sigdocs -f generator/Dockerfile generator
|
||||
|
||||
gen-doc:
|
||||
docker run -e WG=${WG} -e SIG=${SIG} -v $(shell pwd):/go/src/app sigdocs
|
||||
docker build -t $(IMAGE_NAME) -f generator/Dockerfile generator
|
||||
|
||||
gen-docs:
|
||||
docker run -v $(shell pwd):/go/src/app sigdocs
|
||||
docker run --rm -e WG -e SIG -v $(shell pwd):/go/src/app/generated $(IMAGE_NAME) app
|
||||
|
||||
test: build-image
|
||||
docker run --rm $(IMAGE_NAME) go test -v ./...
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
generated/
|
|
@ -1 +1,7 @@
|
|||
FROM golang:1.6-onbuild
|
||||
FROM golang:1.8
|
||||
|
||||
WORKDIR /go/src/app
|
||||
COPY . .
|
||||
|
||||
RUN go-wrapper download
|
||||
RUN go-wrapper install
|
||||
|
|
|
@ -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
|
||||
|
||||
|
@ -21,9 +33,9 @@ make all
|
|||
To build docs for one SIG, run these commands:
|
||||
|
||||
```bash
|
||||
make SIG=sig-apps gen-doc
|
||||
make SIG=sig-testing gen-doc
|
||||
make WG=resource-management gen-doc
|
||||
make SIG=sig-apps gen-docs
|
||||
make SIG=sig-testing gen-docs
|
||||
make WG=resource-management gen-docs
|
||||
```
|
||||
|
||||
where the `SIG` or `WG` var refers to the directory being built.
|
||||
|
|
193
generator/app.go
193
generator/app.go
|
@ -30,25 +30,29 @@ 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")
|
||||
sigListOutput = "sig-list.md"
|
||||
sigIndexOutput = "README.md"
|
||||
githubTeamNames = []string{"misc", "test-failures", "bugs", "feature-requests", "proposals", "pr-reviews", "api-reviews"}
|
||||
beginMarker = "<!-- BEGIN CUSTOM CONTENT -->"
|
||||
endMarker = "<!-- END CUSTOM CONTENT -->"
|
||||
readmeTemplate = "readme.tmpl"
|
||||
listTemplate = "list.tmpl"
|
||||
headerTemplate = "header.tmpl"
|
||||
|
||||
sigsYamlFile = "sigs.yaml"
|
||||
sigListOutput = "sig-list.md"
|
||||
indexFilename = "README.md"
|
||||
baseOutputDir = "generated"
|
||||
|
||||
githubTeamNames = []string{"misc", "test-failures", "bugs", "feature-requests", "proposals", "pr-reviews", "api-reviews"}
|
||||
beginMarker = "<!-- BEGIN CUSTOM CONTENT -->"
|
||||
endMarker = "<!-- END CUSTOM CONTENT -->"
|
||||
)
|
||||
|
||||
// Lead represents a lead engineer for a particular group. There are usually
|
||||
// 2 per group.
|
||||
type Lead struct {
|
||||
Name string
|
||||
Company string
|
||||
GitHub string
|
||||
}
|
||||
|
||||
// Meeting represents a regular meeting for a group.
|
||||
type Meeting struct {
|
||||
Day string
|
||||
UTC string
|
||||
|
@ -56,6 +60,7 @@ type Meeting struct {
|
|||
Frequency string
|
||||
}
|
||||
|
||||
// Contact represents the various contact points for a group.
|
||||
type Contact struct {
|
||||
Slack string
|
||||
MailingList string `yaml:"mailing_list"`
|
||||
|
@ -64,7 +69,8 @@ type Contact struct {
|
|||
GithubTeamNames []string
|
||||
}
|
||||
|
||||
type Sig struct {
|
||||
// Group represents either a Special Interest Group (SIG) or a Working Group (WG)
|
||||
type Group struct {
|
||||
Name string
|
||||
Dir string
|
||||
MissionStatement string `yaml:"mission_statement"`
|
||||
|
@ -75,52 +81,31 @@ type Sig struct {
|
|||
Contact Contact
|
||||
}
|
||||
|
||||
type Wg struct {
|
||||
Name string
|
||||
Dir string
|
||||
MissionStatement string `yaml:"mission_statement"`
|
||||
Organizers []Lead
|
||||
Meetings []Meeting
|
||||
MeetingURL string `yaml:"meeting_url"`
|
||||
MeetingArchiveURL string `yaml:"meeting_archive_url"`
|
||||
Contact Contact
|
||||
// DirName returns the directory that a group's documentation will be
|
||||
// generated into. It is composed of a prefix (sig for SIGs and wg for WGs),
|
||||
// and a formatted version of the group's name (in kebab case).
|
||||
func (e *Group) DirName(prefix string) string {
|
||||
return fmt.Sprintf("%s-%s", prefix, strings.ToLower(strings.Replace(e.Name, " ", "-", -1)))
|
||||
}
|
||||
|
||||
// SetupGitHubTeams will iterate over all the possible teams available to a
|
||||
// group (these are defined by the Kubernetes organisation) and populate a
|
||||
// list using the group's prefix.
|
||||
func (e *Group) SetupGitHubTeams(prefix string) {
|
||||
ghPrefix := e.Contact.GithubTeamPrefix
|
||||
if ghPrefix == "" {
|
||||
ghPrefix = e.DirName(prefix)
|
||||
}
|
||||
|
||||
for _, gtn := range githubTeamNames {
|
||||
e.Contact.GithubTeamNames = append(e.Contact.GithubTeamNames, fmt.Sprintf("%s-%s", ghPrefix, gtn))
|
||||
}
|
||||
}
|
||||
|
||||
// Context is the context for the sigs.yaml file.
|
||||
type Context struct {
|
||||
Sigs []Sig
|
||||
WorkingGroups []Wg
|
||||
}
|
||||
|
||||
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]
|
||||
Sigs []Group
|
||||
WorkingGroups []Group
|
||||
}
|
||||
|
||||
func pathExists(path string) bool {
|
||||
|
@ -130,8 +115,7 @@ func pathExists(path string) bool {
|
|||
|
||||
func createDirIfNotExists(path string) error {
|
||||
if !pathExists(path) {
|
||||
fmt.Printf("%s directory does not exist, creating\n", path)
|
||||
return os.Mkdir(path, 0755)
|
||||
return os.MkdirAll(path, 0755)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -171,7 +155,7 @@ func writeTemplate(templatePath, outputPath string, data interface{}) error {
|
|||
|
||||
// create if not exists
|
||||
if !pathExists(outputPath) {
|
||||
_, err := os.Create(outputPath)
|
||||
_, err = os.Create(outputPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -202,7 +186,6 @@ func writeTemplate(templatePath, outputPath string, data interface{}) error {
|
|||
// custom content block
|
||||
writeCustomContentBlock(f, content)
|
||||
|
||||
fmt.Printf("Generated %s\n", outputPath)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -213,60 +196,33 @@ func writeCustomContentBlock(f *os.File, content string) {
|
|||
}
|
||||
}
|
||||
|
||||
func createReadmeFiles(ctx Context) error {
|
||||
var selectedSig *string
|
||||
if sig, ok := os.LookupEnv("SIG"); ok {
|
||||
selectedSig = &sig
|
||||
func createGroupReadme(groups []Group, prefix string) error {
|
||||
// figure out if the user wants to generate one group
|
||||
var selectedGroupName *string
|
||||
if envVal, ok := os.LookupEnv(strings.ToUpper(prefix)); ok {
|
||||
selectedGroupName = &envVal
|
||||
}
|
||||
for _, sig := range ctx.Sigs {
|
||||
dirName := fmt.Sprintf("sig-%s", strings.ToLower(strings.Replace(sig.Name, " ", "-", -1)))
|
||||
|
||||
if selectedSig != nil && *selectedSig != dirName {
|
||||
fmt.Printf("Skipping %s\n", dirName)
|
||||
for _, group := range groups {
|
||||
group.Dir = group.DirName(prefix)
|
||||
// skip generation if the user specified only one group
|
||||
if selectedGroupName != nil && *selectedGroupName != group.Dir {
|
||||
fmt.Printf("Skipping %s/README.md\n", group.Dir)
|
||||
continue
|
||||
}
|
||||
|
||||
createDirIfNotExists(dirName)
|
||||
fmt.Printf("Generating %s/README.md\n", group.Dir)
|
||||
|
||||
prefix := sig.Contact.GithubTeamPrefix
|
||||
if prefix == "" {
|
||||
prefix = dirName
|
||||
}
|
||||
|
||||
for _, gtn := range githubTeamNames {
|
||||
sig.Contact.GithubTeamNames = append(sig.Contact.GithubTeamNames, fmt.Sprintf("%s-%s", prefix, gtn))
|
||||
}
|
||||
|
||||
outputPath := fmt.Sprintf("%s/%s", dirName, sigIndexOutput)
|
||||
if err := writeTemplate(sigIndexTemplate, outputPath, sig); err != nil {
|
||||
outputDir := filepath.Join(baseOutputDir, group.Dir)
|
||||
if err := createDirIfNotExists(outputDir); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
var selectedWg *string
|
||||
if wg, ok := os.LookupEnv("WG"); ok {
|
||||
selectedWg = &wg
|
||||
}
|
||||
for _, wg := range ctx.WorkingGroups {
|
||||
dirName := fmt.Sprintf("wg-%s", strings.ToLower(strings.Replace(wg.Name, " ", "-", -1)))
|
||||
|
||||
if selectedWg != nil && *selectedWg != dirName {
|
||||
fmt.Printf("Skipping %s\n", dirName)
|
||||
continue
|
||||
}
|
||||
group.SetupGitHubTeams(prefix)
|
||||
|
||||
createDirIfNotExists(dirName)
|
||||
|
||||
prefix := wg.Contact.GithubTeamPrefix
|
||||
if prefix == "" {
|
||||
prefix = dirName
|
||||
}
|
||||
|
||||
for _, gtn := range githubTeamNames {
|
||||
wg.Contact.GithubTeamNames = append(wg.Contact.GithubTeamNames, fmt.Sprintf("%s-%s", prefix, gtn))
|
||||
}
|
||||
|
||||
outputPath := fmt.Sprintf("%s/%s", dirName, sigIndexOutput)
|
||||
if err := writeTemplate(wgIndexTemplate, outputPath, wg); err != nil {
|
||||
outputPath := filepath.Join(outputDir, indexFilename)
|
||||
readmePath := fmt.Sprintf("%s_%s", prefix, readmeTemplate)
|
||||
if err := writeTemplate(readmePath, outputPath, group); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@ -274,12 +230,8 @@ func createReadmeFiles(ctx Context) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func createListFile(ctx Context) error {
|
||||
return writeTemplate(listTemplate, sigListOutput, ctx)
|
||||
}
|
||||
|
||||
func main() {
|
||||
yamlData, err := ioutil.ReadFile(sigsYamlFile)
|
||||
yamlData, err := ioutil.ReadFile(filepath.Join(baseOutputDir, sigsYamlFile))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
@ -289,19 +241,28 @@ 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
|
||||
|
||||
err = createReadmeFiles(ctx)
|
||||
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 = createGroupReadme(ctx.Sigs, "sig")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
err = createListFile(ctx)
|
||||
err = createGroupReadme(ctx.WorkingGroups, "wg")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
fmt.Println("Generating sig-list.md")
|
||||
outputPath := filepath.Join(baseOutputDir, sigListOutput)
|
||||
err = writeTemplate(listTemplate, outputPath, ctx)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,249 @@
|
|||
/*
|
||||
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 (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"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 TestExistantDirNotCreated(t *testing.T) {
|
||||
dir := "./testdata"
|
||||
err := createDirIfNotExists(dir)
|
||||
if err != nil {
|
||||
t.Fatalf("Received error creating dir: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
},
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGroupDirName(t *testing.T) {
|
||||
group := Group{Name: "Foo Bar"}
|
||||
if group.DirName("sig") != "sig-foo-bar" {
|
||||
t.Fatal("DirName incorrect")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetupGithubTeams(t *testing.T) {
|
||||
group := Group{Name: "Foo Bar"}
|
||||
group.SetupGitHubTeams("sig")
|
||||
|
||||
var expected []string
|
||||
for _, ght := range githubTeamNames {
|
||||
expected = append(expected, fmt.Sprintf("sig-foo-bar-%s", ght))
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(group.Contact.GithubTeamNames, expected) {
|
||||
t.Fatalf("%v does not match %v", group.Contact.GithubTeamNames, expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCustomPrefixSetupGithubTeams(t *testing.T) {
|
||||
group := Group{Contact: Contact{GithubTeamPrefix: "foo"}}
|
||||
group.SetupGitHubTeams("")
|
||||
|
||||
var expected []string
|
||||
for _, ght := range githubTeamNames {
|
||||
expected = append(expected, fmt.Sprintf("foo-%s", ght))
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(group.Contact.GithubTeamNames, expected) {
|
||||
t.Fatalf("%v does not match %v", group.Contact.GithubTeamNames, expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateGroupReadmes(t *testing.T) {
|
||||
groups := []Group{
|
||||
Group{Name: "Foo"},
|
||||
Group{Name: "Bar"},
|
||||
}
|
||||
|
||||
err := createGroupReadme(groups, "sig")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
for _, group := range groups {
|
||||
path := filepath.Join(baseOutputDir, group.DirName("sig"), "README.md")
|
||||
if !pathExists(path) {
|
||||
t.Fatalf("%s should exist", path)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestReadmesAreSkipped(t *testing.T) {
|
||||
os.Setenv("SIG", "sig-foo")
|
||||
|
||||
groups := []Group{
|
||||
Group{Name: "Foo"},
|
||||
Group{Name: "Bar"},
|
||||
}
|
||||
|
||||
err := createGroupReadme(groups, "sig")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
for _, group := range groups[1:] {
|
||||
path := filepath.Join(baseOutputDir, group.DirName("sig"), "README.md")
|
||||
if !pathExists(path) {
|
||||
t.Fatalf("%s should exist", path)
|
||||
}
|
||||
}
|
||||
|
||||
os.Setenv("SIG", "")
|
||||
}
|
||||
|
||||
func copyFile(src, dst string) error {
|
||||
// Read all content of src to data
|
||||
data, err := ioutil.ReadFile(src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Write data to dst
|
||||
err = ioutil.WriteFile(dst, data, 0644)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestFullGeneration(t *testing.T) {
|
||||
err := copyFile("testdata/sigs.yaml", "generated/sigs.yaml")
|
||||
if err != nil {
|
||||
t.Fatalf("Error received: %v", err)
|
||||
}
|
||||
|
||||
main()
|
||||
|
||||
expectedDirs := []string{"sig-foo", "sig-bar", "wg-baz"}
|
||||
for _, ed := range expectedDirs {
|
||||
path := filepath.Join(baseOutputDir, ed, "README.md")
|
||||
if !pathExists(path) {
|
||||
t.Fatalf("%s should exist", path)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -24,5 +24,5 @@ When the need arises, a [new SIG can be created](sig-creation-procedure.md)
|
|||
| Name | Organizers | Contact | Meetings |
|
||||
|------|------------|---------|----------|
|
||||
{{- range .WorkingGroups}}
|
||||
|[{{.Name}}]({{.Dir}}/README.md)|{{range .Organizers}}* [{{.Name}}](https://github.com/{{.GitHub}}){{if .Company}}, {{.Company}}{{end}}<br>{{end}}|* [Slack](https://kubernetes.slack.com/messages/{{.Contact.Slack}})<br>* [Mailing List]({{.Contact.MailingList}})|{{ $save := . }}{{range .Meetings}}* [{{.Day}}s at {{.UTC}} UTC ({{.Frequency}})]({{$save.MeetingURL}})<br>{{end}}
|
||||
|[{{.Name}}]({{.Dir}}/README.md)|{{range .Leads}}* [{{.Name}}](https://github.com/{{.GitHub}}){{if .Company}}, {{.Company}}{{end}}<br>{{end}}|* [Slack](https://kubernetes.slack.com/messages/{{.Contact.Slack}})<br>* [Mailing List]({{.Contact.MailingList}})|{{ $save := . }}{{range .Meetings}}* [{{.Day}}s at {{.UTC}} UTC ({{.Frequency}})]({{$save.MeetingURL}})<br>{{end}}
|
||||
{{- end }}
|
|
@ -0,0 +1,29 @@
|
|||
<!---
|
||||
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 -->
|
|
@ -0,0 +1,7 @@
|
|||
Hello!
|
||||
<!-- BEGIN CUSTOM CONTENT -->
|
||||
Example
|
||||
custom
|
||||
content!
|
||||
|
||||
<!-- END CUSTOM CONTENT -->
|
|
@ -0,0 +1 @@
|
|||
{{.Message}}
|
|
@ -0,0 +1,29 @@
|
|||
<!---
|
||||
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 -->
|
|
@ -0,0 +1,5 @@
|
|||
sigs:
|
||||
- name: Foo
|
||||
- name: Bar
|
||||
workinggroups:
|
||||
- name: Baz
|
|
@ -10,7 +10,7 @@
|
|||
Meeting notes and Agenda can be found [here]({{.MeetingArchiveURL}}).
|
||||
|
||||
## Organizers
|
||||
{{- range .Organizers }}
|
||||
{{- range .Leads }}
|
||||
* [{{.Name}}](https://github.com/{{.GitHub}}){{if .Company}}, {{.Company}}{{end}}
|
||||
{{- end }}
|
||||
|
Loading…
Reference in New Issue