func CopyToTarget(ctx *cli.Context) error {
	if len(common.BuildConfig.Build.Copy) < 1 {
		color.White("- No folders need to copy!")
		return nil
	}
	for i := range common.BuildConfig.Build.Copy {
		folder := common.BuildConfig.Build.Copy[i]
		if len(folder) < 1 {
			continue
		}
		if err := copyCommand(folder, common.BuildTarget+"/"); err != nil {
			os.RemoveAll(common.BuildTarget)
			return err
		}
	}
	return nil
}
CopyToTarget Copy folders to target folder
package build
import (
	"errors"
	"fmt"
	"github.com/fatih/color"
	"github.com/ghodss/yaml"
	"github.com/rookie-ninja/rk-common/common"
	"github.com/rookie-ninja/rk/common"
	"github.com/urfave/cli/v2"
	"io/ioutil"
	"os"
	"os/exec"
	"path"
	"strings"
)
var (
	targetFolders = []string{
		"target",
		"target/bin",
	}
)
func ExecCommandsBefore(ctx *cli.Context) error {
	return execCommands(common.BuildConfig.Build.Commands.Before)
}
func ExecCommandsAfter(ctx *cli.Context) error {
	return execCommands(common.BuildConfig.Build.Commands.After)
}
func execCommands(commands []string) error {
	if len(commands) < 1 {
		color.White("- No user commands found!")
		return nil
	}
	for i := range commands {
		cmd := commands[i]
		tokens := strings.Split(cmd, " ")
		if len(tokens) < 1 || len(tokens[0]) < 1 {
			continue
		}
		color.White(fmt.Sprintf("- %s", cmd))
		if len(tokens) > 1 {
			bytes, err := exec.Command(tokens[0], tokens[1:]...).CombinedOutput()
			if err != nil {
				os.RemoveAll(common.BuildTarget)
				return err
			}
			color.White(string(bytes))
		} else {
			bytes, err := exec.Command(tokens[0]).CombinedOutput()
			if err != nil {
				os.RemoveAll(common.BuildTarget)
				return err
			}
			color.White(string(bytes))
		}
	}
	return nil
}
func ExecScriptBefore(ctx *cli.Context) error {
	return execScripts(common.BuildConfig.Build.Scripts.Before)
}
func ExecScriptAfter(ctx *cli.Context) error {
	return execScripts(common.BuildConfig.Build.Scripts.After)
}
func execScripts(scripts []string) error {
	if len(scripts) < 1 {
		color.White("- No user scripts found!")
		return nil
	}
	for i := range scripts {
		script := scripts[i]
		if len(script) < 1 {
			continue
		}
		color.White(fmt.Sprintf("- %s", script))
		bytes, err := exec.Command("sh", script).CombinedOutput()
		if err != nil {
			os.RemoveAll(common.BuildTarget)
			return err
		}
		color.White(string(bytes))
	}
	return nil
}
func WriteRkMetaFile(ctx *cli.Context) error {
	meta := common.GetRkMetaFromCmd()
	color.White("- Write files to %s", path.Join(common.BuildTarget, rkcommon.RkMetaFilePath))
	if raw, err := yaml.Marshal(meta); err != nil {
		color.Yellow("[Warn] %v", err)
	} else {
		if err := ioutil.WriteFile(path.Join(common.BuildTarget, rkcommon.RkMetaFilePath), raw, os.ModePerm); err != nil {
			color.Yellow("[Warn] %v", err)
		}
	}
	return nil
}
func BuildGoFile(ctx *cli.Context) error {
	os.MkdirAll(path.Join(common.BuildTarget, path.Dir(rkcommon.RkMetaFilePath)), os.ModePerm)
	if !rkcommon.FileExists("go.mod") {
		return errors.New("not a go directory, failed to lookup go.mod file")
	}
	for i := range targetFolders {
		if err := os.MkdirAll(targetFolders[i], os.ModePerm); err != nil {
			os.RemoveAll(common.BuildTarget)
			return nil
		}
	}
	if len(common.BuildConfig.Build.Main) < 1 {
		common.BuildConfig.Build.Main = "main.go"
	}
	if len(common.BuildConfig.Build.GOOS) > 0 {
		os.Setenv("GOOS", common.BuildConfig.Build.GOOS)
	}
	if len(common.BuildConfig.Build.GOARCH) > 0 {
		os.Setenv("GOARCH", common.BuildConfig.Build.GOARCH)
	}
	args := []string{
		"build",
		"-o",
		fmt.Sprintf("target/bin/%s", common.TargetPkgName),
	}
	for i := range common.BuildConfig.Build.Args {
		arg := common.BuildConfig.Build.Args[i]
		if len(arg) > 0 {
			args = append(args, strings.Split(arg, " ")...)
		}
	}
	args = append(args, common.BuildConfig.Build.Main)
	color.White("- go %s", strings.Join(args, " "))
	bytes, err := exec.Command("go", args...).CombinedOutput()
	if len(bytes) > 0 {
		color.White(string(bytes))
	}
	if err != nil {
		os.RemoveAll(common.BuildTarget)
		return err
	}
	copyCommand("boot.yaml", common.BuildTarget)
	copyCommand("README.md", path.Join(common.BuildTarget, rkcommon.RkReadmeFilePath))
	copyCommand("LICENSE", path.Join(common.BuildTarget, rkcommon.RkLicenseFilePath))
	copyCommand("go.mod", path.Join(common.BuildTarget, rkcommon.RkDepFilePath))
	copyCommand(path.Base(rkcommon.RkUtHtmlFilePath), path.Join(common.BuildTarget, rkcommon.RkUtHtmlFilePath))
	return nil
}