Skip to content

Commit

Permalink
Closes #9
Browse files Browse the repository at this point in the history
- Add tests for dot-notation variable names
- Restore `-m` parameter
- Fix flag handling
- Add support for multiple default settings files in folder
- Compute reasonable default names for settings and templates
- Create examples and move some tests there
- Update the README.md
  • Loading branch information
nicerobot committed Sep 16, 2018
1 parent ac0c784 commit fbd513e
Show file tree
Hide file tree
Showing 19 changed files with 244 additions and 309 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ PREFIX ?= usr/local

all: release vet test ## Make everything

build: # BUild darwin
build: # Build darwin
goreleaser --config .goreleaser-darwin.yml --debug --rm-dist --skip-publish --skip-validate

release: ## Build releases
Expand Down
48 changes: 22 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,49 +8,43 @@ Render Go text templates from the command line.

Supports providing top-level name/value pairs on the command line:

renderizer --name=value --top=first template-file
echo 'Hello, {{.User}}' | renderizer --user=${USER}

Sets:

Name: value
Top: first
And read from the environment:

**NOTE:**
echo 'Hello, {{.env.User}}' | renderizer

- Template values are provided `--name=value`.
- Renderizer controls are provided using `-NAME[=value]`.
## Usage:

## Example
renderizer [OPTIONS] [--name=value]... [template-file]...

First:

git clone https://github.com/gomatic/renderizer.git
cd renderizer
go build
## Examples

Render the `pod.yaml` using values from `test/.renderizer.yaml`:

renderizer -S=test/.renderizer.yaml test/pod.yaml
renderizer --settings=example/pod/.pod.yaml example/pod/pod.yaml.tmpl

Or set `RENDERIZER` in the environment:

RENDERIZER=test/.renderizer.yaml renderizer test/pod.yaml
RENDERIZER=example/.pod.yaml renderizer example/pod/pod.yaml.tmpl

Alternatively, it'll try `.renderizer.yaml` in the current directory.

(cd test; renderizer pod.yaml)
(cd example/pod; renderizer pod.yaml)

Next, override the `deployment` value to render the "dev" `pod.yaml` (after `cd test/`):
Next, override the `deployment` value to render the "dev" `pod.yaml` (after `cd example/pod`):

renderizer --deployment=dev --name='spaced out' pod.yaml

## Configuration
For more examples, see the [`examples`](examples) folder.

# Configuration

### Settings `-S=`
### Settings

Settings can be loaded from a yaml:

renderizer -S=renderizer.yaml --name=value --top=first template-file
renderizer --settings=.renderizer.yaml --name=value --top=first template-file

### Capitalization `-C`

Expand All @@ -65,17 +59,19 @@ Sets:
Name: value
top: first

### Missing Keys `-M=`
### Missing Keys

Control the missingkeys template-engine option:

renderizer -M=zero --top=first template-file
renderizer --missing=zero --top=first template-file

### Environment

### Environment `-E=`
Provide a name for the environment variables:

Provide a default value for missing environment variables:
renderizer --environment=env template-file

renderizer -E=--missing-- template-file
It defaults to `env` which is effectively the same as the above `--environment=env`.

## Template Functions

Expand Down
5 changes: 5 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Examples

In each folder, just run:

renderizer
5 changes: 5 additions & 0 deletions examples/basic/.basic.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Name: Renderizer
Items:
- one
- two
- three
5 changes: 5 additions & 0 deletions examples/document/.document.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
items:
- apple
- banana
- cherry
foo: true
File renamed without changes.
1 change: 1 addition & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
github.com/gomatic/funcmap v0.0.0-20170407194050-9ab29796c307 h1:vdV1B6lc0iOnze2OvoHREif4bzaYTY5WHo1+HhBD2io=
github.com/gomatic/funcmap v0.0.0-20170407194050-9ab29796c307/go.mod h1:tgYMANYRbfiPtGpM0in6m2dnRENPq5Oj0f+eJkTBT1E=
github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28=
github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/kardianos/osext v0.0.0-20170510131534-ae77be60afb1 h1:PJPDf8OUfOK1bb/NeTKd4f1QXZItOX389VN3B6qC8ro=
github.com/kardianos/osext v0.0.0-20170510131534-ae77be60afb1/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8=
Expand Down
128 changes: 94 additions & 34 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"os"
"path/filepath"
"strings"
"time"

"github.com/kardianos/osext"
"github.com/urfave/cli"
Expand All @@ -19,11 +18,9 @@ var (
commit = "unknown"
date = "none"
selfn, _ = osext.Executable()
selfd, _ = osext.ExecutableFolder()
selfz = filepath.Base(selfn)
semver = version + "-" + commit[:7] + "." + date
appver = selfz + "/" + semver
started = time.Now().Format("20060102T150405Z0700")
)

//
Expand All @@ -33,16 +30,20 @@ type Settings struct {
// Set the Missing Key template option. Defaults to "error".
MissingKey string
// Configuration yaml
ConfigFiles []string
ConfigFiles cli.StringSlice
Defaulted bool
Config map[string]interface{}
//
Arguments []string
// Add the environment map to the variables.
Environment string
//
OutputExtension string
//
TimeFormat string
//
Stdin bool
//
Debugging bool
//
Verbose bool
Expand All @@ -55,6 +56,7 @@ var settings = Settings{
TimeFormat: "20060102T150405",
Environment: "env",
Config: map[string]interface{}{},
ConfigFiles: []string{},
Arguments: []string{},
}

Expand All @@ -66,24 +68,8 @@ func main() {
app.UsageText = "Template renderer"
app.Version = appver
app.EnableBashCompletion = true
configs := cli.StringSlice([]string{".renderizer.yaml"})

// Remove args that are not processed by urfave/cli
var args []string
for _, arg := range os.Args {
larg := strings.ToLower(arg)
switch {
case larg == "-c":
fallthrough
case strings.HasPrefix(arg, "--") && strings.Contains(arg, "="):
settings.Arguments = append(settings.Arguments, arg)

case strings.HasPrefix(arg, "--"):
fallthrough
default:
args = append(args, arg)
}
}
configs := cli.StringSlice{}

app.Commands = []cli.Command{
{
Expand All @@ -98,22 +84,29 @@ func main() {

app.Flags = []cli.Flag{
cli.StringSliceFlag{
Name: "settings, S",
Usage: "load the settings from the provided YAMLs",
Name: "settings, S, s",
Usage: `load the settings from the provided YAMLs (default: ".renderizer.yaml")`,
Value: &configs,
EnvVar: "RENDERIZER",
},
cli.StringFlag{
Name: "environment, env, E",
Usage: "load the environment into the variable name instead of as 'env'",
},
cli.StringFlag{
Name: "missing, M",
Name: "missing, M, m",
Usage: "the 'missingkey' template option (default|zero|error)",
Value: "error",
EnvVar: "RENDERIZER_MISSINGKEY",
Destination: &settings.MissingKey,
},
cli.StringFlag{
Name: "environment, env, E, e",
Usage: "load the environment into the variable name instead of as 'env'",
Value: settings.Environment,
EnvVar: "RENDERIZER_ENVIRONMENT",
},
cli.BoolFlag{
Name: "stdin, c",
Usage: "read from stdin",
Destination: &settings.Stdin,
},
cli.BoolFlag{
Name: "debugging, debug, D",
Usage: "enable debugging server",
Expand All @@ -127,7 +120,35 @@ func main() {
}

app.Before = func(ctx *cli.Context) error {

fi, _ := os.Stdin.Stat()

settings.Stdin = settings.Stdin || (fi.Mode()&os.ModeCharDevice) == 0

settings.Arguments = append(settings.Arguments, ctx.Args()...)
if len(settings.Arguments) == 0 && !settings.Stdin {
// Try default the template name
folderName, err := os.Getwd()
if err != nil {
log.Println(err)
folderName = "renderizer"
} else {
folderName = filepath.Base(folderName)
}

for _, ext := range []string{".tmpl", ""} {
for _, try := range []string{"yaml", "json", "html", "txt", "xml", ""} {
name := fmt.Sprintf("%s.%s%s", folderName, try, ext)
if _, err := os.Stat(name); err == nil {
if settings.Verbose {
log.Printf("using template: %+v", name)
}
settings.Arguments = []string{name}
}
}
}

}

switch settings.MissingKey {
case "zero", "error", "default", "invalid":
Expand All @@ -136,9 +157,15 @@ func main() {
settings.MissingKey = "error"
}

if len(settings.ConfigFiles) == 0 {
if len(configs) == 0 {
name := "renderizer"
if len(settings.Arguments) >= 1 {
name = strings.Split(strings.TrimLeft(filepath.Base(settings.Arguments[0]), "."), ".")[0]
}
settings.Defaulted = true
settings.ConfigFiles = []string{".renderizer.yaml"}
settings.ConfigFiles = []string{"." + name + ".yaml"}
} else {
settings.ConfigFiles = configs
}

for _, config := range settings.ConfigFiles {
Expand All @@ -149,22 +176,55 @@ func main() {
}
} else {
yaml.Unmarshal(in, &settings.Config)
if settings.Verbose && settings.Defaulted {
log.Printf("used config: %+v", settings.ConfigFiles)
if settings.Verbose || settings.Defaulted {
log.Printf("using settings: %+v", settings.ConfigFiles)
}
}
if settings.Debugging {
log.Printf("-settings:%#v", settings)
log.Printf("--settings:%#v", settings)
log.Printf("loaded: %#v", settings.Config)
} else if settings.Verbose {
log.Printf("-settings:%+v", settings)
log.Printf("--settings:%+v", settings)
log.Printf("loaded: %+v", settings.Config)
}
}

return nil
}

// Remove args that are not processed by urfave/cli
args := []string{os.Args[0]}
if len(os.Args) > 1 {
next := false
for _, arg := range os.Args[1:] {
larg := strings.ToLower(arg)
if next {
args = append(args, arg)
next = false
continue
}
if strings.HasPrefix(larg, "--") {
flag := larg
parts := strings.SplitN(larg, "=", 2)
if len(parts) == 2 {
flag = parts[0]
}
switch flag[2:] {
case "settings", "missing":
// If the flag requires a parameter but it is not specified with an =, grab the next argument too.
if !strings.Contains(larg, "=") {
next = true
}
fallthrough
case "debug", "verbose", "version", "stdin":
args = append(args, arg)
continue
}
}
settings.Arguments = append(settings.Arguments, arg)
}
}

app.Action = renderizer
app.Run(args)
}
Loading

0 comments on commit fbd513e

Please sign in to comment.