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:
parent
5d26726bb1
commit
4eec68be4b
18 changed files with 434 additions and 367 deletions
50
tar.go
50
tar.go
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue