Skip to content

Commit

Permalink
Move Path and pathMap under Modules to allow parsing of two dif…
Browse files Browse the repository at this point in the history
…ferent sets of files with different paths. (openconfig#209)

* Move `Path` and `pathMap` under `Modules` to allow parsing of two different sets of files with different paths.

Fixes openconfig#172
  • Loading branch information
wenovus authored Feb 22, 2022
1 parent d8e546c commit fa1e168
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 48 deletions.
6 changes: 3 additions & 3 deletions pkg/util/build_yang.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ import (
// parsed top level modules. It also returns a list of errors encountered while
// parsing, if any.
func ProcessModules(yangfiles, path []string) (map[string]*yang.Entry, []error) {
ms := yang.NewModules()

for _, p := range path {
yang.AddPath(fmt.Sprintf("%s/...", p))
ms.AddPath(fmt.Sprintf("%s/...", p))
}

ms := yang.NewModules()

var processErr []error
for _, name := range yangfiles {
if err := ms.Read(name); err != nil {
Expand Down
42 changes: 17 additions & 25 deletions pkg/yang/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,34 +24,12 @@ import (
"strings"
)

// TODO(borman): encapsulate all of this someday so you can parse
// two completely independent yang files with different Paths.

var (
// Path is the list of directories to look for .yang files in.
Path []string
// pathMap is used to prevent adding dups in Path.
pathMap = map[string]bool{}

// revisionDateSuffixRegex matches on the revision-date portion of a YANG
// file's name.
revisionDateSuffixRegex = regexp.MustCompile(`^@\d{4}-\d{2}-\d{2}\.yang$`)
)

// AddPath adds the directories specified in p, a colon separated list
// of directory names, to Path, if they are not already in Path. Using
// multiple arguments is also supported.
func AddPath(paths ...string) {
for _, path := range paths {
for _, p := range strings.Split(path, ":") {
if !pathMap[p] {
pathMap[p] = true
Path = append(Path, p)
}
}
}
}

// PathsWithModules returns all paths under and including the
// root containing files with a ".yang" extension, as well as
// any error encountered
Expand All @@ -77,6 +55,20 @@ func PathsWithModules(root string) (paths []string, err error) {
return
}

// AddPath adds the directories specified in p, a colon separated list
// of directory names, to Path, if they are not already in Path. Using
// multiple arguments is also supported.
func (ms *Modules) AddPath(paths ...string) {
for _, path := range paths {
for _, p := range strings.Split(path, ":") {
if !ms.pathMap[p] {
ms.pathMap[p] = true
ms.Path = append(ms.Path, p)
}
}
}
}

// readFile makes testing of findFile easier.
var readFile = ioutil.ReadFile

Expand All @@ -96,7 +88,7 @@ var scanDir = findInDir
//
// The current directory (.) is always checked first, no matter the value of
// Path.
func findFile(name string) (string, string, error) {
func (ms *Modules) findFile(name string) (string, string, error) {
slash := strings.Index(name, "/")
if slash < 0 && !strings.HasSuffix(name, ".yang") {
name += ".yang"
Expand All @@ -108,14 +100,14 @@ func findFile(name string) (string, string, error) {

switch data, err := readFile(name); true {
case err == nil:
AddPath(filepath.Dir(name))
ms.AddPath(filepath.Dir(name))
return name, string(data), nil
case slash >= 0:
// If there are any /'s in the name then don't search Path.
return "", "", fmt.Errorf("no such file: %s", name)
}

for _, dir := range Path {
for _, dir := range ms.Path {
var n string
if filepath.Base(dir) == "..." {
n = scanDir(filepath.Dir(dir), name, true)
Expand Down
20 changes: 5 additions & 15 deletions pkg/yang/file_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,7 @@ import (
"testing"
)

func testPathReset() {
Path = []string{}
pathMap = map[string]bool{}
}

func TestFindFile(t *testing.T) {
// clean up global state
defer testPathReset()

sep := string(os.PathSeparator)

for _, tt := range []struct {
Expand All @@ -58,15 +50,16 @@ func TestFindFile(t *testing.T) {
},
} {
var checked []string
Path = tt.path
ms := NewModules()
ms.Path = tt.path
readFile = func(path string) ([]byte, error) {
checked = append(checked, path)
return nil, errors.New("no such file")
}
scanDir = func(dir, name string, recurse bool) string {
return filepath.Join(dir, name)
}
if _, _, err := findFile(tt.name); err == nil {
if _, _, err := ms.findFile(tt.name); err == nil {
t.Errorf("%s unexpectedly succeeded", tt.name)
continue
}
Expand All @@ -77,9 +70,6 @@ func TestFindFile(t *testing.T) {
}

func TestScanForPathsAndAddModules(t *testing.T) {
// clean up global state
defer testPathReset()

// disable any readFile mock setup by other tests
readFile = ioutil.ReadFile

Expand All @@ -93,13 +83,13 @@ func TestScanForPathsAndAddModules(t *testing.T) {
if len(paths) != 2 {
t.Errorf("got %d paths imported, want 2", len(paths))
}
ms := NewModules()
// add the paths found in the scan to the module path
AddPath(paths...)
ms.AddPath(paths...)

// confirm we can load the four modules that exist in
// the two paths we scanned.
modules := []string{"aug", "base", "other", "subdir1"}
ms := NewModules()
for _, name := range modules {
if _, err := ms.GetModule(name); err != nil {
t.Errorf("getting %s: %v", name, err)
Expand Down
7 changes: 6 additions & 1 deletion pkg/yang/modules.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ type Modules struct {
// directly set by the caller to influence how goyang will behave in the presence
// of certain exceptional cases.
ParseOptions Options
// Path is the list of directories to look for .yang files in.
Path []string
// pathMap is used to prevent adding dups in Path.
pathMap map[string]bool
}

// NewModules returns a newly created and initialized Modules.
Expand All @@ -56,6 +60,7 @@ func NewModules() *Modules {
typeDict: newTypeDictionary(),
mergedSubmodule: map[string]bool{},
entryCache: map[Node]*Entry{},
pathMap: map[string]bool{},
}
return ms
}
Expand All @@ -65,7 +70,7 @@ func NewModules() *Modules {
// e.g., foo.yang is named foo). An error is returned if the file is not
// found or there was an error parsing the file.
func (ms *Modules) Read(name string) error {
name, data, err := findFile(name)
name, data, err := ms.findFile(name)
if err != nil {
return err
}
Expand Down
8 changes: 4 additions & 4 deletions yang.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,13 +149,16 @@ Formats:
stop(0)
}

ms := yang.NewModules()
ms.ParseOptions.IgnoreSubmoduleCircularDependencies = ignoreSubmoduleCircularDependencies

for _, path := range paths {
expanded, err := yang.PathsWithModules(path)
if err != nil {
fmt.Fprintln(os.Stderr, err)
continue
}
yang.AddPath(expanded...)
ms.AddPath(expanded...)
}

if format == "" {
Expand All @@ -169,9 +172,6 @@ Formats:

files := getopt.Args()

ms := yang.NewModules()
ms.ParseOptions.IgnoreSubmoduleCircularDependencies = ignoreSubmoduleCircularDependencies

if len(files) == 0 {
data, err := ioutil.ReadAll(os.Stdin)
if err == nil {
Expand Down

0 comments on commit fa1e168

Please sign in to comment.