reference: introduce remoteName variable

This pattern was used in two places, so adding an intermediate variable allows
documenting its purpose. The "remote-name" grammer (which is interchangably
used with "path") also seemed to be missing from the grammar, so adding it.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn 2022-11-10 13:25:03 +01:00
parent 71a0666398
commit bbd41f40bb
No known key found for this signature in database
GPG key ID: 76698F39D527CE8C
3 changed files with 16 additions and 9 deletions

View file

@ -58,14 +58,14 @@ func ParseNormalizedNamed(s string) (Named, error) {
return nil, fmt.Errorf("invalid repository name (%s), cannot specify 64-byte hexadecimal strings", s) return nil, fmt.Errorf("invalid repository name (%s), cannot specify 64-byte hexadecimal strings", s)
} }
domain, remainder := splitDockerDomain(s) domain, remainder := splitDockerDomain(s)
var remoteName string var remote string
if tagSep := strings.IndexRune(remainder, ':'); tagSep > -1 { if tagSep := strings.IndexRune(remainder, ':'); tagSep > -1 {
remoteName = remainder[:tagSep] remote = remainder[:tagSep]
} else { } else {
remoteName = remainder remote = remainder
} }
if strings.ToLower(remoteName) != remoteName { if strings.ToLower(remote) != remote {
return nil, fmt.Errorf("invalid reference format: repository name (%s) must be lowercase", remoteName) return nil, fmt.Errorf("invalid reference format: repository name (%s) must be lowercase", remote)
} }
ref, err := Parse(domain + "/" + remainder) ref, err := Parse(domain + "/" + remainder)
@ -120,7 +120,7 @@ func ParseDockerRef(ref string) (Named, error) {
return TagNameOnly(named), nil return TagNameOnly(named), nil
} }
// splitDockerDomain splits a repository name to domain and remotename string. // splitDockerDomain splits a repository name to domain and remote-name.
// If no valid domain is found, the default domain is used. Repository name // If no valid domain is found, the default domain is used. Repository name
// needs to be already validated before. // needs to be already validated before.
func splitDockerDomain(name string) (domain, remainder string) { func splitDockerDomain(name string) (domain, remainder string) {

View file

@ -4,13 +4,14 @@
// Grammar // Grammar
// //
// reference := name [ ":" tag ] [ "@" digest ] // reference := name [ ":" tag ] [ "@" digest ]
// name := [domain '/'] path-component ['/' path-component]* // name := [domain '/'] remote-name
// domain := host [':' port-number] // domain := host [':' port-number]
// host := domain-name | IPv4address | \[ IPv6address \] ; rfc3986 appendix-A // host := domain-name | IPv4address | \[ IPv6address \] ; rfc3986 appendix-A
// domain-name := domain-component ['.' domain-component]* // domain-name := domain-component ['.' domain-component]*
// domain-component := /([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])/ // domain-component := /([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])/
// port-number := /[0-9]+/ // port-number := /[0-9]+/
// path-component := alpha-numeric [separator alpha-numeric]* // path-component := alpha-numeric [separator alpha-numeric]*
// path (or "remote-name") := path-component ['/' path-component]*
// alpha-numeric := /[a-z0-9]+/ // alpha-numeric := /[a-z0-9]+/
// separator := /[_.]|__|[-]*/ // separator := /[_.]|__|[-]*/
// //

View file

@ -101,7 +101,13 @@ var (
// character, with following parts able to be separated by a separator // character, with following parts able to be separated by a separator
// (one period, one or two underscore and multiple dashes). // (one period, one or two underscore and multiple dashes).
pathComponent = alphanumeric + anyTimes(separator+alphanumeric) pathComponent = alphanumeric + anyTimes(separator+alphanumeric)
namePat = optional(domainAndPort+`/`) + pathComponent + anyTimes(`/`+pathComponent)
// remoteName matches the remote-name of a repository. It consists of one
// or more forward slash (/) delimited path-components:
//
// pathComponent[[/pathComponent] ...] // e.g., "library/ubuntu"
remoteName = pathComponent + anyTimes(`/`+pathComponent)
namePat = optional(domainAndPort+`/`) + remoteName
// NameRegexp is the format for the name component of references, including // NameRegexp is the format for the name component of references, including
// an optional domain and port, but without tag or digest suffix. // an optional domain and port, but without tag or digest suffix.
@ -109,7 +115,7 @@ var (
// anchoredNameRegexp is used to parse a name value, capturing the // anchoredNameRegexp is used to parse a name value, capturing the
// domain and trailing components. // domain and trailing components.
anchoredNameRegexp = regexp.MustCompile(anchored(optional(capture(domainAndPort), `/`), capture(pathComponent, anyTimes(`/`+pathComponent)))) anchoredNameRegexp = regexp.MustCompile(anchored(optional(capture(domainAndPort), `/`), capture(remoteName)))
referencePat = anchored(capture(namePat), optional(`:`, capture(tag)), optional(`@`, capture(digestPat))) referencePat = anchored(capture(namePat), optional(`:`, capture(tag)), optional(`@`, capture(digestPat)))