<commit_before>// Copyright (c) 2017 <NAME> <<EMAIL>>.
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file.

package gonfig

import (
	"fmt"
	"os"
	"path"
	"reflect"
	"strings"

	"github.com/spf13/pflag"
)

const (
	defaultHelpDescription = "print this help menu"
	defaultHelpMessage     = "Usage of __EXEC__:"
)

// createFlagSet builds the flagset for the options in the setup.
func createFlagSet(s *setup) *pflag.FlagSet {
	flagSet := pflag.NewFlagSet(os.Args[0], pflag.ContinueOnError)
	flagSet.SortFlags = false

	for _, opt := range s.allOpts {
		if opt.isParent {
			// Parents are skipped, we should only add the children.
			continue
		}

		switch opt.value.Type().Kind() {
		case reflect.Bool:
			var def bool
			if opt.defaul == "true" {
				def = true
			}
			flagSet.BoolP(opt.fullID(), opt.short, def, opt.desc)

		case reflect.Slice:
			if opt.value.Type().Elem().Kind() == reflect.Uint8 {
				// Special case for byte slices.
				flagSet.StringP(opt.fullID(), opt.short, opt.defaul, opt.desc)
				break
			}
			defSlice, err := readAsCSV(opt.defaul)
			if err != nil {
				panic(fmt.Sprintf(
					"error parsing default value '%s' for slice variable %s: %s",
					opt.defaul, opt.fullID(), err))
			}
			flagSet.StringSliceP(opt.fullID(), opt.short, defSlice, opt.desc)

		default:
			// We use strings for everything else since there is no visual
			// difference in the help output and we need logic for parsing
			// values from into the target type anyhow.
			flagSet.StringP(opt.fullID(), opt.short, opt.defaul, opt.desc)
		}
	}
<commit_msg>Create type-specific flags instead of string ones<commit_after>// Copyright (c) 2017 <NAME> <<EMAIL>>.
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file.

package gonfig

import (
	"fmt"
	"os"
	"path"
	"reflect"
	"strings"

	"github.com/spf13/pflag"
)

const (
	defaultHelpDescription = "print this help menu"
	defaultHelpMessage     = "Usage of __EXEC__:"
)

// addFlag adds a new flag to the flagset for the given option.
// It will try to create a flag with the correct type and fallback to string
// for unsupported types.
func addFlag(flagSet *pflag.FlagSet, opt *option) {
	switch opt.value.Type().Kind() {
	case reflect.Bool:
		var def bool
		if opt.defaultSet {
			def = opt.defaultValue.Bool()
		}
		flagSet.BoolP(opt.fullID(), opt.short, def, opt.desc)

	case reflect.Float32, reflect.Float64:
		var def float64
		if opt.defaultSet {
			def = opt.defaultValue.Float()
		}
		flagSet.Float64P(opt.fullID(), opt.short, def, opt.desc)

	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		var def int64
		if opt.defaultSet {
			def = opt.defaultValue.Int()
		}
		flagSet.Int64P(opt.fullID(), opt.short, def, opt.desc)

	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		var def uint64
		if opt.defaultSet {
			def = opt.defaultValue.Uint()
		}
		flagSet.Uint64P(opt.fullID(), opt.short, def, opt.desc)

	case reflect.Slice:
		if opt.value.Type().Elem().Kind() == reflect.Uint8 {
			// Special case for byte slices.
			flagSet.StringP(opt.fullID(), opt.short, opt.defaul, opt.desc)
			break
		}
		switch opt.value.Type().Elem().Kind() {
		case reflect.Bool:
			var def []bool
			if opt.defaultSet {
				def = opt.defaultValue.Interface().([]bool)
			}
			flagSet.BoolSliceP(opt.fullID(), opt.short, def, opt.desc)

		//TODO pflag.FloatSliceP is missing for now
		//case reflect.Float32, reflect.Float64:
		//	var def []float64
		//	if opt.defaultSet {
		//		def = opt.defaultValue.Convert(reflect.TypeOf(def)).Interface().([]float64)
		//	}
		//	flagSet.Float64P(opt.fullID(), opt.short, def, opt.desc)

		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
			var def []int
			if opt.defaultSet {
				slice := reflect.New(reflect.TypeOf(def))
				if err := convertSlice(opt.defaultValue, slice.Elem()); err != nil {
					panic(fmt.Sprintf("Error creating flag for option %s: %s",
						opt.fullID(), err))
				}
				def = slice.Elem().Interface().([]int)
			}
			flagSet.IntSliceP(opt.fullID(), opt.short, def, opt.desc)

		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
			var def []uint
			if opt.defaultSet {
				slice := reflect.New(reflect.TypeOf(def))
				if err := convertSlice(opt.defaultValue, slice.Elem()); err != nil {
					panic(fmt.Sprintf("Error creating flag for option %s: %s",
						opt.fullID(), err))
				}
				def = slice.Elem().Interface().([]uint)
			}
			flagSet.UintSliceP(opt.fullID(), opt.short, def, opt.desc)

		case reflect.String:
			fallthrough
		default:
			defSlice, err := readAsCSV(opt.defaul)
			if err != nil {
				panic(fmt.Sprintf(
					"error parsing default value '%s' for slice variable %s: %s",
					opt.defaul, opt.fullID(), err))
			}
			flagSet.StringSliceP(opt.fullID(), opt.short, defSlice, opt.desc)
		}

	case reflect.String:
		fallthrough
	default:
		flagSet.StringP(opt.fullID(), opt.short, opt.defaul, opt.desc)
	}
}

// createFlagSet builds the flagset for the options in the setup.
func createFlagSet(s *setup) *pflag.FlagSet {
	flagSet := pflag.NewFlagSet(os.Args[0], pflag.ContinueOnError)
	flagSet.SortFlags = false

	for _, opt := range s.allOpts {
		if opt.isParent {
			// Parents are skipped, we should only add the children.
			continue
		}

		addFlag(flagSet, opt)
	}

{'fraction_non_alphanumeric': 0.1374355195283714, 'fraction_numerical': 0.012896094325718496, 'mean_word_length': 3.319013524264121, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5019936', 'n_tokens_mistral': 2131, 'n_tokens_neox': 1859, 'n_words': 507}