github.com/kbehouse/nsc@v0.0.6/cmd/test.go (about) 1 /* 2 * Copyright 2018 The NATS Authors 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 package cmd 17 18 import ( 19 "bytes" 20 "path/filepath" 21 "sort" 22 "strings" 23 24 "github.com/spf13/cobra" 25 "github.com/spf13/cobra/doc" 26 flag "github.com/spf13/pflag" 27 ) 28 29 // addCmd represents the add command 30 var testCmd = &cobra.Command{ 31 Hidden: true, 32 Use: "test", 33 Short: "Test commands", 34 } 35 36 func createFlagTable() *cobra.Command { 37 var cmds flagTable 38 cmd := &cobra.Command{ 39 Use: "flags", 40 Short: "prints a table with all the flags", 41 SilenceErrors: true, 42 SilenceUsage: true, 43 RunE: func(cmd *cobra.Command, args []string) error { 44 45 var buf Stack 46 buf.Push(rootCmd) 47 48 for { 49 v := buf.Pop() 50 if v == nil { 51 break 52 } 53 if v.HasSubCommands() { 54 for _, vv := range v.Commands() { 55 buf.Push(vv) 56 } 57 continue 58 } else { 59 cmds.addCmd(v) 60 } 61 } 62 return Write("--", []byte(cmds.render())) 63 }, 64 } 65 return cmd 66 } 67 68 func generateDoc() *cobra.Command { 69 cmd := &cobra.Command{ 70 Use: "doc", 71 Short: "generate markdown documentation in the specified directory", 72 Args: cobra.ExactArgs(1), 73 RunE: func(cmd *cobra.Command, args []string) error { 74 dir, err := filepath.Abs(args[0]) 75 if err != nil { 76 return err 77 } 78 if err = MaybeMakeDir(dir); err != nil { 79 return err 80 } 81 return doc.GenMarkdownTree(rootCmd, dir) 82 }, 83 } 84 return cmd 85 } 86 87 type Stack struct { 88 data []*cobra.Command 89 } 90 91 func (s *Stack) Push(v *cobra.Command) { 92 s.data = append([]*cobra.Command{v}, s.data...) 93 } 94 95 func (s *Stack) Pop() *cobra.Command { 96 var v *cobra.Command 97 if len(s.data) == 0 { 98 return nil 99 } 100 v = s.data[0] 101 s.data = s.data[1:] 102 return v 103 } 104 105 func reverse(a []string) { 106 for i := len(a)/2 - 1; i >= 0; i-- { 107 opp := len(a) - 1 - i 108 a[i], a[opp] = a[opp], a[i] 109 } 110 } 111 112 type parsedCommand struct { 113 name string 114 flagMap map[string]string 115 } 116 117 type flagTable struct { 118 commands []parsedCommand 119 } 120 121 func (t *flagTable) addCmd(cmd *cobra.Command) { 122 var c parsedCommand 123 c.flagMap = make(map[string]string) 124 names := []string{cmd.Name()} 125 v := cmd 126 for { 127 p := v.Parent() 128 if p == nil { 129 break 130 } 131 names = append(names, p.Name()) 132 v = p 133 } 134 reverse(names) 135 c.name = strings.Join(names, " ") 136 137 flags := cmd.Flags() 138 flags.VisitAll(func(f *flag.Flag) { 139 c.flagMap[f.Name] = f.Shorthand 140 }) 141 142 t.commands = append(t.commands, c) 143 } 144 145 func (t *flagTable) render() string { 146 var buf bytes.Buffer 147 148 allFlags := make(map[string]bool) 149 for _, c := range t.commands { 150 for n := range c.flagMap { 151 allFlags[n] = true 152 } 153 } 154 var cols []string 155 for k := range allFlags { 156 cols = append(cols, k) 157 } 158 sort.Strings(cols) 159 cols = append([]string{"cmd"}, cols...) 160 161 buf.WriteString(strings.Join(cols, ",")) 162 buf.WriteString("\n") 163 164 for _, c := range t.commands { 165 sf := []string{c.name} 166 for i := 1; i < len(cols); i++ { 167 v, ok := c.flagMap[cols[i]] 168 if v != "" { 169 sf = append(sf, v) 170 } else if ok { 171 sf = append(sf, "-") 172 } else { 173 sf = append(sf, "") 174 } 175 } 176 buf.WriteString(strings.Join(sf, ",")) 177 buf.WriteString("\n") 178 } 179 180 return buf.String() 181 } 182 183 func init() { 184 GetRootCmd().AddCommand(testCmd) 185 testCmd.AddCommand(createGenerateNKeyCmd()) 186 testCmd.AddCommand(createFlagTable()) 187 testCmd.AddCommand(generateDoc()) 188 }