forked from cerc-io/plugeth
289b30715d
This commit converts the dependency management from Godeps to the vendor folder, also switching the tool from godep to trash. Since the upstream tool lacks a few features proposed via a few PRs, until those PRs are merged in (if), use github.com/karalabe/trash. You can update dependencies via trash --update. All dependencies have been updated to their latest version. Parts of the build system are reworked to drop old notions of Godeps and invocation of the go vet command so that it doesn't run against the vendor folder, as that will just blow up during vetting. The conversion drops OpenCL (and hence GPU mining support) from ethash and our codebase. The short reasoning is that there's noone to maintain and having opencl libs in our deps messes up builds as go install ./... tries to build them, failing with unsatisfied link errors for the C OpenCL deps. golang.org/x/net/context is not vendored in. We expect it to be fetched by the user (i.e. using go get). To keep ci.go builds reproducible the package is "vendored" in build/_vendor.
550 lines
13 KiB
Go
550 lines
13 KiB
Go
package cli
|
|
|
|
import (
|
|
"errors"
|
|
"flag"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
// Context is a type that is passed through to
|
|
// each Handler action in a cli application. Context
|
|
// can be used to retrieve context-specific Args and
|
|
// parsed command-line options.
|
|
type Context struct {
|
|
App *App
|
|
Command Command
|
|
flagSet *flag.FlagSet
|
|
setFlags map[string]bool
|
|
globalSetFlags map[string]bool
|
|
parentContext *Context
|
|
}
|
|
|
|
// NewContext creates a new context. For use in when invoking an App or Command action.
|
|
func NewContext(app *App, set *flag.FlagSet, parentCtx *Context) *Context {
|
|
return &Context{App: app, flagSet: set, parentContext: parentCtx}
|
|
}
|
|
|
|
// Int looks up the value of a local int flag, returns 0 if no int flag exists
|
|
func (c *Context) Int(name string) int {
|
|
return lookupInt(name, c.flagSet)
|
|
}
|
|
|
|
// Int64 looks up the value of a local int flag, returns 0 if no int flag exists
|
|
func (c *Context) Int64(name string) int64 {
|
|
return lookupInt64(name, c.flagSet)
|
|
}
|
|
|
|
// Uint looks up the value of a local int flag, returns 0 if no int flag exists
|
|
func (c *Context) Uint(name string) uint {
|
|
return lookupUint(name, c.flagSet)
|
|
}
|
|
|
|
// Uint64 looks up the value of a local int flag, returns 0 if no int flag exists
|
|
func (c *Context) Uint64(name string) uint64 {
|
|
return lookupUint64(name, c.flagSet)
|
|
}
|
|
|
|
// Duration looks up the value of a local time.Duration flag, returns 0 if no
|
|
// time.Duration flag exists
|
|
func (c *Context) Duration(name string) time.Duration {
|
|
return lookupDuration(name, c.flagSet)
|
|
}
|
|
|
|
// Float64 looks up the value of a local float64 flag, returns 0 if no float64
|
|
// flag exists
|
|
func (c *Context) Float64(name string) float64 {
|
|
return lookupFloat64(name, c.flagSet)
|
|
}
|
|
|
|
// Bool looks up the value of a local bool flag, returns false if no bool flag exists
|
|
func (c *Context) Bool(name string) bool {
|
|
return lookupBool(name, c.flagSet)
|
|
}
|
|
|
|
// BoolT looks up the value of a local boolT flag, returns false if no bool flag exists
|
|
func (c *Context) BoolT(name string) bool {
|
|
return lookupBoolT(name, c.flagSet)
|
|
}
|
|
|
|
// String looks up the value of a local string flag, returns "" if no string flag exists
|
|
func (c *Context) String(name string) string {
|
|
return lookupString(name, c.flagSet)
|
|
}
|
|
|
|
// StringSlice looks up the value of a local string slice flag, returns nil if no
|
|
// string slice flag exists
|
|
func (c *Context) StringSlice(name string) []string {
|
|
return lookupStringSlice(name, c.flagSet)
|
|
}
|
|
|
|
// IntSlice looks up the value of a local int slice flag, returns nil if no int
|
|
// slice flag exists
|
|
func (c *Context) IntSlice(name string) []int {
|
|
return lookupIntSlice(name, c.flagSet)
|
|
}
|
|
|
|
// Int64Slice looks up the value of a local int slice flag, returns nil if no int
|
|
// slice flag exists
|
|
func (c *Context) Int64Slice(name string) []int64 {
|
|
return lookupInt64Slice(name, c.flagSet)
|
|
}
|
|
|
|
// Generic looks up the value of a local generic flag, returns nil if no generic
|
|
// flag exists
|
|
func (c *Context) Generic(name string) interface{} {
|
|
return lookupGeneric(name, c.flagSet)
|
|
}
|
|
|
|
// GlobalInt looks up the value of a global int flag, returns 0 if no int flag exists
|
|
func (c *Context) GlobalInt(name string) int {
|
|
if fs := lookupGlobalFlagSet(name, c); fs != nil {
|
|
return lookupInt(name, fs)
|
|
}
|
|
return 0
|
|
}
|
|
|
|
// GlobalInt64 looks up the value of a global int flag, returns 0 if no int flag exists
|
|
func (c *Context) GlobalInt64(name string) int64 {
|
|
if fs := lookupGlobalFlagSet(name, c); fs != nil {
|
|
return lookupInt64(name, fs)
|
|
}
|
|
return 0
|
|
}
|
|
|
|
// GlobalUint looks up the value of a global int flag, returns 0 if no int flag exists
|
|
func (c *Context) GlobalUint(name string) uint {
|
|
if fs := lookupGlobalFlagSet(name, c); fs != nil {
|
|
return lookupUint(name, fs)
|
|
}
|
|
return 0
|
|
}
|
|
|
|
// GlobalUint64 looks up the value of a global int flag, returns 0 if no int flag exists
|
|
func (c *Context) GlobalUint64(name string) uint64 {
|
|
if fs := lookupGlobalFlagSet(name, c); fs != nil {
|
|
return lookupUint64(name, fs)
|
|
}
|
|
return 0
|
|
}
|
|
|
|
// GlobalFloat64 looks up the value of a global float64 flag, returns float64(0)
|
|
// if no float64 flag exists
|
|
func (c *Context) GlobalFloat64(name string) float64 {
|
|
if fs := lookupGlobalFlagSet(name, c); fs != nil {
|
|
return lookupFloat64(name, fs)
|
|
}
|
|
return float64(0)
|
|
}
|
|
|
|
// GlobalDuration looks up the value of a global time.Duration flag, returns 0
|
|
// if no time.Duration flag exists
|
|
func (c *Context) GlobalDuration(name string) time.Duration {
|
|
if fs := lookupGlobalFlagSet(name, c); fs != nil {
|
|
return lookupDuration(name, fs)
|
|
}
|
|
return 0
|
|
}
|
|
|
|
// GlobalBool looks up the value of a global bool flag, returns false if no bool
|
|
// flag exists
|
|
func (c *Context) GlobalBool(name string) bool {
|
|
if fs := lookupGlobalFlagSet(name, c); fs != nil {
|
|
return lookupBool(name, fs)
|
|
}
|
|
return false
|
|
}
|
|
|
|
// GlobalBoolT looks up the value of a global bool flag, returns true if no bool
|
|
// flag exists
|
|
func (c *Context) GlobalBoolT(name string) bool {
|
|
if fs := lookupGlobalFlagSet(name, c); fs != nil {
|
|
return lookupBoolT(name, fs)
|
|
}
|
|
return false
|
|
}
|
|
|
|
// GlobalString looks up the value of a global string flag, returns "" if no
|
|
// string flag exists
|
|
func (c *Context) GlobalString(name string) string {
|
|
if fs := lookupGlobalFlagSet(name, c); fs != nil {
|
|
return lookupString(name, fs)
|
|
}
|
|
return ""
|
|
}
|
|
|
|
// GlobalStringSlice looks up the value of a global string slice flag, returns
|
|
// nil if no string slice flag exists
|
|
func (c *Context) GlobalStringSlice(name string) []string {
|
|
if fs := lookupGlobalFlagSet(name, c); fs != nil {
|
|
return lookupStringSlice(name, fs)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// GlobalIntSlice looks up the value of a global int slice flag, returns nil if
|
|
// no int slice flag exists
|
|
func (c *Context) GlobalIntSlice(name string) []int {
|
|
if fs := lookupGlobalFlagSet(name, c); fs != nil {
|
|
return lookupIntSlice(name, fs)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// GlobalInt64Slice looks up the value of a global int slice flag, returns nil if
|
|
// no int slice flag exists
|
|
func (c *Context) GlobalInt64Slice(name string) []int64 {
|
|
if fs := lookupGlobalFlagSet(name, c); fs != nil {
|
|
return lookupInt64Slice(name, fs)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// GlobalGeneric looks up the value of a global generic flag, returns nil if no
|
|
// generic flag exists
|
|
func (c *Context) GlobalGeneric(name string) interface{} {
|
|
if fs := lookupGlobalFlagSet(name, c); fs != nil {
|
|
return lookupGeneric(name, fs)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// NumFlags returns the number of flags set
|
|
func (c *Context) NumFlags() int {
|
|
return c.flagSet.NFlag()
|
|
}
|
|
|
|
// Set sets a context flag to a value.
|
|
func (c *Context) Set(name, value string) error {
|
|
return c.flagSet.Set(name, value)
|
|
}
|
|
|
|
// GlobalSet sets a context flag to a value on the global flagset
|
|
func (c *Context) GlobalSet(name, value string) error {
|
|
return globalContext(c).flagSet.Set(name, value)
|
|
}
|
|
|
|
// IsSet determines if the flag was actually set
|
|
func (c *Context) IsSet(name string) bool {
|
|
if c.setFlags == nil {
|
|
c.setFlags = make(map[string]bool)
|
|
c.flagSet.Visit(func(f *flag.Flag) {
|
|
c.setFlags[f.Name] = true
|
|
})
|
|
}
|
|
return c.setFlags[name] == true
|
|
}
|
|
|
|
// GlobalIsSet determines if the global flag was actually set
|
|
func (c *Context) GlobalIsSet(name string) bool {
|
|
if c.globalSetFlags == nil {
|
|
c.globalSetFlags = make(map[string]bool)
|
|
ctx := c
|
|
if ctx.parentContext != nil {
|
|
ctx = ctx.parentContext
|
|
}
|
|
for ; ctx != nil && c.globalSetFlags[name] == false; ctx = ctx.parentContext {
|
|
ctx.flagSet.Visit(func(f *flag.Flag) {
|
|
c.globalSetFlags[f.Name] = true
|
|
})
|
|
}
|
|
}
|
|
return c.globalSetFlags[name]
|
|
}
|
|
|
|
// FlagNames returns a slice of flag names used in this context.
|
|
func (c *Context) FlagNames() (names []string) {
|
|
for _, flag := range c.Command.Flags {
|
|
name := strings.Split(flag.GetName(), ",")[0]
|
|
if name == "help" {
|
|
continue
|
|
}
|
|
names = append(names, name)
|
|
}
|
|
return
|
|
}
|
|
|
|
// GlobalFlagNames returns a slice of global flag names used by the app.
|
|
func (c *Context) GlobalFlagNames() (names []string) {
|
|
for _, flag := range c.App.Flags {
|
|
name := strings.Split(flag.GetName(), ",")[0]
|
|
if name == "help" || name == "version" {
|
|
continue
|
|
}
|
|
names = append(names, name)
|
|
}
|
|
return
|
|
}
|
|
|
|
// Parent returns the parent context, if any
|
|
func (c *Context) Parent() *Context {
|
|
return c.parentContext
|
|
}
|
|
|
|
// Args contains apps console arguments
|
|
type Args []string
|
|
|
|
// Args returns the command line arguments associated with the context.
|
|
func (c *Context) Args() Args {
|
|
args := Args(c.flagSet.Args())
|
|
return args
|
|
}
|
|
|
|
// NArg returns the number of the command line arguments.
|
|
func (c *Context) NArg() int {
|
|
return len(c.Args())
|
|
}
|
|
|
|
// Get returns the nth argument, or else a blank string
|
|
func (a Args) Get(n int) string {
|
|
if len(a) > n {
|
|
return a[n]
|
|
}
|
|
return ""
|
|
}
|
|
|
|
// First returns the first argument, or else a blank string
|
|
func (a Args) First() string {
|
|
return a.Get(0)
|
|
}
|
|
|
|
// Tail returns the rest of the arguments (not the first one)
|
|
// or else an empty string slice
|
|
func (a Args) Tail() []string {
|
|
if len(a) >= 2 {
|
|
return []string(a)[1:]
|
|
}
|
|
return []string{}
|
|
}
|
|
|
|
// Present checks if there are any arguments present
|
|
func (a Args) Present() bool {
|
|
return len(a) != 0
|
|
}
|
|
|
|
// Swap swaps arguments at the given indexes
|
|
func (a Args) Swap(from, to int) error {
|
|
if from >= len(a) || to >= len(a) {
|
|
return errors.New("index out of range")
|
|
}
|
|
a[from], a[to] = a[to], a[from]
|
|
return nil
|
|
}
|
|
|
|
func globalContext(ctx *Context) *Context {
|
|
if ctx == nil {
|
|
return nil
|
|
}
|
|
|
|
for {
|
|
if ctx.parentContext == nil {
|
|
return ctx
|
|
}
|
|
ctx = ctx.parentContext
|
|
}
|
|
}
|
|
|
|
func lookupGlobalFlagSet(name string, ctx *Context) *flag.FlagSet {
|
|
if ctx.parentContext != nil {
|
|
ctx = ctx.parentContext
|
|
}
|
|
for ; ctx != nil; ctx = ctx.parentContext {
|
|
if f := ctx.flagSet.Lookup(name); f != nil {
|
|
return ctx.flagSet
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func lookupInt(name string, set *flag.FlagSet) int {
|
|
f := set.Lookup(name)
|
|
if f != nil {
|
|
val, err := strconv.ParseInt(f.Value.String(), 0, 64)
|
|
if err != nil {
|
|
return 0
|
|
}
|
|
return int(val)
|
|
}
|
|
|
|
return 0
|
|
}
|
|
|
|
func lookupInt64(name string, set *flag.FlagSet) int64 {
|
|
f := set.Lookup(name)
|
|
if f != nil {
|
|
val, err := strconv.ParseInt(f.Value.String(), 0, 64)
|
|
if err != nil {
|
|
return 0
|
|
}
|
|
return val
|
|
}
|
|
|
|
return 0
|
|
}
|
|
|
|
func lookupUint(name string, set *flag.FlagSet) uint {
|
|
f := set.Lookup(name)
|
|
if f != nil {
|
|
val, err := strconv.ParseUint(f.Value.String(), 0, 64)
|
|
if err != nil {
|
|
return 0
|
|
}
|
|
return uint(val)
|
|
}
|
|
|
|
return 0
|
|
}
|
|
|
|
func lookupUint64(name string, set *flag.FlagSet) uint64 {
|
|
f := set.Lookup(name)
|
|
if f != nil {
|
|
val, err := strconv.ParseUint(f.Value.String(), 0, 64)
|
|
if err != nil {
|
|
return 0
|
|
}
|
|
return val
|
|
}
|
|
|
|
return 0
|
|
}
|
|
|
|
func lookupDuration(name string, set *flag.FlagSet) time.Duration {
|
|
f := set.Lookup(name)
|
|
if f != nil {
|
|
val, err := time.ParseDuration(f.Value.String())
|
|
if err == nil {
|
|
return val
|
|
}
|
|
}
|
|
|
|
return 0
|
|
}
|
|
|
|
func lookupFloat64(name string, set *flag.FlagSet) float64 {
|
|
f := set.Lookup(name)
|
|
if f != nil {
|
|
val, err := strconv.ParseFloat(f.Value.String(), 64)
|
|
if err != nil {
|
|
return 0
|
|
}
|
|
return val
|
|
}
|
|
|
|
return 0
|
|
}
|
|
|
|
func lookupString(name string, set *flag.FlagSet) string {
|
|
f := set.Lookup(name)
|
|
if f != nil {
|
|
return f.Value.String()
|
|
}
|
|
|
|
return ""
|
|
}
|
|
|
|
func lookupStringSlice(name string, set *flag.FlagSet) []string {
|
|
f := set.Lookup(name)
|
|
if f != nil {
|
|
return (f.Value.(*StringSlice)).Value()
|
|
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func lookupIntSlice(name string, set *flag.FlagSet) []int {
|
|
f := set.Lookup(name)
|
|
if f != nil {
|
|
return (f.Value.(*IntSlice)).Value()
|
|
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func lookupInt64Slice(name string, set *flag.FlagSet) []int64 {
|
|
f := set.Lookup(name)
|
|
if f != nil {
|
|
return (f.Value.(*Int64Slice)).Value()
|
|
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func lookupGeneric(name string, set *flag.FlagSet) interface{} {
|
|
f := set.Lookup(name)
|
|
if f != nil {
|
|
return f.Value
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func lookupBool(name string, set *flag.FlagSet) bool {
|
|
f := set.Lookup(name)
|
|
if f != nil {
|
|
val, err := strconv.ParseBool(f.Value.String())
|
|
if err != nil {
|
|
return false
|
|
}
|
|
return val
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
func lookupBoolT(name string, set *flag.FlagSet) bool {
|
|
f := set.Lookup(name)
|
|
if f != nil {
|
|
val, err := strconv.ParseBool(f.Value.String())
|
|
if err != nil {
|
|
return true
|
|
}
|
|
return val
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
func copyFlag(name string, ff *flag.Flag, set *flag.FlagSet) {
|
|
switch ff.Value.(type) {
|
|
case *StringSlice:
|
|
default:
|
|
set.Set(name, ff.Value.String())
|
|
}
|
|
}
|
|
|
|
func normalizeFlags(flags []Flag, set *flag.FlagSet) error {
|
|
visited := make(map[string]bool)
|
|
set.Visit(func(f *flag.Flag) {
|
|
visited[f.Name] = true
|
|
})
|
|
for _, f := range flags {
|
|
parts := strings.Split(f.GetName(), ",")
|
|
if len(parts) == 1 {
|
|
continue
|
|
}
|
|
var ff *flag.Flag
|
|
for _, name := range parts {
|
|
name = strings.Trim(name, " ")
|
|
if visited[name] {
|
|
if ff != nil {
|
|
return errors.New("Cannot use two forms of the same flag: " + name + " " + ff.Name)
|
|
}
|
|
ff = set.Lookup(name)
|
|
}
|
|
}
|
|
if ff == nil {
|
|
continue
|
|
}
|
|
for _, name := range parts {
|
|
name = strings.Trim(name, " ")
|
|
if !visited[name] {
|
|
copyFlag(name, ff, set)
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
}
|