diff --git a/cmd/genkubedocs/BUILD b/cmd/genkubedocs/BUILD index 1f7eb602571..4f70ec76780 100644 --- a/cmd/genkubedocs/BUILD +++ b/cmd/genkubedocs/BUILD @@ -4,6 +4,7 @@ load( "@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library", + "go_test", ) go_binary( @@ -14,7 +15,10 @@ go_binary( go_library( name = "go_default_library", - srcs = ["gen_kube_docs.go"], + srcs = [ + "gen_kube_docs.go", + "postprocessing.go", + ], importpath = "k8s.io/kubernetes/cmd/genkubedocs", deps = [ "//cmd/cloud-controller-manager/app:go_default_library", @@ -25,7 +29,9 @@ go_library( "//cmd/kubeadm/app/cmd:go_default_library", "//cmd/kubelet/app:go_default_library", "//plugin/cmd/kube-scheduler/app:go_default_library", + "//vendor/github.com/spf13/cobra:go_default_library", "//vendor/github.com/spf13/cobra/doc:go_default_library", + "//vendor/github.com/spf13/pflag:go_default_library", ], ) @@ -41,3 +47,10 @@ filegroup( srcs = [":package-srcs"], tags = ["automanaged"], ) + +go_test( + name = "go_default_test", + srcs = ["postprocessing_test.go"], + importpath = "k8s.io/kubernetes/cmd/genkubedocs", + library = ":go_default_library", +) diff --git a/cmd/genkubedocs/gen_kube_docs.go b/cmd/genkubedocs/gen_kube_docs.go index 47bdf74549e..2285fe4d96d 100644 --- a/cmd/genkubedocs/gen_kube_docs.go +++ b/cmd/genkubedocs/gen_kube_docs.go @@ -21,6 +21,7 @@ import ( "os" "github.com/spf13/cobra/doc" + "github.com/spf13/pflag" ccmapp "k8s.io/kubernetes/cmd/cloud-controller-manager/app" "k8s.io/kubernetes/cmd/genutils" apiservapp "k8s.io/kubernetes/cmd/kube-apiserver/app" @@ -75,9 +76,18 @@ func main() { kubelet := kubeletapp.NewKubeletCommand() doc.GenMarkdownTree(kubelet, outDir) case "kubeadm": + // resets global flags created by kubelet or other commands e.g. + // --azure-container-registry-config from pkg/credentialprovider/azure + // --google-json-key from pkg/credentialprovider/gcp + // --version pkg/version/verflag + pflag.CommandLine = pflag.NewFlagSet(os.Args[0], pflag.ExitOnError) + // generate docs for kubeadm kubeadm := kubeadmapp.NewKubeadmCommand(os.Stdin, os.Stdout, os.Stderr) doc.GenMarkdownTree(kubeadm, outDir) + + // cleanup generated code for usage as include in the website + MarkdownPostProcessing(kubeadm, outDir, cleanupForInclude) default: fmt.Fprintf(os.Stderr, "Module %s is not supported", module) os.Exit(1) diff --git a/cmd/genkubedocs/postprocessing.go b/cmd/genkubedocs/postprocessing.go new file mode 100644 index 00000000000..57b6d95e058 --- /dev/null +++ b/cmd/genkubedocs/postprocessing.go @@ -0,0 +1,73 @@ +/* +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" + "path/filepath" + "strings" + + "github.com/spf13/cobra" +) + +// MarkdownPostProcessing goes though the generated files +func MarkdownPostProcessing(cmd *cobra.Command, dir string, processor func(string) string) error { + for _, c := range cmd.Commands() { + if !c.IsAvailableCommand() || c.IsHelpCommand() { + continue + } + if err := MarkdownPostProcessing(c, dir, processor); err != nil { + return err + } + } + + basename := strings.Replace(cmd.CommandPath(), " ", "_", -1) + ".md" + filename := filepath.Join(dir, basename) + + markdownBytes, err := ioutil.ReadFile(filename) + if err != nil { + return err + } + + processedMarkDown := processor(string(markdownBytes)) + + return ioutil.WriteFile(filename, []byte(processedMarkDown), 0644) +} + +// cleanupForInclude parts of markdown that will make difficult to use it as include in the website: +// - The title of the document (this allow more flexibility for include, e.g. include in tabs) +// - The sections see also, that assumes file will be used as a main page +func cleanupForInclude(md string) string { + lines := strings.Split(md, "\n") + + cleanMd := "" + for i, line := range lines { + if i == 0 { + continue + } + if line == "### SEE ALSO" { + break + } + + cleanMd += line + if i < len(lines)-1 { + cleanMd += "\n" + } + } + + return cleanMd +} diff --git a/cmd/genkubedocs/postprocessing_test.go b/cmd/genkubedocs/postprocessing_test.go new file mode 100644 index 00000000000..57afedf05a2 --- /dev/null +++ b/cmd/genkubedocs/postprocessing_test.go @@ -0,0 +1,57 @@ +/* +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 ( + "testing" +) + +func TestCleanupForInclude(t *testing.T) { + + var tests = []struct { + markdown, expectedMarkdown string + }{ + { // first line is removed + // Nb. fist line is the title of the document, and by removing it you get + // more flexibility for include, e.g. include in tabs + markdown: "line 1\n" + + "line 2\n" + + "line 3", + expectedMarkdown: "line 2\n" + + "line 3", + }, + { // evething after ###SEE ALSO is removed + // Nb. see also, that assumes file will be used as a main page (does not apply to includes) + markdown: "line 1\n" + + "line 2\n" + + "### SEE ALSO\n" + + "line 3", + expectedMarkdown: "line 2\n", + }, + } + for _, rt := range tests { + actual := cleanupForInclude(rt.markdown) + if actual != rt.expectedMarkdown { + t.Errorf( + "failed cleanupForInclude:\n\texpected: %s\n\t actual: %s", + rt.expectedMarkdown, + actual, + ) + } + } + +}