Mercurial > yakumo_izuru > aya
changeset 4:05fc24caac37 draft
render uses strings, not bytes; added helpers for env and run
author | zaitsev.serge |
---|---|
date | Fri, 05 Dec 2014 18:09:03 +0000 |
parents | 53dea9841cd9 |
children | e0ee0721d34f |
files | zs.go zs_test.go |
diffstat | 2 files changed, 99 insertions(+), 33 deletions(-) [+] |
line wrap: on
line diff
--- a/zs.go Fri Dec 05 17:26:59 2014 +0000 +++ b/zs.go Fri Dec 05 18:09:03 2014 +0000 @@ -46,32 +46,30 @@ } func render(s string, vars map[string]string, eval EvalFn) (string, error) { - b := []byte(s) - delim_open := []byte("{{") - delim_close := []byte("}}") + delim_open := "{{" + delim_close := "}}" out := bytes.NewBuffer(nil) for { - if from := bytes.Index(b, delim_open); from == -1 { - out.Write(b) + if from := strings.Index(s, delim_open); from == -1 { + out.WriteString(s) return out.String(), nil } else { - to := bytes.Index(b, delim_close) - if to == -1 { + if to := strings.Index(s, delim_close); to == -1 { return "", fmt.Errorf("Close delim not found") } else { - out.Write(b[:from]) - cmd := b[from+len(delim_open) : to] - b = b[to+len(delim_close):] - m := strings.Fields(string(cmd)) + out.WriteString(s[:from]) + cmd := s[from+len(delim_open) : to] + s = s[to+len(delim_close):] + m := strings.Fields(cmd) if len(m) == 1 { if v, ok := vars[m[0]]; ok { - out.Write([]byte(v)) + out.WriteString(v) continue } } if res, err := eval(m, vars); err == nil { - out.Write([]byte(res)) + out.WriteString(res) } else { log.Println(err) // silent } @@ -80,29 +78,45 @@ } } -func eval(cmd []string, vars map[string]string) (string, error) { - var outbuf, errbuf bytes.Buffer - c := exec.Command(path.Join(ZSDIR, cmd[0]), cmd[1:]...) +func env(vars map[string]string) []string { env := []string{"ZS=" + os.Args[0]} + env = append(env, os.Environ()...) for k, v := range vars { env = append(env, "ZS_"+strings.ToUpper(k)+"="+v) } - c.Env = append(c.Env, env...) - c.Stdout = &outbuf + return env +} + +func run(cmd string, args []string, vars map[string]string, output io.Writer) error { + var errbuf bytes.Buffer + c := exec.Command(cmd, args...) + c.Env = env(vars) + c.Stdout = output c.Stderr = &errbuf - if err := c.Run(); err != nil { + + err := c.Run() + + if errbuf.Len() > 0 { + log.Println(errbuf.String()) + } + + if err != nil { + return err + } + return nil +} + +func eval(cmd []string, vars map[string]string) (string, error) { + outbuf := bytes.NewBuffer(nil) + err := run(path.Join(ZSDIR, cmd[0]), cmd[1:], vars, outbuf) + if err != nil { log.Println(err) - c := exec.Command(path.Join(cmd[0]), cmd[1:]...) - c.Env = append(c.Env, env...) - c.Stdout = &outbuf - c.Stderr = &errbuf - if err := c.Run(); err != nil { + outbuf = bytes.NewBuffer(nil) + err := run(cmd[0], cmd[1:], vars, outbuf) + if err != nil { return "", err } } - if errbuf.Len() > 0 { - log.Println(errbuf.String()) - } return outbuf.String(), nil } @@ -247,11 +261,8 @@ log.Println(err) } default: - cmd := exec.Command(path.Join(ZSDIR, cmd), args...) - cmd.Env = append(cmd.Env, "ZS="+os.Args[0]) - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - if err := cmd.Run(); err != nil { + err := run(path.Join(ZSDIR, cmd), args, map[string]string{}, os.Stdout) + if err != nil { log.Println(err) } }
--- a/zs_test.go Fri Dec 05 17:26:59 2014 +0000 +++ b/zs_test.go Fri Dec 05 18:09:03 2014 +0000 @@ -1,6 +1,13 @@ package main -import "testing" +import ( + "bytes" + "fmt" + "log" + "os" + "strings" + "testing" +) func TestSplit2(t *testing.T) { if a, b := split2("a:b", ":"); a != "a" || b != "b" { @@ -75,4 +82,52 @@ if s, err := render("{{greet}} x{{foo}}z", vars, eval); err != nil || s != "hello xbarz" { t.Error() } + // Test error case + if s, err := render("a {{greet text ", vars, eval); err == nil || len(s) != 0 { + t.Error() + } } + +func TestEnv(t *testing.T) { + e := env(map[string]string{"foo": "bar", "baz": "hello world"}) + mustHave := []string{"ZS=" + os.Args[0], "ZS_FOO=bar", "ZS_BAZ=hello world", "PATH="} + for _, s := range mustHave { + found := false + for _, v := range e { + if strings.HasPrefix(v, s) { + found = true + break + } + } + if !found { + t.Error("Missing", s) + } + } +} + +func TestRun(t *testing.T) { + out := bytes.NewBuffer(nil) + err := run("some_unbelievable_command_name", []string{}, map[string]string{}, out) + if err == nil { + t.Error() + } + + out = bytes.NewBuffer(nil) + err = run(os.Args[0], []string{"-test.run=TestHelperProcess"}, + map[string]string{"helper": "1", "out": "foo", "err": "bar"}, out) + if err != nil { + t.Error(err) + } + if out.String() != "foo\n" { + t.Error(out.String()) + } +} + +func TestHelperProcess(*testing.T) { + if os.Getenv("ZS_HELPER") != "1" { + return + } + defer os.Exit(0) // TODO check exit code + log.Println(os.Getenv("ZS_ERR")) // stderr + fmt.Println(os.Getenv("ZS_OUT")) // stdout +}