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 }