NewTag returns a new Tag representing the given name, according to the given strictness.
(name string, opts ...Option)
| 75 | |
| 76 | // NewTag returns a new Tag representing the given name, according to the given strictness. |
| 77 | func NewTag(name string, opts ...Option) (Tag, error) { |
| 78 | opt := makeOptions(opts...) |
| 79 | base := name |
| 80 | tag := "" |
| 81 | |
| 82 | // Split on ":" |
| 83 | parts := strings.Split(name, tagDelim) |
| 84 | // Verify that we aren't confusing a tag for a hostname w/ port for the purposes of weak validation. |
| 85 | if len(parts) > 1 && !strings.Contains(parts[len(parts)-1], regRepoDelimiter) { |
| 86 | base = strings.Join(parts[:len(parts)-1], tagDelim) |
| 87 | tag = parts[len(parts)-1] |
| 88 | if tag == "" { |
| 89 | return Tag{}, newErrBadName("%s must specify a tag name after the colon", name) |
| 90 | } |
| 91 | } |
| 92 | |
| 93 | // We don't require a tag, but if we get one check it's valid, |
| 94 | // even when not being strict. |
| 95 | // If we are being strict, we want to validate the tag regardless in case |
| 96 | // it's empty. |
| 97 | if tag != "" || opt.strict { |
| 98 | if err := checkTag(tag); err != nil { |
| 99 | return Tag{}, err |
| 100 | } |
| 101 | } |
| 102 | |
| 103 | if tag == "" { |
| 104 | tag = opt.defaultTag |
| 105 | } |
| 106 | |
| 107 | repo, err := NewRepository(base, opts...) |
| 108 | if err != nil { |
| 109 | return Tag{}, err |
| 110 | } |
| 111 | return Tag{ |
| 112 | Repository: repo, |
| 113 | tag: tag, |
| 114 | original: name, |
| 115 | }, nil |
| 116 | } |
| 117 | |
| 118 | // MarshalJSON formats the Tag into a string for JSON serialization. |
| 119 | func (t Tag) MarshalJSON() ([]byte, error) { return json.Marshal(t.String()) } |
searching dependent graphs…