Import of https://github.com/ciena/voltctl at commit 40d61fbf3f910ed4017cf67c9c79e8e1f82a33a5
Change-Id: I8464c59e60d76cb8612891db3303878975b5416c
diff --git a/pkg/format/formatter.go b/pkg/format/formatter.go
new file mode 100644
index 0000000..af92a03
--- /dev/null
+++ b/pkg/format/formatter.go
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2019-present Ciena Corporation
+ *
+ * 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 format
+
+import (
+ "io"
+ "reflect"
+ "regexp"
+ "strings"
+ "text/tabwriter"
+ "text/template"
+ "text/template/parse"
+)
+
+var nameFinder = regexp.MustCompile(`\.([\._A-Za-z0-9]*)}}`)
+
+type Format string
+
+func (f Format) IsTable() bool {
+ return strings.HasPrefix(string(f), "table")
+}
+
+func (f Format) Execute(writer io.Writer, withHeaders bool, nameLimit int, data interface{}) error {
+ var tabWriter *tabwriter.Writer = nil
+ format := f
+
+ if f.IsTable() {
+ tabWriter = tabwriter.NewWriter(writer, 0, 4, 4, ' ', 0)
+ format = Format(strings.TrimPrefix(string(f), "table"))
+ }
+
+ tmpl, err := template.New("output").Parse(string(format))
+ if err != nil {
+ return err
+ }
+
+ if f.IsTable() && withHeaders {
+ var header string
+ for _, n := range tmpl.Tree.Root.Nodes {
+ switch n.Type() {
+ case parse.NodeText:
+ header += n.String()
+ case parse.NodeString:
+ header += n.String()
+ case parse.NodeAction:
+ found := nameFinder.FindStringSubmatch(n.String())
+ if len(found) == 2 {
+ if nameLimit > 0 {
+ parts := strings.Split(found[1], ".")
+ start := len(parts) - nameLimit
+ if start < 0 {
+ start = 0
+ }
+ header += strings.ToUpper(strings.Join(parts[start:], "."))
+ } else {
+ header += strings.ToUpper(found[1])
+ }
+ }
+ }
+ }
+ tabWriter.Write([]byte(header))
+ tabWriter.Write([]byte("\n"))
+
+ slice := reflect.ValueOf(data)
+ if slice.Kind() == reflect.Slice {
+ for i := 0; i < slice.Len(); i++ {
+ tmpl.Execute(tabWriter, slice.Index(i).Interface())
+ tabWriter.Write([]byte("\n"))
+ }
+ } else {
+ tmpl.Execute(tabWriter, data)
+ tabWriter.Write([]byte("\n"))
+ }
+ tabWriter.Flush()
+ return nil
+ }
+
+ slice := reflect.ValueOf(data)
+ if slice.Kind() == reflect.Slice {
+ for i := 0; i < slice.Len(); i++ {
+ tmpl.Execute(writer, slice.Index(i).Interface())
+ writer.Write([]byte("\n"))
+ }
+ } else {
+ tmpl.Execute(writer, data)
+ writer.Write([]byte("\n"))
+ }
+ return nil
+
+}