func NewPackageRoot(name string, url string, repo *git.Repository,
	shaCache *storage.ShaCache) (*PackageRoot, error) {
	versions := PkgRootVersions{}
	contextLog := log.WithFields(log.Fields{"name": name})
	latest := ""
	if err := repo.Tags.Foreach(func(tagRef string, id *git.Oid) error {
		contextLog := contextLog.WithFields(log.Fields{"tagRef": tagRef})
		if !versionTagRef.MatchString(tagRef) {
			contextLog.Debug("skipping non-version tag")
			return nil
		}
		PkgVersion, err := NewPkgVersion(repo, id)
		contextLog = contextLog.WithFields(log.Fields{"PkgVersion": PkgVersion})
		if err != nil || PkgVersion == nil {
			util.LogErr(contextLog, err, "failed to generate package version")
			return nil
		}
		if version, ok := (*PkgVersion)["version"].(string); ok {
			contextLog = contextLog.WithFields(log.Fields{"version": version})
			if versions[version] != nil {
				contextLog.Warn("duplicate version")
			}
			tarball := url + "/" + name + "/-/" + id.String() + ".tgz"
			shasum, ok := shaCache.Get(*id)
			if !ok {
				hasher := sha1.New()
				d, err := storage.NewDownload(repo, id)
				if err != nil || d == nil {
					util.LogErr(contextLog, err, "failed to create download")
					return nil
				}
				if err := d.Start(hasher); err != nil {
					util.LogErr(contextLog, err, "failed to start download")
					return nil
				}
				shasum = hex.EncodeToString(hasher.Sum(nil))
			}
			shaCache.Add(*id, shasum)
			(*PkgVersion)["dist"] = &PackageDist{tarball, shasum}
			versions[version] = PkgVersion
			latest = version
		}
		return nil
	}); err != nil {
		return nil, err
	}
	distTags := PackageDistTags{}
	if latest != "" {
		distTags["latest"] = latest
	}
	packageRoot := &PackageRoot{name, &distTags, &versions}
	return packageRoot, nil
}
NewPackageRoot creates a new CommonJS package root document.
package registry
import (
	"crypto/sha1"
	"encoding/hex"
	log "github.com/Sirupsen/logrus"
	"github.com/alexanderGugel/nerva/storage"
	"github.com/alexanderGugel/nerva/util"
	"github.com/libgit2/git2go"
	"net/http"
	"regexp"
)
type PackageRoot struct {
	Name     string           `json:"name"`
	DistTags *PackageDistTags `json:"dist-tags"`
	Versions *PkgRootVersions `json:"versions"`
}
type PkgRootVersions map[string]*PkgVersion
type PackageDistTags map[string]string
type PackageDist struct {
	Tarball string `json:"tarball"`
	Shasum  string `json:"shasum"`
}
var versionTagRef = regexp.MustCompile("^refs\\/tags\\/v(.*)$")