From 9b6ded97301524450ef208fc7225e1a2e7e022b0 Mon Sep 17 00:00:00 2001 From: Aleksa Sarai Date: Sat, 12 Nov 2016 15:03:20 +1100 Subject: [PATCH] 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 --- tar.go | 9 +++++++-- walk.go | 45 +++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 50 insertions(+), 4 deletions(-) diff --git a/tar.go b/tar.go index 8b8b034..0315052 100644 --- a/tar.go +++ b/tar.go @@ -76,8 +76,13 @@ func (ts *tarStream) readHeaders() { Set: nil, Keywords: []string{"type=dir"}, } - metadataEntries := signatureEntries("") - for _, e := range metadataEntries { + // insert signature and metadata comments first (user, machine, tree, date) + for _, e := range signatureEntries("") { + 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) } diff --git a/walk.go b/walk.go index 8e0763f..1412633 100644 --- a/walk.go +++ b/walk.go @@ -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 , /set ]. +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 and an /unset. + return []Entry{ + { + Type: CommentType, + Raw: fmt.Sprintf("#%16s%s", "keywords: ", strings.Join(keywords, ",")), + }, + { + Type: BlankType, + }, + { + Type: CommentType, + Raw: "# ", + }, + { + Type: SpecialType, + Name: "/set", + Keywords: kvs, + }, + { + Type: SpecialType, + Name: "/unset", + }, + } +}