func createCharts(vcs, dir, path string) error {
	target := dir + "/" + path
	if path == "/" {
		target = dir
	}
	if strings.HasPrefix(path, "/") {
		target = dir + path
	}
	log.Info("vcs source dir is", "dir", target)
	files, err := ioutil.ReadDir(target)
	if err != nil {
		log.Error(err, "read vcs source dir error")
		return err
	}
	dest := tempChartsDir + vcs
	p := action.Package{
		Destination: dest,
	}
TOP:
	for _, f := range files {
		if !f.IsDir() && f.Name() == "Chart.yaml" {
			log.Info("vsc source dir is a helm package", "dir", target)
			_, err := p.Run(target, nil)
			if err != nil {
				log.Error(err, "package chart error")
				return err
			}
			return nil
		}
		if f.Name() == ".git" || f.Name() == ".svn" {
			continue
		}
		if f.IsDir() {
			sp := filepath.Join(target, f.Name())
			files, err := ioutil.ReadDir(sp)
			if err != nil {
				log.Error(err, "read vcs source sub dir error", "name", sp)
				return err
			}
			for _, f := range files {
				if !f.IsDir() && f.Name() == "Chart.yaml" {
					result, err := packageChart(sp, dest)
					if err != nil {
						log.Error(err, "package chart error")
						return err
					}
					log.Info("package chart done", "path", sp, "result", result)
					continue TOP
				}
			}
		}
	}
	return nil
}
createCharts create chart from source dir. We should support two scenario:
1. the path is a helm chart dir
2. the patch contains multiple chart
package helm
import (
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"path/filepath"
	"strings"
	"helm.sh/helm/v3/pkg/action"
	"helm.sh/helm/v3/pkg/chart/loader"
	"helm.sh/helm/v3/pkg/chartutil"
	ctrl "sigs.k8s.io/controller-runtime"
)
var tempChartsDir = "/tmp/vcs-charts/"
var log = ctrl.Log.WithName("helm")
func uploadCharts(repoName string) error {
	url := fmt.Sprintf("%s/api/%s/charts?force=true", "http://captain-chartmuseum:8080", repoName)
	dir := tempChartsDir + repoName
	if _, err := os.Stat(dir); os.IsNotExist(err) {
		log.Info("vcs charts dir not exist, consider no charts found, skip upload", "name", repoName)
		return nil
	}
	files, err := ioutil.ReadDir(dir)
	if err != nil {
		log.Error(err, "read local charts dir error")
		return err
	}
	for _, f := range files {
		if !f.IsDir() {
			if err := postChart(url, filepath.Join(dir, f.Name())); err != nil {
				log.Error(err, "upload chart error", "filename", f.Name())
				return err
			}
			log.Info("upload chart done", "filename", f.Name())
		}
	}
	return nil
}
func SouceToChartRepo(name, dir, path string) error {
	if err := createCharts(name, dir, path); err != nil {
		return err
	}
	if err := uploadCharts(name); err != nil {
		return err
	}
	return nil
}