cmd: Add more docs
This commit is contained in:
parent
32756eb440
commit
0dd1c429a3
@ -107,7 +107,7 @@ func init() {
|
||||
data["parentName"] = parentName
|
||||
data["cmdName"] = cmdName
|
||||
|
||||
filePath := filepath.Join(project.AbsPath(), project.CmdDir(), cmdName+".go")
|
||||
filePath := filepath.Join(project.CmdPath(), cmdName+".go")
|
||||
|
||||
cmdScript, err := executeTemplate(template, data)
|
||||
if err != nil {
|
||||
|
@ -99,38 +99,36 @@ func executeTemplate(tmplStr string, data interface{}) (string, error) {
|
||||
}
|
||||
|
||||
func writeStringToFile(path string, s string) error {
|
||||
return safeWriteToDisk(path, strings.NewReader(s))
|
||||
return writeToFile(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) {
|
||||
dir := filepath.Dir(inpath)
|
||||
ospath := filepath.FromSlash(dir)
|
||||
// writeToFile writes r to file with path only
|
||||
// if file/directory on given path doesn't exist.
|
||||
// If file/directory exists on given path, then
|
||||
// it terminates app and prints an appropriate error.
|
||||
func writeToFile(path string, r io.Reader) error {
|
||||
if exists(path) {
|
||||
return fmt.Errorf("%v already exists", path)
|
||||
}
|
||||
|
||||
if ospath != "" {
|
||||
err = os.MkdirAll(ospath, 0777)
|
||||
if err != nil {
|
||||
return
|
||||
dir := filepath.Dir(path)
|
||||
if dir != "" {
|
||||
if err := os.MkdirAll(dir, 0777); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if 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(path)
|
||||
if err != nil {
|
||||
return
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
_, err = io.Copy(file, r)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
// commentfyString comments every line of in.
|
||||
func commentifyString(in string) string {
|
||||
var newlines []string
|
||||
lines := strings.Split(in, "\n")
|
||||
|
@ -27,7 +27,6 @@ func init() {
|
||||
RootCmd.AddCommand(initCmd)
|
||||
}
|
||||
|
||||
// initialize Command
|
||||
var initCmd = &cobra.Command{
|
||||
Use: "init [name]",
|
||||
Aliases: []string{"initialize", "initialise", "create"},
|
||||
@ -69,27 +68,27 @@ func initializePath(project *Project) {
|
||||
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")
|
||||
er("Cobra will not create a new project in a non empty directory: " + project.AbsPath())
|
||||
}
|
||||
|
||||
// We have a directory and it's empty.. Time to initialize it.
|
||||
createLicenseFile(project)
|
||||
// We have a directory and it's empty. Time to initialize it.
|
||||
createLicenseFile(project.License(), project.AbsPath())
|
||||
createMainFile(project)
|
||||
createRootCmdFile(project)
|
||||
}
|
||||
|
||||
func createLicenseFile(project *Project) {
|
||||
func createLicenseFile(license License, path string) {
|
||||
data := make(map[string]interface{})
|
||||
data["copyright"] = copyrightLine()
|
||||
|
||||
// Generate license template from text and data.
|
||||
text, err := executeTemplate(project.License().Text, data)
|
||||
text, err := executeTemplate(license.Text, data)
|
||||
if err != nil {
|
||||
er(err)
|
||||
}
|
||||
|
||||
// Write license text to LICENSE file.
|
||||
err = writeStringToFile(filepath.Join(project.AbsPath(), "LICENSE"), text)
|
||||
err = writeStringToFile(filepath.Join(path, "LICENSE"), text)
|
||||
if err != nil {
|
||||
er(err)
|
||||
}
|
||||
@ -110,7 +109,7 @@ func main() {
|
||||
data := make(map[string]interface{})
|
||||
data["copyright"] = copyrightLine()
|
||||
data["license"] = project.License().Header
|
||||
data["importpath"] = path.Join(project.Name(), project.CmdDir())
|
||||
data["importpath"] = path.Join(project.Name(), filepath.Base(project.CmdPath()))
|
||||
|
||||
mainScript, err := executeTemplate(mainTemplate, data)
|
||||
if err != nil {
|
||||
@ -199,19 +198,21 @@ func initConfig() {
|
||||
data["copyright"] = copyrightLine()
|
||||
data["viper"] = viper.GetBool("useViper")
|
||||
data["license"] = project.License().Header
|
||||
data["appName"] = path.Base(project.Name())
|
||||
|
||||
rootCmdScript, err := executeTemplate(template, data)
|
||||
if err != nil {
|
||||
er(err)
|
||||
}
|
||||
|
||||
err = writeStringToFile(filepath.Join(project.AbsPath(), project.CmdDir(), "root.go"), rootCmdScript)
|
||||
err = writeStringToFile(filepath.Join(project.CmdPath(), "root.go"), rootCmdScript)
|
||||
if err != nil {
|
||||
er(err)
|
||||
}
|
||||
|
||||
fmt.Println("Your Cobra application is ready at")
|
||||
fmt.Println(project.AbsPath() + "\n")
|
||||
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(`Your Cobra application is ready at
|
||||
` + project.AbsPath() + `.
|
||||
|
||||
Give it a try by going there and running ` + "`go run main.go`." + `
|
||||
Add commands to it by running ` + "`cobra add [cmdname]`.")
|
||||
}
|
||||
|
@ -16,18 +16,17 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
//Licenses contains all possible licenses a user can chose from
|
||||
var Licenses map[string]License
|
||||
// Licenses contains all possible licenses a user can choose from.
|
||||
var Licenses = make(map[string]License)
|
||||
|
||||
//License represents a software license agreement, containing the Name of
|
||||
// the license, its possible matches (on the command line as given to cobra)
|
||||
// License represents a software license agreement, containing the Name of
|
||||
// the license, its possible matches (on the command line as given to cobra),
|
||||
// the header to be used with each file on the file's creating, and the text
|
||||
// of the license
|
||||
type License struct {
|
||||
@ -38,8 +37,6 @@ type License struct {
|
||||
}
|
||||
|
||||
func init() {
|
||||
Licenses = make(map[string]License)
|
||||
|
||||
// Allows a user to not use a license.
|
||||
Licenses["none"] = License{"None", []string{"none", "false"}, "", ""}
|
||||
|
||||
@ -53,6 +50,9 @@ func init() {
|
||||
initAgpl()
|
||||
}
|
||||
|
||||
// getLicense returns license specified by user in flag or in config.
|
||||
// If user didn't specify the license, it returns Apache License 2.0.
|
||||
//
|
||||
// TODO: Inspect project for existing license
|
||||
func getLicense() License {
|
||||
// If explicitly flagged, use that.
|
||||
@ -72,7 +72,6 @@ func getLicense() License {
|
||||
}
|
||||
|
||||
// If user didn't set any license, use Apache 2.0 by default.
|
||||
fmt.Println("apache")
|
||||
return Licenses["apache"]
|
||||
}
|
||||
|
||||
@ -83,15 +82,21 @@ func copyrightLine() string {
|
||||
return "Copyright © " + year + " " + author
|
||||
}
|
||||
|
||||
// findLicense looks for License object of built-in licenses.
|
||||
// If it didn't find license, then the app will be terminated and
|
||||
// error will be printed.
|
||||
func findLicense(name string) License {
|
||||
found := matchLicense(name)
|
||||
if found == "" {
|
||||
er(fmt.Errorf("unknown license %q", name))
|
||||
er("unknown license: " + name)
|
||||
}
|
||||
return Licenses[found]
|
||||
}
|
||||
|
||||
// given a license name, try to match the license indicated
|
||||
// matchLicense compares the given a license name
|
||||
// to PossibleMatches of all built-in licenses.
|
||||
// It returns blank string, if name is blank string or it didn't find
|
||||
// then appropriate match to name.
|
||||
func matchLicense(name string) string {
|
||||
if name == "" {
|
||||
return ""
|
||||
|
@ -6,14 +6,17 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Project contains name, license and paths to projects.
|
||||
type Project struct {
|
||||
absPath string
|
||||
cmdDir string
|
||||
cmdPath string
|
||||
srcPath string
|
||||
license License
|
||||
name string
|
||||
}
|
||||
|
||||
// NewProject returns Project with specified project name.
|
||||
// If projectName is blank string, it returns nil.
|
||||
func NewProject(projectName string) *Project {
|
||||
if projectName == "" {
|
||||
return nil
|
||||
@ -25,8 +28,8 @@ func NewProject(projectName string) *Project {
|
||||
// 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.
|
||||
// 2. If there are no created project with this path, and user is in GOPATH,
|
||||
// then use GOPATH/src+projectName.
|
||||
if p.absPath == "" {
|
||||
wd, err := os.Getwd()
|
||||
if err != nil {
|
||||
@ -34,7 +37,7 @@ func NewProject(projectName string) *Project {
|
||||
}
|
||||
for _, goPath := range goPaths {
|
||||
if filepath.HasPrefix(wd, goPath) {
|
||||
p.absPath = filepath.Join(goPath, projectName)
|
||||
p.absPath = filepath.Join(goPath, "src", projectName)
|
||||
break
|
||||
}
|
||||
}
|
||||
@ -48,14 +51,9 @@ func NewProject(projectName string) *Project {
|
||||
return p
|
||||
}
|
||||
|
||||
// findPackage returns full path to go package. It supports multiple GOPATHs.
|
||||
// findPackage returns full path to existing go package in 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"
|
||||
// If packageName is "", findPackage returns "".
|
||||
func findPackage(packageName string) string {
|
||||
if packageName == "" {
|
||||
return ""
|
||||
@ -71,6 +69,10 @@ func findPackage(packageName string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
// NewProjectFromPath returns Project with specified absolute path to
|
||||
// package.
|
||||
// If absPath is blank string or if absPath is not actually absolute,
|
||||
// it returns nil.
|
||||
func NewProjectFromPath(absPath string) *Project {
|
||||
if absPath == "" || !filepath.IsAbs(absPath) {
|
||||
return nil
|
||||
@ -78,51 +80,68 @@ func NewProjectFromPath(absPath string) *Project {
|
||||
|
||||
p := new(Project)
|
||||
p.absPath = absPath
|
||||
p.absPath = strings.TrimSuffix(p.absPath, p.CmdDir())
|
||||
p.absPath = strings.TrimSuffix(p.absPath, findCmdDir(p.absPath))
|
||||
p.name = filepath.ToSlash(trimSrcPath(p.absPath, p.SrcPath()))
|
||||
return p
|
||||
}
|
||||
|
||||
// trimSrcPath trims at the end of absPaththe srcPath.
|
||||
func trimSrcPath(absPath, srcPath string) string {
|
||||
relPath, err := filepath.Rel(srcPath, absPath)
|
||||
if err != nil {
|
||||
er("Cobra only supports project within $GOPATH")
|
||||
er("Cobra supports project only within $GOPATH")
|
||||
}
|
||||
return relPath
|
||||
}
|
||||
|
||||
// License returns the License object of project.
|
||||
func (p *Project) License() License {
|
||||
if p.license.Text == "" { // check if license is not blank
|
||||
if p.license.Text == "" && p.license.Name != "None" {
|
||||
p.license = getLicense()
|
||||
}
|
||||
|
||||
return p.license
|
||||
}
|
||||
|
||||
// Name returns the name of project, e.g. "github.com/spf13/cobra"
|
||||
func (p Project) Name() string {
|
||||
return p.name
|
||||
}
|
||||
|
||||
func (p *Project) CmdDir() string {
|
||||
// CmdPath returns absolute path to directory, where all commands are located.
|
||||
//
|
||||
// CmdPath returns blank string, only if p.AbsPath() is a blank string.
|
||||
func (p *Project) CmdPath() string {
|
||||
if p.absPath == "" {
|
||||
return ""
|
||||
}
|
||||
if p.cmdDir == "" {
|
||||
p.cmdDir = findCmdDir(p.absPath)
|
||||
if p.cmdPath == "" {
|
||||
p.cmdPath = filepath.Join(p.absPath, findCmdDir(p.absPath))
|
||||
}
|
||||
return p.cmdDir
|
||||
return p.cmdPath
|
||||
}
|
||||
|
||||
// findCmdDir checks if base of absPath is cmd dir and returns it or
|
||||
// looks for existing cmd dir in absPath.
|
||||
// If the cmd dir doesn't exist, empty, or cannot be found,
|
||||
// it returns "cmd".
|
||||
func findCmdDir(absPath string) string {
|
||||
if !exists(absPath) || isEmpty(absPath) {
|
||||
return "cmd"
|
||||
}
|
||||
|
||||
base := filepath.Base(absPath)
|
||||
for _, cmdDir := range cmdDirs {
|
||||
if base == cmdDir {
|
||||
return cmdDir
|
||||
}
|
||||
}
|
||||
|
||||
files, _ := filepath.Glob(filepath.Join(absPath, "c*"))
|
||||
for _, f := range files {
|
||||
for _, c := range cmdDirs {
|
||||
if f == c {
|
||||
return c
|
||||
for _, file := range files {
|
||||
for _, cmdDir := range cmdDirs {
|
||||
if file == cmdDir {
|
||||
return cmdDir
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -130,10 +149,12 @@ func findCmdDir(absPath string) string {
|
||||
return "cmd"
|
||||
}
|
||||
|
||||
// AbsPath returns absolute path of project.
|
||||
func (p Project) AbsPath() string {
|
||||
return p.absPath
|
||||
}
|
||||
|
||||
// SrcPath returns absolute path to $GOPATH/src where project is located.
|
||||
func (p *Project) SrcPath() string {
|
||||
if p.srcPath != "" {
|
||||
return p.srcPath
|
||||
|
@ -23,7 +23,6 @@ import (
|
||||
|
||||
var cfgFile, projectBase, userLicense string // are used for flags
|
||||
|
||||
// RootCmd represents the base command when called without any subcommands
|
||||
var RootCmd = &cobra.Command{
|
||||
Use: "cobra",
|
||||
Short: "A generator for Cobra based Applications",
|
||||
@ -32,7 +31,6 @@ This application is a tool to generate the needed files
|
||||
to quickly create a Cobra application.`,
|
||||
}
|
||||
|
||||
//Execute adds all child commands to the root command sets flags appropriately.
|
||||
func Execute() {
|
||||
if err := RootCmd.Execute(); err != nil {
|
||||
fmt.Println(err)
|
||||
|
Loading…
Reference in New Issue
Block a user