github.com/tcnksm/gcli@v0.2.4-0.20170129033839-7eb950507e5a/command/design.go (about)

     1  package command
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"strings"
     7  
     8  	"github.com/BurntSushi/toml"
     9  	"github.com/tcnksm/gcli/skeleton"
    10  	"github.com/tcnksm/go-gitconfig"
    11  )
    12  
    13  const (
    14  	defaultOutputFmt = "%s-design.toml"
    15  )
    16  
    17  // DesignCommand is a Command that generates a new cli project
    18  type DesignCommand struct {
    19  	Meta
    20  }
    21  
    22  // Run generates a new cli project. It returns exit code
    23  func (c *DesignCommand) Run(args []string) int {
    24  
    25  	var (
    26  		output       string
    27  		owner        string
    28  		commands     []*skeleton.Command
    29  		flags        []*skeleton.Flag
    30  		frameworkStr string
    31  	)
    32  
    33  	uflag := c.Meta.NewFlagSet("design", c.Help())
    34  
    35  	uflag.Var((*CommandFlag)(&commands), "command", "command")
    36  	uflag.Var((*CommandFlag)(&commands), "c", "command (short)")
    37  
    38  	uflag.Var((*FlagFlag)(&flags), "flag", "flag")
    39  	uflag.Var((*FlagFlag)(&flags), "f", "flag (short)")
    40  
    41  	uflag.StringVar(&frameworkStr, "framework", defaultFrameworkString, "framework")
    42  	uflag.StringVar(&frameworkStr, "F", defaultFrameworkString, "framework (short)")
    43  
    44  	uflag.StringVar(&owner, "owner", "", "owner")
    45  	uflag.StringVar(&owner, "o", "", "owner (short)")
    46  
    47  	uflag.StringVar(&output, "output", "", "output")
    48  	uflag.StringVar(&output, "O", "", "output (short)")
    49  
    50  	if err := uflag.Parse(args); err != nil {
    51  		return 1
    52  	}
    53  
    54  	parsedArgs := uflag.Args()
    55  	if len(parsedArgs) != 1 {
    56  		msg := fmt.Sprintf("Invalid arguments: usage gcli design [option] NAME")
    57  		c.UI.Error(msg)
    58  		return 1
    59  	}
    60  
    61  	name := parsedArgs[0]
    62  
    63  	// If output file name is not provided use default one
    64  	if len(output) == 0 {
    65  		output = fmt.Sprintf(defaultOutputFmt, name)
    66  	}
    67  
    68  	if _, err := os.Stat(output); !os.IsNotExist(err) {
    69  		msg := fmt.Sprintf("Cannot create design file %s: file exists", output)
    70  		c.UI.Error(msg)
    71  		return 1
    72  	}
    73  
    74  	outputFile, err := os.Create(output)
    75  	if err != nil {
    76  		msg := fmt.Sprintf("Cannot create design file %s: %s", output, err)
    77  		c.UI.Error(msg)
    78  		return 1
    79  	}
    80  
    81  	if owner == "" {
    82  		owner, err = gitconfig.GithubUser()
    83  		if err != nil {
    84  			owner, _ = gitconfig.Username()
    85  		}
    86  	}
    87  
    88  	// If no commands are specified, set emply value so that
    89  	// user can understand how to write
    90  	if len(commands) < 1 && len(flags) < 1 {
    91  		commands = []*skeleton.Command{
    92  			&skeleton.Command{
    93  				Name: "",
    94  			},
    95  		}
    96  	}
    97  
    98  	// Define Executable
    99  	executable := &skeleton.Executable{
   100  		Name:         name,
   101  		Owner:        owner,
   102  		Commands:     commands,
   103  		Flags:        flags,
   104  		Version:      skeleton.DefaultVersion,
   105  		Description:  skeleton.DefaultDescription,
   106  		FrameworkStr: frameworkStr,
   107  	}
   108  
   109  	if err := toml.NewEncoder(outputFile).Encode(executable); err != nil {
   110  		msg := fmt.Sprintf("Failed to generate design file: %s", err)
   111  		c.UI.Error(msg)
   112  		return 1
   113  	}
   114  
   115  	c.UI.Info(fmt.Sprintf("====> Successfully generated %s", output))
   116  	return ExitCodeOK
   117  }
   118  
   119  // Synopsis is a one-line, short synopsis of the command.
   120  func (c *DesignCommand) Synopsis() string {
   121  	return "Generate project design template"
   122  }
   123  
   124  // Help is a long-form help text that includes the command-line
   125  // usage, a brief few sentences explaining the function of the command,
   126  // and the complete list of flags the command accepts.
   127  func (c *DesignCommand) Help() string {
   128  	helpText := `
   129  Generate project design template (as toml file). You can pass that file to 'gcli apply'
   130  command and generate CLI tool based on template file. You can define what command
   131  and what flag you need on that file.
   132  
   133  Usage:
   134  
   135    gcli design [option] NAME
   136  
   137  
   138  Options:
   139  
   140    -command=name, -c           Command name which you want to add.
   141                                This is valid only when cli pacakge support commands.
   142                                This can be specified multiple times. Synopsis can be
   143                                set after ":". Namely, you can specify command by 
   144                                -command=NAME:SYNOPSYS. Only NAME is required.
   145                                You can set multiple variables at same time with ","
   146                                separator.
   147  
   148    -flag=name, -f              Global flag option name which you want to add.
   149                                This can be specified multiple times. By default, flag type
   150                                is string and its description is empty. You can set them,
   151                                with ":" separator. Namaly, you can specify flag by
   152                                -flag=NAME:TYPE:DESCIRPTION. Order must be flow  this and
   153                                TYPE must be string, bool or int. Only NAME is required.
   154                                You can set multiple variables at same time with ","
   155                                separator.
   156  
   157    -framework=name, -F         Cli framework name. By default, gcli use "codegangsta/cli"
   158                                To check cli framework you can use, run 'gcli list'.
   159                                If you set invalid framework, it will be failed.
   160  
   161    -owner=name, -o             Command owner (author) name. This value is also used for
   162                                import path name. By default, owner name is extracted from
   163                                ~/.gitconfig variable.
   164  
   165  
   166    -output, -O                 Change output file name. By default, gcli use "NAME-design.toml"
   167  `
   168  	return strings.TrimSpace(helpText)
   169  }