<commit_before>// Copyright (c) 2011, SoundCloud Ltd., <NAME>
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Source code and contact info at http://github.com/kesselborn/go-getopt

package getopt

import (
	"fmt"
	"os"
	"path/filepath"
)

type Definitions []Option
type Description string

type Options struct {
	description Description
	definitions Definitions
}

func (optionsDefinition Options) setEnvAndConfigValues(options map[string]OptionValue, environment map[string]string) (err *GetOptError) {
	significantEnvVars := make(map[string]Option)

	for _, opt := range optionsDefinition.definitions {
		if value := opt.EnvVar(); value != "" {
			significantEnvVars[value] = opt
		}
	}

	for key, significantEnvVar := range significantEnvVars {
		if value := environment[key]; value != "" {
			options[significantEnvVar.Key()], err = assignValue(significantEnvVar.DefaultValue, value)
			if err != nil {
				break
			}
		}
	}

	return
}

func checkOptionsDefinitionConsistency(optionsDefinition Options) (err *GetOptError) {
	consistencyErrorPrefix := "wrong getopt usage: "

	foundOptionalArg := false
	for _, option := range optionsDefinition.definitions {
		switch {
		case option.Flags&IsArg > 0 && option.Flags&Required == 0 && option.Flags&Optional == 0:
			err = &GetOptError{ConsistencyError, consistencyErrorPrefix + "an argument must be explicitly set to be Optional or Required"}
		case option.Flags&IsArg > 0 && option.Flags&Optional > 0:
			foundOptionalArg = true
		case option.Flags&IsArg > 0 && option.Flags&Required > 0 && foundOptionalArg:
			err = &GetOptError{ConsistencyError, consistencyErrorPrefix + "a required argument can't come after an optional argument"}
		case option.Flags&Optional > 0 && option.Flags&Required > 0:
			err = &GetOptError{ConsistencyError, consistencyErrorPrefix + "an option can not be Required and Optional"}
		case option.Flags&Flag > 0 && option.Flags&ExampleIsDefault > 0:
			err = &GetOptError{ConsistencyError, consistencyErrorPrefix + "an option can not be a Flag and have ExampleIsDefault"}
		case option.Flags&Required > 0 && option.Flags&ExampleIsDefault > 0:
			err = &GetOptError{ConsistencyError, consistencyErrorPrefix + "an option can not be Required and have ExampleIsDefault"}
		case option.Flags&NoLongOpt > 0 && !option.HasShortOpt() && option.Flags&IsArg == 0:
			err = &GetOptError{ConsistencyError, consistencyErrorPrefix + "an option must have either NoLongOpt or a ShortOption"}
		case option.Flags&Flag > 0 && option.Flags&IsArg > 0:
			err = &GetOptError{ConsistencyError, consistencyErrorPrefix + "an option can not be a Flag and be an argument (IsArg)"}
		}
	}

	return
}

func (options Options) FindOption(optionString string) (option Option, found bool) {
	for _, cur := range options.definitions {
		if cur.ShortOpt() == optionString || cur.LongOpt() == optionString {
			option = cur
			found = true
			break
		}
	}

	return option, found
}

func (options Options) IsOptional(optionName string) (isRequired bool) {
	if option, found := options.FindOption(optionName); found && option.Flags&Optional != 0 {
		isRequired = true
	}

	return isRequired
}

func (options Options) IsRequired(optionName string) (isRequired bool) {
	if option, found := options.FindOption(optionName); found && option.Flags&Required != 0 {
		isRequired = true
	}

	return isRequired
}

func (options Options) IsFlag(optionName string) (isFlag bool) {
	if option, found := options.FindOption(optionName); found && option.Flags&Flag != 0 {
		isFlag = true
	}

	return isFlag
}

func (options Options) ConfigOptionKey() (key string) {
	for _, option := range options.definitions {
		if option.Flags&IsConfigFile > 0 {
			key = option.Key()
			break
		}
	}

	return
}

func (options Options) RequiredArguments() (requiredOptions Options) {
	for _, cur := range options.definitions {
		if cur.Flags&Required != 0 && cur.Flags&IsArg != 0 {
			requiredOptions.definitions = append(requiredOptions.definitions, cur)
		}
	}

	return
}

func (options Options) RequiredOptions() (requiredOptions []string) {
	for _, cur := range options.definitions {
		if cur.Flags&Required != 0 && cur.Flags&IsArg == 0 && cur.Flags&IsPassThrough == 0 {
			requiredOptions = append(requiredOptions, cur.LongOpt())
		}
	}

	return
}

func (options Options) UsageCustomArg0(arg0 string) (output string) {
	output = "Usage: " + arg0

	passThroughSeparatorPrinted := false
	for _, option := range options.definitions {
		if option.Flags&IsPassThrough > 0 && !passThroughSeparatorPrinted {
			output = output + " --"
			passThroughSeparatorPrinted = true
		}

		output = output + " " + option.Usage()
	}

	output = output + "\n\n"

	return
}

func (options Options) Usage() (output string) {
	return options.UsageCustomArg0(filepath.Base(os.Args[0]))
}

func (options Options) Help(description string) (output string) {
	return options.HelpCustomArg0(description, filepath.Base(os.Args[0]))
}

func (options Options) HelpCustomArg0(description string, arg0 string) (output string) {
	output = options.UsageCustomArg0(arg0)
	if options.description != "" {
		output = output + string(options.description) + "\n\n"
	}
<commit_msg>split Usage function for later use in sub command overview<commit_after>// Copyright (c) 2011, SoundCloud Ltd., <NAME>
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Source code and contact info at http://github.com/kesselborn/go-getopt

package getopt

import (
	"fmt"
	"os"
	"path/filepath"
)

type Definitions []Option
type Description string

type Options struct {
	description Description
	definitions Definitions
}

func (optionsDefinition Options) setEnvAndConfigValues(options map[string]OptionValue, environment map[string]string) (err *GetOptError) {
	significantEnvVars := make(map[string]Option)

	for _, opt := range optionsDefinition.definitions {
		if value := opt.EnvVar(); value != "" {
			significantEnvVars[value] = opt
		}
	}

	for key, significantEnvVar := range significantEnvVars {
		if value := environment[key]; value != "" {
			options[significantEnvVar.Key()], err = assignValue(significantEnvVar.DefaultValue, value)
			if err != nil {
				break
			}
		}
	}

	return
}

func checkOptionsDefinitionConsistency(optionsDefinition Options) (err *GetOptError) {
	consistencyErrorPrefix := "wrong getopt usage: "

	foundOptionalArg := false
	for _, option := range optionsDefinition.definitions {
		switch {
		case option.Flags&IsArg > 0 && option.Flags&Required == 0 && option.Flags&Optional == 0:
			err = &GetOptError{ConsistencyError, consistencyErrorPrefix + "an argument must be explicitly set to be Optional or Required"}
		case option.Flags&IsArg > 0 && option.Flags&Optional > 0:
			foundOptionalArg = true
		case option.Flags&IsArg > 0 && option.Flags&Required > 0 && foundOptionalArg:
			err = &GetOptError{ConsistencyError, consistencyErrorPrefix + "a required argument can't come after an optional argument"}
		case option.Flags&Optional > 0 && option.Flags&Required > 0:
			err = &GetOptError{ConsistencyError, consistencyErrorPrefix + "an option can not be Required and Optional"}
		case option.Flags&Flag > 0 && option.Flags&ExampleIsDefault > 0:
			err = &GetOptError{ConsistencyError, consistencyErrorPrefix + "an option can not be a Flag and have ExampleIsDefault"}
		case option.Flags&Required > 0 && option.Flags&ExampleIsDefault > 0:
			err = &GetOptError{ConsistencyError, consistencyErrorPrefix + "an option can not be Required and have ExampleIsDefault"}
		case option.Flags&NoLongOpt > 0 && !option.HasShortOpt() && option.Flags&IsArg == 0:
			err = &GetOptError{ConsistencyError, consistencyErrorPrefix + "an option must have either NoLongOpt or a ShortOption"}
		case option.Flags&Flag > 0 && option.Flags&IsArg > 0:
			err = &GetOptError{ConsistencyError, consistencyErrorPrefix + "an option can not be a Flag and be an argument (IsArg)"}
		}
	}

	return
}

func (options Options) FindOption(optionString string) (option Option, found bool) {
	for _, cur := range options.definitions {
		if cur.ShortOpt() == optionString || cur.LongOpt() == optionString {
			option = cur
			found = true
			break
		}
	}

	return option, found
}

func (options Options) IsOptional(optionName string) (isRequired bool) {
	if option, found := options.FindOption(optionName); found && option.Flags&Optional != 0 {
		isRequired = true
	}

	return isRequired
}

func (options Options) IsRequired(optionName string) (isRequired bool) {
	if option, found := options.FindOption(optionName); found && option.Flags&Required != 0 {
		isRequired = true
	}

	return isRequired
}

func (options Options) IsFlag(optionName string) (isFlag bool) {
	if option, found := options.FindOption(optionName); found && option.Flags&Flag != 0 {
		isFlag = true
	}

	return isFlag
}

func (options Options) ConfigOptionKey() (key string) {
	for _, option := range options.definitions {
		if option.Flags&IsConfigFile > 0 {
			key = option.Key()
			break
		}
	}

	return
}

func (options Options) RequiredArguments() (requiredOptions Options) {
	for _, cur := range options.definitions {
		if cur.Flags&Required != 0 && cur.Flags&IsArg != 0 {
			requiredOptions.definitions = append(requiredOptions.definitions, cur)
		}
	}

	return
}

func (options Options) RequiredOptions() (requiredOptions []string) {
	for _, cur := range options.definitions {
		if cur.Flags&Required != 0 && cur.Flags&IsArg == 0 && cur.Flags&IsPassThrough == 0 {
			requiredOptions = append(requiredOptions, cur.LongOpt())
		}
	}

	return
}

func (options Options) commandDefinition(arg0 string) (output string) {
  output = arg0

	passThroughSeparatorPrinted := false
	for _, option := range options.definitions {
		if option.Flags&IsPassThrough > 0 && !passThroughSeparatorPrinted {
			output = output + " --"
			passThroughSeparatorPrinted = true
		}

		output = output + " " + option.Usage()
	}

  return
}

func (options Options) UsageCustomArg0(arg0 string) (output string) {
  return "Usage: " + options.commandDefinition(arg0)  + "\n\n"
}

func (options Options) Usage() (output string) {
	return options.UsageCustomArg0(filepath.Base(os.Args[0]))
}

func (options Options) Help(description string) (output string) {
	return options.HelpCustomArg0(description, filepath.Base(os.Args[0]))
}

func (options Options) HelpCustomArg0(description string, arg0 string) (output string) {
	output = options.UsageCustomArg0(arg0)
	if options.description != "" {
		output = output + string(options.description) + "\n\n"
	}

{'fraction_non_alphanumeric': 0.11367505201437487, 'fraction_numerical': 0.008133156799697372, 'mean_word_length': 4.610079575596817, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 37, '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': '6453895', 'n_tokens_mistral': 3402, 'n_tokens_neox': 3133, 'n_words': 908}