entries: prepend all hierarchies with keyword metadata

In order to ensure that CollectUsedKeywords works on manifests as
expected (it returns the keywords the manifest was generated with),
prepend every manifest with a dummy /set and /unset entry which just
tags the manifest as "this is a keyword used".

Signed-off-by: Aleksa Sarai <asarai@suse.de>
This commit is contained in:
Aleksa Sarai 2016-11-12 15:03:20 +11:00
parent 690c85d4e8
commit 9b6ded9730
No known key found for this signature in database
GPG Key ID: 9E18AA267DDB8DB4
2 changed files with 50 additions and 4 deletions

9
tar.go
View File

@ -76,8 +76,13 @@ func (ts *tarStream) readHeaders() {
Set: nil,
Keywords: []string{"type=dir"},
}
metadataEntries := signatureEntries("<user specified tar archive>")
for _, e := range metadataEntries {
// insert signature and metadata comments first (user, machine, tree, date)
for _, e := range signatureEntries("<user specified tar archive>") {
e.Pos = len(ts.creator.DH.Entries)
ts.creator.DH.Entries = append(ts.creator.DH.Entries, e)
}
// insert keyword metadata next
for _, e := range keywordEntries(ts.keywords) {
e.Pos = len(ts.creator.DH.Entries)
ts.creator.DH.Entries = append(ts.creator.DH.Entries, e)
}

45
walk.go
View File

@ -7,6 +7,7 @@ import (
"os/user"
"path/filepath"
"sort"
"strings"
"time"
)
@ -23,11 +24,16 @@ var defaultSetKeywords = []string{"type=file", "nlink=1", "flags=none", "mode=06
func Walk(root string, exlcudes []ExcludeFunc, keywords []string) (*DirectoryHierarchy, error) {
creator := dhCreator{DH: &DirectoryHierarchy{}}
// insert signature and metadata comments first (user, machine, tree, date)
metadataEntries := signatureEntries(root)
for _, e := range metadataEntries {
for _, e := range signatureEntries(root) {
e.Pos = len(creator.DH.Entries)
creator.DH.Entries = append(creator.DH.Entries, e)
}
// insert keyword metadata next
for _, e := range keywordEntries(keywords) {
e.Pos = len(creator.DH.Entries)
creator.DH.Entries = append(creator.DH.Entries, e)
}
// walk the directory and add entries
err := startWalk(&creator, root, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
@ -360,3 +366,38 @@ func signatureEntries(root string) []Entry {
return sigEntries
}
// keywordEntries returns a slice of entries that ensure that a manifest
// generated with a particular keyword set will still be recognised as having
// that keyword set. Namely this is [/set <keywords>, /set <none>].
func keywordEntries(keywords []string) []Entry {
// Convert all of the keywords to zero-value keyvals.
kvs := []string{}
for _, kw := range keywords {
kvs = append(kvs, kw+"=")
}
// Create a /set <kvs> and an /unset.
return []Entry{
{
Type: CommentType,
Raw: fmt.Sprintf("#%16s%s", "keywords: ", strings.Join(keywords, ",")),
},
{
Type: BlankType,
},
{
Type: CommentType,
Raw: "# <keywords>",
},
{
Type: SpecialType,
Name: "/set",
Keywords: kvs,
},
{
Type: SpecialType,
Name: "/unset",
},
}
}