github.com/goplus/igop@v0.25.0/cmd/internal/base/base.go (about) 1 /* 2 Copyright 2021 The GoPlus Authors (goplus.org) 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 // Package base defines shared xtype pieces of the gop command, 18 // in particular logging and the Command structure. 19 package base 20 21 import ( 22 "flag" 23 "fmt" 24 "io" 25 "os" 26 "strings" 27 ) 28 29 // A Command is an implementation of a gop command 30 // like gop export or gop install. 31 type Command struct { 32 // Run runs the command. 33 // The args are the arguments after the command name. 34 Run func(cmd *Command, args []string) 35 36 // UsageLine is the one-line usage message. 37 // The words between "gop" and the first flag or argument in the line are taken to be the command name. 38 UsageLine string 39 40 // Short is the short description shown in the 'gop help' output. 41 Short string 42 43 // Flag is a set of flags specific to this command. 44 Flag flag.FlagSet 45 46 // Commands lists the available commands and help topics. 47 // The order here is the order in which they are printed by 'gop help'. 48 // Note that subcommands are in general best avoided. 49 Commands []*Command 50 } 51 52 // igop command 53 var Igop = &Command{ 54 UsageLine: "igop", 55 Short: `igop is a SSA interpreter of Go/Go+ source code.`, 56 // Commands initialized in package main 57 } 58 59 // LongName returns the command's long name: all the words in the usage line between "gop" and a flag or argument, 60 func (c *Command) LongName() string { 61 name := c.UsageLine 62 name = strings.TrimPrefix(name, "igop ") 63 if i := strings.Index(name, " "); i >= 0 { 64 name = name[:i] 65 } 66 return name 67 } 68 69 // Name returns the command's short name: the last word in the usage line before a flag or argument. 70 func (c *Command) Name() string { 71 name := c.LongName() 72 if i := strings.LastIndex(name, " "); i >= 0 { 73 name = name[i+1:] 74 } 75 return name 76 } 77 78 // Usage show the command usage. 79 func (c *Command) Usage(w io.Writer) { 80 fmt.Fprintf(w, "%s\n\nUsage: %s\n", c.Short, c.UsageLine) 81 82 // restore output of flag 83 defer c.Flag.SetOutput(c.Flag.Output()) 84 85 c.Flag.SetOutput(w) 86 c.Flag.PrintDefaults() 87 fmt.Fprintln(w) 88 os.Exit(2) 89 } 90 91 // Runnable reports whether the command can be run; otherwise 92 // it is a documentation pseudo-command. 93 func (c *Command) Runnable() bool { 94 return c.Run != nil 95 } 96 97 // Usage is the usage-reporting function, filled in by package main 98 // but here for reference by other packages. 99 var Usage func() 100 101 // CmdName - "build", "install", "list", "mod tidy", etc. 102 var CmdName string 103 104 // Main runs a command. 105 func Main(c *Command, app string, args []string) { 106 name := c.UsageLine 107 if i := strings.Index(name, " ["); i >= 0 { 108 c.UsageLine = app + name[i:] 109 } 110 c.Run(c, args) 111 }