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  }