2020-05-12 17:47:43 +00:00
|
|
|
/*
|
|
|
|
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
|
|
|
|
|
|
|
|
https://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"
|
|
|
|
"os"
|
2021-05-03 17:02:24 +05:30
|
|
|
"path/filepath"
|
|
|
|
"strings"
|
2020-05-12 17:47:43 +00:00
|
|
|
|
2021-05-03 17:02:24 +05:30
|
|
|
"github.com/spf13/cobra"
|
2020-05-12 17:47:43 +00:00
|
|
|
"github.com/spf13/cobra/doc"
|
|
|
|
|
|
|
|
"opendev.org/airship/airshipctl/cmd"
|
2021-05-03 17:02:24 +05:30
|
|
|
"opendev.org/airship/airshipctl/pkg/fs"
|
2020-05-12 17:47:43 +00:00
|
|
|
)
|
|
|
|
|
2021-05-03 17:02:24 +05:30
|
|
|
var toctree = `####################
|
|
|
|
%s
|
|
|
|
####################
|
|
|
|
|
|
|
|
.. toctree::
|
|
|
|
:maxdepth: 2
|
|
|
|
|
|
|
|
`
|
|
|
|
|
2020-05-12 17:47:43 +00:00
|
|
|
func main() {
|
2020-08-25 17:37:19 -05:00
|
|
|
rootCmd := cmd.NewAirshipCTLCommand(os.Stdout)
|
2021-05-03 17:02:24 +05:30
|
|
|
fs := fs.NewDocumentFs()
|
|
|
|
dir := "./docs/source/cli"
|
2020-05-12 17:47:43 +00:00
|
|
|
|
|
|
|
// Remote auto-generated notice
|
|
|
|
rootCmd.DisableAutoGenTag = true
|
|
|
|
|
2021-05-03 17:02:24 +05:30
|
|
|
// Generating .rst file for airshipctl root command
|
|
|
|
if err := genReSTRoot(rootCmd, dir, fs); err != nil {
|
|
|
|
fmt.Fprintln(os.Stdout, err)
|
|
|
|
os.Exit(1)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Generating .rst files for airshipctl commands and sub-commands
|
|
|
|
if err := genReST(rootCmd, dir, fs); err != nil {
|
2020-05-12 17:47:43 +00:00
|
|
|
fmt.Fprintln(os.Stdout, err)
|
|
|
|
os.Exit(1)
|
|
|
|
}
|
|
|
|
}
|
2021-05-03 17:02:24 +05:30
|
|
|
|
|
|
|
// Generate .rst file for airshipctl root command
|
|
|
|
func genReSTRoot(cmd *cobra.Command, dir string, fs fs.FileSystem) error {
|
|
|
|
basename := strings.Replace(cmd.CommandPath(), " ", "_", -1) + ".rst"
|
|
|
|
fileName := filepath.Join(dir, basename)
|
|
|
|
f, err := fs.Create(fileName)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
defer f.Close()
|
|
|
|
|
|
|
|
if err := fs.WriteFile(fileName, []byte(filePrepender(fileName))); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Invoking the doc.GenReSTCustom function to generate ReST file
|
|
|
|
// for the airshipctl root command
|
|
|
|
if err := doc.GenReSTCustom(cmd, f, linkHandler); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Default filePrepender
|
|
|
|
func filePrepender(filename string) string {
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
|
|
|
|
// Custom linkHandler called when adding `SeeAlso` section
|
|
|
|
// to the document in the cobra.doc.GenReSTTreeCustom function
|
|
|
|
func linkHandler(name, ref string) string {
|
|
|
|
return fmt.Sprintf(":ref:`%s <%s>`", name, ref)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Generates .rst files for all the commands and subcommands in airshipctl
|
|
|
|
func genReST(cmd *cobra.Command, dir string, fs fs.FileSystem) error {
|
|
|
|
// Used to populate the top level index.rst with each airshipctl command folder names
|
|
|
|
fileName := filepath.Join(dir, "index.rst")
|
|
|
|
if _, err := fs.Create(fileName); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
rootIndexRst := fmt.Sprintf(toctree, "Commands") + cmdFileName(cmd)
|
|
|
|
|
|
|
|
// Loop over each airshipctl command like baremetal, phase, plan...etc
|
|
|
|
for _, c := range cmd.Commands() {
|
|
|
|
// Spliting the command to extract the command type
|
|
|
|
// which would be baremetal, phase, plan...etc
|
|
|
|
names := strings.Split(c.CommandPath(), " ")
|
|
|
|
cmdName := names[len(names)-1]
|
|
|
|
// Generates separate folder for current airshipctl command
|
|
|
|
cmdDir := filepath.Join(dir, cmdName)
|
|
|
|
if err := checkAndCreateDir(cmdDir, fs); err != nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
// Generating .rst files for all subcommands in the current airshipctl command
|
|
|
|
if err := doc.GenReSTTreeCustom(c, cmdDir, filePrepender, linkHandler); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
// Create index.rst file for the current airshipctl command
|
|
|
|
// This creates index.rst file in the appropriate folder
|
|
|
|
// Example: In case of baremetal it creates an index.rst in the
|
|
|
|
// baremetal folder. It adds the toctree details to file name.
|
|
|
|
if err := genIndexReST(c, cmdDir, cmdName, fs); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
// Update the top-level index.rst file with the airshipctl command name
|
|
|
|
// to invoke the index.rst in the sub folders
|
|
|
|
// For example in case of baremetal: We create index.rst file for baremetal
|
|
|
|
// subcommands in baremetal directory. So we refer this index.rst in the
|
|
|
|
// top-level index.rst as below.
|
|
|
|
rootIndexRst = rootIndexRst + " " + cmdName + "/index\n"
|
|
|
|
}
|
|
|
|
if err := fs.WriteFile(fileName, []byte(rootIndexRst)); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check the dir and if not present creates one
|
|
|
|
func checkAndCreateDir(dir string, fs fs.FileSystem) error {
|
|
|
|
if !fs.Exists(dir) {
|
|
|
|
if err := fs.Mkdir(dir); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if !fs.IsDir(dir) {
|
|
|
|
return fmt.Errorf("expecting %s to be a directory", dir)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Generates index.rst for a given airshipctl command
|
|
|
|
func genIndexReST(cmd *cobra.Command, cmdDir string, cmdName string, fs fs.FileSystem) error {
|
|
|
|
cmdIndexFileName := filepath.Join(cmdDir, "index.rst")
|
|
|
|
if _, err := fs.Create(cmdIndexFileName); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
cmdIndexRst := fmt.Sprintf(toctree, cmdName)
|
|
|
|
// Updating the current index.rst with all the sub-commands file name details
|
|
|
|
cmdIndexRst = updateIndexReSt(cmdIndexRst, cmd)
|
|
|
|
if err := fs.WriteFile(cmdIndexFileName, []byte(cmdIndexRst)); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Updates the index.rst file with the subcommand file names
|
|
|
|
func updateIndexReSt(indexrst string, cmd *cobra.Command) string {
|
|
|
|
indexrst += cmdFileName(cmd)
|
|
|
|
for _, c := range cmd.Commands() {
|
|
|
|
// Skipping help commands as they are not documented by the doc.cobra library
|
|
|
|
if !c.IsAvailableCommand() || c.IsAdditionalHelpTopicCommand() {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
indexrst = updateIndexReSt(indexrst, c)
|
|
|
|
}
|
|
|
|
return indexrst
|
|
|
|
}
|
|
|
|
|
|
|
|
// Generate the file name corresponding to the cmd
|
|
|
|
func cmdFileName(cmd *cobra.Command) string {
|
|
|
|
return " " + strings.Replace(cmd.CommandPath(), " ", "_", -1) + "\n"
|
|
|
|
}
|