cmd: Rewrite
This commit is contained in:
		@ -79,11 +79,11 @@ A few good real world examples may better illustrate this point.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
In the following example, 'server' is a command, and 'port' is a flag:
 | 
					In the following example, 'server' is a command, and 'port' is a flag:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    > hugo server --port=1313
 | 
					    hugo server --port=1313
 | 
				
			||||||
 | 
					
 | 
				
			||||||
In this command we are telling Git to clone the url bare.
 | 
					In this command we are telling Git to clone the url bare.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    > git clone URL --bare
 | 
					    git clone URL --bare
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Commands
 | 
					## Commands
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -130,7 +130,7 @@ Using Cobra is easy. First, use `go get` to install the latest version
 | 
				
			|||||||
of the library. This command will install the `cobra` generator executible
 | 
					of the library. This command will install the `cobra` generator executible
 | 
				
			||||||
along with the library:
 | 
					along with the library:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    > go get -v github.com/spf13/cobra/cobra
 | 
					    go get -v github.com/spf13/cobra/cobra
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Next, include Cobra in your application:
 | 
					Next, include Cobra in your application:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -180,7 +180,7 @@ commands you want. It's the easiest way to incorporate Cobra into your applicati
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
In order to use the cobra command, compile it using the following command:
 | 
					In order to use the cobra command, compile it using the following command:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    > go get github.com/spf13/cobra/cobra
 | 
					    go get github.com/spf13/cobra/cobra
 | 
				
			||||||
 | 
					
 | 
				
			||||||
This will create the cobra executable under your `$GOPATH/bin` directory.
 | 
					This will create the cobra executable under your `$GOPATH/bin` directory.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -15,8 +15,8 @@ package cmd
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
 | 
						"os"
 | 
				
			||||||
	"path/filepath"
 | 
						"path/filepath"
 | 
				
			||||||
	"strings"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/spf13/cobra"
 | 
						"github.com/spf13/cobra"
 | 
				
			||||||
	"github.com/spf13/viper"
 | 
						"github.com/spf13/viper"
 | 
				
			||||||
@ -26,9 +26,8 @@ func init() {
 | 
				
			|||||||
	RootCmd.AddCommand(addCmd)
 | 
						RootCmd.AddCommand(addCmd)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var pName string
 | 
					var parentName string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// initialize Command
 | 
					 | 
				
			||||||
var addCmd = &cobra.Command{
 | 
					var addCmd = &cobra.Command{
 | 
				
			||||||
	Use:     "add [command name]",
 | 
						Use:     "add [command name]",
 | 
				
			||||||
	Aliases: []string{"command"},
 | 
						Aliases: []string{"command"},
 | 
				
			||||||
@ -40,35 +39,28 @@ and register it to its parent (default RootCmd).
 | 
				
			|||||||
If you want your command to be public, pass in the command name
 | 
					If you want your command to be public, pass in the command name
 | 
				
			||||||
with an initial uppercase letter.
 | 
					with an initial uppercase letter.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Example: cobra add server  -> resulting in a new cmd/server.go
 | 
					Example: cobra add server -> resulting in a new cmd/server.go`,
 | 
				
			||||||
  `,
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Run: func(cmd *cobra.Command, args []string) {
 | 
						Run: func(cmd *cobra.Command, args []string) {
 | 
				
			||||||
		if len(args) != 1 {
 | 
							if len(args) < 1 {
 | 
				
			||||||
			er("add needs a name for the command")
 | 
								er("add needs a name for the command")
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		guessProjectPath()
 | 
							wd, err := os.Getwd()
 | 
				
			||||||
		createCmdFile(args[0])
 | 
							if err != nil {
 | 
				
			||||||
 | 
								er(err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							project := NewProjectFromPath(wd)
 | 
				
			||||||
 | 
							createCmdFile(project, args[0])
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func init() {
 | 
					func init() {
 | 
				
			||||||
	addCmd.Flags().StringVarP(&pName, "parent", "p", "RootCmd", "name of parent command for this command")
 | 
						addCmd.Flags().StringVarP(&parentName, "parent", "p", "RootCmd", "name of parent command for this command")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func parentName() string {
 | 
					func createCmdFile(project *Project, cmdName string) {
 | 
				
			||||||
	if !strings.HasSuffix(strings.ToLower(pName), "cmd") {
 | 
						template := `{{comment .copyright}}
 | 
				
			||||||
		return pName + "Cmd"
 | 
					{{comment .license}}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return pName
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func createCmdFile(cmdName string) {
 | 
					 | 
				
			||||||
	lic := getLicense()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	template := `{{ comment .copyright }}
 | 
					 | 
				
			||||||
{{ comment .license }}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
package cmd
 | 
					package cmd
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -79,8 +71,8 @@ import (
 | 
				
			|||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// {{.cmdName}}Cmd represents the {{.cmdName}} command
 | 
					// {{.cmdName}}Cmd represents the {{.cmdName}} command
 | 
				
			||||||
var {{ .cmdName }}Cmd = &cobra.Command{
 | 
					var {{.cmdName}}Cmd = &cobra.Command{
 | 
				
			||||||
	Use:   "{{ .cmdName }}",
 | 
						Use:   "{{.cmdName}}",
 | 
				
			||||||
	Short: "A brief description of your command",
 | 
						Short: "A brief description of your command",
 | 
				
			||||||
	Long: ` + "`" + `A longer description that spans multiple lines and likely contains examples
 | 
						Long: ` + "`" + `A longer description that spans multiple lines and likely contains examples
 | 
				
			||||||
and usage of using your command. For example:
 | 
					and usage of using your command. For example:
 | 
				
			||||||
@ -89,13 +81,12 @@ Cobra is a CLI library for Go that empowers applications.
 | 
				
			|||||||
This application is a tool to generate the needed files
 | 
					This application is a tool to generate the needed files
 | 
				
			||||||
to quickly create a Cobra application.` + "`" + `,
 | 
					to quickly create a Cobra application.` + "`" + `,
 | 
				
			||||||
	Run: func(cmd *cobra.Command, args []string) {
 | 
						Run: func(cmd *cobra.Command, args []string) {
 | 
				
			||||||
		// TODO: Work your own magic here
 | 
							fmt.Println("{{.cmdName}} called")
 | 
				
			||||||
		fmt.Println("{{ .cmdName }} called")
 | 
					 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func init() {
 | 
					func init() {
 | 
				
			||||||
	{{ .parentName }}.AddCommand({{ .cmdName }}Cmd)
 | 
						{{.parentName}}.AddCommand({{.cmdName}}Cmd)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Here you will define your flags and configuration settings.
 | 
						// Here you will define your flags and configuration settings.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -106,23 +97,26 @@ func init() {
 | 
				
			|||||||
	// Cobra supports local flags which will only run when this command
 | 
						// Cobra supports local flags which will only run when this command
 | 
				
			||||||
	// is called directly, e.g.:
 | 
						// is called directly, e.g.:
 | 
				
			||||||
	// {{.cmdName}}Cmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
 | 
						// {{.cmdName}}Cmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
`
 | 
					`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var data map[string]interface{}
 | 
						data := make(map[string]interface{})
 | 
				
			||||||
	data = make(map[string]interface{})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	data["copyright"] = copyrightLine()
 | 
						data["copyright"] = copyrightLine()
 | 
				
			||||||
	data["license"] = lic.Header
 | 
						data["license"] = project.License().Header
 | 
				
			||||||
	data["appName"] = projectName()
 | 
					 | 
				
			||||||
	data["viper"] = viper.GetBool("useViper")
 | 
						data["viper"] = viper.GetBool("useViper")
 | 
				
			||||||
	data["parentName"] = parentName()
 | 
						data["parentName"] = parentName
 | 
				
			||||||
	data["cmdName"] = cmdName
 | 
						data["cmdName"] = cmdName
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err := writeTemplateToFile(filepath.Join(ProjectPath(), guessCmdDir()), cmdName+".go", template, data)
 | 
						filePath := filepath.Join(project.AbsPath(), project.CmdDir(), cmdName+".go")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cmdScript, err := executeTemplate(template, data)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		er(err)
 | 
							er(err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	fmt.Println(cmdName, "created at", filepath.Join(ProjectPath(), guessCmdDir(), cmdName+".go"))
 | 
						err = writeStringToFile(filePath, cmdScript)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							er(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fmt.Println(cmdName, "created at", filePath)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -23,266 +23,103 @@ import (
 | 
				
			|||||||
	"text/template"
 | 
						"text/template"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// var BaseDir = ""
 | 
					var funcMap = template.FuncMap{
 | 
				
			||||||
// var AppName = ""
 | 
						"comment": commentifyString,
 | 
				
			||||||
// var CommandDir = ""
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var funcMap template.FuncMap
 | 
					var projectPath string
 | 
				
			||||||
var projectPath = ""
 | 
					 | 
				
			||||||
var inputPath = ""
 | 
					 | 
				
			||||||
var projectBase = ""
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
// for testing only
 | 
					var cmdDirs = [...]string{"cmd", "cmds", "command", "commands"}
 | 
				
			||||||
var testWd = ""
 | 
					var goPaths, srcPaths []string
 | 
				
			||||||
 | 
					 | 
				
			||||||
var cmdDirs = []string{"cmd", "cmds", "command", "commands"}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
func init() {
 | 
					func init() {
 | 
				
			||||||
	funcMap = template.FuncMap{
 | 
						// Initialize goPaths and srcPaths
 | 
				
			||||||
		"comment": commentifyString,
 | 
						envGoPath := os.Getenv("GOPATH")
 | 
				
			||||||
 | 
						if envGoPath == "" {
 | 
				
			||||||
 | 
							er("$GOPATH is not set")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						goPaths = filepath.SplitList(envGoPath)
 | 
				
			||||||
 | 
						srcPaths = make([]string, 0, len(goPaths))
 | 
				
			||||||
 | 
						for _, goPath := range goPaths {
 | 
				
			||||||
 | 
							srcPaths = append(srcPaths, filepath.Join(goPath, "src"))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func er(msg interface{}) {
 | 
					func er(msg interface{}) {
 | 
				
			||||||
	fmt.Println("Error:", msg)
 | 
						fmt.Println("Error:", msg)
 | 
				
			||||||
	os.Exit(-1)
 | 
						os.Exit(1)
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Check if a file or directory exists.
 | 
					 | 
				
			||||||
func exists(path string) (bool, error) {
 | 
					 | 
				
			||||||
	_, err := os.Stat(path)
 | 
					 | 
				
			||||||
	if err == nil {
 | 
					 | 
				
			||||||
		return true, nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if os.IsNotExist(err) {
 | 
					 | 
				
			||||||
		return false, nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return false, err
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func ProjectPath() string {
 | 
					 | 
				
			||||||
	if projectPath == "" {
 | 
					 | 
				
			||||||
		guessProjectPath()
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return projectPath
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// wrapper of the os package so we can test better
 | 
					 | 
				
			||||||
func getWd() (string, error) {
 | 
					 | 
				
			||||||
	if testWd == "" {
 | 
					 | 
				
			||||||
		return os.Getwd()
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return testWd, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func guessCmdDir() string {
 | 
					 | 
				
			||||||
	guessProjectPath()
 | 
					 | 
				
			||||||
	if b, _ := isEmpty(projectPath); b {
 | 
					 | 
				
			||||||
		return "cmd"
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	files, _ := filepath.Glob(projectPath + string(os.PathSeparator) + "c*")
 | 
					 | 
				
			||||||
	for _, f := range files {
 | 
					 | 
				
			||||||
		for _, c := range cmdDirs {
 | 
					 | 
				
			||||||
			if f == c {
 | 
					 | 
				
			||||||
				return c
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return "cmd"
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func guessImportPath() string {
 | 
					 | 
				
			||||||
	guessProjectPath()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if !strings.HasPrefix(projectPath, getSrcPath()) {
 | 
					 | 
				
			||||||
		er("Cobra only supports project within $GOPATH")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return filepath.ToSlash(filepath.Clean(strings.TrimPrefix(projectPath, getSrcPath())))
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func getSrcPath() string {
 | 
					 | 
				
			||||||
	return filepath.Join(os.Getenv("GOPATH"), "src") + string(os.PathSeparator)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func projectName() string {
 | 
					 | 
				
			||||||
	return filepath.Base(ProjectPath())
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func guessProjectPath() {
 | 
					 | 
				
			||||||
	// if no path is provided... assume CWD.
 | 
					 | 
				
			||||||
	if inputPath == "" {
 | 
					 | 
				
			||||||
		x, err := getWd()
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			er(err)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		// inspect CWD
 | 
					 | 
				
			||||||
		base := filepath.Base(x)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		// if we are in the cmd directory.. back up
 | 
					 | 
				
			||||||
		for _, c := range cmdDirs {
 | 
					 | 
				
			||||||
			if base == c {
 | 
					 | 
				
			||||||
				projectPath = filepath.Dir(x)
 | 
					 | 
				
			||||||
				return
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if projectPath == "" {
 | 
					 | 
				
			||||||
			projectPath = filepath.Clean(x)
 | 
					 | 
				
			||||||
			return
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	srcPath := getSrcPath()
 | 
					 | 
				
			||||||
	// if provided, inspect for logical locations
 | 
					 | 
				
			||||||
	if strings.ContainsRune(inputPath, os.PathSeparator) {
 | 
					 | 
				
			||||||
		if filepath.IsAbs(inputPath) || filepath.HasPrefix(inputPath, string(os.PathSeparator)) {
 | 
					 | 
				
			||||||
			// if Absolute, use it
 | 
					 | 
				
			||||||
			projectPath = filepath.Clean(inputPath)
 | 
					 | 
				
			||||||
			return
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		// If not absolute but contains slashes,
 | 
					 | 
				
			||||||
		// assuming it means create it from $GOPATH
 | 
					 | 
				
			||||||
		count := strings.Count(inputPath, string(os.PathSeparator))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		switch count {
 | 
					 | 
				
			||||||
		// If only one directory deep, assume "github.com"
 | 
					 | 
				
			||||||
		case 1:
 | 
					 | 
				
			||||||
			projectPath = filepath.Join(srcPath, "github.com", inputPath)
 | 
					 | 
				
			||||||
			return
 | 
					 | 
				
			||||||
		case 2:
 | 
					 | 
				
			||||||
			projectPath = filepath.Join(srcPath, inputPath)
 | 
					 | 
				
			||||||
			return
 | 
					 | 
				
			||||||
		default:
 | 
					 | 
				
			||||||
			er("Unknown directory")
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		// hardest case.. just a word.
 | 
					 | 
				
			||||||
		if projectBase == "" {
 | 
					 | 
				
			||||||
			x, err := getWd()
 | 
					 | 
				
			||||||
			if err == nil {
 | 
					 | 
				
			||||||
				projectPath = filepath.Join(x, inputPath)
 | 
					 | 
				
			||||||
				return
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			er(err)
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			projectPath = filepath.Join(srcPath, projectBase, inputPath)
 | 
					 | 
				
			||||||
			return
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// isEmpty checks if a given path is empty.
 | 
					// isEmpty checks if a given path is empty.
 | 
				
			||||||
func isEmpty(path string) (bool, error) {
 | 
					func isEmpty(path string) bool {
 | 
				
			||||||
	if b, _ := exists(path); !b {
 | 
					 | 
				
			||||||
		return false, fmt.Errorf("%q path does not exist", path)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	fi, err := os.Stat(path)
 | 
						fi, err := os.Stat(path)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return false, err
 | 
							er(err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if fi.IsDir() {
 | 
						if fi.IsDir() {
 | 
				
			||||||
		f, err := os.Open(path)
 | 
							f, err := os.Open(path)
 | 
				
			||||||
		// FIX: Resource leak - f.close() should be called here by defer or is missed
 | 
					 | 
				
			||||||
		// if the err != nil branch is taken.
 | 
					 | 
				
			||||||
		defer f.Close()
 | 
					 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return false, err
 | 
								er(err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		list, _ := f.Readdir(-1)
 | 
							defer f.Close()
 | 
				
			||||||
		// f.Close() - see bug fix above
 | 
							dirs, err := f.Readdirnames(1)
 | 
				
			||||||
		return len(list) == 0, nil
 | 
							if err != nil && err != io.EOF {
 | 
				
			||||||
 | 
								er(err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return len(dirs) == 0
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return fi.Size() == 0, nil
 | 
						return fi.Size() == 0
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// isDir checks if a given path is a directory.
 | 
					// exists checks if a file or directory exists.
 | 
				
			||||||
func isDir(path string) (bool, error) {
 | 
					func exists(path string) bool {
 | 
				
			||||||
	fi, err := os.Stat(path)
 | 
						if path == "" {
 | 
				
			||||||
	if err != nil {
 | 
							return false
 | 
				
			||||||
		return false, err
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return fi.IsDir(), nil
 | 
						_, err := os.Stat(path)
 | 
				
			||||||
 | 
						if err == nil {
 | 
				
			||||||
 | 
							return true
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if !os.IsNotExist(err) {
 | 
				
			||||||
 | 
							er(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return false
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// dirExists checks if a path exists and is a directory.
 | 
					func executeTemplate(tmplStr string, data interface{}) (string, error) {
 | 
				
			||||||
func dirExists(path string) (bool, error) {
 | 
						tmpl, err := template.New("").Funcs(funcMap).Parse(tmplStr)
 | 
				
			||||||
	fi, err := os.Stat(path)
 | 
					 | 
				
			||||||
	if err == nil && fi.IsDir() {
 | 
					 | 
				
			||||||
		return true, nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if os.IsNotExist(err) {
 | 
					 | 
				
			||||||
		return false, nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return false, err
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func writeTemplateToFile(path string, file string, template string, data interface{}) error {
 | 
					 | 
				
			||||||
	filename := filepath.Join(path, file)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	r, err := templateToReader(template, data)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return "", err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err = safeWriteToDisk(filename, r)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func writeStringToFile(path, file, text string) error {
 | 
					 | 
				
			||||||
	filename := filepath.Join(path, file)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	r := strings.NewReader(text)
 | 
					 | 
				
			||||||
	err := safeWriteToDisk(filename, r)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func templateToReader(tpl string, data interface{}) (io.Reader, error) {
 | 
					 | 
				
			||||||
	tmpl := template.New("")
 | 
					 | 
				
			||||||
	tmpl.Funcs(funcMap)
 | 
					 | 
				
			||||||
	tmpl, err := tmpl.Parse(tpl)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	buf := new(bytes.Buffer)
 | 
						buf := new(bytes.Buffer)
 | 
				
			||||||
	err = tmpl.Execute(buf, data)
 | 
						err = tmpl.Execute(buf, data)
 | 
				
			||||||
 | 
						return buf.String(), err
 | 
				
			||||||
	return buf, err
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Same as WriteToDisk but checks to see if file/directory already exists.
 | 
					func writeStringToFile(path string, s string) error {
 | 
				
			||||||
 | 
						return safeWriteToDisk(path, strings.NewReader(s))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// safeWriteToDisk as WriteToDisk but checks to see if file/directory already exists.
 | 
				
			||||||
func safeWriteToDisk(inpath string, r io.Reader) (err error) {
 | 
					func safeWriteToDisk(inpath string, r io.Reader) (err error) {
 | 
				
			||||||
	dir, _ := filepath.Split(inpath)
 | 
						dir := filepath.Dir(inpath)
 | 
				
			||||||
	ospath := filepath.FromSlash(dir)
 | 
						ospath := filepath.FromSlash(dir)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ospath != "" {
 | 
						if ospath != "" {
 | 
				
			||||||
		err = os.MkdirAll(ospath, 0777) // rwx, rw, r
 | 
							err = os.MkdirAll(ospath, 0777)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ex, err := exists(inpath)
 | 
						if exists(inpath) {
 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if ex {
 | 
					 | 
				
			||||||
		return fmt.Errorf("%v already exists", inpath)
 | 
							return fmt.Errorf("%v already exists", inpath)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						if _, err := os.Stat(inpath); err != nil && !os.IsNotExist(err) {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	file, err := os.Create(inpath)
 | 
						file, err := os.Create(inpath)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
@ -297,15 +134,15 @@ func safeWriteToDisk(inpath string, r io.Reader) (err error) {
 | 
				
			|||||||
func commentifyString(in string) string {
 | 
					func commentifyString(in string) string {
 | 
				
			||||||
	var newlines []string
 | 
						var newlines []string
 | 
				
			||||||
	lines := strings.Split(in, "\n")
 | 
						lines := strings.Split(in, "\n")
 | 
				
			||||||
	for _, x := range lines {
 | 
						for _, line := range lines {
 | 
				
			||||||
		if !strings.HasPrefix(x, "//") {
 | 
							if strings.HasPrefix(line, "//") {
 | 
				
			||||||
			if x != "" {
 | 
								newlines = append(newlines, line)
 | 
				
			||||||
				newlines = append(newlines, "// "+x)
 | 
					 | 
				
			||||||
			} else {
 | 
					 | 
				
			||||||
				newlines = append(newlines, "//")
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			newlines = append(newlines, x)
 | 
								if line == "" {
 | 
				
			||||||
 | 
									newlines = append(newlines, "//")
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									newlines = append(newlines, "// "+line)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return strings.Join(newlines, "\n")
 | 
						return strings.Join(newlines, "\n")
 | 
				
			||||||
 | 
				
			|||||||
@ -1,35 +0,0 @@
 | 
				
			|||||||
package cmd
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"path/filepath"
 | 
					 | 
				
			||||||
	"testing"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func checkGuess(t *testing.T, wd, input, expected string) {
 | 
					 | 
				
			||||||
	testWd = wd
 | 
					 | 
				
			||||||
	inputPath = input
 | 
					 | 
				
			||||||
	guessProjectPath()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if projectPath != expected {
 | 
					 | 
				
			||||||
		t.Errorf("Unexpected Project Path. \n Got: %q\nExpected: %q\n", projectPath, expected)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	reset()
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func reset() {
 | 
					 | 
				
			||||||
	testWd = ""
 | 
					 | 
				
			||||||
	inputPath = ""
 | 
					 | 
				
			||||||
	projectPath = ""
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func TestProjectPath(t *testing.T) {
 | 
					 | 
				
			||||||
	checkGuess(t, "", filepath.Join("github.com", "spf13", "hugo"), filepath.Join(getSrcPath(), "github.com", "spf13", "hugo"))
 | 
					 | 
				
			||||||
	checkGuess(t, "", filepath.Join("spf13", "hugo"), filepath.Join(getSrcPath(), "github.com", "spf13", "hugo"))
 | 
					 | 
				
			||||||
	checkGuess(t, "", filepath.Join("/", "bar", "foo"), filepath.Join("/", "bar", "foo"))
 | 
					 | 
				
			||||||
	checkGuess(t, "/bar/foo", "baz", filepath.Join("/", "bar", "foo", "baz"))
 | 
					 | 
				
			||||||
	checkGuess(t, "/bar/foo/cmd", "", filepath.Join("/", "bar", "foo"))
 | 
					 | 
				
			||||||
	checkGuess(t, "/bar/foo/command", "", filepath.Join("/", "bar", "foo"))
 | 
					 | 
				
			||||||
	checkGuess(t, "/bar/foo/commands", "", filepath.Join("/", "bar", "foo"))
 | 
					 | 
				
			||||||
	checkGuess(t, "github.com/spf13/hugo/../hugo", "", filepath.Join("github.com", "spf13", "hugo"))
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -14,10 +14,10 @@
 | 
				
			|||||||
package cmd
 | 
					package cmd
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"bytes"
 | 
					 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"os"
 | 
						"os"
 | 
				
			||||||
	"strings"
 | 
						"path"
 | 
				
			||||||
 | 
						"path/filepath"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/spf13/cobra"
 | 
						"github.com/spf13/cobra"
 | 
				
			||||||
	"github.com/spf13/viper"
 | 
						"github.com/spf13/viper"
 | 
				
			||||||
@ -45,79 +45,60 @@ and the appropriate structure for a Cobra-based CLI application.
 | 
				
			|||||||
Init will not use an existing directory with contents.`,
 | 
					Init will not use an existing directory with contents.`,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Run: func(cmd *cobra.Command, args []string) {
 | 
						Run: func(cmd *cobra.Command, args []string) {
 | 
				
			||||||
		switch len(args) {
 | 
							var project *Project
 | 
				
			||||||
		case 0:
 | 
							if len(args) == 0 {
 | 
				
			||||||
			inputPath = ""
 | 
								wd, err := os.Getwd()
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
		case 1:
 | 
									er(err)
 | 
				
			||||||
			inputPath = args[0]
 | 
								}
 | 
				
			||||||
 | 
								project = NewProjectFromPath(wd)
 | 
				
			||||||
		default:
 | 
							} else if len(args) == 1 {
 | 
				
			||||||
			er("init doesn't support more than 1 parameter")
 | 
								project = NewProject(args[0])
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								er("please enter the name")
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		guessProjectPath()
 | 
					
 | 
				
			||||||
		initializePath(projectPath)
 | 
							initializePath(project)
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func initializePath(path string) {
 | 
					func initializePath(project *Project) {
 | 
				
			||||||
	b, err := exists(path)
 | 
						if !exists(project.AbsPath()) { // If path doesn't yet exist, create it
 | 
				
			||||||
 | 
							err := os.MkdirAll(project.AbsPath(), os.ModePerm)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								er(err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else if !isEmpty(project.AbsPath()) { // If path exists and is not empty don't use it
 | 
				
			||||||
 | 
							er("Cobra will not create a new project in a non empty directory")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// We have a directory and it's empty.. Time to initialize it.
 | 
				
			||||||
 | 
						createLicenseFile(project)
 | 
				
			||||||
 | 
						createMainFile(project)
 | 
				
			||||||
 | 
						createRootCmdFile(project)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func createLicenseFile(project *Project) {
 | 
				
			||||||
 | 
						data := make(map[string]interface{})
 | 
				
			||||||
 | 
						data["copyright"] = copyrightLine()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Generate license template from text and data.
 | 
				
			||||||
 | 
						text, err := executeTemplate(project.License().Text, data)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		er(err)
 | 
							er(err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if !b { // If path doesn't yet exist, create it
 | 
						// Write license text to LICENSE file.
 | 
				
			||||||
		err := os.MkdirAll(path, os.ModePerm)
 | 
						err = writeStringToFile(filepath.Join(project.AbsPath(), "LICENSE"), text)
 | 
				
			||||||
		if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
			er(err)
 | 
							er(err)
 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	} else { // If path exists and is not empty don't use it
 | 
					 | 
				
			||||||
		empty, err := exists(path)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			er(err)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if !empty {
 | 
					 | 
				
			||||||
			er("Cobra will not create a new project in a non empty directory")
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	// We have a directory and it's empty.. Time to initialize it.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	createLicenseFile()
 | 
					 | 
				
			||||||
	createMainFile()
 | 
					 | 
				
			||||||
	createRootCmdFile()
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func createLicenseFile() {
 | 
					 | 
				
			||||||
	lic := getLicense()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Don't bother writing a LICENSE file if there is no text.
 | 
					 | 
				
			||||||
	if lic.Text != "" {
 | 
					 | 
				
			||||||
		data := make(map[string]interface{})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		// Try to remove the email address, if any
 | 
					 | 
				
			||||||
		data["copyright"] = strings.Split(copyrightLine(), " <")[0]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		data["appName"] = projectName()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		// Generate license template from text and data.
 | 
					 | 
				
			||||||
		r, _ := templateToReader(lic.Text, data)
 | 
					 | 
				
			||||||
		buf := new(bytes.Buffer)
 | 
					 | 
				
			||||||
		buf.ReadFrom(r)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		err := writeTemplateToFile(ProjectPath(), "LICENSE", buf.String(), data)
 | 
					 | 
				
			||||||
		_ = err
 | 
					 | 
				
			||||||
		// if err != nil {
 | 
					 | 
				
			||||||
		// 	er(err)
 | 
					 | 
				
			||||||
		// }
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func createMainFile() {
 | 
					func createMainFile(project *Project) {
 | 
				
			||||||
	lic := getLicense()
 | 
						mainTemplate := `{{ comment .copyright }}
 | 
				
			||||||
 | 
					{{if .license}}{{ comment .license }}{{end}}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	template := `{{ comment .copyright }}
 | 
					 | 
				
			||||||
{{if .license}}{{ comment .license }}
 | 
					 | 
				
			||||||
{{end}}
 | 
					 | 
				
			||||||
package main
 | 
					package main
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import "{{ .importpath }}"
 | 
					import "{{ .importpath }}"
 | 
				
			||||||
@ -127,31 +108,25 @@ func main() {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
`
 | 
					`
 | 
				
			||||||
	data := make(map[string]interface{})
 | 
						data := make(map[string]interface{})
 | 
				
			||||||
 | 
					 | 
				
			||||||
	data["copyright"] = copyrightLine()
 | 
						data["copyright"] = copyrightLine()
 | 
				
			||||||
	data["appName"] = projectName()
 | 
						data["license"] = project.License().Header
 | 
				
			||||||
 | 
						data["importpath"] = path.Join(project.Name(), project.CmdDir())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Generate license template from header and data.
 | 
						mainScript, err := executeTemplate(mainTemplate, data)
 | 
				
			||||||
	r, _ := templateToReader(lic.Header, data)
 | 
						if err != nil {
 | 
				
			||||||
	buf := new(bytes.Buffer)
 | 
							er(err)
 | 
				
			||||||
	buf.ReadFrom(r)
 | 
						}
 | 
				
			||||||
	data["license"] = buf.String()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	data["importpath"] = guessImportPath() + "/" + guessCmdDir()
 | 
						err = writeStringToFile(filepath.Join(project.AbsPath(), "main.go"), mainScript)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
	err := writeTemplateToFile(ProjectPath(), "main.go", template, data)
 | 
							er(err)
 | 
				
			||||||
	_ = err
 | 
						}
 | 
				
			||||||
	// if err != nil {
 | 
					 | 
				
			||||||
	// 	er(err)
 | 
					 | 
				
			||||||
	// }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func createRootCmdFile() {
 | 
					func createRootCmdFile(project *Project) {
 | 
				
			||||||
	lic := getLicense()
 | 
						template := `{{comment .copyright}}
 | 
				
			||||||
 | 
					{{if .license}}{{comment .license}}{{end}}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	template := `{{ comment .copyright }}
 | 
					 | 
				
			||||||
{{if .license}}{{ comment .license }}
 | 
					 | 
				
			||||||
{{end}}
 | 
					 | 
				
			||||||
package cmd
 | 
					package cmd
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
@ -159,14 +134,14 @@ import (
 | 
				
			|||||||
	"os"
 | 
						"os"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/spf13/cobra"
 | 
						"github.com/spf13/cobra"
 | 
				
			||||||
{{ if .viper }}	"github.com/spf13/viper"
 | 
					{{if .viper}}	"github.com/spf13/viper"{{end}}
 | 
				
			||||||
{{ end }})
 | 
					)
 | 
				
			||||||
{{if .viper}}
 | 
					
 | 
				
			||||||
var cfgFile string
 | 
					{{if .viper}}var cfgFile string{{end}}
 | 
				
			||||||
{{ end }}
 | 
					
 | 
				
			||||||
// RootCmd represents the base command when called without any subcommands
 | 
					// RootCmd represents the base command when called without any subcommands
 | 
				
			||||||
var RootCmd = &cobra.Command{
 | 
					var RootCmd = &cobra.Command{
 | 
				
			||||||
	Use:   "{{ .appName }}",
 | 
						Use:   "{{.appName}}",
 | 
				
			||||||
	Short: "A brief description of your application",
 | 
						Short: "A brief description of your application",
 | 
				
			||||||
	Long: ` + "`" + `A longer description that spans multiple lines and likely contains
 | 
						Long: ` + "`" + `A longer description that spans multiple lines and likely contains
 | 
				
			||||||
examples and usage of using your application. For example:
 | 
					examples and usage of using your application. For example:
 | 
				
			||||||
@ -174,9 +149,9 @@ examples and usage of using your application. For example:
 | 
				
			|||||||
Cobra is a CLI library for Go that empowers applications.
 | 
					Cobra is a CLI library for Go that empowers applications.
 | 
				
			||||||
This application is a tool to generate the needed files
 | 
					This application is a tool to generate the needed files
 | 
				
			||||||
to quickly create a Cobra application.` + "`" + `,
 | 
					to quickly create a Cobra application.` + "`" + `,
 | 
				
			||||||
// Uncomment the following line if your bare application
 | 
						// Uncomment the following line if your bare application
 | 
				
			||||||
// has an action associated with it:
 | 
						// has an action associated with it:
 | 
				
			||||||
//	Run: func(cmd *cobra.Command, args []string) { },
 | 
						//	Run: func(cmd *cobra.Command, args []string) { },
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Execute adds all child commands to the root command sets flags appropriately.
 | 
					// Execute adds all child commands to the root command sets flags appropriately.
 | 
				
			||||||
@ -189,57 +164,54 @@ func Execute() {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func init() {
 | 
					func init() {
 | 
				
			||||||
{{ if .viper }}	cobra.OnInitialize(initConfig)
 | 
					{{if .viper}}	cobra.OnInitialize(initConfig){{end}}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{{ end }}	// Here you will define your flags and configuration settings.
 | 
						// Here you will define your flags and configuration settings.
 | 
				
			||||||
	// Cobra supports Persistent Flags, which, if defined here,
 | 
						// Cobra supports Persistent Flags, which, if defined here,
 | 
				
			||||||
	// will be global for your application.
 | 
						// will be global for your application.{{ if .viper }}
 | 
				
			||||||
{{ if .viper }}
 | 
						RootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.{{ .appName }}.yaml)"){{ else }}
 | 
				
			||||||
	RootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.{{ .appName }}.yaml)")
 | 
						// RootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.{{ .appName }}.yaml)"){{ end }}
 | 
				
			||||||
{{ else }}
 | 
					
 | 
				
			||||||
	// RootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.{{ .appName }}.yaml)")
 | 
						// Cobra also supports local flags, which will only run
 | 
				
			||||||
{{ end }}	// Cobra also supports local flags, which will only run
 | 
					 | 
				
			||||||
	// when this action is called directly.
 | 
						// when this action is called directly.
 | 
				
			||||||
	RootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
 | 
						RootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
 | 
				
			||||||
}
 | 
					}{{ if .viper }}
 | 
				
			||||||
{{ if .viper }}
 | 
					
 | 
				
			||||||
// initConfig reads in config file and ENV variables if set.
 | 
					// initConfig reads in config file and ENV variables if set.
 | 
				
			||||||
func initConfig() {
 | 
					func initConfig() {
 | 
				
			||||||
	if cfgFile != "" { // enable ability to specify config file via flag
 | 
						if cfgFile != "" { // enable ability to specify config file via flag
 | 
				
			||||||
		viper.SetConfigFile(cfgFile)
 | 
							viper.SetConfigFile(cfgFile)
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							viper.SetConfigName(".{{ .appName }}") // name of config file (without extension)
 | 
				
			||||||
 | 
							viper.AddConfigPath(os.Getenv("HOME")) // adding home directory as first search path
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	viper.SetConfigName(".{{ .appName }}") // name of config file (without extension)
 | 
					 | 
				
			||||||
	viper.AddConfigPath(os.Getenv("HOME")) // adding home directory as first search path
 | 
					 | 
				
			||||||
	viper.AutomaticEnv()                   // read in environment variables that match
 | 
						viper.AutomaticEnv()                   // read in environment variables that match
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// If a config file is found, read it in.
 | 
						// If a config file is found, read it in.
 | 
				
			||||||
	if err := viper.ReadInConfig(); err == nil {
 | 
						if err := viper.ReadInConfig(); err == nil {
 | 
				
			||||||
		fmt.Println("Using config file:", viper.ConfigFileUsed())
 | 
							fmt.Println("Using config file:", viper.ConfigFileUsed())
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}{{ end }}
 | 
				
			||||||
{{ end }}`
 | 
					`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	data := make(map[string]interface{})
 | 
						data := make(map[string]interface{})
 | 
				
			||||||
 | 
					 | 
				
			||||||
	data["copyright"] = copyrightLine()
 | 
						data["copyright"] = copyrightLine()
 | 
				
			||||||
	data["appName"] = projectName()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Generate license template from header and data.
 | 
					 | 
				
			||||||
	r, _ := templateToReader(lic.Header, data)
 | 
					 | 
				
			||||||
	buf := new(bytes.Buffer)
 | 
					 | 
				
			||||||
	buf.ReadFrom(r)
 | 
					 | 
				
			||||||
	data["license"] = buf.String()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	data["viper"] = viper.GetBool("useViper")
 | 
						data["viper"] = viper.GetBool("useViper")
 | 
				
			||||||
 | 
						data["license"] = project.License().Header
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err := writeTemplateToFile(ProjectPath()+string(os.PathSeparator)+guessCmdDir(), "root.go", template, data)
 | 
						rootCmdScript, err := executeTemplate(template, data)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							er(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						err = writeStringToFile(filepath.Join(project.AbsPath(), project.CmdDir(), "root.go"), rootCmdScript)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		er(err)
 | 
							er(err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fmt.Println("Your Cobra application is ready at")
 | 
						fmt.Println("Your Cobra application is ready at")
 | 
				
			||||||
	fmt.Println(ProjectPath())
 | 
						fmt.Println(project.AbsPath() + "\n")
 | 
				
			||||||
	fmt.Println("Give it a try by going there and running `go run main.go`")
 | 
						fmt.Println("Give it a try by going there and running `go run main.go`.")
 | 
				
			||||||
	fmt.Println("Add commands to it by running `cobra add [cmdname]`")
 | 
						fmt.Println("Add commands to it by running `cobra add [cmdname]`")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -19,18 +19,17 @@ func initApache2() {
 | 
				
			|||||||
	Licenses["apache"] = License{
 | 
						Licenses["apache"] = License{
 | 
				
			||||||
		Name:            "Apache 2.0",
 | 
							Name:            "Apache 2.0",
 | 
				
			||||||
		PossibleMatches: []string{"apache", "apache20", "apache 2.0", "apache2.0", "apache-2.0"},
 | 
							PossibleMatches: []string{"apache", "apache20", "apache 2.0", "apache2.0", "apache-2.0"},
 | 
				
			||||||
		Header: `
 | 
							Header: `Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
					you may not use this file except in compliance with the License.
 | 
				
			||||||
// you may not use this file except in compliance with the License.
 | 
					You may obtain a copy of the License at
 | 
				
			||||||
// You may obtain a copy of the License at
 | 
					
 | 
				
			||||||
//
 | 
					    http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
					
 | 
				
			||||||
//
 | 
					Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
// Unless required by applicable law or agreed to in writing, software
 | 
					distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
					WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
					See the License for the specific language governing permissions and
 | 
				
			||||||
// See the License for the specific language governing permissions and
 | 
					limitations under the License.`,
 | 
				
			||||||
// limitations under the License.`,
 | 
					 | 
				
			||||||
		Text: `
 | 
							Text: `
 | 
				
			||||||
                                 Apache License
 | 
					                                 Apache License
 | 
				
			||||||
                           Version 2.0, January 2004
 | 
					                           Version 2.0, January 2004
 | 
				
			||||||
 | 
				
			|||||||
@ -16,6 +16,7 @@
 | 
				
			|||||||
package cmd
 | 
					package cmd
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -42,9 +43,6 @@ func init() {
 | 
				
			|||||||
	// Allows a user to not use a license.
 | 
						// Allows a user to not use a license.
 | 
				
			||||||
	Licenses["none"] = License{"None", []string{"none", "false"}, "", ""}
 | 
						Licenses["none"] = License{"None", []string{"none", "false"}, "", ""}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Allows a user to use config for a custom license.
 | 
					 | 
				
			||||||
	Licenses["custom"] = License{"Custom", []string{}, "", ""}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	initApache2()
 | 
						initApache2()
 | 
				
			||||||
	initMit()
 | 
						initMit()
 | 
				
			||||||
	initBsdClause3()
 | 
						initBsdClause3()
 | 
				
			||||||
@ -53,49 +51,29 @@ func init() {
 | 
				
			|||||||
	initGpl3()
 | 
						initGpl3()
 | 
				
			||||||
	initLgpl()
 | 
						initLgpl()
 | 
				
			||||||
	initAgpl()
 | 
						initAgpl()
 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Licenses["apache20"] = License{
 | 
					 | 
				
			||||||
	// 	Name:            "Apache 2.0",
 | 
					 | 
				
			||||||
	// 	PossibleMatches: []string{"apache", "apache20", ""},
 | 
					 | 
				
			||||||
	//   Header: `
 | 
					 | 
				
			||||||
	//   `,
 | 
					 | 
				
			||||||
	// 	Text: `
 | 
					 | 
				
			||||||
	//   `,
 | 
					 | 
				
			||||||
	// }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// TODO: Inspect project for existing license
 | 
				
			||||||
func getLicense() License {
 | 
					func getLicense() License {
 | 
				
			||||||
	l := whichLicense()
 | 
						// If explicitly flagged, use that.
 | 
				
			||||||
	if l != "" {
 | 
					 | 
				
			||||||
		if x, ok := Licenses[l]; ok {
 | 
					 | 
				
			||||||
			return x
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return Licenses["apache"]
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func whichLicense() string {
 | 
					 | 
				
			||||||
	// if explicitly flagged, use that
 | 
					 | 
				
			||||||
	if userLicense != "" {
 | 
						if userLicense != "" {
 | 
				
			||||||
		return matchLicense(userLicense)
 | 
							return findLicense(userLicense)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// if already present in the project, use that
 | 
						// If user wants to have custom license, use that.
 | 
				
			||||||
	// TODO: Inspect project for existing license
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// default to viper's setting
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if viper.IsSet("license.header") || viper.IsSet("license.text") {
 | 
						if viper.IsSet("license.header") || viper.IsSet("license.text") {
 | 
				
			||||||
		if custom, ok := Licenses["custom"]; ok {
 | 
							return License{Header: viper.GetString("license.header"),
 | 
				
			||||||
			custom.Header = viper.GetString("license.header")
 | 
								Text: "license.text"}
 | 
				
			||||||
			custom.Text = viper.GetString("license.text")
 | 
					 | 
				
			||||||
			Licenses["custom"] = custom
 | 
					 | 
				
			||||||
			return "custom"
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return matchLicense(viper.GetString("license"))
 | 
						// If user wants to have built-in license, use that.
 | 
				
			||||||
 | 
						if viper.IsSet("license") {
 | 
				
			||||||
 | 
							return findLicense(viper.GetString("license"))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// If user didn't set any license, use Apache 2.0 by default.
 | 
				
			||||||
 | 
						fmt.Println("apache")
 | 
				
			||||||
 | 
						return Licenses["apache"]
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func copyrightLine() string {
 | 
					func copyrightLine() string {
 | 
				
			||||||
@ -105,14 +83,27 @@ func copyrightLine() string {
 | 
				
			|||||||
	return "Copyright © " + year + " " + author
 | 
						return "Copyright © " + year + " " + author
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// given a license name (in), try to match the license indicated
 | 
					func findLicense(name string) License {
 | 
				
			||||||
func matchLicense(in string) string {
 | 
						found := matchLicense(name)
 | 
				
			||||||
 | 
						if found == "" {
 | 
				
			||||||
 | 
							er(fmt.Errorf("unknown license %q", name))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return Licenses[found]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// given a license name, try to match the license indicated
 | 
				
			||||||
 | 
					func matchLicense(name string) string {
 | 
				
			||||||
 | 
						if name == "" {
 | 
				
			||||||
 | 
							return ""
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for key, lic := range Licenses {
 | 
						for key, lic := range Licenses {
 | 
				
			||||||
		for _, match := range lic.PossibleMatches {
 | 
							for _, match := range lic.PossibleMatches {
 | 
				
			||||||
			if strings.EqualFold(in, match) {
 | 
								if strings.EqualFold(name, match) {
 | 
				
			||||||
				return key
 | 
									return key
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return ""
 | 
						return ""
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										154
									
								
								cobra/cmd/project.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										154
									
								
								cobra/cmd/project.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,154 @@
 | 
				
			|||||||
 | 
					package cmd
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"os"
 | 
				
			||||||
 | 
						"path/filepath"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Project struct {
 | 
				
			||||||
 | 
						absPath string
 | 
				
			||||||
 | 
						cmdDir  string
 | 
				
			||||||
 | 
						srcPath string
 | 
				
			||||||
 | 
						license License
 | 
				
			||||||
 | 
						name    string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func NewProject(projectName string) *Project {
 | 
				
			||||||
 | 
						if projectName == "" {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						p := new(Project)
 | 
				
			||||||
 | 
						p.name = projectName
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 1. Find already created protect.
 | 
				
			||||||
 | 
						p.absPath = findPackage(projectName)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 2. If there are no created project with this path and user in GOPATH,
 | 
				
			||||||
 | 
						// then use GOPATH+projectName.
 | 
				
			||||||
 | 
						if p.absPath == "" {
 | 
				
			||||||
 | 
							wd, err := os.Getwd()
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								er(err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							for _, goPath := range goPaths {
 | 
				
			||||||
 | 
								if filepath.HasPrefix(wd, goPath) {
 | 
				
			||||||
 | 
									p.absPath = filepath.Join(goPath, projectName)
 | 
				
			||||||
 | 
									break
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 3. If user is not in GOPATH, then use (first GOPATH)+projectName.
 | 
				
			||||||
 | 
						if p.absPath == "" {
 | 
				
			||||||
 | 
							p.absPath = filepath.Join(srcPaths[0], projectName)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return p
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// findPackage returns full path to go package. It supports multiple GOPATHs.
 | 
				
			||||||
 | 
					// findPackage returns "", if it can't find path.
 | 
				
			||||||
 | 
					// If packageName is "", findPackage returns "" too.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// For example, package "github.com/spf13/hugo"
 | 
				
			||||||
 | 
					// is located in /home/user/go/src/github.com/spf13/hugo,
 | 
				
			||||||
 | 
					// then `findPackage("github.com/spf13/hugo")`
 | 
				
			||||||
 | 
					// will return "/home/user/go/src/github.com/spf13/hugo"
 | 
				
			||||||
 | 
					func findPackage(packageName string) string {
 | 
				
			||||||
 | 
						if packageName == "" {
 | 
				
			||||||
 | 
							return ""
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, srcPath := range srcPaths {
 | 
				
			||||||
 | 
							packagePath := filepath.Join(srcPath, packageName)
 | 
				
			||||||
 | 
							if exists(packagePath) {
 | 
				
			||||||
 | 
								return packagePath
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return ""
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func NewProjectFromPath(absPath string) *Project {
 | 
				
			||||||
 | 
						if absPath == "" || !filepath.IsAbs(absPath) {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						p := new(Project)
 | 
				
			||||||
 | 
						p.absPath = absPath
 | 
				
			||||||
 | 
						p.absPath = strings.TrimSuffix(p.absPath, p.CmdDir())
 | 
				
			||||||
 | 
						p.name = filepath.ToSlash(trimSrcPath(p.absPath, p.SrcPath()))
 | 
				
			||||||
 | 
						return p
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func trimSrcPath(absPath, srcPath string) string {
 | 
				
			||||||
 | 
						relPath, err := filepath.Rel(srcPath, absPath)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							er("Cobra only supports project within $GOPATH")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return relPath
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (p *Project) License() License {
 | 
				
			||||||
 | 
						if p.license.Text == "" { // check if license is not blank
 | 
				
			||||||
 | 
							p.license = getLicense()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return p.license
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (p Project) Name() string {
 | 
				
			||||||
 | 
						return p.name
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (p *Project) CmdDir() string {
 | 
				
			||||||
 | 
						if p.absPath == "" {
 | 
				
			||||||
 | 
							return ""
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if p.cmdDir == "" {
 | 
				
			||||||
 | 
							p.cmdDir = findCmdDir(p.absPath)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return p.cmdDir
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func findCmdDir(absPath string) string {
 | 
				
			||||||
 | 
						if !exists(absPath) || isEmpty(absPath) {
 | 
				
			||||||
 | 
							return "cmd"
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						files, _ := filepath.Glob(filepath.Join(absPath, "c*"))
 | 
				
			||||||
 | 
						for _, f := range files {
 | 
				
			||||||
 | 
							for _, c := range cmdDirs {
 | 
				
			||||||
 | 
								if f == c {
 | 
				
			||||||
 | 
									return c
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return "cmd"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (p Project) AbsPath() string {
 | 
				
			||||||
 | 
						return p.absPath
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (p *Project) SrcPath() string {
 | 
				
			||||||
 | 
						if p.srcPath != "" {
 | 
				
			||||||
 | 
							return p.srcPath
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if p.absPath == "" {
 | 
				
			||||||
 | 
							p.srcPath = srcPaths[0]
 | 
				
			||||||
 | 
							return p.srcPath
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, srcPath := range srcPaths {
 | 
				
			||||||
 | 
							if strings.HasPrefix(p.absPath, srcPath) {
 | 
				
			||||||
 | 
								p.srcPath = srcPath
 | 
				
			||||||
 | 
								break
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return p.srcPath
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -21,8 +21,7 @@ import (
 | 
				
			|||||||
	"github.com/spf13/viper"
 | 
						"github.com/spf13/viper"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var cfgFile string
 | 
					var cfgFile, projectBase, userLicense string // are used for flags
 | 
				
			||||||
var userLicense string
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
// RootCmd represents the base command when called without any subcommands
 | 
					// RootCmd represents the base command when called without any subcommands
 | 
				
			||||||
var RootCmd = &cobra.Command{
 | 
					var RootCmd = &cobra.Command{
 | 
				
			||||||
@ -42,7 +41,7 @@ func Execute() {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func init() {
 | 
					func init() {
 | 
				
			||||||
	cobra.OnInitialize(initConfig)
 | 
						initViper()
 | 
				
			||||||
	RootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.cobra.yaml)")
 | 
						RootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.cobra.yaml)")
 | 
				
			||||||
	RootCmd.PersistentFlags().StringVarP(&projectBase, "projectbase", "b", "", "base project directory, e.g. github.com/spf13/")
 | 
						RootCmd.PersistentFlags().StringVarP(&projectBase, "projectbase", "b", "", "base project directory, e.g. github.com/spf13/")
 | 
				
			||||||
	RootCmd.PersistentFlags().StringP("author", "a", "YOUR NAME", "Author name for copyright attribution")
 | 
						RootCmd.PersistentFlags().StringP("author", "a", "YOUR NAME", "Author name for copyright attribution")
 | 
				
			||||||
@ -55,17 +54,16 @@ func init() {
 | 
				
			|||||||
	viper.SetDefault("license", "apache")
 | 
						viper.SetDefault("license", "apache")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Read in config file and ENV variables if set.
 | 
					func initViper() {
 | 
				
			||||||
func initConfig() {
 | 
					 | 
				
			||||||
	if cfgFile != "" { // enable ability to specify config file via flag
 | 
						if cfgFile != "" { // enable ability to specify config file via flag
 | 
				
			||||||
		viper.SetConfigFile(cfgFile)
 | 
							viper.SetConfigFile(cfgFile)
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							viper.AddConfigPath(os.Getenv("HOME"))
 | 
				
			||||||
 | 
							viper.SetConfigName(".cobra")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	viper.SetConfigName(".cobra")          // name of config file (without extension)
 | 
						viper.AutomaticEnv()
 | 
				
			||||||
	viper.AddConfigPath(os.Getenv("HOME")) // adding home directory as first search path
 | 
					 | 
				
			||||||
	viper.AutomaticEnv()                   // read in environment variables that match
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// If a config file is found, read it in.
 | 
					 | 
				
			||||||
	if err := viper.ReadInConfig(); err == nil {
 | 
						if err := viper.ReadInConfig(); err == nil {
 | 
				
			||||||
		fmt.Println("Using config file:", viper.ConfigFileUsed())
 | 
							fmt.Println("Using config file:", viper.ConfigFileUsed())
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user