*: refactoring to support streams
when creating a manifest from, or validating, a stream like a tar archive, it requires thinking about some of the functions differently than walking a directory tree. This is the beginning of allowing for such features. Signed-off-by: Vincent Batts <vbatts@hashbangbash.com>
This commit is contained in:
parent
119cdc314c
commit
faa80931af
11 changed files with 534 additions and 133 deletions
41
keywords.go
41
keywords.go
|
@ -1,6 +1,7 @@
|
|||
package mtree
|
||||
|
||||
import (
|
||||
"archive/tar"
|
||||
"crypto/md5"
|
||||
"crypto/sha1"
|
||||
"crypto/sha256"
|
||||
|
@ -17,7 +18,10 @@ import (
|
|||
// KeywordFunc is the type of a function called on each file to be included in
|
||||
// a DirectoryHierarchy, that will produce the string output of the keyword to
|
||||
// be included for the file entry. Otherwise, empty string.
|
||||
type KeywordFunc func(path string, info os.FileInfo) (string, error)
|
||||
// io.Reader `r` is to the file stream for the file payload. While this
|
||||
// function takes an io.Reader, the caller needs to reset it to the beginning
|
||||
// for each new KeywordFunc
|
||||
type KeywordFunc func(path string, info os.FileInfo, r io.Reader) (string, error)
|
||||
|
||||
// KeyVal is a "keyword=value"
|
||||
type KeyVal string
|
||||
|
@ -165,7 +169,7 @@ var (
|
|||
)
|
||||
|
||||
var (
|
||||
modeKeywordFunc = func(path string, info os.FileInfo) (string, error) {
|
||||
modeKeywordFunc = func(path string, info os.FileInfo, r io.Reader) (string, error) {
|
||||
permissions := info.Mode().Perm()
|
||||
if os.ModeSetuid&info.Mode() > 0 {
|
||||
permissions |= (1 << 11)
|
||||
|
@ -178,52 +182,43 @@ var (
|
|||
}
|
||||
return fmt.Sprintf("mode=%#o", permissions), nil
|
||||
}
|
||||
sizeKeywordFunc = func(path string, info os.FileInfo) (string, error) {
|
||||
sizeKeywordFunc = func(path string, info os.FileInfo, r io.Reader) (string, error) {
|
||||
return fmt.Sprintf("size=%d", info.Size()), nil
|
||||
}
|
||||
cksumKeywordFunc = func(path string, info os.FileInfo) (string, error) {
|
||||
cksumKeywordFunc = func(path string, info os.FileInfo, r io.Reader) (string, error) {
|
||||
if !info.Mode().IsRegular() {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
fh, err := os.Open(path)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer fh.Close()
|
||||
sum, _, err := cksum(fh)
|
||||
sum, _, err := cksum(r)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return fmt.Sprintf("cksum=%d", sum), nil
|
||||
}
|
||||
hasherKeywordFunc = func(name string, newHash func() hash.Hash) KeywordFunc {
|
||||
return func(path string, info os.FileInfo) (string, error) {
|
||||
return func(path string, info os.FileInfo, r io.Reader) (string, error) {
|
||||
if !info.Mode().IsRegular() {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
fh, err := os.Open(path)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer fh.Close()
|
||||
|
||||
h := newHash()
|
||||
if _, err := io.Copy(h, fh); err != nil {
|
||||
if _, err := io.Copy(h, r); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return fmt.Sprintf("%s=%x", name, h.Sum(nil)), nil
|
||||
}
|
||||
}
|
||||
timeKeywordFunc = func(path string, info os.FileInfo) (string, error) {
|
||||
timeKeywordFunc = func(path string, info os.FileInfo, r io.Reader) (string, error) {
|
||||
t := info.ModTime().UnixNano()
|
||||
if t == 0 {
|
||||
return "time=0.000000000", nil
|
||||
}
|
||||
return fmt.Sprintf("time=%d.%9.9d", (t / 1e9), (t % (t / 1e9))), nil
|
||||
}
|
||||
linkKeywordFunc = func(path string, info os.FileInfo) (string, error) {
|
||||
linkKeywordFunc = func(path string, info os.FileInfo, r io.Reader) (string, error) {
|
||||
if sys, ok := info.Sys().(*tar.Header); ok {
|
||||
return sys.Linkname, nil
|
||||
}
|
||||
|
||||
if info.Mode()&os.ModeSymlink != 0 {
|
||||
str, err := os.Readlink(path)
|
||||
if err != nil {
|
||||
|
@ -233,7 +228,7 @@ var (
|
|||
}
|
||||
return "", nil
|
||||
}
|
||||
typeKeywordFunc = func(path string, info os.FileInfo) (string, error) {
|
||||
typeKeywordFunc = func(path string, info os.FileInfo, r io.Reader) (string, error) {
|
||||
if info.Mode().IsDir() {
|
||||
return "type=dir", nil
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue