Repository: openconfig/goyang
Pull request #156 (2020-12-16 20:30:17)

Add util package for goyang
The contents for `ProcessModules ` are copied from a private repository.


Patch:
diff --git a/pkg/util/build_yang.go b/pkg/util/build_yang.go
new file mode 100644
index 0000000..9f39221
--- /dev/null
+++ b/pkg/util/build_yang.go
@@ -0,0 +1,56 @@
+// Copyright 2020 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package util
+
+import (
+	"fmt"
+
+	"github.com/openconfig/goyang/pkg/yang"
+)
+
+// ProcessModules takes a list of modules, and a path specification and
+// runs the yang parser against them, returning a slice of yang.Entry
+// pointers which represent the top level modules that are to be parsed
+// by the struct generation.
+func ProcessModules(yangf, path []string) (map[string]*yang.Entry, []error) {
+	for _, p := range path {
+		yang.AddPath(fmt.Sprintf("%s/...", p))
+	}
+
+	ms := yang.NewModules()
+
+	var processErr []error
+	for _, name := range yangf {
+		if err := ms.Read(name); err != nil {
+			processErr = append(processErr, err)
+		}
+	}
+
+	if len(processErr) > 0 {
+		return nil, processErr
+	}
+
+	if errs := ms.Process(); len(errs) != 0 {
+		return nil, errs
+	}
+
+	entries := make(map[string]*yang.Entry)
+	for _, m := range ms.Modules {
+		e := yang.ToEntry(m)
+		entries[e.Name] = e
+	}
+
+	return entries, nil
+}


Test patch:
diff --git a/pkg/util/build_yang_test.go b/pkg/util/build_yang_test.go
new file mode 100644
index 0000000..8b9cf23
--- /dev/null
+++ b/pkg/util/build_yang_test.go
@@ -0,0 +1,69 @@
+// Copyright 2020 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package util
+
+import "testing"
+
+// TestProcessModules tests the ProcessModules function - which takes an input
+// set of modules and processes them using the goyang compiler into a set of
+// yang.Entry pointers.
+func TestProcessModules(t *testing.T) {
+	tests := []struct {
+		name     string
+		inFiles  []string
+		inPath   []string
+		wantErr  bool
+		wantMods []string
+	}{{
+		name:     "simple valid module",
+		inFiles:  []string{"testdata/00-valid-module.yang"},
+		inPath:   []string{"testdata"},
+		wantMods: []string{"test-module"},
+	}, {
+		name:    "simple invalid module",
+		inFiles: []string{"testdata/01-invalid-module.yang"},
+		inPath:  []string{"testdata"},
+		wantErr: true,
+	}, {
+		name:     "valid import",
+		inFiles:  []string{"testdata/02-valid-import.yang"},
+		inPath:   []string{"testdata/subdir"},
+		wantMods: []string{"test-module"},
+	}, {
+		name:    "invalid import",
+		inFiles: []string{"testdata/03-invalid-import.yang"},
+		inPath:  []string{},
+		wantErr: true,
+	}, {
+		name:     "two modules",
+		inFiles:  []string{"testdata/04-valid-module-one.yang", "testdata/04-valid-module-two.yang"},
+		inPath:   []string{},
+		wantMods: []string{"module-one", "module-two"},
+	}}
+
+	for _, tt := range tests {
+		entries, errs := ProcessModules(tt.inFiles, tt.inPath)
+		if len(errs) != 0 && !tt.wantErr {
+			t.Errorf("%s: unexpected error processing modules: %v", tt.name, errs)
+			continue
+		}
+
+		for _, m := range tt.wantMods {
+			if _, ok := entries[m]; !ok {
+				t.Errorf("%s: could not find module %s", tt.name, m)
+			}
+		}
+	}
+}
diff --git a/pkg/util/testdata/00-valid-module.yang b/pkg/util/testdata/00-valid-module.yang
new file mode 100644
index 0000000..b216af1
--- /dev/null
+++ b/pkg/util/testdata/00-valid-module.yang
@@ -0,0 +1,6 @@
+module test-module {
+  prefix "t";
+  namespace "urn:t";
+
+  leaf valid-leaf { type string; }
+}
diff --git a/pkg/util/testdata/01-invalid-module.yang b/pkg/util/testdata/01-invalid-module.yang
new file mode 100644
index 0000000..7e28c90
--- /dev/null
+++ b/pkg/util/testdata/01-invalid-module.yang
@@ -0,0 +1,6 @@
+module test-module {
+  prefix "t";
+  namespace "urn:t";
+
+  leaf invalid-leaf { }
+}
diff --git a/pkg/util/testdata/02-valid-import.yang b/pkg/util/testdata/02-valid-import.yang
new file mode 100644
index 0000000..621a107
--- /dev/null
+++ b/pkg/util/testdata/02-valid-import.yang
@@ -0,0 +1,6 @@
+module test-module {
+  prefix "t";
+  namespace "urn:t";
+
+  import imported { prefix "i"; }
+}
diff --git a/pkg/util/testdata/03-invalid-import.yang b/pkg/util/testdata/03-invalid-import.yang
new file mode 100644
index 0000000..65ba27a
--- /dev/null
+++ b/pkg/util/testdata/03-invalid-import.yang
@@ -0,0 +1,6 @@
+module test-module {
+  prefix "t";
+  namespace "urn:t";
+
+  import import-not-found { prefix "i"; }
+}
diff --git a/pkg/util/testdata/04-valid-module-one.yang b/pkg/util/testdata/04-valid-module-one.yang
new file mode 100644
index 0000000..28ed770
--- /dev/null
+++ b/pkg/util/testdata/04-valid-module-one.yang
@@ -0,0 +1,6 @@
+module module-one {
+  prefix "t";
+  namespace "urn:t";
+
+  leaf one { type int8; }
+}
diff --git a/pkg/util/testdata/04-valid-module-two.yang b/pkg/util/testdata/04-valid-module-two.yang
new file mode 100644
index 0000000..d17cbcc
--- /dev/null
+++ b/pkg/util/testdata/04-valid-module-two.yang
@@ -0,0 +1,6 @@
+module module-two {
+  prefix "t";
+  namespace "urn:t";
+
+  leaf two { type int8; }
+}
diff --git a/pkg/util/testdata/subdir/imported.yang b/pkg/util/testdata/subdir/imported.yang
new file mode 100644
index 0000000..71ddd93
--- /dev/null
+++ b/pkg/util/testdata/subdir/imported.yang
@@ -0,0 +1,5 @@
+module imported {
+  prefix "imported";
+  namespace "urn:i";
+  
+}