Skip to content

Commit

Permalink
Add option to load style config from file (#92)
Browse files Browse the repository at this point in the history
  • Loading branch information
Kamsiy authored May 6, 2023
1 parent 8032824 commit e9da3c1
Show file tree
Hide file tree
Showing 10 changed files with 215 additions and 4 deletions.
43 changes: 43 additions & 0 deletions printer/opts.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
package printer

import (
"encoding/json"
"os"
"path/filepath"

"go.szostok.io/version/style"
"go.szostok.io/version/upgrade"
"gopkg.in/yaml.v3"
)

// Inspired by https://github.com/kubernetes-sigs/controller-runtime/blob/v0.12.3/pkg/client/options.go
Expand Down Expand Up @@ -195,3 +200,41 @@ func WithUpgradeNotice(owner, repo string, opts ...upgrade.Options) *EnableUpgra
func (c *EnableUpgradeNotice) ApplyToContainerOption(cfg *ContainerOptions) {
cfg.UpgradeNotice = upgrade.NewGitHubDetector(c.owner, c.repo, c.upgradeOpts...)
}

// WithPrettyStyleFromEnv Load a custom style from environment variable
func WithPrettyStyleFromEnv(envVariable string) (*CustomPrettyStyle, error) {
path := os.Getenv(envVariable)
options, err := parseConfigFile(path)

return options, err
}

// WithPrettyStyleFile Load a custom style from file
func WithPrettyStyleFile(path string) (*CustomPrettyStyle, error) {
options, err := parseConfigFile(path)

return options, err
}

func parseConfigFile(fileName string) (*CustomPrettyStyle, error) {
options := &CustomPrettyStyle{cfg: PrettyDefaultRenderConfig()}
if fileName == "" {
return options, nil
}

fileName = filepath.Clean(fileName)
body, err := os.ReadFile(fileName)
if err != nil {
return options, err
}

extension := filepath.Ext(fileName)
switch extension {
case ".yml", ".yaml":
err = yaml.Unmarshal(body, &options.cfg)
case ".json":
err = json.Unmarshal(body, &options.cfg)
}

return options, err
}
11 changes: 7 additions & 4 deletions printer/pretty.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,8 @@ type (
PrettyPostRenderFunc func(body string, isSmartTerminal bool) (string, error)
)

var (
// PrettyLayoutGoTpl prints all version data in a 'key value' manner.
PrettyLayoutGoTpl = `{{ AdjustKeyWidth .ExtraFields }}
// PrettyLayoutGoTpl prints all version data in a 'key value' manner.
var PrettyLayoutGoTpl = `{{ AdjustKeyWidth .ExtraFields }}
{{ Header .Meta.CLIName }}
{{ Key "Version" }} {{ .Version | Val }}
Expand All @@ -35,7 +34,6 @@ var (
{{ $item.Key | Key }} {{ $item.Value | Val }}
{{- end}}
`
)

// Pretty prints human-readable version printing.
type Pretty struct {
Expand Down Expand Up @@ -91,3 +89,8 @@ func (p *Pretty) execute(in *version.Info, isSmartTerminal bool) (string, error)

return p.customRenderFn(in, isSmartTerminal)
}

// PrettyDefaultRenderConfig returns the default render configuration when no customizations are provided.
func PrettyDefaultRenderConfig() *style.Config {
return style.DefaultConfig(PrettyLayoutGoTpl)
}
63 changes: 63 additions & 0 deletions printer/printer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,69 @@ func TestPrinterPrint(t *testing.T) {
assertGoldenFile(t, normalized)
}

// It uses the golden files, to update them run:
//
// go test -v -run=TestPrinterStyleFileOptions ./printer/... -update
func TestPrinterStyleFileOptions(t *testing.T) {
tests := []struct {
testName string
fileName string
}{
{
testName: "Print custom layout",
fileName: "testdata/TestPrinterStyleFileOptions/customStyle",
},
{
testName: "Print default layout",
fileName: "testdata/TestPrinterStyleFileOptions/invalidStyle",
},
}

for _, tc := range tests {
t.Run(tc.testName, func(t *testing.T) {
yamlStyle, err := printer.WithPrettyStyleFile(tc.fileName + ".yaml")
require.NoError(t, err)

jsonStyle, err := printer.WithPrettyStyleFile(tc.fileName + ".json")
require.NoError(t, err)

t.Setenv("config-file", tc.fileName+".yaml")

envStyle, err := printer.WithPrettyStyleFromEnv("config-file")
require.NoError(t, err)

validateStyle(yamlStyle, t)
validateStyle(jsonStyle, t)
validateStyle(envStyle, t)
})
}
}

// It uses the golden files, to update them run:
//
// go test -v -run=TestPrinterStyleFromEnvOptionsUseDefaults ./printer/... -update
func TestPrinterStyleFromEnvOptionsUseDefaults(t *testing.T) {
emptyStyle, err := printer.WithPrettyStyleFromEnv("empty-variable")
require.NoError(t, err)

validateStyle(emptyStyle, t)
}

func validateStyle(customStyle *printer.CustomPrettyStyle, t *testing.T) {
t.Helper()

p := printer.New(customStyle)
var buff strings.Builder

err := p.Print(&buff)

require.NoError(t, err)

stripped := strings.TrimSpace(buff.String())
normalized := normalizeOutput(stripped)
assertGoldenFile(t, normalized)
}

// normalizeOutput normalize dynamic fields such as platform and binary name.
func normalizeOutput(data string) string {
data = strings.ReplaceAll(data, os.Args[0], "fixed-name")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
-> fixed-name

Version (devel)
Dirty Build no
Go version 1.19.4
Compiler gc
Platform fixed-platform
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
▓▓▓ fixed-name

Version (devel)
Git Commit N/A
Build Date N/A
Commit Date N/A
Dirty Build no
Go version 1.19.4
Compiler gc
Platform fixed-platform
28 changes: 28 additions & 0 deletions printer/testdata/TestPrinterStyleFileOptions/customStyle.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"formatting": {
"header": {
"prefix": "-> ",
"color": "Magenta",
"background": "",
"options": null
},
"key": {
"color": "Yellow",
"background": "",
"options": [
"Bold"
]
},
"val": {
"color": "Green",
"background": "",
"options": null
},
"date": {
"enableHumanizedSuffix": false
}
},
"layout": {
"goTemplate": "{{ AdjustKeyWidth .ExtraFields }}\n{{ Header .Meta.CLIName }}\n\n {{ Key \"Version\" }} {{ .Version | Val }}\n {{ Key \"Dirty Build\" }} {{ .DirtyBuild | FmtBool | Val }}\n {{ Key \"Go version\" }} {{ .GoVersion | trimPrefix \"go\"| Val }}\n {{ Key \"Compiler\" }} {{ .Compiler | Val }}\n {{ Key \"Platform\" }} {{ .Platform | Val }}\n {{- range $item := (.ExtraFields | Extra) }}\n {{ $item.Key | Key }} {{ $item.Value | Val }}\n {{- end}}\n"
}
}
31 changes: 31 additions & 0 deletions printer/testdata/TestPrinterStyleFileOptions/customStyle.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
formatting:
header:
prefix: '-> '
color: Magenta
background: ""
options: []
key:
color: Yellow
background: ""
options:
- Bold
val:
color: Green
background: ""
options: []
date:
enableHumanizedSuffix: true

layout:
goTemplate: |
{{ AdjustKeyWidth .ExtraFields }}
{{ Header .Meta.CLIName }}
{{ Key "Version" }} {{ .Version | Val }}
{{ Key "Dirty Build" }} {{ .DirtyBuild | FmtBool | Val }}
{{ Key "Go version" }} {{ .GoVersion | trimPrefix "go"| Val }}
{{ Key "Compiler" }} {{ .Compiler | Val }}
{{ Key "Platform" }} {{ .Platform | Val }}
{{- range $item := (.ExtraFields | Extra) }}
{{ $item.Key | Key }} {{ $item.Value | Val }}
{{- end}}
10 changes: 10 additions & 0 deletions printer/testdata/TestPrinterStyleFileOptions/invalidStyle.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"format": {
"header": {
"prefix": "-> ",
"color": "Magenta",
"background": "",
"options": null
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
format:
header:
prefix: '-> '
color: Magenta
background: ""
options: []
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
▓▓▓ fixed-name

Version (devel)
Git Commit N/A
Build Date N/A
Commit Date N/A
Dirty Build no
Go version 1.19.4
Compiler gc
Platform fixed-platform

0 comments on commit e9da3c1

Please sign in to comment.