<commit_before>// Package cli is a library to help creating command line tools.
package cli

import (
	"flag"
	"fmt"
	"os"
)

// To add a module, implement this interface. Definition is the command
// definition. Exec is the behaviour that you want to implement as a command
type Command interface {
	Definition() string // usually it's the output for --help
	Exec(args []string) error
}

// Module is the shared structure of commands and sub-commands.
type Module struct {
	children map[string]*Module // Non-nil if sub-command
	command  Command            // Non-nil if command
}

// NewCLI returns a root Module that you can add commands and
// another modules (sub-commands).
func NewCLI() *Module {
	return &Module{
		children: make(map[string]*Module, 0),
	}
}

// AddCommand adds a new command this module.
func (m *Module) AddCommand(name string, command Command) {
	child := &Module{
		command: command,
	}
	m.children[name] = child
}

// AddSubCommand adds a new sub-command this module.
func (m *Module) AddSubCommand(name string) *Module {
	child := &Module{
		children: make(map[string]*Module, 0),
	}
	m.children[name] = child
	return child
}

// Run is the function that is intended to be run from main().
func (m *Module) Run() {
	flag.Parse()
	args := flag.Args()

	command, args, err := m.findCommand(args)
	if err != nil {
		exitErr(err)
	}

	err = command.Exec(args)
	if err != nil {
		exitErr(err)
	}

	os.Exit(0)
}

func (m *Module) findCommand(args []string) (Command, []string, error) {
	newArgs := args // this is the subset of args and will be returned with command

	// Iterate over args and update the module pointer "m"
	for _, arg := range args {
		if m.command == nil {
			// m is a sub-command
			m = m.children[arg]
			newArgs = args[1:]
			continue
		}
	}

	if m == nil {
		return nil, nil, fmt.Errorf("Command not found")
	}

	// m is a command or sub-command we don't care because we are
	// returning Command interface
	return m, newArgs, nil
}

func exitErr(err error) {
	fmt.Fprintf(os.Stderr, "%s\n", err.Error())
	os.Exit(1)
}

////////////////////////////////////////////////////////////////////////
// Methods below implement Command interface for Module (sub-command) //
////////////////////////////////////////////////////////////////////////

func (m *Module) Definition() string {
	if m.command != nil {
		// m is a command<commit_msg>fix args<commit_after>// Package cli is a library to help creating command line tools.
package cli

import (
	"flag"
	"fmt"
	"os"
)

// To add a module, implement this interface. Definition is the command
// definition. Exec is the behaviour that you want to implement as a command
type Command interface {
	Definition() string // usually it's the output for --help
	Exec(args []string) error
}

// Module is the shared structure of commands and sub-commands.
type Module struct {
	children map[string]*Module // Non-nil if sub-command
	command  Command            // Non-nil if command
}

// NewCLI returns a root Module that you can add commands and
// another modules (sub-commands).
func NewCLI() *Module {
	return &Module{
		children: make(map[string]*Module, 0),
	}
}

// AddCommand adds a new command this module.
func (m *Module) AddCommand(name string, command Command) {
	child := &Module{
		command: command,
	}
	m.children[name] = child
}

// AddSubCommand adds a new sub-command this module.
func (m *Module) AddSubCommand(name string) *Module {
	child := &Module{
		children: make(map[string]*Module, 0),
	}
	m.children[name] = child
	return child
}

// Run is the function that is intended to be run from main().
func (m *Module) Run() {
	flag.Parse()
	args := flag.Args()

	command, args, err := m.findCommand(args)
	if err != nil {
		exitErr(err)
	}

	err = command.Exec(args)
	if err != nil {
		exitErr(err)
	}

	os.Exit(0)
}

func (m *Module) findCommand(args []string) (Command, []string, error) {
	newArgs := args // this is the subset of args and will be returned with command

	// Iterate over args and update the module pointer "m"
	for _, arg := range args {
		if m.children != nil {
			// m is a sub-command
			m = m.children[arg]
			newArgs = newArgs[1:]
			continue
		}
	}

	if m == nil {
		return nil, nil, fmt.Errorf("Command not found")
	}

	// m is a command or sub-command we don't care because we are
	// returning Command interface
	return m, newArgs, nil
}

func exitErr(err error) {
	fmt.Fprintf(os.Stderr, "%s\n", err.Error())
	os.Exit(1)
}

////////////////////////////////////////////////////////////////////////
// Methods below implement Command interface for Module (sub-command) //
////////////////////////////////////////////////////////////////////////

func (m *Module) Definition() string {
	if m.command != nil {
		// m is a command
{'fraction_non_alphanumeric': 0.17509972706277557, 'fraction_numerical': 0.0020995171110644553, 'mean_word_length': 2.5873493975903616, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, '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': '7230573', 'n_tokens_mistral': 1499, 'n_tokens_neox': 1438, 'n_words': 556}