...

Source file src/github.com/google/go-containerregistry/pkg/name/tag.go

Documentation: github.com/google/go-containerregistry/pkg/name

     1  // Copyright 2018 Google LLC All Rights Reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //    http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package name
    16  
    17  import (
    18  	"strings"
    19  )
    20  
    21  const (
    22  	// TODO(dekkagaijin): use the docker/distribution regexes for validation.
    23  	tagChars = "abcdefghijklmnopqrstuvwxyz0123456789_-.ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    24  	tagDelim = ":"
    25  )
    26  
    27  // Tag stores a docker tag name in a structured form.
    28  type Tag struct {
    29  	Repository
    30  	tag      string
    31  	original string
    32  }
    33  
    34  // Ensure Tag implements Reference
    35  var _ Reference = (*Tag)(nil)
    36  
    37  // Context implements Reference.
    38  func (t Tag) Context() Repository {
    39  	return t.Repository
    40  }
    41  
    42  // Identifier implements Reference.
    43  func (t Tag) Identifier() string {
    44  	return t.TagStr()
    45  }
    46  
    47  // TagStr returns the tag component of the Tag.
    48  func (t Tag) TagStr() string {
    49  	return t.tag
    50  }
    51  
    52  // Name returns the name from which the Tag was derived.
    53  func (t Tag) Name() string {
    54  	return t.Repository.Name() + tagDelim + t.TagStr()
    55  }
    56  
    57  // String returns the original input string.
    58  func (t Tag) String() string {
    59  	return t.original
    60  }
    61  
    62  // Scope returns the scope required to perform the given action on the tag.
    63  func (t Tag) Scope(action string) string {
    64  	return t.Repository.Scope(action)
    65  }
    66  
    67  func checkTag(name string) error {
    68  	return checkElement("tag", name, tagChars, 1, 128)
    69  }
    70  
    71  // NewTag returns a new Tag representing the given name, according to the given strictness.
    72  func NewTag(name string, opts ...Option) (Tag, error) {
    73  	opt := makeOptions(opts...)
    74  	base := name
    75  	tag := ""
    76  
    77  	// Split on ":"
    78  	parts := strings.Split(name, tagDelim)
    79  	// Verify that we aren't confusing a tag for a hostname w/ port for the purposes of weak validation.
    80  	if len(parts) > 1 && !strings.Contains(parts[len(parts)-1], regRepoDelimiter) {
    81  		base = strings.Join(parts[:len(parts)-1], tagDelim)
    82  		tag = parts[len(parts)-1]
    83  	}
    84  
    85  	// We don't require a tag, but if we get one check it's valid,
    86  	// even when not being strict.
    87  	// If we are being strict, we want to validate the tag regardless in case
    88  	// it's empty.
    89  	if tag != "" || opt.strict {
    90  		if err := checkTag(tag); err != nil {
    91  			return Tag{}, err
    92  		}
    93  	}
    94  
    95  	if tag == "" {
    96  		tag = opt.defaultTag
    97  	}
    98  
    99  	repo, err := NewRepository(base, opts...)
   100  	if err != nil {
   101  		return Tag{}, err
   102  	}
   103  	return Tag{
   104  		Repository: repo,
   105  		tag:        tag,
   106  		original:   name,
   107  	}, nil
   108  }
   109  

View as plain text