Beispiel #1
0
// ApplyWithError populates the flag given the flag set and environment
func (f Float64Flag) ApplyWithError(set *flag.FlagSet) error {
	if f.EnvVar != "" {
		for _, envVar := range strings.Split(f.EnvVar, ",") {
			envVar = strings.TrimSpace(envVar)
			if envVal, ok := syscall.Getenv(envVar); ok {
				envValFloat, err := strconv.ParseFloat(envVal, 10)
				if err != nil {
					return fmt.Errorf("could not parse %s as float64 value for flag %s: %s", envVal, f.Name, err)
				}

				f.Value = float64(envValFloat)
				break
			}
		}
	}

	eachName(f.Name, func(name string) {
		if f.Destination != nil {
			set.Float64Var(f.Destination, name, f.Value, f.Usage)
			return
		}
		set.Float64(name, f.Value, f.Usage)
	})

	return nil
}
Beispiel #2
0
func Flags(flagSet *flag.FlagSet, prefix string, includeParallelFlags bool) {
	prefix = processPrefix(prefix)
	flagSet.Int64Var(&(GinkgoConfig.RandomSeed), prefix+"seed", time.Now().Unix(), "The seed used to randomize the spec suite.")
	flagSet.BoolVar(&(GinkgoConfig.RandomizeAllSpecs), prefix+"randomizeAllSpecs", false, "If set, ginkgo will randomize all specs together.  By default, ginkgo only randomizes the top level Describe/Context groups.")
	flagSet.BoolVar(&(GinkgoConfig.SkipMeasurements), prefix+"skipMeasurements", false, "If set, ginkgo will skip any measurement specs.")
	flagSet.BoolVar(&(GinkgoConfig.FailOnPending), prefix+"failOnPending", false, "If set, ginkgo will mark the test suite as failed if any specs are pending.")
	flagSet.BoolVar(&(GinkgoConfig.FailFast), prefix+"failFast", false, "If set, ginkgo will stop running a test suite after a failure occurs.")
	flagSet.BoolVar(&(GinkgoConfig.DryRun), prefix+"dryRun", false, "If set, ginkgo will walk the test hierarchy without actually running anything.  Best paired with -v.")
	flagSet.StringVar(&(GinkgoConfig.FocusString), prefix+"focus", "", "If set, ginkgo will only run specs that match this regular expression.")
	flagSet.StringVar(&(GinkgoConfig.SkipString), prefix+"skip", "", "If set, ginkgo will only run specs that do not match this regular expression.")
	flagSet.BoolVar(&(GinkgoConfig.EmitSpecProgress), prefix+"progress", false, "If set, ginkgo will emit progress information as each spec runs to the GinkgoWriter.")

	if includeParallelFlags {
		flagSet.IntVar(&(GinkgoConfig.ParallelNode), prefix+"parallel.node", 1, "This worker node's (one-indexed) node number.  For running specs in parallel.")
		flagSet.IntVar(&(GinkgoConfig.ParallelTotal), prefix+"parallel.total", 1, "The total number of worker nodes.  For running specs in parallel.")
		flagSet.StringVar(&(GinkgoConfig.SyncHost), prefix+"parallel.synchost", "", "The address for the server that will synchronize the running nodes.")
		flagSet.StringVar(&(GinkgoConfig.StreamHost), prefix+"parallel.streamhost", "", "The address for the server that the running nodes should stream data to.")
	}

	flagSet.BoolVar(&(DefaultReporterConfig.NoColor), prefix+"noColor", false, "If set, suppress color output in default reporter.")
	flagSet.Float64Var(&(DefaultReporterConfig.SlowSpecThreshold), prefix+"slowSpecThreshold", 5.0, "(in seconds) Specs that take longer to run than this threshold are flagged as slow by the default reporter (default: 5 seconds).")
	flagSet.BoolVar(&(DefaultReporterConfig.NoisyPendings), prefix+"noisyPendings", true, "If set, default reporter will shout about pending tests.")
	flagSet.BoolVar(&(DefaultReporterConfig.Verbose), prefix+"v", false, "If set, default reporter print out all specs as they begin.")
	flagSet.BoolVar(&(DefaultReporterConfig.Succinct), prefix+"succinct", false, "If set, default reporter prints out a very succinct report")
	flagSet.BoolVar(&(DefaultReporterConfig.FullTrace), prefix+"trace", false, "If set, default reporter prints out the full stack trace when a failure occurs")
}
Beispiel #3
0
// ParamsParser implements a command line parameter parser for the ping module
func (r *run) ParamsParser(args []string) (interface{}, error) {
	var (
		err      error
		pa       params
		d, p     string
		dp, c, t float64
		fs       flag.FlagSet
	)
	if len(args) < 1 || args[0] == "" || args[0] == "help" {
		printHelp(true)
		return nil, fmt.Errorf("help printed")
	}
	fs.Init("ping", flag.ContinueOnError)
	fs.StringVar(&d, "d", "www.google.com", "see help")
	fs.Float64Var(&dp, "dp", -1, "see help")
	fs.StringVar(&p, "p", "icmp", "see help")
	fs.Float64Var(&c, "c", 3, "see help")
	fs.Float64Var(&t, "t", 5, "see help")

	err = fs.Parse(args)
	if err != nil {
		return nil, err
	}
	pa.Destination = d
	pa.DestinationPort = dp
	pa.Protocol = p
	pa.Count = c
	pa.Timeout = t
	r.Parameters = pa
	return pa, r.ValidateParameters()
}
Beispiel #4
0
// FlagByType sets the appropriate flag for its type.
func FlagByType(fs *flag.FlagSet, structName string, fval reflect.Value, ftype reflect.StructField) {
	// Get a pointer; FlagSet needs a pointer to set the struct's field
	if fval.Kind() == reflect.Ptr {
		// Short-circuit
		log.Printf("Skipping field %s: %s", ftype.Name, ftype.Type.String())
		return
	}
	//log.Printf("Getting pointer to %s", ftype.Name)
	fval = fval.Addr()
	flagName := NameToFlag(ftype.Name)
	flagHelp := fmt.Sprintf("%s:%s", structName, ftype.Name)
	log.Printf("Converting %s => %s", ftype.Name, flagName)

	//log.Printf("Switching on type %s...", ftype.Type.String())
	switch fval := fval.Interface().(type) {
	case *int:
		fs.IntVar(fval, flagName, 0, flagHelp)
	case *float64:
		fs.Float64Var(fval, flagName, 0.0, flagHelp)
	case *string:
		fs.StringVar(fval, flagName, "", flagHelp)
	case *bool:
		fs.BoolVar(fval, flagName, false, flagHelp)
	case *time.Time:
		t := (*time.Time)(fval) // Get a *time.Time pointer to fval
		*t = time.Now()         // Set a default of time.Now()
		fs.Var((*TimeFlag)(fval), flagName, flagHelp)
	default:
		log.Printf("unexpected type %s\n", ftype.Type.String())
	}
}
Beispiel #5
0
func addBaseFlags(flags *flag.FlagSet) {
	flags.StringVar(&BaseOptions.Connection, "connection", "", "connection parameters")
	flags.StringVar(&BaseOptions.CacheDir, "cachedir", defaultCacheDir, "cache directory")
	flags.StringVar(&BaseOptions.DiffDir, "diffdir", "", "diff directory for last.state.txt")
	flags.StringVar(&BaseOptions.MappingFile, "mapping", "", "mapping file")
	flags.IntVar(&BaseOptions.Srid, "srid", defaultSrid, "srs id")
	flags.StringVar(&BaseOptions.LimitTo, "limitto", "", "limit to geometries")
	flags.Float64Var(&BaseOptions.LimitToCacheBuffer, "limittocachebuffer", 0.0, "limit to buffer for cache")
	flags.StringVar(&BaseOptions.ConfigFile, "config", "", "config (json)")
	flags.StringVar(&BaseOptions.Httpprofile, "httpprofile", "", "bind address for profile server")
	flags.BoolVar(&BaseOptions.Quiet, "quiet", false, "quiet log output")
	flags.StringVar(&BaseOptions.Schemas.Import, "dbschema-import", defaultSchemaImport, "db schema for imports")
	flags.StringVar(&BaseOptions.Schemas.Production, "dbschema-production", defaultSchemaProduction, "db schema for production")
	flags.StringVar(&BaseOptions.Schemas.Backup, "dbschema-backup", defaultSchemaBackup, "db schema for backups")
}
Beispiel #6
0
// ParamsParser implements a command line parameters parser that takes a string
// and returns a Parameters structure in an interface. It will display the module
// help if the arguments string spell the work 'help'
func (r *run) ParamsParser(args []string) (interface{}, error) {
	var (
		err                               error
		names, libraries, bytes, contents flagParam
		offset, maxlength                 float64
		matchall, matchany, logfailures   bool
		fs                                flag.FlagSet
	)
	if len(args) < 1 || args[0] == "" || args[0] == "help" {
		printHelp(true)
		return nil, nil
	}
	fs.Init("memory", flag.ContinueOnError)
	fs.Var(&names, "name", "see help")
	fs.Var(&libraries, "lib", "see help")
	fs.Var(&bytes, "bytes", "see help")
	fs.Var(&contents, "content", "see help")
	fs.Float64Var(&offset, "maxdepth", 0, "see help")
	fs.Float64Var(&maxlength, "matchlimit", 0, "see help")
	fs.BoolVar(&matchall, "matchall", true, "see help")
	fs.BoolVar(&matchany, "matchany", false, "see help")
	fs.BoolVar(&logfailures, "logfailures", false, "see help")
	err = fs.Parse(args)
	if err != nil {
		return nil, err
	}
	var s search
	s.Names = names
	s.Libraries = libraries
	s.Bytes = bytes
	s.Contents = contents
	s.Options.Offset = offset
	s.Options.MaxLength = maxlength
	s.Options.MatchAll = matchall
	if matchany {
		s.Options.MatchAll = false
	}
	s.Options.LogFailures = logfailures
	p := newParameters()
	p.Searches["s1"] = s
	r.Parameters = *p
	return r.Parameters, r.ValidateParameters()
}
Beispiel #7
0
// registerFlagStruct parse struct field, and register with flag set
func registerFlagStruct(i interface{}, fs *flag.FlagSet) error {
	if fs.Parsed() {
		return ErrFlagParsed
	}

	sf := structFields(i)
	for _, fd := range sf {
		field := fd.field

		flagName := fd.tag.name
		flagUsage := fd.tag.usage
		fieldPtr := unsafe.Pointer(fd.value.UnsafeAddr())

		switch field.Type.Kind() {
		case reflect.Int:
			fs.IntVar((*int)(fieldPtr), flagName, fd.tag.intValue(), flagUsage)
		case reflect.Int64:
			fs.Int64Var((*int64)(fieldPtr), flagName, fd.tag.int64Value(), flagUsage)
		case reflect.Uint:
			fs.UintVar((*uint)(fieldPtr), flagName, fd.tag.uintValue(), flagUsage)
		case reflect.Uint64:
			fs.Uint64Var((*uint64)(fieldPtr), flagName, fd.tag.uint64Value(), flagUsage)
		case reflect.String:
			fs.StringVar((*string)(fieldPtr), flagName, fd.tag.stringValue(), flagUsage)
		case reflect.Bool:
			fs.BoolVar((*bool)(fieldPtr), flagName, fd.tag.boolValue(), flagUsage)
		case reflect.Float64:
			fs.Float64Var((*float64)(fieldPtr), flagName, fd.tag.float64Value(), flagUsage)
		default:
			if !reflect.PtrTo(field.Type).Implements(flagValueType) {
				return ErrUnsupportType
			}

			fieldValue := reflect.NewAt(field.Type, fieldPtr)
			switch value := fieldValue.Interface().(type) {
			case flag.Value:
				fs.Var(value, flagName, flagUsage)
			}
		}
	}

	return nil
}
Beispiel #8
0
func (m *gocoverdir) setupFlags(fs *flag.FlagSet) {
	fs.StringVar(&m.args.covermode, "covermode", "", "Same as -covermode in 'go test'.  If running with -race, probably best not to set this.")
	fs.IntVar(&m.args.cpu, "cpu", -1, "Same as -cpu in 'go test'")
	fs.BoolVar(&m.args.race, "race", false, "Same as -race in 'go test'")
	fs.DurationVar(&m.args.timeout, "timeout", time.Second*3, "Same as -timeout in 'go test'")
	coveroutdir := os.Getenv("GOCOVERDIR_DIR")
	if coveroutdir == "" {
		coveroutdir = os.TempDir()
	}
	fs.StringVar(&m.args.coverprofile, "coverprofile", filepath.Join(coveroutdir, "coverage.out"), "Same as -coverprofile in 'go test', but will be a combined cover profile.")

	fs.IntVar(&m.args.depth, "depth", 10, "Directory depth to search.")
	fs.StringVar(&m.args.ignoreDirs, "ignoredirs", ".git:Godeps:vendor", "Color separated path of directories to ignore")

	fs.StringVar(&m.args.logfile, "logfile", "-", "Logfile to print debug output to.  Empty means be silent unless there is an error, then dump to stderr")

	fs.BoolVar(&m.args.printcoverage, "printcoverage", false, "Print coverage amount to stdout")
	fs.Float64Var(&m.args.requiredcoverage, "requiredcoverage", 0.0, "Program will fatal if coverage is < this value")
	fs.BoolVar(&m.args.htmlcoverage, "htmlcoverage", false, "If true, will generate coverage output in a temp file")
}
Beispiel #9
0
// Apply populates the flag given the flag set and environment
func (f Float64Flag) Apply(set *flag.FlagSet) {
	if f.EnvVars != nil {
		for _, envVar := range f.EnvVars {
			if envVal := os.Getenv(envVar); envVal != "" {
				envValFloat, err := strconv.ParseFloat(envVal, 10)
				if err == nil {
					f.Value = float64(envValFloat)
				}
			}
		}
	}

	for _, name := range f.Names() {
		if f.Destination != nil {
			set.Float64Var(f.Destination, name, f.Value, f.Usage)
			continue
		}
		set.Float64(name, f.Value, f.Usage)
	}
}
Beispiel #10
0
Datei: flag.go Projekt: nlf/dlite
// Apply populates the flag given the flag set and environment
func (f Float64Flag) Apply(set *flag.FlagSet) {
	if f.EnvVar != "" {
		for _, envVar := range strings.Split(f.EnvVar, ",") {
			envVar = strings.TrimSpace(envVar)
			if envVal := os.Getenv(envVar); envVal != "" {
				envValFloat, err := strconv.ParseFloat(envVal, 10)
				if err == nil {
					f.Value = float64(envValFloat)
				}
			}
		}
	}

	eachName(f.Name, func(name string) {
		if f.Destination != nil {
			set.Float64Var(f.Destination, name, f.Value, f.Usage)
			return
		}
		set.Float64(name, f.Value, f.Usage)
	})
}
Beispiel #11
0
func addFieldFlag(field reflect.StructField, value reflect.Value, fs *flag.FlagSet) {
	name, usage := getFieldNameUsage(field)
	ptr := unsafe.Pointer(value.UnsafeAddr())
	switch field.Type.Kind() {
	case reflect.Bool:
		fs.BoolVar((*bool)(ptr), name, *(*bool)(ptr), usage)
	case reflect.Float64:
		fs.Float64Var((*float64)(ptr), name, *(*float64)(ptr), usage)
	case reflect.Int64:
		fs.Int64Var((*int64)(ptr), name, *(*int64)(ptr), usage)
	case reflect.Int:
		fs.IntVar((*int)(ptr), name, *(*int)(ptr), usage)
	case reflect.String:
		fs.StringVar((*string)(ptr), name, *(*string)(ptr), usage)
	case reflect.Uint64:
		fs.Uint64Var((*uint64)(ptr), name, *(*uint64)(ptr), usage)
	case reflect.Uint:
		fs.UintVar((*uint)(ptr), name, *(*uint)(ptr), usage)
	default:
		panic(fmt.Sprintf("unsupported type: %v", field.Type))
	}
}
Beispiel #12
0
func (p *DifferencerConfig) CreateFlags(f *flag.FlagSet) {
	f.BoolVar(
		&p.MatchEnds, "match-ends", true, `
		Before computing the alignment between lines of two files, should
		the common prefix and suffix be identified, reducing the number of
		lines being aligned by the more general technique? (Improves the
		alignment of inserted functions in C-like languages, as the trailing
		curly braces get matched to the correct function more often.)
		`)

	f.BoolVar(
		&p.MatchNormalizedEnds, "match-normalized-ends", true, `
		When matching the common prefix and suffix, after matching full lines,
		should common normalized prefix and suffix lines be matched?
		`)

	f.BoolVar(
		&p.AlignNormalizedLines, "align-normalized-lines", true, `
		When computing an alignment between files, should lines be normalized
		before comparing (i.e. compare hashes of normalized lines, not of full
		lines).
		`)

	f.BoolVar(
		&p.AlignRareLines, "align-rare-lines", true, `
		When computing an alignment between files, should unique/rare lines be
		used for computing the alignment, or all lines?
		`)

	f.IntVar(
		&p.MaxRareLineOccurrencesInRange, "max-rare-line-occurrences-in-range", 1, `
		When deciding which lines are rare in a region being aligned, how many
		times may a line appear (actually, how many times may its hash appear)
		and still be considered rare?
		`)

	f.IntVar(
		&p.MaxRareLineOccurrencesInFile, "max-rare-line-occurrences-in-file", 3, `
		When selecting rare lines, discard those lines whose hash, after
		normalization, appears more than this many times. If 0, not applied.
		`)

	f.BoolVar(
		&p.RequireSameRarity, "require-same-rarity", true, `
		When deciding which lines are rare in two regions being aligned,
		must those lines appear the same number of times in each region?
		`)

	f.BoolVar(
		&p.DetectBlockMoves, "detect-block-moves", true, `
		When computing an alignment between files, should blocks of moved lines
		be detected (i.e. detect re-ordering of paragraphs/functions).
		`)

	f.Float64Var(
		&p.LcsNormalizedSimilarity, "lcs-normalized-similarity", 0.5, `
		When computing the longest common subsequence (LCS) of two file ranges,
	  how similar are two normalized lines to be considered, where 0 is
	  completely dissimilar, and 1 is equal.
		`)

	f.BoolVar(
		&p.LengthWeightedSimilarity, "length-weighted-similarity", true, `
		When computing an LCS alignment between files, should longer equal lines
		be weighted more heavily that short lines?
		`)

	f.BoolVar(
		&p.OmitProbablyCommonLines, "omit-probably-common-lines", true, `
		When doing alignment (initial or move/copy detection), omit from
		consideration the lines that are probably common (e.g. "/*" or "}").
		`)
}
Beispiel #13
0
// Add the flags accepted by run to the supplied flag set, returning the
// variables into which the flags will parse.
func populateFlagSet(fs *flag.FlagSet) (flags *flagStorage) {
	flags = new(flagStorage)

	flags.MountOptions = make(map[string]string)
	fs.Var(
		mountpkg.OptionValue(flags.MountOptions),
		"o",
		"Additional system-specific mount options. Be careful!")

	fs.Int64Var(
		&flags.Uid,
		"uid",
		-1,
		"If non-negative, the UID that owns all inodes. The default is the UID of "+
			"the gcsfuse process.")

	fs.Int64Var(
		&flags.Gid,
		"gid",
		-1,
		"If non-negative, the GID that owns all inodes. The default is the GID of "+
			"the gcsfuse process.")

	fs.UintVar(
		&flags.FileMode,
		"file-mode",
		0644,
		"Permissions bits for files. Default is 0644.")

	fs.UintVar(
		&flags.DirMode,
		"dir-mode",
		0755,
		"Permissions bits for directories. Default is 0755.")

	fs.StringVar(
		&flags.TempDir,
		"temp-dir", "",
		"The temporary directory in which to store local copies of GCS objects. "+
			"If empty, the system default (probably /tmp) will be used.")

	fs.Int64Var(
		&flags.TempDirLimit,
		"temp-dir-bytes", 1<<31,
		"A desired limit on the number of bytes used in --temp-dir. May be "+
			"exceeded for dirty files that have not been flushed or closed.")

	fs.Uint64Var(
		&flags.GCSChunkSize,
		"gcs-chunk-size", 1<<24,
		"If set to a non-zero value N, split up GCS objects into multiple "+
			"chunks of size at most N when reading, and do not read or cache "+
			"unnecessary chunks.")

	fs.BoolVar(
		&flags.ImplicitDirs,
		"implicit-dirs",
		false,
		"Implicitly define directories based on their content. See "+
			"docs/semantics.md.")

	fs.DurationVar(
		&flags.StatCacheTTL,
		"stat-cache-ttl",
		time.Minute,
		"How long to cache StatObject results from GCS.")

	fs.DurationVar(
		&flags.TypeCacheTTL,
		"type-cache-ttl",
		time.Minute,
		"How long to cache name -> file/dir type mappings in directory inodes.")

	fs.Float64Var(
		&flags.OpRateLimitHz,
		"limit-ops-per-sec",
		5.0,
		"If positive, a limit on the rate at which we send requests to GCS, "+
			"measured over a 30-second window.")

	fs.Float64Var(
		&flags.EgressBandwidthLimitBytesPerSecond,
		"limit-bytes-per-sec",
		-1,
		"If positive, a limit on the GCS -> gcsfuse bandwidth for reading "+
			"objects, measured over a 30-second window.")

	return
}
Beispiel #14
0
// ParamsParser implements a command line parameters parser that takes a string
// and returns a Parameters structure in an interface. It will display the module
// help if the arguments string spell the work 'help'
func (r *run) ParamsParser(args []string) (interface{}, error) {
	var (
		err error
		paths, names, sizes, modes, mtimes, contents, md5s, sha1s, sha2s,
		sha3s, mismatch flagParam
		maxdepth, matchlimit                                           float64
		returnsha256, matchall, matchany, macroal, verbose, decompress bool
		fs                                                             flag.FlagSet
	)
	if len(args) < 1 || args[0] == "" || args[0] == "help" {
		printHelp(true)
		return nil, nil
	}
	fs.Init("file", flag.ContinueOnError)
	fs.Var(&paths, "path", "see help")
	fs.Var(&names, "name", "see help")
	fs.Var(&sizes, "size", "see help")
	fs.Var(&modes, "mode", "see help")
	fs.Var(&mtimes, "mtime", "see help")
	fs.Var(&contents, "content", "see help")
	fs.Var(&md5s, "md5", "see help")
	fs.Var(&sha1s, "sha1", "see help")
	fs.Var(&sha2s, "sha2", "see help")
	fs.Var(&sha3s, "sha3", "see help")
	fs.Var(&mismatch, "mismatch", "see help")
	fs.Float64Var(&maxdepth, "maxdepth", 1000, "see help")
	fs.Float64Var(&matchlimit, "matchlimit", 1000, "see help")
	fs.BoolVar(&matchall, "matchall", true, "see help")
	fs.BoolVar(&matchany, "matchany", false, "see help")
	fs.BoolVar(&macroal, "macroal", false, "see help")
	fs.BoolVar(&debug, "verbose", false, "see help")
	fs.BoolVar(&returnsha256, "returnsha256", false, "see help")
	fs.BoolVar(&decompress, "decompress", false, "see help")
	err = fs.Parse(args)
	if err != nil {
		return nil, err
	}
	var s search
	s.Paths = paths
	s.Names = names
	s.Sizes = sizes
	s.Modes = modes
	s.Mtimes = mtimes
	s.Contents = contents
	s.MD5 = md5s
	s.SHA1 = sha1s
	s.SHA2 = sha2s
	s.SHA3 = sha3s
	s.Options.MaxDepth = maxdepth
	s.Options.MatchLimit = matchlimit
	s.Options.Macroal = macroal
	s.Options.Mismatch = mismatch
	s.Options.MatchAll = matchall
	s.Options.ReturnSHA256 = returnsha256
	s.Options.Decompress = decompress
	if matchany {
		s.Options.MatchAll = false
	}
	if verbose {
		s.Options.Debug = "print"
	}
	p := newParameters()
	p.Searches["s1"] = s
	r.Parameters = *p
	return r.Parameters, r.ValidateParameters()
}
Beispiel #15
0
// ParamsParser implements a command line parameters parser that takes a string
// and returns a Parameters structure in an interface. It will display the module
// help if the arguments string spell the work 'help'
func (r *run) ParamsParser(args []string) (interface{}, error) {
	var (
		err error
		paths, names, sizes, modes, mtimes, contents, md5s, sha1s, sha256s,
		sha384s, sha512s, sha3_224s, sha3_256s, sha3_384s, sha3_512s flagParam
		maxdepth, matchlimit float64
		matchall, matchany   bool
		fs                   flag.FlagSet
	)
	if len(args) < 1 || args[0] == "" || args[0] == "help" {
		printHelp(true)
		return nil, nil
	}
	fs.Init("file", flag.ContinueOnError)
	fs.Var(&paths, "path", "see help")
	fs.Var(&names, "name", "see help")
	fs.Var(&sizes, "size", "see help")
	fs.Var(&modes, "mode", "see help")
	fs.Var(&mtimes, "mtime", "see help")
	fs.Var(&contents, "content", "see help")
	fs.Var(&md5s, "md5", "see help")
	fs.Var(&sha1s, "sha1", "see help")
	fs.Var(&sha256s, "sha256", "see help")
	fs.Var(&sha384s, "sha384", "see help")
	fs.Var(&sha512s, "sha512", "see help")
	fs.Var(&sha3_224s, "sha3_224", "see help")
	fs.Var(&sha3_256s, "sha3_256", "see help")
	fs.Var(&sha3_384s, "sha3_384", "see help")
	fs.Var(&sha3_512s, "sha3_512", "see help")
	fs.Float64Var(&maxdepth, "maxdepth", 0, "see help")
	fs.Float64Var(&matchlimit, "matchlimit", 0, "see help")
	fs.BoolVar(&matchall, "matchall", true, "see help")
	fs.BoolVar(&matchany, "matchany", false, "see help")
	err = fs.Parse(args)
	if err != nil {
		return nil, err
	}
	var s search
	s.Paths = paths
	s.Names = names
	s.Sizes = sizes
	s.Modes = modes
	s.Mtimes = mtimes
	s.Contents = contents
	s.MD5 = md5s
	s.SHA1 = sha1s
	s.SHA256 = sha256s
	s.SHA384 = sha384s
	s.SHA512 = sha512s
	s.SHA3_224 = sha3_224s
	s.SHA3_256 = sha3_256s
	s.SHA3_384 = sha3_384s
	s.SHA3_512 = sha3_512s
	s.Options.MaxDepth = maxdepth
	s.Options.MatchLimit = matchlimit
	s.Options.MatchAll = matchall
	if matchany {
		s.Options.MatchAll = false
	}
	p := newParameters()
	p.Searches["s1"] = s
	r.Parameters = *p
	return r.Parameters, r.ValidateParameters()
}
Beispiel #16
0
// Register fields in the given struct that have the tag `flag:"name,desc"`.
// Nested structs are supported as long as the field is a struct value field and not pointer to a struct.
// Exception to this is the use of StringList which needs to be a pointer.  The StringList type implements
// the Set and String methods required by the flag package and is dynamically allocated when registering its flag.
// See the test case for example.
func RegisterFlags(name string, val interface{}, fs *flag.FlagSet) {
	t := reflect.TypeOf(val).Elem()
	v := reflect.Indirect(reflect.ValueOf(val)) // the actual value of val
	for i := 0; i < t.NumField(); i++ {
		field := t.Field(i)

		if field.Anonymous && field.Type.Kind() == reflect.Struct {
			RegisterFlags(name+"."+field.Name, v.Field(i).Addr().Interface(), fs)
			continue
		}

		// See https://golang.org/ref/spec#Uniqueness_of_identifiers
		exported := field.PkgPath == ""
		if exported {

			tag := field.Tag
			spec := tag.Get("flag")
			if spec == "" {
				continue
			}

			// Bind the flag based on the tag spec
			f, d := "", ""
			p := strings.Split(spec, ",")
			if len(p) == 1 {
				// Just one field, use it as description
				f = fmt.Sprintf("%s.%s", name, strings.ToLower(field.Name))
				d = strings.Trim(p[0], " ")
			} else {
				// More than one, the first is the name of the flag
				f = strings.Trim(p[0], " ")
				d = strings.Trim(p[1], " ")
			}

			fv := v.Field(i).Interface()
			if v.Field(i).CanAddr() {
				ptr := v.Field(i).Addr().Interface() // The pointer value

				switch fv := fv.(type) {
				case bool:
					fs.BoolVar(ptr.(*bool), f, fv, d)
				case string:
					fs.StringVar(ptr.(*string), f, fv, d)
				case uint:
					fs.UintVar(ptr.(*uint), f, fv, d)
				case uint64:
					fs.Uint64Var(ptr.(*uint64), f, fv, d)
				case int64:
					fs.Int64Var(ptr.(*int64), f, fv, d)
				case int:
					fs.IntVar(ptr.(*int), f, fv, d)
				case float64:
					fs.Float64Var(ptr.(*float64), f, fv, d)
				case time.Duration:
					fs.DurationVar(ptr.(*time.Duration), f, fv, d)
				case []time.Duration:
					if len(fv) == 0 {
						// Special case where we allocate an empty list - otherwise it's default.
						v.Field(i).Set(reflect.ValueOf([]time.Duration{}))
					}
					fs.Var(&durationListProxy{list: ptr.(*[]time.Duration)}, f, d)
				default:
					// We only register if the field is a concrete vale and not a pointer
					// since we don't automatically allocate zero value structs to fill the field slot.
					switch field.Type.Kind() {

					case reflect.String:
						fs.Var(&aliasProxy{
							fieldType:  field.Type,
							ptr:        ptr,
							fromString: stringFromString,
							toString: func(v interface{}) string {
								return fmt.Sprint("%v", v)
							},
						}, f, d)
					case reflect.Bool:
						fs.Var(&aliasProxy{
							fieldType:  field.Type,
							ptr:        ptr,
							fromString: boolFromString,
							toString: func(v interface{}) string {
								return fmt.Sprint("%v", v)
							},
						}, f, d)
					case reflect.Float64:
						fs.Var(&aliasProxy{
							fieldType:  field.Type,
							ptr:        ptr,
							fromString: float64FromString,
							toString: func(v interface{}) string {
								return fmt.Sprint("%v", v)
							},
						}, f, d)
					case reflect.Int:
						fs.Var(&aliasProxy{
							fieldType:  field.Type,
							ptr:        ptr,
							fromString: intFromString,
							toString: func(v interface{}) string {
								return fmt.Sprint("%v", v)
							},
						}, f, d)
					case reflect.Int64:
						fs.Var(&aliasProxy{
							fieldType:  field.Type,
							ptr:        ptr,
							fromString: int64FromString,
							toString: func(v interface{}) string {
								return fmt.Sprint("%v", v)
							},
						}, f, d)
					case reflect.Uint:
						fs.Var(&aliasProxy{
							fieldType:  field.Type,
							ptr:        ptr,
							fromString: uintFromString,
							toString: func(v interface{}) string {
								return fmt.Sprint("%v", v)
							},
						}, f, d)
					case reflect.Uint64:
						fs.Var(&aliasProxy{
							fieldType:  field.Type,
							ptr:        ptr,
							fromString: uint64FromString,
							toString: func(v interface{}) string {
								return fmt.Sprint("%v", v)
							},
						}, f, d)
					case reflect.Struct:
						RegisterFlags(f, ptr, fs)
					case reflect.Slice:
						et := field.Type.Elem()
						proxy := &sliceProxy{
							fieldType: field.Type,
							elemType:  et,
							slice:     ptr,
							defaults:  reflect.ValueOf(fv).Len() > 0,
							toString: func(v interface{}) string {
								return fmt.Sprint("%v", v)
							},
						}
						fs.Var(proxy, f, d)
						switch {
						// Checking for string is placed here first because other types are
						// convertible to string as well.
						case reflect.TypeOf(string("")).ConvertibleTo(et):
							proxy.fromString = stringFromString
						case reflect.TypeOf(bool(true)).ConvertibleTo(et):
							proxy.fromString = boolFromString
						case reflect.TypeOf(float64(1.)).ConvertibleTo(et):
							proxy.fromString = float64FromString
						case reflect.TypeOf(int(1)).ConvertibleTo(et):
							proxy.fromString = intFromString
						case reflect.TypeOf(int64(1)).ConvertibleTo(et):
							proxy.fromString = int64FromString
						case reflect.TypeOf(uint(1)).ConvertibleTo(et):
							proxy.fromString = uintFromString
						case reflect.TypeOf(uint64(1)).ConvertibleTo(et):
							proxy.fromString = uint64FromString
						case reflect.TypeOf(time.Second).AssignableTo(et):
							proxy.fromString = durationFromString
						}
					}
				}
			}
		}
	}
}