func (ref *Reference) FullName() string {
	if ref.Tag == "" {
		return ref.Repo
	}
	return fmt.Sprintf("%s:%s", ref.Repo, ref.Tag)
}
FullName the full name of a reference (repo:tag)
package registry  
import (
	"errors"
	"fmt"
	"net/url"
	"regexp"
	"strconv"
	"strings"
)
var (
	validPortRegEx = regexp.MustCompile(`^([1-9]\d{0,3}|0|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$`)  
	referenceDelimiter = regexp.MustCompile(`[:]`)
	errEmptyRepo       = errors.New("parsed repo was empty")
	errTooManyColons   = errors.New("ref may only contain a single colon character (:) unless specifying a port number")
)
type (
	Reference struct {
		Tag  string
		Repo string
	}
)
func ParseReference(s string) (*Reference, error) {
	if s == "" {
		return nil, errEmptyRepo
	}
	splitComponents := fixSplitComponents(referenceDelimiter.Split(s, -1))
	if len(splitComponents) > 3 {
		return nil, errTooManyColons
	}
	var ref *Reference
	switch len(splitComponents) {
	case 1:
		ref = &Reference{Repo: splitComponents[0]}
	case 2:
		ref = &Reference{Repo: splitComponents[0], Tag: splitComponents[1]}
	case 3:
		ref = &Reference{Repo: strings.Join(splitComponents[:2], ":"), Tag: splitComponents[2]}
	}
	err := ref.validate()
	if err != nil {
		return nil, err
	}
	return ref, nil
}