github.com/1aal/kubeblocks@v0.0.0-20231107070852-e1c03e598921/hack/docgen/lorryctl/main.go (about) 1 /* 2 Copyright (C) 2022-2023 ApeCloud Co., Ltd 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package main 18 19 import ( 20 "fmt" 21 "io" 22 "log" 23 "os" 24 "path/filepath" 25 "strings" 26 27 "github.com/spf13/cobra" 28 "github.com/spf13/cobra/doc" 29 30 lorryctl "github.com/1aal/kubeblocks/pkg/lorry/ctl" 31 ) 32 33 func genMarkdownTreeForOverview(cmd *cobra.Command, dir string) error { 34 filename := filepath.Join(dir, "cli.md") 35 f, err := os.Create(filename) 36 if err != nil { 37 return err 38 } 39 defer f.Close() 40 41 if _, err = io.WriteString(f, `--- 42 title: KubeBlocks Lorry CLI Overview 43 description: KubeBlocks Lorry CLI overview 44 sidebar_position: 1 45 --- 46 47 `); err != nil { 48 return err 49 } 50 51 for _, c := range cmd.Commands() { 52 if !c.IsAvailableCommand() || c.IsAdditionalHelpTopicCommand() { 53 continue 54 } 55 56 // write parent command name 57 link := strings.ReplaceAll(cmd.Name()+" "+c.Name(), " ", "_") 58 _, err = io.WriteString(f, fmt.Sprintf("## [%s](%s.md)\n\n", c.Name(), link)) 59 if err != nil { 60 return err 61 } 62 63 // write command description 64 switch { 65 case c.Long != "": 66 _, err = io.WriteString(f, fmt.Sprintf("%s\n\n", c.Long)) 67 case c.Short != "": 68 _, err = io.WriteString(f, fmt.Sprintf("%s\n\n", c.Short)) 69 } 70 if err != nil { 71 return err 72 } 73 74 // write subcommands 75 for _, sub := range c.Commands() { 76 if !sub.IsAvailableCommand() || sub.IsAdditionalHelpTopicCommand() { 77 continue 78 } 79 subName := cmd.Name() + " " + c.Name() + " " + sub.Name() 80 link = strings.ReplaceAll(subName, " ", "_") 81 _, err = io.WriteString(f, fmt.Sprintf("* [%s](%s.md)\t - %s\n", subName, link, sub.Short)) 82 if err != nil { 83 return err 84 } 85 } 86 _, err = io.WriteString(f, "\n\n") 87 if err != nil { 88 return err 89 } 90 } 91 return nil 92 } 93 94 func main() { 95 rootPath := "./docs/user_docs/lorryctl" 96 if len(os.Args) > 1 { 97 rootPath = os.Args[1] 98 } 99 100 fmt.Println("Scanning CLI docs rootPath: ", rootPath) 101 ctl := lorryctl.RootCmd 102 ctl.Long = fmt.Sprintf("```\n%s\n```", ctl.Long) 103 104 err := doc.GenMarkdownTree(ctl, rootPath) 105 if err != nil { 106 log.Fatal(err) 107 } 108 109 ctl.Long = fmt.Sprintf("```\n%s\n```", ctl.Long) 110 err = genMarkdownTreeForOverview(ctl, rootPath) 111 if err != nil { 112 log.Fatal("generate docs for cli overview failed", err) 113 } 114 115 err = filepath.Walk(rootPath, func(path string, info os.FileInfo, err error) error { 116 if err != nil { 117 return err 118 } 119 if info.IsDir() { 120 return nil 121 } 122 data, err := os.ReadFile(path) 123 if err != nil { 124 return err 125 } 126 lines := strings.Split(string(data), "\n") 127 if len(lines) == 0 { 128 return nil 129 } 130 131 firstLine := lines[0] 132 if !strings.HasPrefix(firstLine, "## lorryctl") { 133 return nil 134 } 135 136 var lastIdx int 137 for idx := len(lines) - 1; idx >= 0; idx-- { 138 if strings.Contains(lines[idx], "Auto generated") { 139 lastIdx = idx 140 break 141 } 142 } 143 if lastIdx == 0 { 144 return nil 145 } 146 lines[lastIdx] = "#### Go Back to [LorryCtl Overview](cli.md) Homepage.\n" 147 148 // update the title 149 lines[0] = "---" 150 title := strings.TrimPrefix(firstLine, "## ") 151 newLines := []string{"---", "title: " + title} 152 for idx, line := range lines { 153 if strings.Contains(line, "[kbcli](kbcli.md)") { 154 lines[idx] = "" 155 continue 156 } 157 } 158 newLines = append(newLines, lines...) 159 content := strings.Join(newLines, "\n") 160 return os.WriteFile(path, []byte(content), info.Mode()) 161 }) 162 if err != nil { 163 log.Fatal(err) 164 } 165 }