feat: unifood base with GET dishes (#1)

Features:
- CLI structure with verbs and resources
- Application config and parameters
- Output formatters
- Initial resource: dishes

Reviewed-on: #1
Co-authored-by: bdoerfchen <git@bissendorf.co>
Co-committed-by: bdoerfchen <git@bissendorf.co>
This commit is contained in:
2025-07-20 17:29:04 +00:00
committed by bissendorf
parent ad082a3f12
commit ec66365b5e
27 changed files with 893 additions and 0 deletions

15
core/output/formatter.go Normal file
View File

@ -0,0 +1,15 @@
package output
import (
"git.bissendorf.co/bissendorf/unifood/m/v2/core/interfaces"
)
var Formatters = map[string]interfaces.Formatter{
"json": &JsonFormatter{},
"yaml": &YamlFormatter{},
"go": &GoFormatter{},
"table": &TableFormatter{},
"csv": &TableFormatter{HideSummary: true, RenderFormat: tableFormatCSV},
"html": &TableFormatter{HideSummary: true, RenderFormat: tableFormatHTML},
"markdown": &TableFormatter{HideSummary: true, RenderFormat: tableFormatMarkdown},
}

15
core/output/go.go Normal file
View File

@ -0,0 +1,15 @@
package output
import (
"fmt"
"io"
"strings"
"git.bissendorf.co/bissendorf/unifood/m/v2/core/interfaces"
)
type GoFormatter struct{}
func (f *GoFormatter) Format(list *interfaces.ResourceList) (io.Reader, error) {
return strings.NewReader(fmt.Sprintf("%#v", list)), nil
}

17
core/output/json.go Normal file
View File

@ -0,0 +1,17 @@
package output
import (
"bytes"
"encoding/json"
"io"
"git.bissendorf.co/bissendorf/unifood/m/v2/core/interfaces"
)
type JsonFormatter struct{}
func (f *JsonFormatter) Format(list *interfaces.ResourceList) (io.Reader, error) {
var buffer = make([]byte, 0, 1024)
outputBuffer := bytes.NewBuffer(buffer)
return outputBuffer, json.NewEncoder(outputBuffer).Encode(list)
}

81
core/output/table.go Normal file
View File

@ -0,0 +1,81 @@
package output
import (
"bytes"
"fmt"
"io"
"git.bissendorf.co/bissendorf/unifood/m/v2/core/interfaces"
"git.bissendorf.co/bissendorf/unifood/m/v2/util"
"github.com/jedib0t/go-pretty/table"
)
type tableRenderFormat string
const (
tableFormatNormal tableRenderFormat = "table"
tableFormatCSV tableRenderFormat = "csv"
tableFormatHTML tableRenderFormat = "html"
tableFormatMarkdown tableRenderFormat = "markdown"
)
type TableFormatter struct {
HideSummary bool
RenderFormat tableRenderFormat
}
func (f *TableFormatter) Format(list *interfaces.ResourceList) (io.Reader, error) {
var buffer = make([]byte, 0, 1024)
outputBuffer := bytes.NewBuffer(buffer)
if !f.HideSummary {
outputBuffer.WriteString(
fmt.Sprintf("Resource: %s\r\nCount: %v\r\n\r\n", list.ItemKind, len(list.Items)),
)
}
if len(list.Items) <= 0 {
return outputBuffer, nil
}
// Setup table
t := table.NewWriter()
t.SetOutputMirror(outputBuffer)
t.SetStyle(table.StyleLight)
// Write header
tableFormat, ok := list.Items[0].(interfaces.TableOutput)
headerRow := []any{"Name"}
if ok {
columnHeaders := util.Transform(tableFormat.ColumnNames(), func(i *string) any { return *i })
headerRow = append(headerRow, columnHeaders...)
}
t.AppendHeader(headerRow)
// Write rows
for _, item := range list.Items {
rowOutput := []any{item.Name()}
itemFormatter, ok := item.(interfaces.TableOutput)
if ok {
rowOutput = append(rowOutput, itemFormatter.Columns()...)
}
t.AppendRow(rowOutput)
}
// Render
switch f.RenderFormat {
case tableFormatCSV:
t.RenderCSV()
case tableFormatHTML:
t.RenderHTML()
case tableFormatMarkdown:
t.RenderMarkdown()
default:
t.Render()
}
return outputBuffer, nil
}

20
core/output/yaml.go Normal file
View File

@ -0,0 +1,20 @@
package output
import (
"bytes"
"io"
"git.bissendorf.co/bissendorf/unifood/m/v2/core/interfaces"
"github.com/goccy/go-yaml"
)
type YamlFormatter struct{}
func (f *YamlFormatter) Format(list *interfaces.ResourceList) (io.Reader, error) {
buffer, err := yaml.Marshal(list)
if err != nil {
return nil, err
}
return bytes.NewBuffer(buffer), nil
}