1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-07-31 14:24:25 +03:00

update dependencies

This commit is contained in:
Dawid Dziurla
2019-12-13 11:29:12 +01:00
parent 3074ae99ea
commit be8f589c32
185 changed files with 45125 additions and 44833 deletions

View File

@ -12,3 +12,5 @@
# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736
.glide/
.idea/

View File

@ -172,41 +172,57 @@ Other more specific types can also be used as flag types. They will be automati
- time.Duration
- []time.Duration
# Recommended Program Structure
# An Example Program
Best practice when using flaggy includes setting your program's name, description, and version (at build time).
Best practice when using flaggy includes setting your program's name, description, and version (at build time) as shown in this example program.
```go
package main
import "github.com/integrii/flaggy"
// make a variable for the version which will be set at build time
// Make a variable for the version which will be set at build time.
var version = "unknown"
// keep subcommands as globals so you can easily check if they were used later on
// Keep subcommands as globals so you can easily check if they were used later on.
var mySubcommand *flaggy.Subcommand
// Setup the variables you want your incoming flags to set.
var testVar string
// If you would like an environment variable as the default for a value, just populate the flag
// with the value of the environment by default. If the flag corresponding to this value is not
// used, then it will not be changed.
var myVar = os.Getenv("MY_VAR")
func init() {
// Set your program's name and description. These appear in help output.
flaggy.SetName("Test Program")
flaggy.SetDescription("A little example program")
// you can disable various things by changing bools on the default parser
// (or your own parser if you have created one)
// You can disable various things by changing bools on the default parser
// (or your own parser if you have created one).
flaggy.DefaultParser.ShowHelpOnUnexpected = false
// you can set a help prepend or append on the default parser
// You can set a help prepend or append on the default parser.
flaggy.DefaultParser.AdditionalHelpPrepend = "http://github.com/integrii/flaggy"
// Add a flag to the main program (this will be available in all subcommands as well).
flaggy.String(&testVar, "tv", "testVariable", "A variable just for testing things!")
// create any subcommands and set their parameters
// Create any subcommands and set their parameters.
mySubcommand = flaggy.NewSubcommand("mySubcommand")
mySubcommand.Description = "My great subcommand!"
// Add a flag to the subcommand.
mySubcommand.String(&myVar, "mv", "myVariable", "A variable just for me!")
// set the version and parse all inputs into variables
// Set the version and parse all inputs into variables.
flaggy.SetVersion(version)
flaggy.Parse()
}
func main(){
if mySubcommand.Used {
...

View File

@ -5,22 +5,20 @@ package flaggy
// The return values represent the key being set, and any errors
// returned when setting the key, such as failures to convert the string
// into the appropriate flag value. We stop assigning values as soon
// as we find a parser that accepts it.
// as we find a any parser that accepts it.
func setValueForParsers(key string, value string, parsers ...ArgumentParser) (bool, error) {
var valueWasSet bool
for _, p := range parsers {
valueWasSet, err := p.SetValueForKey(key, value)
if err != nil {
return valueWasSet, err
}
if valueWasSet {
break
return true, nil
}
}
return valueWasSet, nil
return false, nil
}
// ArgumentParser represents a parser or subcommand

View File

@ -327,6 +327,18 @@ func exitOrPanic(code int) {
os.Exit(code)
}
// ShowHelpOnUnexpectedEnable enables the ShowHelpOnUnexpected behavior on the
// default parser. This causes unknown inputs to error out.
func ShowHelpOnUnexpectedEnable() {
DefaultParser.ShowHelpOnUnexpected = true
}
// ShowHelpOnUnexpectedDisable disables the ShowHelpOnUnexpected behavior on the
// default parser. This causes unknown inputs to error out.
func ShowHelpOnUnexpectedDisable() {
DefaultParser.ShowHelpOnUnexpected = false
}
// AddPositionalValue adds a positional value to the main parser at the global
// context
func AddPositionalValue(assignmentVar *string, name string, relativePosition int, required bool, description string) {

23
vendor/github.com/integrii/flaggy/parsedValue.go generated vendored Normal file
View File

@ -0,0 +1,23 @@
package flaggy
// parsedValue represents a flag or subcommand that was parsed. Primairily used
// to account for all parsed values in order to determine if unknown values were
// passed to the root parser after all subcommands have been parsed.
type parsedValue struct {
Key string
Value string
IsPositional bool // indicates that this value was positional and not a key/value
}
// newParsedValue creates and returns a new parsedValue struct with the
// supplied values set
func newParsedValue(key string, value string, isPositional bool) parsedValue {
if len(key) == 0 && len(value) == 0 {
panic("cant add parsed value with no key or value")
}
return parsedValue{
Key: key,
Value: value,
IsPositional: isPositional,
}
}

View File

@ -4,18 +4,20 @@ import (
"errors"
"fmt"
"os"
"strconv"
"text/template"
)
// Parser represents the set of vars and subcommands we are expecting
// from our input args, and the parser than handles them all.
// Parser represents the set of flags and subcommands we are expecting
// from our input arguments. Parser is the top level struct responsible for
// parsing an entire set of subcommands and flags.
type Parser struct {
Subcommand
Version string // the optional version of the parser.
ShowHelpWithHFlag bool // display help when -h or --help passed
ShowVersionWithVersionFlag bool // display the version when --version passed
ShowHelpOnUnexpected bool // display help when an unexpected flag is passed
ShowHelpOnUnexpected bool // display help when an unexpected flag or subcommand is passed
TrailingArguments []string // everything after a -- is placed here
HelpTemplate *template.Template // template for Help output
trailingArgumentsExtracted bool // indicates that trailing args have been parsed and should not be appended again
@ -46,8 +48,89 @@ func (p *Parser) ParseArgs(args []string) error {
return errors.New("Parser.Parse() called twice on parser with name: " + " " + p.Name + " " + p.ShortName)
}
p.parsed = true
// debugPrint("Kicking off parsing with args:", args)
return p.parse(p, args, 0)
debugPrint("Kicking off parsing with args:", args)
err := p.parse(p, args, 0)
if err != nil {
return err
}
// if we are set to crash on unexpected args, look for those here TODO
if p.ShowHelpOnUnexpected {
parsedValues := p.findAllParsedValues()
debugPrint("parsedValues:", parsedValues)
argsNotParsed := findArgsNotInParsedValues(args, parsedValues)
if len(argsNotParsed) > 0 {
// flatten out unused args for our error message
var argsNotParsedFlat string
for _, a := range argsNotParsed {
argsNotParsedFlat = argsNotParsedFlat + " " + a
}
p.ShowHelpAndExit("Unknown arguments supplied: " + argsNotParsedFlat)
}
}
return nil
}
// findArgsNotInParsedValues finds arguments not used in parsed values. The
// incoming args should be in the order supplied by the user and should not
// include the invoked binary, which is normally the first thing in os.Args.
func findArgsNotInParsedValues(args []string, parsedValues []parsedValue) []string {
var argsNotUsed []string
var skipNext bool
for _, a := range args {
// if the final argument (--) is seen, then we stop checking because all
// further values are trailing arguments.
if determineArgType(a) == argIsFinal {
return argsNotUsed
}
// allow for skipping the next arg when needed
if skipNext {
skipNext = false
continue
}
// strip flag slashes from incoming arguments so they match up with the
// keys from parsedValues.
arg := parseFlagToName(a)
// indicates that we found this arg used in one of the parsed values. Used
// to indicate which values should be added to argsNotUsed.
var foundArgUsed bool
// search all args for a corresponding parsed value
for _, pv := range parsedValues {
// this argumenet was a key
// debugPrint(pv.Key, "==", arg)
debugPrint(pv.Key + "==" + arg + " || (" + strconv.FormatBool(pv.IsPositional) + " && " + pv.Value + " == " + arg + ")")
if pv.Key == arg || (pv.IsPositional && pv.Value == arg) {
debugPrint("Found matching parsed arg for " + pv.Key)
foundArgUsed = true // the arg was used in this parsedValues set
// if the value is not a positional value and the parsed value had a
// value that was not blank, we skip the next value in the argument list
if !pv.IsPositional && len(pv.Value) > 0 {
skipNext = true
break
}
}
// this prevents excessive parsed values from being checked after we find
// the arg used for the first time
if foundArgUsed {
break
}
}
// if the arg was not used in any parsed values, then we add it to the slice
// of arguments not used
if !foundArgUsed {
argsNotUsed = append(argsNotUsed, arg)
}
}
return argsNotUsed
}
// ShowVersionAndExit shows the version of this parser
@ -105,7 +188,8 @@ func (p *Parser) ShowHelpWithMessage(message string) {
}
}
// Disable show version with --version. It is enabled by default.
// DisableShowVersionWithVersion disables the showing of version information
// with --version. It is enabled by default.
func (p *Parser) DisableShowVersionWithVersion() {
p.ShowVersionWithVersionFlag = false
}

View File

@ -23,15 +23,20 @@ type Subcommand struct {
Subcommands []*Subcommand
Flags []*Flag
PositionalFlags []*PositionalValue
AdditionalHelpPrepend string // additional prepended message when Help is displayed
AdditionalHelpAppend string // additional appended message when Help is displayed
Used bool // indicates this subcommand was found and parsed
Hidden bool // indicates this subcommand should be hidden from help
ParsedValues []parsedValue // a list of values and positionals parsed
AdditionalHelpPrepend string // additional prepended message when Help is displayed
AdditionalHelpAppend string // additional appended message when Help is displayed
Used bool // indicates this subcommand was found and parsed
Hidden bool // indicates this subcommand should be hidden from help
}
// NewSubcommand creates a new subcommand that can have flags or PositionalFlags
// added to it. The position starts with 1, not 0
func NewSubcommand(name string) *Subcommand {
if len(name) == 0 {
fmt.Fprintln(os.Stderr, "Error creating subcommand (NewSubcommand()). No subcommand name was specified.")
exitOrPanic(2)
}
newSC := &Subcommand{
Name: name,
}
@ -39,10 +44,11 @@ func NewSubcommand(name string) *Subcommand {
}
// parseAllFlagsFromArgs parses the non-positional flags such as -f or -v=value
// out of the supplied args and returns the positional items in order.
// out of the supplied args and returns the resulting positional items in order,
// all the flag names found (without values), a bool to indicate if help was
// requested, and any errors found during parsing
func (sc *Subcommand) parseAllFlagsFromArgs(p *Parser, args []string) ([]string, bool, error) {
var err error
var positionalOnlyArguments []string
var helpRequested bool // indicates the user has supplied -h and we
// should render help if we are the last subcommand
@ -58,7 +64,7 @@ func (sc *Subcommand) parseAllFlagsFromArgs(p *Parser, args []string) ([]string,
// find all the normal flags (not positional) and parse them out
for i, a := range args {
debugPrint("parsing arg", 1, a)
debugPrint("parsing arg:", a)
// evaluate if there is a following arg to avoid panics
var nextArgExists bool
@ -121,62 +127,107 @@ func (sc *Subcommand) parseAllFlagsFromArgs(p *Parser, args []string) ([]string,
// this positional argument into a slice of their own, so that
// we can determine if its a subcommand or positional value later
positionalOnlyArguments = append(positionalOnlyArguments, a)
case argIsFlagWithSpace:
// track this as a parsed value with the subcommand
sc.addParsedPositionalValue(a)
case argIsFlagWithSpace: // a flag with a space. ex) -k v or --key value
a = parseFlagToName(a)
// debugPrint("Arg", i, "is flag with space:", a)
// parse next arg as value to this flag and apply to subcommand flags
// if the flag is a bool flag, then we check for a following positional
// and skip it if necessary
if flagIsBool(sc, p, a) {
debugPrint(sc.Name, "bool flag", a, "next var is:", nextArg)
_, err = setValueForParsers(a, "true", p, sc)
// set the value in this subcommand and its root parser
valueSet, err := setValueForParsers(a, "true", p, sc)
// if an error occurs, just return it and quit parsing
if err != nil {
return []string{}, false, err
}
// by default, we just assign the next argument to the value and continue
// log all values parsed by this subcommand. We leave the value blank
// because the bool value had no explicit true or false supplied
if valueSet {
sc.addParsedFlag(a, "")
}
// we've found and set a standalone bool flag, so we move on to the next
// argument in the list of arguments
continue
}
skipNext = true
debugPrint(sc.Name, "NOT bool flag", a)
// debugPrint(sc.Name, "NOT bool flag", a)
// if the next arg was not found, then show a Help message
if !nextArgExists {
p.ShowHelpWithMessage("Expected a following arg for flag " + a + ", but it did not exist.")
exitOrPanic(2)
}
_, err = setValueForParsers(a, nextArg, p, sc)
valueSet, err := setValueForParsers(a, nextArg, p, sc)
if err != nil {
return []string{}, false, err
}
case argIsFlagWithValue:
// log all parsed values in the subcommand
if valueSet {
sc.addParsedFlag(a, nextArg)
}
case argIsFlagWithValue: // a flag with an equals sign. ex) -k=v or --key=value
// debugPrint("Arg", i, "is flag with value:", a)
a = parseFlagToName(a)
// parse flag into key and value and apply to subcommand flags
key, val := parseArgWithValue(a)
_, err = setValueForParsers(key, val, p, sc)
// set the value in this subcommand and its root parser
valueSet, err := setValueForParsers(key, val, p, sc)
if err != nil {
return []string{}, false, err
}
// if this flag type was found and not set, and the parser is set to show
// Help when an unknown flag is found, then show Help and exit.
}
// log all values parsed by the subcommand
if valueSet {
sc.addParsedFlag(a, val)
}
}
}
return positionalOnlyArguments, helpRequested, nil
}
// Parse causes the argument parser to parse based on the supplied []string.
// depth specifies the non-flag subcommand positional depth
// findAllParsedValues finds all values parsed by all subcommands and this
// subcommand and its child subcommands
func (sc *Subcommand) findAllParsedValues() []parsedValue {
parsedValues := sc.ParsedValues
for _, sc := range sc.Subcommands {
// skip unused subcommands
if !sc.Used {
continue
}
parsedValues = append(parsedValues, sc.findAllParsedValues()...)
}
return parsedValues
}
// parse causes the argument parser to parse based on the supplied []string.
// depth specifies the non-flag subcommand positional depth. A slice of flags
// and subcommands parsed is returned so that the parser can ultimately decide
// if there were any unexpected values supplied by the user
func (sc *Subcommand) parse(p *Parser, args []string, depth int) error {
debugPrint("- Parsing subcommand", sc.Name, "with depth of", depth, "and args", args)
// if a command is parsed, its used
sc.Used = true
debugPrint("used subcommand", sc.Name, sc.ShortName)
if len(sc.Name) > 0 {
sc.addParsedPositionalValue(sc.Name)
}
if len(sc.ShortName) > 0 {
sc.addParsedPositionalValue(sc.ShortName)
}
// as subcommands are used, they become the context of the parser. This helps
// us understand how to display help based on which subcommand is being used
@ -191,9 +242,10 @@ func (sc *Subcommand) parse(p *Parser, args []string, depth int) error {
sc.ensureNoConflictWithBuiltinVersion()
}
// Parse the normal flags out of the argument list and retain the positionals.
// Apply the flags to the parent parser and the current subcommand context.
// ./command -f -z subcommand someVar -b becomes ./command subcommand somevar
// Parse the normal flags out of the argument list and return the positionals
// (subcommands and positional values), along with the flags used.
// Then the flag values are applied to the parent parser and the current
// subcommand being parsed.
positionalOnlyArguments, helpRequested, err := sc.parseAllFlagsFromArgs(p, args)
if err != nil {
return err
@ -292,7 +344,7 @@ func (sc *Subcommand) parse(p *Parser, args []string, depth int) error {
}
// find any positionals that were not used on subcommands that were
// found and throw help (unknown argument)
// found and throw help (unknown argument) in the global parse or subcommand
for _, pv := range p.PositionalFlags {
if pv.Required && !pv.Found {
p.ShowHelpWithMessage("Required global positional variable " + pv.Name + " not found at position " + strconv.Itoa(pv.Position))
@ -309,6 +361,17 @@ func (sc *Subcommand) parse(p *Parser, args []string, depth int) error {
return nil
}
// addParsedFlag makes it easy to append flag values parsed by the subcommand
func (sc *Subcommand) addParsedFlag(key string, value string) {
sc.ParsedValues = append(sc.ParsedValues, newParsedValue(key, value, false))
}
// addParsedPositionalValue makes it easy to append positionals parsed by the
// subcommand
func (sc *Subcommand) addParsedPositionalValue(value string) {
sc.ParsedValues = append(sc.ParsedValues, newParsedValue("", value, true))
}
// FlagExists lets you know if the flag name exists as either a short or long
// name in the (sub)command
func (sc *Subcommand) FlagExists(name string) bool {