Skip to content

Commit

Permalink
feat: support forcing environment type
Browse files Browse the repository at this point in the history
  • Loading branch information
ivanvc committed Jul 18, 2023
1 parent b7ef71b commit 9b64bbb
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 15 deletions.
10 changes: 9 additions & 1 deletion internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ type Config struct {
Env string
UseStdin bool
SetDebugLogLevel bool
ForceYAMLEnv bool
ForceTOMLEnv bool
ForceJSONEnv bool
}

func init() {
Expand All @@ -30,7 +33,9 @@ If you specify that the template comes from the stdin by setting the option flag
If you set it as the first argument, it assumes that it is a file.
For the environment (-env) it will expect it as inline data. However, if you
start it with @, it will assume it is a file.
start it with @, it will assume it is a file. It tries to guess the format,
giving precedence to JSON, then TOML, and lastly to YAML. Unless you specify to
force parsing it via an option flag.
The output is sent to stdout.
Expand All @@ -49,6 +54,9 @@ func Load() *Config {
flag.StringVar(&c.Env, "env", "", "The environment for the template (YAML, JSON or TOML).")
flag.BoolVar(&c.UseStdin, "stdin", false, "Read template from stdin.")
flag.BoolVar(&c.SetDebugLogLevel, "debug", false, "Set log level to debug.")
flag.BoolVar(&c.ForceYAMLEnv, "yaml", false, "Force the environment to be parsed as a YAML.")
flag.BoolVar(&c.ForceTOMLEnv, "toml", false, "Force the environment to be parsed as a TOML.")
flag.BoolVar(&c.ForceJSONEnv, "json", false, "Force the environment to be parsed as a JSON.")
flag.Parse()

c.InputFile = flag.Arg(0)
Expand Down
51 changes: 44 additions & 7 deletions internal/template/environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import (

type environment any

func loadEnvironment(cfg *config.Config) environment {
func loadEnvironment(input []byte, forceJSON, forceTOML, forceYAML bool) environment {
log.Default().SetLevel(log.DebugLevel)
var env environment

if len(input) > 0 && input[0] == '@' {
Expand All @@ -28,22 +29,58 @@ func loadEnvironment(cfg *config.Config) environment {
}

log.Debug("Loading environment", "input", string(input))
if forceJSON {
loadJSONEnvironment(input, &env)
return env
}
if forceTOML {
loadTOMLEnvironment(input, &env)
return env
}
if forceYAML {
loadYAMLEnvironment(input, &env)
return env
}

if err := loadJSONEnvironment(input, &env); err == nil {
return env
}
if err := loadTOMLEnvironment(input, &env); err == nil {
return env
}
if err := loadYAMLEnvironment(input, &env); err == nil {
return env
}

return env
}

func loadJSONEnvironment(input []byte, env *environment) error {
if err := json.Unmarshal(input, &env); err == nil {
log.Debug("Loaded JSON environment", "env", env)
return env
return nil
} else {
log.Debug("Error parsing JSON", "error", err)
return err
}
}

func loadTOMLEnvironment(input []byte, env *environment) error {
if err := toml.Unmarshal(input, &env); err == nil {
log.Debug("Loaded TOML environment", "env", env)
return env
return nil
} else {
log.Debug("Error parsing TOML", "error", err)
return err
}
if err := yaml.Unmarshal(input, &env); err != nil {
}

func loadYAMLEnvironment(input []byte, env *environment) error {
if err := yaml.Unmarshal(input, &env); err == nil {
log.Debug("Loaded YAML environment", "env", env)
return nil
} else {
log.Debug("Error parsing YAML", "error", err)
return err
}

log.Debug("Loaded YAML environment", "env", env)
return env
}
46 changes: 40 additions & 6 deletions internal/template/environment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,71 @@ import (
)

func TestLoadingInvalidEnvironment(t *testing.T) {
env := loadEnvironment([]byte("yaml: yaml: yaml"))
env := loadEnvironment([]byte("yaml: yaml: yaml"), false, false, false)
if env != nil {
t.Errorf("Expecting type to be nil, got %v", env)
}
}

func TestLoadingAYAMLEnvironment(t *testing.T) {
env := loadEnvironment([]byte("test: true"))
env := loadEnvironment([]byte("test: true"), false, false, false)
if !env.(map[any]any)["test"].(bool) {
t.Errorf("Expecting parsed YAML to be true, got %v", env.(map[any]any)["test"])
}
env = loadEnvironment([]byte("- a"))
env = loadEnvironment([]byte("- a"), false, false, false)
if env.([]any)[0].(string) != "a" {
t.Errorf("Expecting parsed YAML to be %q, got %q", "a", env.([]any)[0])
}
}

func TestLoadingJSONEnvironment(t *testing.T) {
env := loadEnvironment([]byte(`{"test":true}`))
env := loadEnvironment([]byte(`{"test":true}`), false, false, false)
if !env.(map[string]any)["test"].(bool) {
t.Errorf("Expecting parsed JSON to be true, got %v", env.(map[string]any)["test"])
}
env = loadEnvironment([]byte(`["a"]`))
env = loadEnvironment([]byte(`["a"]`), false, false, false)
if env.([]any)[0].(string) != "a" {
t.Errorf("Expecting parsed JSON to be %q, got %q", "a", env.([]any)[0])
}
}

func TestLoadingTOMLEnvironment(t *testing.T) {
env := loadEnvironment([]byte(`test=true`))
env := loadEnvironment([]byte(`test=true`), false, false, false)
if !env.(map[string]any)["test"].(bool) {
t.Errorf("Expecting parsed TOML to be true, got %v", env.(map[string]any)["test"])
}
}

func TestForceLoadingInvalidEnvironments(t *testing.T) {
tt := [][]any{
[]any{"", true, false, false},
[]any{":", true, false, false},
[]any{"{'json':true}", true, false, false},
[]any{":", false, true, false},
[]any{"foo", false, true, false},
[]any{":", false, false, true},
}
for _, c := range tt {
if e := loadEnvironment([]byte(c[0].(string)), c[1].(bool), c[2].(bool), c[3].(bool)); e != nil {
t.Errorf("Expecting loaded environment to be nil, got %v", e)
}
}
}

func TestForceLoadingJSONEnvironment(t *testing.T) {
if e := loadEnvironment([]byte("[1,2,3]"), true, false, false); e == nil {
t.Errorf("Expecting loaded environment to not be nil, got %v", e)
}
}

func TestForceLoadingYAMLEnvironment(t *testing.T) {
if e := loadEnvironment([]byte(`{"not":"json"}`), false, false, true); e == nil {
t.Errorf("Expecting loaded environment to not be nil, got %v", e)
}
}

func TestForceLoadingTOMLEnvironment(t *testing.T) {
if e := loadEnvironment([]byte("[1]"), false, true, false); e == nil {
t.Errorf("Expecting loaded environment to not be nil, got %v", e)
}
}
2 changes: 1 addition & 1 deletion internal/template/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func Execute(cfg *config.Config) {
}
log.Debug("Loaded input template", "tpl", input)

env := loadEnvironment([]byte(cfg.Env))
env := loadEnvironment([]byte(cfg.Env), cfg.ForceJSONEnv, cfg.ForceTOMLEnv, cfg.ForceYAMLEnv)

t := template.New("__tpl_input")
tpl := template.Must(
Expand Down

0 comments on commit 9b64bbb

Please sign in to comment.