func newCommandGroup(name string, ptr interface{}) *CommandGroup {
	ptrVal := reflect.ValueOf(ptr)
	if !isPtrToStruct(ptrVal) {
		panic("The passed interface is not a pointer to a struct.")
	}
	structVal := reflect.ValueOf(ptr).Elem()
	structTyp := reflect.TypeOf(ptr).Elem()
	cmdGroup := CommandGroup{
		command:     ptr,
		commandName: name,
	}
	cmdGroup.subCommandByName = make(map[string]reflect.Value)
	for i := 0; i < structVal.NumMethod(); i++ {
		methodName := structTyp.Method(i).Name
		lowerName := strings.ToLower(methodName)
		cmdGroup.subCommandByName[lowerName] = structVal.MethodByName(methodName)
	}
	cmdGroup.subCommandGroups = make(map[string]*CommandGroup)
	for i := 0; i < structVal.NumField(); i++ {
		fieldTyp := structTyp.Field(i)
		fieldVal := structVal.Field(i)
		if isPtrToStruct(fieldVal) {
			lowerName := strings.ToLower(fieldTyp.Name)
			cmdGroup.subCommandGroups[lowerName] = newCommandGroup(
				lowerName, fieldVal.Interface(),
			)
		}
	}
	return &cmdGroup
}
newCommandGroup constructs a new command group from a struct pointer
package simplecli
import (
	"fmt"
	"os"
	"reflect"
	"strconv"
	"strings"
)
var programName = os.Args[0]
var programArgs = os.Args[1:]
const OptionPrefix = `--`
func Handle(command interface{}) {
	cmdGroup := newCommandGroup(programName, command)
	defer cmdGroup.gracefulExit()
	cmdGroup.handle(programArgs)
}
type CommandGroup struct {
	command          interface{}
	commandName      string
	subCommandByName map[string]reflect.Value
	subCommandGroups map[string]*CommandGroup
}