forked from AliyunContainerService/pouch
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathparse.go
134 lines (111 loc) · 2.69 KB
/
parse.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
package reference
import (
"errors"
digest "github.com/opencontainers/go-digest"
)
var (
// ErrInvalid is used to return error if reference is invalid
ErrInvalid = errors.New("invalid reference")
// defaultTag is latest if there is no tag
defaultTag = "latest"
)
// Parse parses ref into reference.Named.
func Parse(ref string) (Named, error) {
if ok := regRef.MatchString(ref); !ok {
return nil, ErrInvalid
}
name, tag, digStr := splitReference(ref)
namedRef := namedReference{name}
if digStr != "" {
dig, err := digest.Parse(digStr)
if err != nil {
return nil, err
}
if tag == "" {
return canonicalDigestedReference{
Named: namedRef,
digest: dig,
}, nil
}
return reference{
Named: namedRef,
tag: tag,
digest: dig,
}, nil
}
if tag != "" {
return taggedReference{
Named: namedRef,
tag: tag,
}, nil
}
return namedRef, nil
}
// WithDefaultTagIfMissing adds default tag "latest" for the Named reference.
func WithDefaultTagIfMissing(named Named) Named {
if IsNamedOnly(named) {
return taggedReference{
Named: named,
tag: defaultTag,
}
}
return named
}
// WithTag adds tag for the Named reference.
func WithTag(named Named, tag string) Named {
return taggedReference{
Named: named,
tag: tag,
}
}
// WithDigest adds digest for the Named reference.
func WithDigest(named Named, dig digest.Digest) Named {
return canonicalDigestedReference{
Named: named,
digest: dig,
}
}
// TrimTagForDigest removes the tag information if the Named reference is digest.
func TrimTagForDigest(named Named) Named {
if digRef, ok := named.(Digested); ok {
return WithDigest(named, digRef.Digest())
}
return named
}
// IsNamedOnly return true if the ref is the Named without tag or digest.
func IsNamedOnly(ref Named) bool {
if _, ok := ref.(Tagged); ok {
return false
}
if _, ok := ref.(CanonicalDigested); ok {
return false
}
return true
}
// IsCanonicalDigested return true if the ref is the canonical digested reference.
func IsCanonicalDigested(ref Named) bool {
if _, ok := ref.(Tagged); ok {
return false
}
_, ok := ref.(CanonicalDigested)
return ok
}
// IsNameTagged return true if the ref is the Named with tag.
func IsNameTagged(ref Named) bool {
if _, ok := ref.(Digested); ok {
return false
}
_, ok := ref.(Tagged)
return ok
}
// splitReference splits reference into name, tag and digest in string format.
func splitReference(ref string) (name string, tag string, digStr string) {
name = ref
if loc := regDigest.FindStringIndex(name); loc != nil {
name, digStr = name[:loc[0]], name[loc[0]+1:]
}
if loc := regTag.FindStringIndex(name); loc != nil {
name, tag = name[:loc[0]], name[loc[0]+1:]
}
return
}