Skip to content

Commit

Permalink
fixup! Support a config file to use instead of commandline arguments
Browse files Browse the repository at this point in the history
  • Loading branch information
hairyhenderson committed Apr 25, 2020
1 parent ef0f6a2 commit 78d6bb0
Show file tree
Hide file tree
Showing 22 changed files with 987 additions and 493 deletions.
10 changes: 10 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ jobs:
- run: make build
env:
GOPATH: ${{ runner.workspace }}
- name: Save binary
uses: actions/upload-artifact@v1
with:
name: gomplate
path: bin/gomplate
- run: make test
env:
GOPATH: ${{ runner.workspace }}
Expand All @@ -41,6 +46,11 @@ jobs:
- run: make build
env:
GOPATH: ${{ runner.workspace }}
- name: Save binary
uses: actions/upload-artifact@v1
with:
name: gomplate.exe
path: bin/gomplate.exe
- run: make test
env:
GOPATH: ${{ runner.workspace }}
Expand Down
24 changes: 24 additions & 0 deletions cmd/gomplate/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ package main
import (
"context"
"fmt"
"time"

"github.com/hairyhenderson/gomplate/v3/conv"
"github.com/hairyhenderson/gomplate/v3/env"
"github.com/hairyhenderson/gomplate/v3/internal/config"

Expand All @@ -26,6 +28,7 @@ var fs = afero.NewOsFs()
// - validates the final config
// - converts the config to a *gomplate.Config for further use (TODO: eliminate this part)
func loadConfig(cmd *cobra.Command, args []string) (*config.Config, error) {
ctx := cmd.Context()
flagConfig, err := cobraConfig(cmd, args)
if err != nil {
return nil, err
Expand All @@ -41,6 +44,11 @@ func loadConfig(cmd *cobra.Command, args []string) (*config.Config, error) {
cfg = cfg.MergeFrom(flagConfig)
}

cfg, err = applyEnvVars(ctx, cfg)
if err != nil {
return nil, err
}

// reset defaults before validation
cfg.ApplyDefaults()

Expand Down Expand Up @@ -227,3 +235,19 @@ func processIncludes(includes, excludes []string) []string {
out = append(out, excludes...)
return out
}

func applyEnvVars(ctx context.Context, cfg *config.Config) (*config.Config, error) {
if to := env.Getenv("GOMPLATE_PLUGIN_TIMEOUT"); cfg.PluginTimeout == 0 && to != "" {
t, err := time.ParseDuration(to)
if err != nil {
return nil, fmt.Errorf("GOMPLATE_PLUGIN_TIMEOUT set to invalid value %q: %w", to, err)
}
cfg.PluginTimeout = t
}

if !cfg.SuppressEmpty && conv.ToBool(env.Getenv("GOMPLATE_SUPPRESS_EMPTY", "false")) {
cfg.SuppressEmpty = true
}

return cfg, nil
}
80 changes: 80 additions & 0 deletions cmd/gomplate/config_test.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package main

import (
"context"
"os"
"testing"
"time"

"github.com/hairyhenderson/gomplate/v3/internal/config"

Expand Down Expand Up @@ -79,6 +81,7 @@ func TestLoadConfig(t *testing.T) {
RDelim: "}}",
PostExecInput: os.Stdin,
OutWriter: os.Stdout,
PluginTimeout: 5 * time.Second,
}
assert.NoError(t, err)
assert.EqualValues(t, expected, out)
Expand All @@ -92,6 +95,7 @@ func TestLoadConfig(t *testing.T) {
RDelim: "}}",
PostExecInput: os.Stdin,
OutWriter: os.Stdout,
PluginTimeout: 5 * time.Second,
}
assert.NoError(t, err)
assert.EqualValues(t, expected, out)
Expand All @@ -106,6 +110,8 @@ func TestLoadConfig(t *testing.T) {
PostExec: []string{"tr", "[a-z]", "[A-Z]"},
PostExecInput: out.PostExecInput,
OutWriter: out.PostExecInput,
OutputFiles: []string{"-"},
PluginTimeout: 5 * time.Second,
}
assert.NoError(t, err)
assert.EqualValues(t, expected, out)
Expand Down Expand Up @@ -176,3 +182,77 @@ func TestPickConfigFile(t *testing.T) {
assert.True(t, req)
assert.Equal(t, "config.file", cf)
}

func TestApplyEnvVars_PluginTimeout(t *testing.T) {
os.Setenv("GOMPLATE_PLUGIN_TIMEOUT", "bogus")

ctx := context.TODO()
cfg := &config.Config{}
_, err := applyEnvVars(ctx, cfg)
assert.Error(t, err)

cfg = &config.Config{
PluginTimeout: 2 * time.Second,
}
expected := &config.Config{
PluginTimeout: 2 * time.Second,
}
actual, err := applyEnvVars(ctx, cfg)
assert.NoError(t, err)
assert.EqualValues(t, expected, actual)

os.Setenv("GOMPLATE_PLUGIN_TIMEOUT", "2s")
defer os.Unsetenv("GOMPLATE_PLUGIN_TIMEOUT")

cfg = &config.Config{}
actual, err = applyEnvVars(ctx, cfg)
assert.NoError(t, err)
assert.EqualValues(t, expected, actual)

cfg = &config.Config{
PluginTimeout: 100 * time.Millisecond,
}
expected = &config.Config{
PluginTimeout: 100 * time.Millisecond,
}
actual, err = applyEnvVars(ctx, cfg)
assert.NoError(t, err)
assert.EqualValues(t, expected, actual)

}

func TestApplyEnvVars_SuppressEmpty(t *testing.T) {
os.Setenv("GOMPLATE_SUPPRESS_EMPTY", "bogus")
defer os.Unsetenv("GOMPLATE_SUPPRESS_EMPTY")

ctx := context.TODO()
cfg := &config.Config{}
expected := &config.Config{
SuppressEmpty: false,
}
actual, err := applyEnvVars(ctx, cfg)
assert.NoError(t, err)
assert.EqualValues(t, expected, actual)

os.Setenv("GOMPLATE_SUPPRESS_EMPTY", "true")

cfg = &config.Config{}
expected = &config.Config{
SuppressEmpty: true,
}
actual, err = applyEnvVars(ctx, cfg)
assert.NoError(t, err)
assert.EqualValues(t, expected, actual)

os.Setenv("GOMPLATE_SUPPRESS_EMPTY", "false")

cfg = &config.Config{
SuppressEmpty: true,
}
expected = &config.Config{
SuppressEmpty: true,
}
actual, err = applyEnvVars(ctx, cfg)
assert.NoError(t, err)
assert.EqualValues(t, expected, actual)
}
4 changes: 1 addition & 3 deletions cmd/gomplate/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,7 @@ func newGomplateCmd() *cobra.Command {
Str("build", version.GitCommit).
Msgf("config is:\n%v", cfg)

conf := cfg.ToGConfig()

err = gomplate.RunTemplatesWithContext(ctx, conf)
err = gomplate.RunTemplatesWithContext(ctx, cfg)
cmd.SilenceErrors = true
cmd.SilenceUsage = true

Expand Down
44 changes: 28 additions & 16 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ package gomplate

import (
"io"
"os"
"strconv"
"strings"

"github.com/hairyhenderson/gomplate/v3/internal/config"
)

// Config - values necessary for rendering templates with gomplate.
Expand Down Expand Up @@ -52,20 +52,6 @@ func (o *Config) defaults() *Config {
return o
}

// parse an os.FileMode out of the string, and let us know if it's an override or not...
func (o *Config) getMode() (os.FileMode, bool, error) {
modeOverride := o.OutMode != ""
m, err := strconv.ParseUint("0"+o.OutMode, 8, 32)
if err != nil {
return 0, false, err
}
mode := os.FileMode(m)
if mode == 0 && o.Input != "" {
mode = 0644
}
return mode, modeOverride, nil
}

// nolint: gocyclo
func (o *Config) String() string {
o.defaults()
Expand Down Expand Up @@ -124,3 +110,29 @@ func (o *Config) String() string {
}
return c
}

func (o *Config) toNewConfig() (*config.Config, error) {
cfg := &config.Config{
Input: o.Input,
InputFiles: o.InputFiles,
InputDir: o.InputDir,
ExcludeGlob: o.ExcludeGlob,
OutputFiles: o.OutputFiles,
OutputDir: o.OutputDir,
OutputMap: o.OutputMap,
OutMode: o.OutMode,
LDelim: o.LDelim,
RDelim: o.RDelim,
Templates: o.Templates,
OutWriter: o.Out,
}
err := cfg.ParsePluginFlags(o.Plugins)
if err != nil {
return nil, err
}
err = cfg.ParseDataSourceFlags(o.DataSources, o.Contexts, o.DataSourceHeaders)
if err != nil {
return nil, err
}
return cfg, nil
}
25 changes: 0 additions & 25 deletions config_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package gomplate

import (
"os"
"testing"

"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -47,27 +46,3 @@ output: {{ .in }}`

assert.Equal(t, expected, c.String())
}

func TestGetMode(t *testing.T) {
c := &Config{}
m, o, err := c.getMode()
assert.NoError(t, err)
assert.Equal(t, os.FileMode(0), m)
assert.False(t, o)

c = &Config{OutMode: "755"}
m, o, err = c.getMode()
assert.NoError(t, err)
assert.Equal(t, os.FileMode(0755), m)
assert.True(t, o)

c = &Config{OutMode: "0755"}
m, o, err = c.getMode()
assert.NoError(t, err)
assert.Equal(t, os.FileMode(0755), m)
assert.True(t, o)

c = &Config{OutMode: "foo"}
_, _, err = c.getMode()
assert.Error(t, err)
}
17 changes: 4 additions & 13 deletions context.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package gomplate

import (
"context"
"os"
"strings"

"github.com/hairyhenderson/gomplate/v3/data"
"github.com/hairyhenderson/gomplate/v3/internal/config"
)

// context for templates
Expand All @@ -20,11 +22,10 @@ func (c *tmplctx) Env() map[string]string {
return env
}

func createTmplContext(contexts []string, d *data.Data) (interface{}, error) {
func createTmplContext(ctx context.Context, contexts config.DSources, d *data.Data) (interface{}, error) {
var err error
tctx := &tmplctx{}
for _, c := range contexts {
a := parseAlias(c)
for a := range contexts {
if a == "." {
return d.Datasource(a)
}
Expand All @@ -35,13 +36,3 @@ func createTmplContext(contexts []string, d *data.Data) (interface{}, error) {
}
return tctx, nil
}

func parseAlias(arg string) string {
parts := strings.SplitN(arg, "=", 2)
switch len(parts) {
case 1:
return strings.SplitN(parts[0], ".", 2)[0]
default:
return parts[0]
}
}
26 changes: 8 additions & 18 deletions context_test.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package gomplate

import (
"context"
"net/url"
"os"
"testing"

"github.com/hairyhenderson/gomplate/v3/data"
"github.com/hairyhenderson/gomplate/v3/internal/config"

"github.com/stretchr/testify/assert"
)
Expand All @@ -24,7 +26,8 @@ func TestEnvGetsUpdatedEnvironment(t *testing.T) {
}

func TestCreateContext(t *testing.T) {
c, err := createTmplContext(nil, nil)
ctx := context.TODO()
c, err := createTmplContext(ctx, nil, nil)
assert.NoError(t, err)
assert.Empty(t, c)

Expand All @@ -40,31 +43,18 @@ func TestCreateContext(t *testing.T) {
}
os.Setenv("foo", "foo: bar")
defer os.Unsetenv("foo")
c, err = createTmplContext([]string{"foo=" + fooURL}, d)
c, err = createTmplContext(ctx, map[string]config.DSConfig{"foo": {URL: uf}}, d)
assert.NoError(t, err)
assert.IsType(t, &tmplctx{}, c)
ctx := c.(*tmplctx)
ds := ((*ctx)["foo"]).(map[string]interface{})
tctx := c.(*tmplctx)
ds := ((*tctx)["foo"]).(map[string]interface{})
assert.Equal(t, "bar", ds["foo"])

os.Setenv("bar", "bar: baz")
defer os.Unsetenv("bar")
c, err = createTmplContext([]string{".=" + barURL}, d)
c, err = createTmplContext(ctx, map[string]config.DSConfig{".": {URL: ub}}, d)
assert.NoError(t, err)
assert.IsType(t, map[string]interface{}{}, c)
ds = c.(map[string]interface{})
assert.Equal(t, "baz", ds["bar"])
}

func TestParseAlias(t *testing.T) {
testdata := map[string]string{
"": "",
"foo": "foo",
"foo.bar": "foo",
"a=b": "a",
".=foo": ".",
}
for k, v := range testdata {
assert.Equal(t, v, parseAlias(k))
}
}
Loading

0 comments on commit 78d6bb0

Please sign in to comment.