From 5372b5fc47a80c092145c96a05904c11e638ec85 Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Fri, 29 Jul 2016 10:18:17 -0400 Subject: [PATCH] hierarchy: provide option to list the used keywords in a spec To increase a user's control on how they validate a directory or tar archive with a specification, it is helpful to know which keywords are actually used in the spec provided. This way, the user can see what keywords to use or not use with the '-k' or '-K' flags. Signed-off-by: Stephen Chung --- cmd/gomtree/main.go | 41 ++++++++++++++++++++++++++++++----------- hierarchy.go | 24 ++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 11 deletions(-) diff --git a/cmd/gomtree/main.go b/cmd/gomtree/main.go index 8af7f55..47d9e7b 100644 --- a/cmd/gomtree/main.go +++ b/cmd/gomtree/main.go @@ -15,17 +15,17 @@ import ( ) var ( - flCreate = flag.Bool("c", false, "create a directory hierarchy spec") - flFile = flag.String("f", "", "directory hierarchy spec to validate") - flPath = flag.String("p", "", "root path that the hierarchy spec is relative to") - flAddKeywords = flag.String("K", "", "Add the specified (delimited by comma or space) keywords to the current set of keywords") - flUseKeywords = flag.String("k", "", "Use the specified (delimited by comma or space) keywords as the current set of keywords") - flListKeywords = flag.Bool("list-keywords", false, "List the keywords available") - flResultFormat = flag.String("result-format", "bsd", "output the validation results using the given format (bsd, json, path)") - flTar = flag.String("T", "", "use tar archive to create or validate a directory hierarchy spec") - flBsdKeywords = flag.Bool("bsd-keywords", false, "only operate on keywords that are supported by upstream mtree(8)") - - flDebug = flag.Bool("debug", false, "output debug info to STDERR") + flCreate = flag.Bool("c", false, "create a directory hierarchy spec") + flFile = flag.String("f", "", "directory hierarchy spec to validate") + flPath = flag.String("p", "", "root path that the hierarchy spec is relative to") + flAddKeywords = flag.String("K", "", "Add the specified (delimited by comma or space) keywords to the current set of keywords") + flUseKeywords = flag.String("k", "", "Use the specified (delimited by comma or space) keywords as the current set of keywords") + flListKeywords = flag.Bool("list-keywords", false, "List the keywords available") + flResultFormat = flag.String("result-format", "bsd", "output the validation results using the given format (bsd, json, path)") + flTar = flag.String("T", "", "use tar archive to create or validate a directory hierarchy spec") + flBsdKeywords = flag.Bool("bsd-keywords", false, "only operate on keywords that are supported by upstream mtree(8)") + flListUsedKeywords = flag.Bool("list-used", false, "list all the keywords found in a validation manifest") + flDebug = flag.Bool("debug", false, "output debug info to STDERR") ) var formats = map[string]func(*mtree.Result) string{ @@ -156,6 +156,25 @@ func main() { } } + // -list-used + if *flListUsedKeywords { + if *flFile == "" { + log.Println("no specification provided. please provide a validation manifest") + defer os.Exit(1) + isErr = true + return + } + fmt.Printf("Keywords used in [%s]:\n", *flFile) + for _, kw := range mtree.CollectUsedKeywords(dh) { + fmt.Printf(" %s", kw) + if _, ok := mtree.KeywordFuncs[kw]; !ok { + fmt.Print(" (unsupported)") + } + fmt.Printf("\n") + } + return + } + // -p var rootPath = "." if *flPath != "" { diff --git a/hierarchy.go b/hierarchy.go index 28d7fdc..60c9192 100644 --- a/hierarchy.go +++ b/hierarchy.go @@ -25,3 +25,27 @@ func (dh DirectoryHierarchy) WriteTo(w io.Writer) (n int64, err error) { } return sum, nil } + +// CollectUsedKeywords collects and returns all the keywords used in a +// a DirectoryHierarchy +func CollectUsedKeywords(dh *DirectoryHierarchy) []string { + if dh != nil { + usedkeywords := []string{} + for _, e := range dh.Entries { + switch e.Type { + case FullType, RelativeType, SpecialType: + if e.Type != SpecialType || e.Name == "/set" { + kvs := e.Keywords + for _, kv := range kvs { + kw := KeyVal(kv).Keyword() + if !inSlice(kw, usedkeywords) { + usedkeywords = append(usedkeywords, kw) + } + } + } + } + } + return usedkeywords + } + return nil +}