From a6cbaf61ecdb98ab42042dfafe29ef563a75eb4e Mon Sep 17 00:00:00 2001 From: Ian Walter Date: Wed, 27 Apr 2016 22:44:53 -0400 Subject: [PATCH] Working on #266: Ability to add nested commands * Modified `cobra add` command to be able to parse argument into nested command structure * Modified `createCmdFile` function to accept cmdPath * Modified cmdFile template to specify package name and to TitleCase command names so that they can be accessed by child packages. * Simplified `writeTemplateToFile` function so that just the file path is passed instead of base path and filename. --- cobra/cmd/add.go | 48 ++++++++++++++++++++++++++++++++++---------- cobra/cmd/helpers.go | 14 +++---------- cobra/cmd/init.go | 6 +++--- 3 files changed, 43 insertions(+), 25 deletions(-) diff --git a/cobra/cmd/add.go b/cobra/cmd/add.go index b89d4c47..7867e94a 100644 --- a/cobra/cmd/add.go +++ b/cobra/cmd/add.go @@ -14,6 +14,7 @@ package cmd import ( + "path" "fmt" "path/filepath" "strings" @@ -48,7 +49,25 @@ Example: cobra add server -> resulting in a new cmd/server.go er("add needs a name for the command") } guessProjectPath() - createCmdFile(args[0]) + + // Iterate over command parts delimited by "/". + currentPath := "" + cmdParts := strings.Split(args[0], "/") + for n, cmd := range cmdParts { + // + if n > 0 { + // Set parent name to previous command's name. + pName = cmdParts[n-1] + + // + currentPath += pName + "/" + } + + // TODO Create command file if it does not already exist. + createCmdFile(cmd, currentPath) + } + + }, } @@ -64,13 +83,13 @@ func parentName() string { return pName } -func createCmdFile(cmdName string) { +func createCmdFile(cmdName, cmdPath string) { lic := getLicense() template := `{{ comment .copyright }} {{ comment .license }} -package cmd +package {{ .packageName }} import ( "fmt" @@ -78,8 +97,8 @@ import ( "github.com/spf13/cobra" ) -// {{.cmdName}}Cmd represents the {{.cmdName}} command -var {{ .cmdName }}Cmd = &cobra.Command{ +// {{ .cmdName | title }}Cmd represents the {{ .cmdName }} command +{{ .cmdName | title }}Cmd := &cobra.Command{ Use: "{{ .cmdName }}", Short: "A brief description of your command", Long: ` + "`" + `A longer description that spans multiple lines and likely contains examples @@ -95,7 +114,7 @@ to quickly create a Cobra application.` + "`" + `, } func init() { - {{ .parentName }}.AddCommand({{ .cmdName }}Cmd) + {{ .parentName | title }}.AddCommand({{ .cmdName | title }}Cmd) // Here you will define your flags and configuration settings. @@ -110,8 +129,14 @@ func init() { } ` - var data map[string]interface{} - data = make(map[string]interface{}) + data := make(map[string]interface{}) + + data["packageName"] = "cmd" + + // + if cmdPath != "" { + data["packageName"] = path.Base(cmdPath) + } data["copyright"] = copyrightLine() data["license"] = lic.Header @@ -120,9 +145,10 @@ func init() { data["parentName"] = parentName() data["cmdName"] = cmdName - err := writeTemplateToFile(filepath.Join(ProjectPath(), guessCmdDir()), cmdName+".go", template, data) - if err != nil { + file := filepath.Join(ProjectPath(), guessCmdDir(), cmdPath, cmdName+".go") + + if err := writeTemplateToFile(file, template, data); err != nil { er(err) } - fmt.Println(cmdName, "created at", filepath.Join(ProjectPath(), guessCmdDir(), cmdName+".go")) + fmt.Println(cmdName, "created at", file) } diff --git a/cobra/cmd/helpers.go b/cobra/cmd/helpers.go index 7cd3be18..4218b034 100644 --- a/cobra/cmd/helpers.go +++ b/cobra/cmd/helpers.go @@ -224,21 +224,13 @@ func dirExists(path string) (bool, error) { return false, err } -func writeTemplateToFile(path string, file string, template string, data interface{}) error { - filename := filepath.Join(path, file) - +func writeTemplateToFile(file string, template string, data interface{}) error { r, err := templateToReader(template, data) - if err != nil { return err } - err = safeWriteToDisk(filename, r) - - if err != nil { - return err - } - return nil + return safeWriteToDisk(file, r) } func writeStringToFile(path, file, text string) error { @@ -254,7 +246,7 @@ func writeStringToFile(path, file, text string) error { } func templateToReader(tpl string, data interface{}) (io.Reader, error) { - tmpl := template.New("") + tmpl := template.New("").Funcs(template.FuncMap{"title": strings.Title}) tmpl.Funcs(funcMap) tmpl, err := tmpl.Parse(tpl) diff --git a/cobra/cmd/init.go b/cobra/cmd/init.go index 13792f12..8fe6c303 100644 --- a/cobra/cmd/init.go +++ b/cobra/cmd/init.go @@ -104,7 +104,7 @@ func createLicenseFile() { buf := new(bytes.Buffer) buf.ReadFrom(r) - err := writeTemplateToFile(ProjectPath(), "LICENSE", buf.String(), data) + err := writeTemplateToFile(ProjectPath()+"LICENSE", buf.String(), data) _ = err // if err != nil { // er(err) @@ -139,7 +139,7 @@ func main() { data["importpath"] = guessImportPath() + "/" + guessCmdDir() - err := writeTemplateToFile(ProjectPath(), "main.go", template, data) + err := writeTemplateToFile(ProjectPath()+"main.go", template, data) _ = err // if err != nil { // er(err) @@ -233,7 +233,7 @@ func initConfig() { data["viper"] = viper.GetBool("useViper") - err := writeTemplateToFile(ProjectPath()+string(os.PathSeparator)+guessCmdDir(), "root.go", template, data) + err := writeTemplateToFile(ProjectPath()+string(os.PathSeparator)+guessCmdDir()+"root.go", template, data) if err != nil { er(err) }