github.com/mgoltzsche/ctnr@v0.7.1-alpha/pkg/fs/source/sourcefile.go (about)

     1  package source
     2  
     3  import (
     4  	"github.com/mgoltzsche/ctnr/pkg/fs"
     5  	"github.com/opencontainers/go-digest"
     6  	"github.com/pkg/errors"
     7  )
     8  
     9  var _ fs.Source = &sourceFile{}
    10  
    11  type sourceFile struct {
    12  	fs.Readable
    13  	attrs fs.NodeAttrs
    14  }
    15  
    16  func NewSourceFile(reader fs.Readable, attrs fs.FileAttrs) *sourceFile {
    17  	return NewSourceFileHashed(reader, attrs, "")
    18  }
    19  
    20  func NewSourceFileHashed(reader fs.Readable, attrs fs.FileAttrs, hash string) *sourceFile {
    21  	return &sourceFile{reader, fs.NodeAttrs{fs.NodeInfo{fs.TypeFile, attrs}, fs.DerivedAttrs{Hash: hash}}}
    22  }
    23  
    24  func (s *sourceFile) Attrs() fs.NodeInfo {
    25  	return s.attrs.NodeInfo
    26  }
    27  
    28  func (s *sourceFile) HashIfAvailable() string {
    29  	return s.attrs.Hash
    30  }
    31  
    32  func (s *sourceFile) Hash() (h string, err error) {
    33  	if s.attrs.Hash == "" {
    34  		f, err := s.Reader()
    35  		if err != nil {
    36  			return "", errors.Wrap(err, "hash")
    37  		}
    38  		defer func() {
    39  			if e := f.Close(); e != nil && err == nil {
    40  				err = e
    41  			}
    42  		}()
    43  		d, err := digest.FromReader(f)
    44  		if err != nil {
    45  			return "", errors.Errorf("hash %s: %s", s.Readable, err)
    46  		}
    47  		s.attrs.Hash = d.String()
    48  	}
    49  	return s.attrs.Hash, nil
    50  }
    51  
    52  func (s *sourceFile) DeriveAttrs() (fs.DerivedAttrs, error) {
    53  	_, err := s.Hash()
    54  	return s.attrs.DerivedAttrs, err
    55  }
    56  
    57  func (s *sourceFile) Write(path, name string, w fs.Writer, written map[fs.Source]string) (err error) {
    58  	if linkDest, ok := written[s]; ok {
    59  		err = w.Link(path, linkDest)
    60  	} else {
    61  		written[s] = path
    62  		_, err = w.File(path, s)
    63  	}
    64  	return err
    65  }
    66  
    67  func (s *sourceFile) Equal(o fs.Source) (bool, error) {
    68  	if !s.attrs.NodeInfo.Equal(o.Attrs()) {
    69  		return false, nil
    70  	}
    71  	oa, err := o.DeriveAttrs()
    72  	if err != nil {
    73  		return false, errors.Wrap(err, "equal")
    74  	}
    75  	a, err := s.DeriveAttrs()
    76  	return a.Equal(&oa), errors.Wrap(err, "equal")
    77  }