func GetMinor(part string) string {
	minor := part
	index := strings.Index(minor, "beta")
	if index < 0 {
		index = strings.Index(minor, "rc")
	}
	if index > 0 {
		minor = minor[:index]
	}
	return minor
}
GetMinor returns the minor part of the version number.
package extract
import (
	"bytes"
	"fmt"
	"go/constant"
	"go/format"
	"go/types"
	"math/big"
	"os"
	"path"
	"regexp"
	"runtime"
	"strconv"
	"strings"
	"text/template"
)
const model = `
package {{.Dest}}
import (
{{- range $key, $value := .Imports }}
	{{- if $value}}
	"{{$key}}"
	{{- end}}
{{- end}}
{{- if .ImportSelf}}
	"{{.PkgName}}"
{{- end}}
	"reflect"
	"github.com/got-reload/got-reload/pkg/reloader"
	_ "github.com/got-reload/got-reload/pkg/reloader/start"
)
func init() {
	reloader.RegisterAll(map[string]map[string]reflect.Value{
    	                  "{{.PkgName}}": {
		{{- if .Val}}
		{{range $key, $value := .Val -}}
			{{- if $value.Addr -}}
				"{{$key}}": reflect.ValueOf(&{{$value.Name}}).Elem(),
			{{else -}}
				"{{$key}}": reflect.ValueOf({{$value.Name}}),
			{{end -}}
		{{end}}
		{{- end}}
		{{- if .Typ}}
		{{range $key, $value := .Typ -}}
			"{{$key}}": reflect.ValueOf((*{{$value}})(nil)),
		{{end}}
		{{- end}}
		{{- if .Wrap}}
		{{range $key, $value := .Wrap -}}
			"_{{$key}}": reflect.ValueOf((*{{$value.Name}})(nil)),
		{{end}}
		{{- end}}
	},
	})
}
{{range $key, $value := .Wrap -}}
	type {{$value.Name}} struct {
		{{range $m := $value.Method -}}
		W{{$m.Name}} func{{$m.Param}} {{$m.Result}}
		{{end}}
	}
	{{range $m := $value.Method -}}
		func (W {{$value.Name}}) {{$m.Name}}{{$m.Param}} {{$m.Result}} { {{$m.Ret}} W.W{{$m.Name}}{{$m.Arg}} }
	{{end}}
{{end}}
`
type Val struct {
	Name string  
	Addr bool    
}
type Method struct {
	Name, Param, Result, Arg, Ret string
}
type Wrap struct {
	Name   string
	Method []Method
}
var restricted = map[string]bool{
	"osExit":        true,
	"osFindProcess": true,
	"logFatal":      true,
	"logFatalf":     true,
	"logFatalln":    true,
	"logLogger":     true,
	"logNew":        true,
}
func matchList(name string, list []string) (match bool, err error) {
	for _, re := range list {
		match, err = regexp.MatchString(re, name)
		if err != nil || match {
			return
		}
	}
	return
}
func GenContent(destPkg, importPath string, importSelf bool, p *types.Package, setFuncs []string, exported map[types.Object]bool) ([]byte, error) {
	prefix := "_" + importPath + "_"
	prefix = strings.NewReplacer("/", "_", "-", "_", ".", "_").Replace(prefix)
	typ := map[string]string{}
	val := map[string]Val{}
	wrap := map[string]Wrap{}
	imports := map[string]bool{}
	sc := p.Scope()
	for _, pkg := range p.Imports() {
		imports[pkg.Path()] = false
	}
	qualify := func(pkg *types.Package) string {
		if pkg.Path() != importPath {
			imports[pkg.Path()] = true
		}
		return pkg.Name()
	}
	for _, name := range sc.Names() {
		o := sc.Lookup(name)
		if exported[o] {
			name = "GRL_" + name
		} else if !o.Exported() {
			continue
		}
		pname := name
		if importSelf {
			pname = path.Base(importPath) + "." + name
		}
		switch o := o.(type) {
		case *types.Const:
			if b, ok := o.Type().(*types.Basic); ok && (b.Info()&types.IsUntyped) != 0 {
				val[name] = Val{fixConst(pname, o.Val(), imports), false}
			} else {
				val[name] = Val{pname, false}
			}
		case *types.Func:
			val[name] = Val{pname, false}
		case *types.Var:
			val[name] = Val{pname, true}
		case *types.TypeName:
			typ[name] = pname
			if t, ok := o.Type().Underlying().(*types.Interface); ok {
				var methods []Method
				for i := 0; i < t.NumMethods(); i++ {
					f := t.Method(i)
					if !f.Exported() {
						continue
					}
					sign := f.Type().(*types.Signature)
					args := make([]string, sign.Params().Len())
					params := make([]string, len(args))
					for j := range args {
						v := sign.Params().At(j)
						if args[j] = v.Name(); args[j] == "" {
							args[j] = fmt.Sprintf("a%d", j)
						}
						params[j] = args[j] + " " + types.TypeString(v.Type(), qualify)
					}
					arg := "(" + strings.Join(args, ", ") + ")"
					param := "(" + strings.Join(params, ", ") + ")"
					results := make([]string, sign.Results().Len())
					for j := range results {
						v := sign.Results().At(j)
						results[j] = v.Name() + " " + types.TypeString(v.Type(), qualify)
					}
					result := "(" + strings.Join(results, ", ") + ")"
					ret := ""
					if sign.Results().Len() > 0 {
						ret = "return"
					}
					methods = append(methods, Method{f.Name(), param, result, arg, ret})
				}
				wrap[name] = Wrap{prefix + name, methods}
			}
		}
	}
	for _, name := range setFuncs {
		val[name] = Val{name, false}
	}
	var buildTags string
	if isInStdlib(importPath) {
		var err error
		buildTags, err = genBuildTags()
		if err != nil {
			return nil, err
		}
	}
	base := template.New("extract")
	parse, err := base.Parse(model)
	if err != nil {
		return nil, fmt.Errorf("template parsing error: %w", err)
	}
	if importPath == "log/syslog" {
		buildTags += ",!windows,!nacl,!plan9"
	}
	if importPath == "syscall" {
		switch os.Getenv("GOOS") {
		case "android":
			buildTags += ",!linux"
		case "illumos":
			buildTags += ",!solaris"
		}
	}
	b := new(bytes.Buffer)
	data := map[string]interface{}{
		"Dest":    destPkg,
		"Imports": imports,
		"ImportSelf": importSelf,
		"PkgName":    importPath,
		"Val":        val,
		"Typ":        typ,
		"Wrap":       wrap,
		"BuildTags":  buildTags,
	}
	err = parse.Execute(b, data)
	if err != nil {
		return nil, fmt.Errorf("template error: %w", err)
	}
	source, err := format.Source(b.Bytes())
	if err != nil {
		return nil, fmt.Errorf("failed to format source: %w: %s", err, b.Bytes())
	}
	return source, nil
}
func fixConst(name string, val constant.Value, imports map[string]bool) string {
	var (
		tok string
		str string
	)
	switch val.Kind() {
	case constant.String:
		tok = "STRING"
		str = val.ExactString()
	case constant.Int:
		tok = "INT"
		str = val.ExactString()
	case constant.Float:
		v := constant.Val(val)  
		f, ok := v.(*big.Float)
		if !ok {
			f = new(big.Float).SetRat(v.(*big.Rat))
		}
		tok = "FLOAT"
		str = f.Text('g', int(f.Prec()))
	case constant.Complex:
		fallthrough
	default:
		return name
	}
	imports["go/constant"] = true
	imports["go/token"] = true
	return fmt.Sprintf("constant.MakeFromLiteral(%q, token.%s, 0)", str, tok)
}