gitlab.com/go-turbo/command@v0.0.0-20181230142125-c7fabe092ebf/package.go (about)

     1  // Copyright (c) 2018-2019 The Go-Turbo Project
     2  // Copyright (c) 2016-2017 Mathias J. Hennig
     3  //
     4  // Redistribution and use in source and binary forms, with or without
     5  // modification, are permitted provided that the following conditions are met:
     6  //
     7  // 1. Redistributions of source code must retain the above copyright notice,
     8  //    this list of conditions and the following disclaimer.
     9  //
    10  // 2. Redistributions in binary form must reproduce the above copyright
    11  //    notice, this list of conditions and the following disclaimer in the
    12  //    documentation and/or other materials provided with the distribution.
    13  //
    14  // THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS "AS IS" AND ANY
    15  // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
    16  // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
    17  // DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY
    18  // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
    19  // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
    20  // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
    21  // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    22  // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
    23  // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    24  
    25  // Package command provides utilities for CLI applications.
    26  package command
    27  
    28  // Standard packages are documented at https://golang.org/pkg/.
    29  import (
    30  	"flag"
    31  	"fmt"
    32  	"io"
    33  )
    34  
    35  // WriteOptions generates the part of a CLI executable's `--help` message that
    36  // lists and briefly explains the flags or options available to the user.
    37  // The output format (see examples) is an attempt to align the behavior of Go's
    38  // native package `flag` with the expectations of POSIX system users.
    39  func WriteOptions(output io.Writer, flags *flag.FlagSet) error {
    40  
    41  	handler := func(item *flag.Flag) {
    42  
    43  		if len(item.Name) == 1 {
    44  			fmt.Fprint(output, "    -")
    45  		} else {
    46  			fmt.Fprint(output, "    --")
    47  		}
    48  
    49  		if item.DefValue == "false" {
    50  			fmt.Fprintln(output, item.Name)
    51  		} else if item.DefValue == "true" {
    52  			fmt.Fprintln(output, item.Name+"=false")
    53  		} else {
    54  			fmt.Fprintln(output, item.Name, "...")
    55  		}
    56  
    57  		fmt.Fprintln(output, "       ", item.Usage)
    58  	}
    59  
    60  	fmt.Fprintln(output, "Options:")
    61  	flags.VisitAll(handler)
    62  
    63  	fmt.Fprintln(output, "    --help, -h")
    64  	fmt.Fprintln(output, "        Print this message and exit gracefully.")
    65  
    66  	_, err := fmt.Fprintln(output)
    67  	return err
    68  }
    69  
    70  // WriteUsage generates the part of a CLI executable's `--help` message that
    71  // provides a brief overview of the invocation scheme, based on the given name
    72  // and examples.
    73  func WriteUsage(output io.Writer, name string, examples ...string) error {
    74  
    75  	fmt.Fprintln(output, "Usage: ", name, examples[0])
    76  
    77  	for _, item := range examples[1:] {
    78  		fmt.Fprintln(output, "       ", name, item)
    79  	}
    80  
    81  	_, err := fmt.Fprintln(output)
    82  	return err
    83  }
    84  
    85  // Option implements the flag.Value interface based on the signature of
    86  // method Set. In combination with method FlagSet.Var or function flag.Var,
    87  // it allows for defining custom flags by decorating closures, lexical mutators
    88  // and the like. Refer to https://golang.org/pkg/flag/ for more information.
    89  type (
    90  	Option func(value string) error
    91  )
    92  
    93  // Set invokes the underlying function, passing through the given string
    94  // and returned error value. Invocation on a nil pointer is not an error.
    95  func (flag Option) Set(value string) (err error) {
    96  
    97  	if flag != nil {
    98  		err = flag(value)
    99  	}
   100  
   101  	return err
   102  }
   103  
   104  // String always returns "...".
   105  func (flag Option) String() string {
   106  
   107  	return "..."
   108  }