Repository: go-go-golems/glazed
Pull request #304 (2023-06-22 22:25:18)

:art: Make the API changes necessary to support parka config file options
Related to https://github.com/go-go-golems/parka/issues/51

- :art: Rename helper functions to load ParameterDefinitions from a YAML list
- :art: Handle nil setting for rename fields
- :art: Add UniqueStrings helper method
- :art: Add ContentType method to OutputFormatter
- :ambulance: Make TestFormatter support ContentType as well



Patch:
diff --git a/pkg/cmds/parameters/parameters.go b/pkg/cmds/parameters/parameters.go
index 08890c7..c3ce36b 100644
--- a/pkg/cmds/parameters/parameters.go
+++ b/pkg/cmds/parameters/parameters.go
@@ -782,7 +782,7 @@ func (p *ParameterDefinition) CheckValueValidity(v interface{}) error {
 	return nil
 }
 
-func InitFlagsFromYaml(yamlContent []byte) (map[string]*ParameterDefinition, []*ParameterDefinition) {
+func LoadParameterDefinitionsFromYAML(yamlContent []byte) (map[string]*ParameterDefinition, []*ParameterDefinition) {
 	flags := make(map[string]*ParameterDefinition)
 	flagList := make([]*ParameterDefinition, 0)
 
diff --git a/pkg/formatters/csv/csv.go b/pkg/formatters/csv/csv.go
index de5ae3f..cc1bb6a 100644
--- a/pkg/formatters/csv/csv.go
+++ b/pkg/formatters/csv/csv.go
@@ -21,6 +21,13 @@ type OutputFormatter struct {
 	Separator           rune
 }
 
+func (f *OutputFormatter) ContentType() string {
+	if f.Separator == '\t' {
+		return "text/tab-separated-values"
+	}
+	return "text/csv"
+}
+
 type OutputFormatterOption func(*OutputFormatter)
 
 func WithOutputFile(outputFile string) OutputFormatterOption {
diff --git a/pkg/formatters/excel/excel.go b/pkg/formatters/excel/excel.go
index ef1bdb6..0f657bf 100644
--- a/pkg/formatters/excel/excel.go
+++ b/pkg/formatters/excel/excel.go
@@ -129,6 +129,10 @@ func (E *OutputFormatter) Output(ctx context.Context, w io.Writer) error {
 	return nil
 }
 
+func (f *OutputFormatter) ContentType() string {
+	return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
+}
+
 type OutputFormatterOption func(*OutputFormatter)
 
 func WithSheetName(sheetName string) OutputFormatterOption {
diff --git a/pkg/formatters/formatter.go b/pkg/formatters/formatter.go
index 3262dab..8969f6f 100644
--- a/pkg/formatters/formatter.go
+++ b/pkg/formatters/formatter.go
@@ -53,6 +53,8 @@ type OutputFormatter interface {
 	GetTable() (*types.Table, error)
 
 	Output(ctx context.Context, w io.Writer) error
+
+	ContentType() string
 }
 
 func ComputeOutputFilename(outputFile string, outputFileTemplate string, row types.Row, index int) (string, error) {
diff --git a/pkg/formatters/json/json.go b/pkg/formatters/json/json.go
index bb21f65..e5d2a87 100644
--- a/pkg/formatters/json/json.go
+++ b/pkg/formatters/json/json.go
@@ -47,6 +47,10 @@ func (f *OutputFormatter) AddTableMiddlewareAtIndex(i int, mw middlewares.TableM
 	f.middlewares = append(f.middlewares[:i], append([]middlewares.TableMiddleware{mw}, f.middlewares[i:]...)...)
 }
 
+func (f *OutputFormatter) ContentType() string {
+	return "application/json"
+}
+
 func (f *OutputFormatter) Output(ctx context.Context, w io.Writer) error {
 	f.Table.Finalize()
 
@@ -78,10 +82,10 @@ func (f *OutputFormatter) Output(ctx context.Context, w io.Writer) error {
 			encoder.SetIndent("", "  ")
 			err = encoder.Encode(row.GetValues())
 			if err != nil {
-				f_.Close()
+				_ = f_.Close()
 				return err
 			}
-			f_.Close()
+			_ = f_.Close()
 			_, _ = fmt.Fprintf(w, "Wrote output to %s\n", outputFileName)
 		}
 
@@ -93,7 +97,9 @@ func (f *OutputFormatter) Output(ctx context.Context, w io.Writer) error {
 		if err != nil {
 			return err
 		}
-		defer f_.Close()
+		defer func(f_ *os.File) {
+			_ = f_.Close()
+		}(f_)
 		w = f_
 	}
 
diff --git a/pkg/formatters/simple/simple.go b/pkg/formatters/simple/simple.go
index b903db5..dce1643 100644
--- a/pkg/formatters/simple/simple.go
+++ b/pkg/formatters/simple/simple.go
@@ -60,6 +60,10 @@ func NewSingleColumnFormatter(column types.FieldName, opts ...SingleColumnFormat
 	return f
 }
 
+func (s *SingleColumnFormatter) ContentType() string {
+	return "text/plain"
+}
+
 func (s *SingleColumnFormatter) AddRow(row types.Row) {
 	s.Table.Rows = append(s.Table.Rows, row)
 }
diff --git a/pkg/formatters/table/table.go b/pkg/formatters/table/table.go
index 190a380..7357405 100644
--- a/pkg/formatters/table/table.go
+++ b/pkg/formatters/table/table.go
@@ -115,6 +115,17 @@ func NewOutputFormatter(tableFormat string, opts ...OutputFormatterOption) *Outp
 	return f
 }
 
+func (tof *OutputFormatter) ContentType() string {
+	switch tof.TableFormat {
+	case "csv":
+		return "text/csv"
+	case "html":
+		return "text/html"
+	default:
+		return "text/plain"
+	}
+}
+
 func (tof *OutputFormatter) GetTable() (*types.Table, error) {
 	return tof.Table, nil
 }
diff --git a/pkg/formatters/template/template.go b/pkg/formatters/template/template.go
index 45d7aff..6edc160 100644
--- a/pkg/formatters/template/template.go
+++ b/pkg/formatters/template/template.go
@@ -128,6 +128,10 @@ func (t *OutputFormatter) Output(ctx context.Context, w io.Writer) error {
 	return nil
 }
 
+func (f *OutputFormatter) ContentType() string {
+	return "text/plain"
+}
+
 type OutputFormatterOption func(*OutputFormatter)
 
 func WithTemplateFuncMaps(templateFuncMaps []template.FuncMap) OutputFormatterOption {
diff --git a/pkg/formatters/yaml/yaml.go b/pkg/formatters/yaml/yaml.go
index 9d4d801..7b4d3e4 100644
--- a/pkg/formatters/yaml/yaml.go
+++ b/pkg/formatters/yaml/yaml.go
@@ -127,6 +127,10 @@ func (f *OutputFormatter) Output(ctx context.Context, w io.Writer) error {
 	}
 }
 
+func (f *OutputFormatter) ContentType() string {
+	return "application/yaml"
+}
+
 type OutputFormatterOption func(*OutputFormatter)
 
 func WithYAMLOutputFile(outputFile string) OutputFormatterOption {
diff --git a/pkg/helpers/strings/strings.go b/pkg/helpers/strings/strings.go
index 9e4c759..d074e4d 100644
--- a/pkg/helpers/strings/strings.go
+++ b/pkg/helpers/strings/strings.go
@@ -55,3 +55,15 @@ func ToAlphaString(n int) string {
 	// otherwise, we need to recursively call ToAlphaString with the quotient and add the corresponding letter
 	return ToAlphaString(quotient) + string(rune('A'+remainder))
 }
+
+func UniqueStrings(s []string) []string {
+	unique := make(map[string]bool)
+	for _, item := range s {
+		unique[item] = true
+	}
+	var result []string
+	for item := range unique {
+		result = append(result, item)
+	}
+	return result
+}
diff --git a/pkg/settings/settings_rename.go b/pkg/settings/settings_rename.go
index 24067c7..b379435 100644
--- a/pkg/settings/settings_rename.go
+++ b/pkg/settings/settings_rename.go
@@ -67,6 +67,13 @@ func NewRenameParameterLayer(options ...layers.ParameterLayerOptions) (*RenamePa
 }
 
 func NewRenameSettingsFromParameters(ps map[string]interface{}) (*RenameSettings, error) {
+	if ps["rename"] == nil {
+		return &RenameSettings{
+			RenameFields:  map[types.FieldName]string{},
+			RenameRegexps: table.RegexpReplacements{},
+		}, nil
+	}
+
 	renameFields, ok := cast.CastList2[string, interface{}](ps["rename"])
 	if !ok {
 		return nil, errors.Errorf("Invalid rename fields %s", ps["rename"])


Test patch:
diff --git a/cmd/glaze/cmds/html/parse_test.go b/cmd/glaze/cmds/html/parse_test.go
index 7c3d4e3..f2b488d 100644
--- a/cmd/glaze/cmds/html/parse_test.go
+++ b/cmd/glaze/cmds/html/parse_test.go
@@ -27,6 +27,10 @@ func NewTestProcessor() *TestProcessor {
 
 type TestFormatter struct{}
 
+func (t TestFormatter) ContentType() string {
+	return "text/plain"
+}
+
 func (t TestFormatter) AddRow(row types.Row) {
 }
 
diff --git a/pkg/cmds/parameters/parameters_test.go b/pkg/cmds/parameters/parameters_test.go
index f8af30f..3ce17ab 100644
--- a/pkg/cmds/parameters/parameters_test.go
+++ b/pkg/cmds/parameters/parameters_test.go
@@ -16,7 +16,7 @@ var testParameterDefinitions map[string]*ParameterDefinition
 var testParameterDefinitionsList []*ParameterDefinition
 
 func init() {
-	testParameterDefinitions, testParameterDefinitionsList = InitFlagsFromYaml(testFlagsYaml)
+	testParameterDefinitions, testParameterDefinitionsList = LoadParameterDefinitionsFromYAML(testFlagsYaml)
 }
 
 func TestSetValueFromDefaultInt(t *testing.T) {