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 10, 2020
1 parent 9ee9f82 commit 1df0a0b
Show file tree
Hide file tree
Showing 13 changed files with 382 additions and 403 deletions.
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))
}
}
8 changes: 8 additions & 0 deletions data/datasource.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,14 @@ func NewData(datasourceArgs, headerArgs []string) (*Data, error) {
return data, nil
}

// FromConfig - internal use only!
func FromConfig(sources map[string]*Source, extraHeaders map[string]http.Header) *Data {
return &Data{
Sources: sources,
extraHeaders: extraHeaders,
}
}

// Source - a data source
type Source struct {
Alias string
Expand Down
46 changes: 26 additions & 20 deletions gomplate.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package gomplate
import (
"bytes"
"context"
"fmt"
"io"
"os"
"path"
Expand All @@ -14,7 +15,9 @@ import (
"time"

"github.com/hairyhenderson/gomplate/v3/data"
"github.com/hairyhenderson/gomplate/v3/internal/config"
"github.com/pkg/errors"
"github.com/rs/zerolog"
"github.com/spf13/afero"
)

Expand Down Expand Up @@ -109,42 +112,45 @@ func parseTemplateArg(templateArg string, ta templateAliases) error {

// RunTemplates - run all gomplate templates specified by the given configuration
func RunTemplates(o *Config) error {
return RunTemplatesWithContext(context.Background(), o)
cfg, err := o.toNewConfig()
if err != nil {
return err
}
return RunTemplatesWithContext(context.Background(), cfg)
}

// RunTemplatesWithContext - run all gomplate templates specified by the given configuration
func RunTemplatesWithContext(ctx context.Context, o *Config) error {
func RunTemplatesWithContext(ctx context.Context, cfg *config.Config) error {
log := zerolog.Ctx(ctx)

Metrics = newMetrics()
defer runCleanupHooks()
// make sure config is sane
o.defaults()
ds := append(o.DataSources, o.Contexts...)
d, err := data.NewData(ds, o.DataSourceHeaders)
if err != nil {
return err
}

d := data.FromConfig(cfg.Sources(), cfg.ExtraHeaders)
log.Debug().Str("data", fmt.Sprintf("%+v", d)).Msg("created data from config")

addCleanupHook(d.Cleanup)
nested, err := parseTemplateArgs(o.Templates)
nested, err := parseTemplateArgs(cfg.Templates)
if err != nil {
return err
}
c, err := createTmplContext(o.Contexts, d)
c, err := createTmplContext(ctx, cfg.Context, d)
if err != nil {
return err
}
funcMap := Funcs(d)
err = bindPlugins(ctx, o.Plugins, funcMap)
err = bindPlugins(ctx, cfg.Plugins, funcMap)
if err != nil {
return err
}
g := newGomplate(funcMap, o.LDelim, o.RDelim, nested, c)
g := newGomplate(funcMap, cfg.LDelim, cfg.RDelim, nested, c)

return g.runTemplates(ctx, o)
return g.runTemplates(ctx, cfg)
}

func (g *gomplate) runTemplates(ctx context.Context, o *Config) error {
func (g *gomplate) runTemplates(ctx context.Context, cfg *config.Config) error {
start := time.Now()
tmpl, err := gatherTemplates(o, chooseNamer(o, g))
tmpl, err := gatherTemplates(cfg, chooseNamer(cfg, g))
Metrics.GatherDuration = time.Since(start)
if err != nil {
Metrics.Errors++
Expand All @@ -166,11 +172,11 @@ func (g *gomplate) runTemplates(ctx context.Context, o *Config) error {
return nil
}

func chooseNamer(o *Config, g *gomplate) func(string) (string, error) {
if o.OutputMap == "" {
return simpleNamer(o.OutputDir)
func chooseNamer(cfg *config.Config, g *gomplate) func(string) (string, error) {
if cfg.OutputMap == "" {
return simpleNamer(cfg.OutputDir)
}
return mappingNamer(o.OutputMap, g)
return mappingNamer(cfg.OutputMap, g)
}

func simpleNamer(outDir string) func(inPath string) (string, error) {
Expand Down
Loading

0 comments on commit 1df0a0b

Please sign in to comment.