func (c *NewCommand) Run(args []string) int {
	var (
		commands     []*skeleton.Command
		flags        []*skeleton.Flag
		frameworkStr string
		owner        string
		staticDir    string
		vcsHost      string
		current      bool
		skipTest     bool
		verbose      bool
	)
	uflag := c.Meta.NewFlagSet("new", c.Help())
	uflag.Var((*CommandFlag)(&commands), "command", "command")
	uflag.Var((*CommandFlag)(&commands), "c", "command (short)")
	uflag.Var((*FlagFlag)(&flags), "flag", "flag")
	uflag.Var((*FlagFlag)(&flags), "f", "flag (short)")
	uflag.StringVar(&frameworkStr, "framework", defaultFrameworkString, "framework")
	uflag.StringVar(&frameworkStr, "F", defaultFrameworkString, "framework (short)")
	uflag.StringVar(&owner, "owner", "", "owner")
	uflag.StringVar(&owner, "o", "", "owner (short)")
	uflag.StringVar(&staticDir, "static-dir", "", "")
	uflag.StringVar(&vcsHost, "vcs", DefaultVCSHost, "")
	uflag.BoolVar(&current, "current", false, "current")
	uflag.BoolVar(&current, "C", false, "current")
	uflag.BoolVar(&skipTest, "skip-test", false, "skip-test")
	uflag.BoolVar(&skipTest, "T", false, "skip-test (short)")
	uflag.BoolVar(&verbose, "verbose", false, "verbose")
	uflag.BoolVar(&verbose, "V", false, "verbose (short)")
	if err := uflag.Parse(args); err != nil {
		return 1
	}
	parsedArgs := uflag.Args()
	if len(parsedArgs) != 1 {
		msg := fmt.Sprintf("Invalid arguments: %s", strings.Join(parsedArgs, " "))
		c.UI.Error(msg)
		return 1
	}
	name := parsedArgs[0]
	if owner == "" {
		var err error
		owner, err = gitconfig.GithubUser()
		if err != nil {
			owner, err = gitconfig.Username()
			if err != nil {
				msg := "Cannot find owner name\n" +
					"By default, owener name is retrieved from `~/.gitconfig` file.\n" +
					"Please set one via -owner option or `~/.gitconfig` file."
				c.UI.Error(msg)
				return 1
			}
		}
	}
	currentDir, err := os.Getwd()
	if err != nil {
		c.UI.Error(fmt.Sprintf(
			"Failed to get current directroy: %s", err))
		return ExitCodeFailed
	}
	gopaths := filepath.SplitList(os.Getenv(EnvGoPath))
	gopath := ""
	if len(gopaths) == 0 {
		c.UI.Error(fmt.Sprintf(
			"Failed to read GOPATH: it should not be empty"))
		return ExitCodeFailed
	}
	for _, path := range gopaths {
		absPath, err := filepath.Abs(path)
		if err != nil {
			c.UI.Error(fmt.Sprintf(
				"Cannot parse GOPATH"))
			continue
		}
		if strings.HasPrefix(currentDir, absPath) {
			gopath = absPath
			break
		}
	}
	if gopath == "" {
		c.UI.Output("")
		c.UI.Output(fmt.Sprintf("===> WARNING: You are not in the directories defined in $GOPATH."))
		c.UI.Output(fmt.Sprintf("     Uses first location in $GOPATH."))
		c.UI.Output("")
		gopath, err = filepath.Abs(gopaths[0])
		if err != nil {
			c.UI.Error(fmt.Sprintf("Cannot parse GOPATH"))
			return ExitCodeFailed
		}
	}
	idealDir := filepath.Join(gopath, "src", vcsHost, owner)
	output := name
	if currentDir != idealDir && !current {
		c.UI.Output("")
		c.UI.Output(fmt.Sprintf("====> WARNING: You are not in the directory gcli expects."))
		c.UI.Output(fmt.Sprintf("      The codes will be generated be in $GOPATH/src/%s/%s.", vcsHost, owner))
		c.UI.Output(fmt.Sprintf("      Not in the current directory. This is because the output"))
		c.UI.Output(fmt.Sprintf("      codes use import path based on that path."))
		c.UI.Output("")
		output = filepath.Join(idealDir, name)
	}
	if _, err := os.Stat(output); !os.IsNotExist(err) {
		msg := fmt.Sprintf("Cannot create directory %s: file exists", output)
		c.UI.Error(msg)
		return 1
	}
	framework, err := skeleton.FrameworkByName(frameworkStr)
	if err != nil {
		c.UI.Error(fmt.Sprintf("Failed to generate %q: %s", name, err.Error()))
		return 1
	}
	if staticDir == "" {
		localDir, err := c.LocalDir()
		if err != nil {
			c.UI.Error(err.Error())
			return ExitCodeFailed
		}
		staticDir = filepath.Join(localDir, DefaultLocalStaticDir)
	}
	executable := &skeleton.Executable{
		Name:        name,
		Owner:       owner,
		VCSHost:     vcsHost,
		Commands:    commands,
		Flags:       flags,
		Version:     skeleton.DefaultVersion,
		Description: skeleton.DefaultDescription,
	}
	artifactCh, errCh := make(chan string), make(chan error)
	skeleton := &skeleton.Skeleton{
		Path:       output,
		StaticDir:  staticDir,
		Framework:  framework,
		SkipTest:   skipTest,
		Executable: executable,
		ArtifactCh: artifactCh,
		ErrCh:      errCh,
		Verbose:    verbose,
		LogWriter:  os.Stdout,
	}
	doneCh := skeleton.Generate()
	for {
		select {
		case artifact := <-artifactCh:
			c.UI.Output(fmt.Sprintf("  Created %s", artifact))
		case err := <-errCh:
			c.UI.Error(fmt.Sprintf("Failed to generate %s: %s", output, err.Error()))
			if _, err := os.Stat(output); !os.IsNotExist(err) {
				c.UI.Output(fmt.Sprintf("Cleanup %s", output))
				os.RemoveAll(output)
			}
			return ExitCodeFailed
		case <-doneCh:
			c.UI.Info(fmt.Sprintf("====> Successfully generated %s", name))
			return ExitCodeOK
		}
	}
}
Run generates a new cli project. It returns exit code
package command
import (
	"fmt"
	"os"
	"path/filepath"
	"strings"
	"github.com/tcnksm/gcli/skeleton"
	"github.com/tcnksm/go-gitconfig"
)
type NewCommand struct {
	Meta
}