From 0c556ae0cc369d43b0486c429a3ba03c4fd69410 Mon Sep 17 00:00:00 2001 From: Dmitry Ledentsov Date: Sun, 31 Dec 2023 19:03:11 +0100 Subject: [PATCH] prepare recursive script parsing --- common/nix_candidate_source.go | 40 +++++++++++++++------------------- common/script_parser.go | 27 +++++++++++++++++++++++ 2 files changed, 44 insertions(+), 23 deletions(-) create mode 100644 common/script_parser.go diff --git a/common/nix_candidate_source.go b/common/nix_candidate_source.go index 48736fc..d9195ad 100644 --- a/common/nix_candidate_source.go +++ b/common/nix_candidate_source.go @@ -10,20 +10,21 @@ import ( g "github.com/zyedidia/generic" "github.com/zyedidia/generic/hashset" - "mvdan.cc/sh/v3/syntax" ) type NixCandidateSource struct { - fs Filesystem - sources map[string]*PathSetIn - key string + fs Filesystem + sources map[string]*PathSetIn + expandedPathsAlreadyCrawled map[string]bool + key string } func NewNixCandidateSource(fs Filesystem, key string) CandidateSource { res := &NixCandidateSource{ - fs: fs, - sources: map[string]*PathSetIn{}, - key: key, + fs: fs, + sources: map[string]*PathSetIn{}, + expandedPathsAlreadyCrawled: map[string]bool{}, + key: key, } res.crawlKnownPaths() res.crawlPathLists() @@ -40,30 +41,23 @@ func (s *NixCandidateSource) WhereSet(somePath string) *PathSetIn { func (s *NixCandidateSource) crawlKnownPaths() { ForEachKnownPath(func(originalSource, expandedSource string) { - // try getting the contents - input, err := readAllText(expandedSource) - if err != nil { + if s.expandedPathsAlreadyCrawled[expandedSource] { return } + // do not crawl this file again + s.expandedPathsAlreadyCrawled[expandedSource] = true - // parse - r := strings.NewReader(input) - f, err := syntax.NewParser().Parse(r, "") + // try getting the contents + input, err := readAllText(expandedSource) if err != nil { return } - syntax.Walk(f, func(node syntax.Node) bool { - switch x := node.(type) { - case *syntax.Assign: - if s.key == x.Name.Value { - harvestedPaths := s.harvestPaths(input[x.Value.Pos().Offset():x.Value.End().Offset()]) - for _, harvestedPath := range harvestedPaths { - s.tryUpdatePathMap(harvestedPath, originalSource, expandedSource) - } - } + ForEachVariableAssignment(s.key, input, func(value string) { + harvestedPaths := s.harvestPaths(value) + for _, harvestedPath := range harvestedPaths { + s.tryUpdatePathMap(harvestedPath, originalSource, expandedSource) } - return true }) }) } diff --git a/common/script_parser.go b/common/script_parser.go new file mode 100644 index 0000000..36c16d6 --- /dev/null +++ b/common/script_parser.go @@ -0,0 +1,27 @@ +package common + +import ( + "strings" + + "mvdan.cc/sh/v3/syntax" +) + +func ForEachVariableAssignment(key, input string, fn func(string)) { + // parse + r := strings.NewReader(input) + f, err := syntax.NewParser().Parse(r, "") + if err != nil { + return + } + + syntax.Walk(f, func(node syntax.Node) bool { + switch x := node.(type) { + case *syntax.Assign: + if key == x.Name.Value { + value := input[x.Value.Pos().Offset():x.Value.End().Offset()] + fn(value) + } + } + return true + }) +}