Blame SOURCES/golist-bootstrap-cli-no-vendor.patch

92f5a5
diff --git a/cmd/golist/golist.go b/cmd/golist/golist.go
92f5a5
index ee028ae..e9c038d 100644
92f5a5
--- a/cmd/golist/golist.go
92f5a5
+++ b/cmd/golist/golist.go
92f5a5
@@ -11,9 +11,8 @@ import (
92f5a5
 	"strings"
92f5a5
 	"text/template"
92f5a5
 
92f5a5
-	"github.com/urfave/cli"
92f5a5
-
92f5a5
 	"pagure.io/golist/pkg/util"
92f5a5
+	"pagure.io/golist/pkg/cli"
92f5a5
 )
92f5a5
 
92f5a5
 var (
92f5a5
@@ -100,7 +99,6 @@ func main() {
92f5a5
 	}
92f5a5
 
92f5a5
 	app.Action = func(c *cli.Context) error {
92f5a5
-
92f5a5
 		if len(c.StringSlice("package-path")) == 0 {
92f5a5
 			return fmt.Errorf("--package-path is not set")
92f5a5
 		}
92f5a5
diff --git a/pkg/cli/cli.go b/pkg/cli/cli.go
92f5a5
new file mode 100644
92f5a5
index 0000000..ec91056
92f5a5
--- /dev/null
92f5a5
+++ b/pkg/cli/cli.go
92f5a5
@@ -0,0 +1,293 @@
92f5a5
+package cli
92f5a5
+
92f5a5
+/* golist uses a very small portion of functionality
92f5a5
+   from github.com/urfave/cli. This module provides
92f5a5
+   minimal substitute API implementations for only the
92f5a5
+   core functionality used by golist, for the purpose of
92f5a5
+   bootstrapping golist without additional dependencies.
92f5a5
+*/
92f5a5
+
92f5a5
+import (
92f5a5
+	"strings"
92f5a5
+	"fmt"
92f5a5
+	"os"
92f5a5
+)
92f5a5
+
92f5a5
+type String string
92f5a5
+type StringSlice []string
92f5a5
+type Bool bool
92f5a5
+
92f5a5
+type Flag interface {
92f5a5
+	name() string
92f5a5
+	usage() string
92f5a5
+}
92f5a5
+
92f5a5
+type BoolFlag struct {
92f5a5
+	Name string
92f5a5
+	Usage string
92f5a5
+	Value bool
92f5a5
+}
92f5a5
+
92f5a5
+type StringFlag struct {
92f5a5
+	Name string
92f5a5
+	Usage string
92f5a5
+	Value string
92f5a5
+}
92f5a5
+
92f5a5
+type StringSliceFlag struct {
92f5a5
+	Name string
92f5a5
+	Usage string
92f5a5
+	Value *StringSlice
92f5a5
+}
92f5a5
+
92f5a5
+type App struct {
92f5a5
+	Name string
92f5a5
+	Usage string
92f5a5
+	Version string
92f5a5
+	Flags []Flag
92f5a5
+	Action func(*Context) error
92f5a5
+
92f5a5
+}
92f5a5
+
92f5a5
+func NewApp() App {
92f5a5
+	var a App
92f5a5
+	return a
92f5a5
+}
92f5a5
+
92f5a5
+func (a *App) Run(osArgs []string) error {
92f5a5
+	c, err := newContext(a.Flags, osArgs)
92f5a5
+	if err != nil {
92f5a5
+		return err
92f5a5
+	}
92f5a5
+	if c.Bool("help") {
92f5a5
+		a.PrintHelp()
92f5a5
+		os.Exit(0)
92f5a5
+	}
92f5a5
+	return a.Action(c)
92f5a5
+}
92f5a5
+
92f5a5
+func (a *App) PrintHelp() {
92f5a5
+	maxNameLen := 0
92f5a5
+	for _, flag := range a.Flags {
92f5a5
+		length := len(flag.name())
92f5a5
+		if length > maxNameLen {
92f5a5
+			maxNameLen = length
92f5a5
+		}
92f5a5
+	}
92f5a5
+	fmtSpec := "%-" + fmt.Sprintf("%v", maxNameLen + 6) + "s\t%s\n"
92f5a5
+	fmt.Printf("%s - %s\n", a.Name, a.Usage)
92f5a5
+	fmt.Printf("Options:\n")
92f5a5
+	for _, flag := range a.Flags {
92f5a5
+		flagNameSlice := append([]string{canonicalName(flag)}, alternateNames(flag)...)
92f5a5
+		for i, _ := range flagNameSlice {
92f5a5
+			if len(flagNameSlice[i]) > 1 {
92f5a5
+				flagNameSlice[i] = fmt.Sprintf("--%s", flagNameSlice[i])
92f5a5
+			} else {
92f5a5
+				flagNameSlice[i] = fmt.Sprintf("-%s", flagNameSlice[i])
92f5a5
+			}
92f5a5
+		}
92f5a5
+		flagNameStr := strings.Join(flagNameSlice, ", ")
92f5a5
+		switch flag.(type) {
92f5a5
+			case StringFlag:
92f5a5
+				flagNameStr = fmt.Sprintf("  %s value", flagNameStr)
92f5a5
+			case StringSliceFlag:
92f5a5
+				flagNameStr = fmt.Sprintf("  %s value", flagNameStr)
92f5a5
+			case BoolFlag:
92f5a5
+				flagNameStr = fmt.Sprintf("  %s", flagNameStr)
92f5a5
+		}
92f5a5
+		fmt.Printf(fmtSpec, flagNameStr, flag.usage())
92f5a5
+	}
92f5a5
+}
92f5a5
+
92f5a5
+
92f5a5
+type Context struct {
92f5a5
+	flagValues map[string]interface{}
92f5a5
+	flagDecls map[string]Flag
92f5a5
+	altFlags map[string]string
92f5a5
+	positionalArgs []string
92f5a5
+}
92f5a5
+
92f5a5
+func (c *Context) Bool(flag string) bool {
92f5a5
+	iface, ok := c.flagDecls[flag]
92f5a5
+	if !ok {
92f5a5
+		panic("undefined flag" + flag)
92f5a5
+	}
92f5a5
+	switch iface.(type) {
92f5a5
+		case BoolFlag:
92f5a5
+			break
92f5a5
+		default:
92f5a5
+			panic("flag type mismatch - expected BoolFlag, got: " + flag)
92f5a5
+	}
92f5a5
+	val, ok := c.flagValues[flag]
92f5a5
+	if !ok {
92f5a5
+		return iface.(BoolFlag).Value
92f5a5
+	}
92f5a5
+	return val.(bool)
92f5a5
+}
92f5a5
+
92f5a5
+func (c *Context) String(flag string) string {
92f5a5
+	iface, ok := c.flagDecls[flag]
92f5a5
+	if !ok {
92f5a5
+		panic("undefined flag" + flag)
92f5a5
+	}
92f5a5
+	switch iface.(type) {
92f5a5
+		case StringFlag:
92f5a5
+			break
92f5a5
+		default:
92f5a5
+			panic("flag type mismatch - expected StringFlag, got: " + flag)
92f5a5
+	}
92f5a5
+	val, ok:= c.flagValues[flag]
92f5a5
+	if !ok {
92f5a5
+		return iface.(StringFlag).Value
92f5a5
+	}
92f5a5
+	return val.(string)
92f5a5
+}
92f5a5
+
92f5a5
+func (c *Context) StringSlice(flag string) []string {
92f5a5
+	iface, ok := c.flagDecls[flag];
92f5a5
+	if !ok {
92f5a5
+		panic("undefined flag" + flag)
92f5a5
+	}
92f5a5
+	switch iface.(type) {
92f5a5
+		case StringSliceFlag:
92f5a5
+			break
92f5a5
+		default:
92f5a5
+			panic("flag type mismatch - expected StringSliceFlag, got: " + flag)
92f5a5
+	}
92f5a5
+	val, ok := c.flagValues[flag]
92f5a5
+	if !ok {
92f5a5
+		val = iface.(StringSliceFlag).Value
92f5a5
+		if val != nil {
92f5a5
+			return []string{}
92f5a5
+		}
92f5a5
+	}
92f5a5
+	return val.([]string)
92f5a5
+}
92f5a5
+
92f5a5
+// Create a hash mapping from flag names to declarations
92f5a5
+// and alt names to flag names.
92f5a5
+func (c *Context) setupFlags(flagDecls []Flag) error {
92f5a5
+	helpFlag := BoolFlag {
92f5a5
+		Name: "help, h",
92f5a5
+		Usage: "Show help message",
92f5a5
+	}
92f5a5
+	flagDecls = append(flagDecls, helpFlag)
92f5a5
+	for _, flag := range flagDecls {
92f5a5
+		flagName := canonicalName(flag)
92f5a5
+		if _, ok:= c.flagDecls[flagName]; ok {
92f5a5
+			return fmt.Errorf("cannot redeclare flag: %s", flagName)
92f5a5
+		}
92f5a5
+		c.flagDecls[flagName] = flag
92f5a5
+		altFlagNames := alternateNames(flag)
92f5a5
+		for _, altName := range altFlagNames {
92f5a5
+			c.altFlags[altName] = flagName
92f5a5
+		}
92f5a5
+	}
92f5a5
+	return nil
92f5a5
+}
92f5a5
+
92f5a5
+func (c *Context) parseArgs(osArgs []string) error {
92f5a5
+	// process command line arguments as a stream of tokens.
92f5a5
+	// operations consume the first token in the stream until
92f5a5
+	// the stream is empty.
92f5a5
+	argStream := osArgs
92f5a5
+	for len(argStream) > 0 {
92f5a5
+		arg := argStream[0]
92f5a5
+		if ! isFlag(arg) {
92f5a5
+			argStream = argStream[1:]
92f5a5
+			c.positionalArgs = append(c.positionalArgs, arg)
92f5a5
+
92f5a5
+		} else {
92f5a5
+			arg = trimFlag(arg)
92f5a5
+			if _, ok:= c.altFlags[arg]; ok {
92f5a5
+				arg = c.altFlags[arg]
92f5a5
+			}
92f5a5
+			iface, ok := c.flagDecls[arg]
92f5a5
+			if !ok {
92f5a5
+				return fmt.Errorf("unexpected argument: %v", arg)
92f5a5
+			}
92f5a5
+			switch flag := iface.(type) {
92f5a5
+				case StringFlag:
92f5a5
+					argStream = argStream[1:]
92f5a5
+					if len(argStream) == 0 {
92f5a5
+						return fmt.Errorf("expected value for argument: %v", arg)
92f5a5
+					}
92f5a5
+					if isFlag(argStream[0]) {
92f5a5
+						return fmt.Errorf("unexpected flag: %v", arg)
92f5a5
+					}
92f5a5
+					c.flagValues[arg] = argStream[0]
92f5a5
+				case StringSliceFlag:
92f5a5
+					argStream = argStream[1:]
92f5a5
+					if len (argStream) == 0 {
92f5a5
+						return fmt.Errorf("expected value for argument: %v", arg)
92f5a5
+					}
92f5a5
+					if isFlag(argStream[0]) {
92f5a5
+						return fmt.Errorf("unexpected flag: %v", arg)
92f5a5
+					}
92f5a5
+					c.flagValues[arg] = make([]string, 0)
92f5a5
+					c.flagValues[arg] = append(c.flagValues[arg].([]string), argStream[0])
92f5a5
+					argStream = argStream[1:]
92f5a5
+					for len(argStream) > 0 && ! isFlag(argStream[0]) {
92f5a5
+						c.flagValues[arg] = append(c.flagValues[arg].([]string), argStream[0])
92f5a5
+						argStream = argStream[1:]
92f5a5
+					}
92f5a5
+				case BoolFlag:
92f5a5
+					argStream = argStream[1:]
92f5a5
+					c.flagValues[canonicalName(flag)] = true
92f5a5
+				default:
92f5a5
+					return fmt.Errorf("unexpected flag: %v", arg)
92f5a5
+			}
92f5a5
+		}
92f5a5
+	}
92f5a5
+	return nil
92f5a5
+}
92f5a5
+
92f5a5
+func newContext(flags []Flag, osArgs []string) (*Context, error) {
92f5a5
+	var c Context
92f5a5
+	c.flagValues = make(map[string]interface{})
92f5a5
+	c.flagDecls = make(map[string]Flag)
92f5a5
+	c.altFlags = make(map[string]string)
92f5a5
+	c.altFlags = make(map[string]string)
92f5a5
+	if err := c.setupFlags(flags); err != nil {
92f5a5
+		return nil, err
92f5a5
+	}
92f5a5
+	if err := c.parseArgs(osArgs); err != nil {
92f5a5
+		return nil, err
92f5a5
+	}
92f5a5
+	return &c, nil
92f5a5
+}
92f5a5
+
92f5a5
+func (f StringFlag) name() string {return f.Name}
92f5a5
+func (f StringFlag) usage() string {return f.Usage}
92f5a5
+func (f BoolFlag) name() string {return f.Name}
92f5a5
+func (f BoolFlag) usage() string {return f.Usage}
92f5a5
+func (f StringSliceFlag) name() string {return f.Name}
92f5a5
+func (f StringSliceFlag) usage() string {return f.Usage}
92f5a5
+
92f5a5
+// takes a Flag with a comma delimited string
92f5a5
+// of flag names and returns the first one
92f5a5
+func canonicalName(flag Flag) string {
92f5a5
+	flagNames := strings.Split(flag.name(), ",")
92f5a5
+	return strings.TrimSpace(flagNames[0])
92f5a5
+}
92f5a5
+
92f5a5
+// takes a Flag with a comma delimited string
92f5a5
+// of flag names and returns them as a string slice
92f5a5
+// with the canonical (first) flag ommitted
92f5a5
+func alternateNames(flag Flag) []string {
92f5a5
+	flagNames := strings.Split(flag.name(), ",")
92f5a5
+	altNames := flagNames[1:]
92f5a5
+	for i, _ := range altNames {
92f5a5
+		altNames[i] = strings.TrimSpace(altNames[i])
92f5a5
+	}
92f5a5
+	return altNames
92f5a5
+}
92f5a5
+
92f5a5
+func isFlag(arg string) bool {
92f5a5
+  return strings.HasPrefix(arg, "-")
92f5a5
+}
92f5a5
+
92f5a5
+func trimFlag(arg string) string {
92f5a5
+  return strings.Trim(strings.Trim(arg, "-"), "-")
92f5a5
+}
92f5a5
+