Skip to content

Commit

Permalink
Merge pull request #14 from drewstinnett/feature-plugin-redux
Browse files Browse the repository at this point in the history
Feature: Make Formatters Pluggable (Again)
  • Loading branch information
drewstinnett authored Feb 17, 2024
2 parents e3c1c8b + 307c331 commit dcc0222
Show file tree
Hide file tree
Showing 23 changed files with 180 additions and 215 deletions.
27 changes: 21 additions & 6 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,27 +14,42 @@ jobs:
test:
strategy:
matrix:
go-version: [1.19.x]
go-version: [stable,oldstable]
os: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- name: Install Go
uses: actions/setup-go@v2
uses: actions/setup-go@v4
with:
go-version: ${{ matrix.go-version }}
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v4
- name: Test
run: go test ./...
runexamples:
strategy:
matrix:
go-version: [stable,oldstable]
os: [ubuntu-latest]
runs-on: ${{ matrix.os }}
steps:
- name: Install Go
uses: actions/setup-go@v4
with:
go-version: ${{ matrix.go-version }}
- name: Checkout code
uses: actions/checkout@v4
- name: Test Examples
run: for EX in $(ls _examples); do go run ./_examples/$EX; done
coverage:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
with:
fetch-depth: 2
- uses: actions/setup-go@v2
- uses: actions/setup-go@v4
with:
go-version: '1.19.x'
go-version: 'stable'
- name: Run coverage
run: go test -race -coverprofile=coverage.txt -covermode=atomic
- name: Upload coverage to Codecov
Expand Down
21 changes: 0 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,27 +70,6 @@ w.MustPrint(struct {
// {"FirstName":"Bob","LastName":"Ross"}
```

### Cobra Integration

To simplify using this in new projects, you can use the `NewWithCobraCmd`
method. Example:

```go
// By default, look for a field called 'format'
w, err := NewWithCobraCmd(cmd, nil)
```

```go
// Or pass a configuration object with what the field is called
w, err := NewWithCobraCmd(cmd, &gout.CobraCmdConfig{
FormatField: "my-special-name-field",
})
```

By default, the gout will use os.Stdout as the default writer.

See [_examples](_examples/) for more example usage

## Built-in Formatters

### YAML
Expand Down
12 changes: 6 additions & 6 deletions _examples/basic/main.go
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
package main

import (
"fmt"
"os"

gout "github.com/drewstinnett/gout/v2"
"github.com/drewstinnett/gout/v2/formats/json"
"github.com/drewstinnett/gout/v2/formats"
_ "github.com/drewstinnett/gout/v2/formats/builtin"
)

func main() {
w, err := gout.New()
if err != nil {
panic(err)
}
w := gout.New()
fmt.Printf("Active Formatters: %v\n", formats.Names())
// By Default, the YAML format is use, Let's change it to json though
w.SetFormatter(json.Formatter{})
// w.SetFormatter(json.Formatter{})

// By Default, print to stdout. Let's change it to stderr though
w.SetWriter(os.Stderr)
Expand Down
25 changes: 12 additions & 13 deletions _examples/formats/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"

gout "github.com/drewstinnett/gout/v2"
"github.com/drewstinnett/gout/v2/formats"
)

type sample struct {
Expand All @@ -21,19 +22,17 @@ func main() {
sample{FirstName: "Freddy", LastName: "Krueger", Age: 35},
sample{FirstName: "Michael", LastName: "Myers", Age: 13},
}
c, _ := gout.New()
for formatN, formatF := range gout.BuiltInFormatters {
if formatN != "gotemplate" {
fmt.Printf("# Format: %v\n", formatN)
c.SetFormatter(formatF)
// CSV Formatter won't work on a single object, has to be iterable
if formatN != "csv" {
fmt.Println("## Person")
c.MustPrint(person)
}
fmt.Println("## People")
c.MustPrint(people)
fmt.Println()
g := gout.New()
for formatN, formatG := range formats.Formats {
fmt.Printf("# Format: %v\n", formatN)
g.SetFormatter(formatG())
// CSV Formatter won't work on a single object, has to be iterable
if formatN != "csv" {
fmt.Println("## Person")
g.MustPrint(person)
}
fmt.Println("## People")
g.MustPrint(people)
fmt.Println()
}
}
12 changes: 8 additions & 4 deletions _examples/gotemplate/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"

gout "github.com/drewstinnett/gout/v2"
"github.com/drewstinnett/gout/v2/config"
"github.com/drewstinnett/gout/v2/formats/gotemplate"
)

Expand All @@ -21,12 +22,15 @@ func main() {
sample{FirstName: "Freddy", LastName: "Krueger", Age: 35},
sample{FirstName: "Michael", LastName: "Myers", Age: 13},
}
c, _ := gout.New()
c.SetFormatter(gotemplate.Formatter{
Template: "{{ range . }}{{ .FirstName }} {{ .LastName }} is {{ .Age }} years old\n{{ end }}",
g := gout.New()
g.SetFormatter(gotemplate.Formatter{
Opts: config.FormatterOpts{
"template": "{{ range . }}{{ .FirstName }} {{ .LastName }} is {{ .Age }} years old\n{{ end }}",
},
})
//"template": "{{ range . }}{{ .FirstName }} {{ .LastName }} is {{ .Age }} years old\n{{ end }}",
fmt.Printf("# Format: gotemplate\n## People\n")
c.MustPrint(people)
g.MustPrint(people)
fmt.Println()

// fmt.Println(string(b))
Expand Down
12 changes: 12 additions & 0 deletions formats/builtin/builtin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
Package builtin is a helper to register all the built in formatters
*/
package builtin

import (
_ "github.com/drewstinnett/gout/v2/formats/gotemplate"
_ "github.com/drewstinnett/gout/v2/formats/json"
_ "github.com/drewstinnett/gout/v2/formats/plain"
_ "github.com/drewstinnett/gout/v2/formats/xml"
_ "github.com/drewstinnett/gout/v2/formats/yaml"
)
11 changes: 0 additions & 11 deletions formats/csv/csv.go

This file was deleted.

20 changes: 0 additions & 20 deletions formats/csv/csv_test.go

This file was deleted.

23 changes: 5 additions & 18 deletions formats/gotemplate/gotemplate.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"text/template"

"github.com/drewstinnett/gout/v2/config"
"github.com/drewstinnett/gout/v2/formats"
)

type Formatter struct {
Expand Down Expand Up @@ -35,22 +36,8 @@ func (w Formatter) Format(v interface{}) ([]byte, error) {
return doc.Bytes(), nil
}

/*
func (w Formatter) formatWithOpts(v interface{}, o config.FormatterOpts) ([]byte, error) {
if _, ok := o["template"]; !ok {
return nil, errors.New("Must pass 'template' in to options")
}
tpl := o["template"].(string)
var doc bytes.Buffer
tmpl, err := template.New("item").Parse(tpl)
if err != nil {
return nil, err
}
err = tmpl.Execute(&doc, v)
if err != nil {
return nil, err
}
return doc.Bytes(), nil
func init() {
formats.Add("gotemplate", func() formats.Formatter {
return &Formatter{}
})
}
*/
8 changes: 8 additions & 0 deletions formats/json/json.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package json
import (
"context"
ujson "encoding/json"

"github.com/drewstinnett/gout/v2/formats"
)

type Formatter struct {
Expand Down Expand Up @@ -30,3 +32,9 @@ func (w *Formatter) withContext(ctx context.Context) *Formatter {
w.ctx = ctx
return w
}

func init() {
formats.Add("json", func() formats.Formatter {
return &Formatter{}
})
}
8 changes: 8 additions & 0 deletions formats/plain/plain.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,18 @@ package plain

import (
"fmt"

"github.com/drewstinnett/gout/v2/formats"
)

type Formatter struct{}

func (w Formatter) Format(v interface{}) ([]byte, error) {
return []byte(fmt.Sprintf("%+v\n", v)), nil
}

func init() {
formats.Add("plain", func() formats.Formatter {
return &Formatter{}
})
}
29 changes: 29 additions & 0 deletions formats/registry.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package formats

import (
"sort"
)

type Creator func() Formatter

var Formats = map[string]Creator{}

// Add a new format creator
func Add(name string, creator Creator) {
Formats[name] = creator
}

// Names returns a slice of the names of the formatters
func Names() []string {
ret := []string{}
for k := range Formats {
ret = append(ret, k)
}
sort.Strings(ret)
return ret
}

// Formatter interface that defines how a thing can be formatted for output
type Formatter interface {
Format(interface{}) ([]byte, error)
}
17 changes: 17 additions & 0 deletions formats/registry_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package formats_test

import (
"testing"

"github.com/drewstinnett/gout/v2/formats"
_ "github.com/drewstinnett/gout/v2/formats/builtin"
"github.com/stretchr/testify/require"
)

func TestBuiltinRegistry(t *testing.T) {
require.Equal(
t,
[]string{"gotemplate", "json", "plain", "xml", "yaml"},
formats.Names(),
)
}
11 changes: 0 additions & 11 deletions formats/toml/toml.go

This file was deleted.

19 changes: 0 additions & 19 deletions formats/toml/toml_test.go

This file was deleted.

8 changes: 8 additions & 0 deletions formats/xml/xml.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,18 @@ package xml

import (
uxml "encoding/xml"

"github.com/drewstinnett/gout/v2/formats"
)

type Formatter struct{}

func (w Formatter) Format(v interface{}) ([]byte, error) {
return uxml.Marshal(v)
}

func init() {
formats.Add("xml", func() formats.Formatter {
return &Formatter{}
})
}
Loading

0 comments on commit dcc0222

Please sign in to comment.