1
0
Fork 0
mirror of https://github.com/vbatts/go-mtree.git synced 2025-07-03 22:28:29 +00:00

*: make Keyword and KeyVal pervasive

Signed-off-by: Vincent Batts <vbatts@hashbangbash.com>
This commit is contained in:
Vincent Batts 2016-11-17 19:47:31 -05:00
parent 5d26726bb1
commit 4eec68be4b
Signed by: vbatts
GPG key ID: 10937E57733F1362
18 changed files with 434 additions and 367 deletions

50
tar.go
View file

@ -17,11 +17,15 @@ type Streamer interface {
Hierarchy() (*DirectoryHierarchy, error)
}
var tarDefaultSetKeywords = []string{"type=file", "flags=none", "mode=0664"}
var tarDefaultSetKeywords = []KeyVal{
"type=file",
"flags=none",
"mode=0664",
}
// NewTarStreamer streams a tar archive and creates a file hierarchy based off
// of the tar metadata headers
func NewTarStreamer(r io.Reader, keywords []string) Streamer {
func NewTarStreamer(r io.Reader, keywords []Keyword) Streamer {
pR, pW := io.Pipe()
ts := &tarStream{
pipeReader: pR,
@ -45,17 +49,17 @@ type tarStream struct {
pipeWriter *io.PipeWriter
teeReader io.Reader
tarReader *tar.Reader
keywords []string
keywords []Keyword
err error
}
func (ts *tarStream) readHeaders() {
// remove "time" keyword
notimekws := []string{}
notimekws := []Keyword{}
for _, kw := range ts.keywords {
if !inSlice(kw, notimekws) {
if !InKeywordSlice(kw, notimekws) {
if kw == "time" {
if !inSlice("tar_time", ts.keywords) {
if !InKeywordSlice("tar_time", ts.keywords) {
notimekws = append(notimekws, "tar_time")
}
} else {
@ -74,7 +78,7 @@ func (ts *tarStream) readHeaders() {
Type: CommentType,
},
Set: nil,
Keywords: []string{"type=dir"},
Keywords: []KeyVal{"type=dir"},
}
metadataEntries := signatureEntries("<user specified tar archive>")
for _, e := range metadataEntries {
@ -242,7 +246,7 @@ func populateTree(root, e *Entry, hdr *tar.Header) error {
Name: encoded,
Type: RelativeType,
Parent: parent,
Keywords: []string{"type=dir"}, // temp data
Keywords: []KeyVal{"type=dir"}, // temp data
Set: nil, // temp data
}
pathname, err := newEntry.Path()
@ -276,7 +280,7 @@ func populateTree(root, e *Entry, hdr *tar.Header) error {
// root: the "head" of the sub-tree to flatten
// creator: a dhCreator that helps with the '/set' keyword
// keywords: keywords specified by the user that should be evaluated
func flatten(root *Entry, creator *dhCreator, keywords []string) {
func flatten(root *Entry, creator *dhCreator, keywords []Keyword) {
if root == nil || creator == nil {
return
}
@ -292,18 +296,19 @@ func flatten(root *Entry, creator *dhCreator, keywords []string) {
if root.Set != nil {
// Check if we need a new set
consolidatedKeys := keyvalSelector(append(tarDefaultSetKeywords, root.Set.Keywords...), keywords)
if creator.curSet == nil {
creator.curSet = &Entry{
Type: SpecialType,
Name: "/set",
Keywords: keywordSelector(append(tarDefaultSetKeywords, root.Set.Keywords...), keywords),
Keywords: consolidatedKeys,
Pos: len(creator.DH.Entries),
}
creator.DH.Entries = append(creator.DH.Entries, *creator.curSet)
} else {
needNewSet := false
for _, k := range root.Set.Keywords {
if !inSlice(k, creator.curSet.Keywords) {
if !inKeyValSlice(k, creator.curSet.Keywords) {
needNewSet = true
break
}
@ -313,7 +318,7 @@ func flatten(root *Entry, creator *dhCreator, keywords []string) {
Name: "/set",
Type: SpecialType,
Pos: len(creator.DH.Entries),
Keywords: keywordSelector(append(tarDefaultSetKeywords, root.Set.Keywords...), keywords),
Keywords: consolidatedKeys,
}
creator.DH.Entries = append(creator.DH.Entries, *creator.curSet)
}
@ -331,7 +336,7 @@ func flatten(root *Entry, creator *dhCreator, keywords []string) {
}
root.Set = creator.curSet
if creator.curSet != nil {
root.Keywords = setDifference(root.Keywords, creator.curSet.Keywords)
root.Keywords = keyValDifference(root.Keywords, creator.curSet.Keywords)
}
root.Pos = len(creator.DH.Entries)
creator.DH.Entries = append(creator.DH.Entries, *root)
@ -376,11 +381,11 @@ func resolveHardlinks(root *Entry, hardlinks map[string][]string, countlinks boo
}
linkfile.Keywords = basefile.Keywords
if countlinks {
linkfile.Keywords = append(linkfile.Keywords, fmt.Sprintf("nlink=%d", len(links)+1))
linkfile.Keywords = append(linkfile.Keywords, KeyVal(fmt.Sprintf("nlink=%d", len(links)+1)))
}
}
if countlinks {
basefile.Keywords = append(basefile.Keywords, fmt.Sprintf("nlink=%d", len(links)+1))
basefile.Keywords = append(basefile.Keywords, KeyVal(fmt.Sprintf("nlink=%d", len(links)+1)))
}
}
}
@ -410,19 +415,6 @@ func filter(root *Entry, p func(*Entry) bool) []Entry {
return nil
}
func setDifference(this, that []string) []string {
if len(this) == 0 {
return that
}
diff := []string{}
for _, kv := range this {
if !inSlice(kv, that) {
diff = append(diff, kv)
}
}
return diff
}
func (ts *tarStream) setErr(err error) {
ts.err = err
}
@ -444,7 +436,7 @@ func (ts *tarStream) Hierarchy() (*DirectoryHierarchy, error) {
if ts.root == nil {
return nil, fmt.Errorf("root Entry not found, nothing to flatten")
}
resolveHardlinks(ts.root, ts.hardlinks, inSlice("nlink", ts.keywords))
resolveHardlinks(ts.root, ts.hardlinks, InKeywordSlice(Keyword("nlink"), ts.keywords))
flatten(ts.root, &ts.creator, ts.keywords)
return ts.creator.DH, nil
}