Changeset 5 in code


Ignore:
Timestamp:
Dec 5, 2014, 6:09:03 PM (11 years ago)
Author:
zaitsev.serge
Message:

render uses strings, not bytes; added helpers for env and run

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/zs.go

    r4 r5  
    4747
    4848func render(s string, vars map[string]string, eval EvalFn) (string, error) {
    49         b := []byte(s)
    50         delim_open := []byte("{{")
    51         delim_close := []byte("}}")
     49        delim_open := "{{"
     50        delim_close := "}}"
    5251
    5352        out := bytes.NewBuffer(nil)
    5453        for {
    55                 if from := bytes.Index(b, delim_open); from == -1 {
    56                         out.Write(b)
     54                if from := strings.Index(s, delim_open); from == -1 {
     55                        out.WriteString(s)
    5756                        return out.String(), nil
    5857                } else {
    59                         to := bytes.Index(b, delim_close)
    60                         if to == -1 {
     58                        if to := strings.Index(s, delim_close); to == -1 {
    6159                                return "", fmt.Errorf("Close delim not found")
    6260                        } else {
    63                                 out.Write(b[:from])
    64                                 cmd := b[from+len(delim_open) : to]
    65                                 b = b[to+len(delim_close):]
    66                                 m := strings.Fields(string(cmd))
     61                                out.WriteString(s[:from])
     62                                cmd := s[from+len(delim_open) : to]
     63                                s = s[to+len(delim_close):]
     64                                m := strings.Fields(cmd)
    6765                                if len(m) == 1 {
    6866                                        if v, ok := vars[m[0]]; ok {
    69                                                 out.Write([]byte(v))
     67                                                out.WriteString(v)
    7068                                                continue
    7169                                        }
    7270                                }
    7371                                if res, err := eval(m, vars); err == nil {
    74                                         out.Write([]byte(res))
     72                                        out.WriteString(res)
    7573                                } else {
    7674                                        log.Println(err) // silent
     
    8179}
    8280
    83 func eval(cmd []string, vars map[string]string) (string, error) {
    84         var outbuf, errbuf bytes.Buffer
    85         c := exec.Command(path.Join(ZSDIR, cmd[0]), cmd[1:]...)
     81func env(vars map[string]string) []string {
    8682        env := []string{"ZS=" + os.Args[0]}
     83        env = append(env, os.Environ()...)
    8784        for k, v := range vars {
    8885                env = append(env, "ZS_"+strings.ToUpper(k)+"="+v)
    8986        }
    90         c.Env = append(c.Env, env...)
    91         c.Stdout = &outbuf
     87        return env
     88}
     89
     90func run(cmd string, args []string, vars map[string]string, output io.Writer) error {
     91        var errbuf bytes.Buffer
     92        c := exec.Command(cmd, args...)
     93        c.Env = env(vars)
     94        c.Stdout = output
    9295        c.Stderr = &errbuf
    93         if err := c.Run(); err != nil {
    94                 log.Println(err)
    95                 c := exec.Command(path.Join(cmd[0]), cmd[1:]...)
    96                 c.Env = append(c.Env, env...)
    97                 c.Stdout = &outbuf
    98                 c.Stderr = &errbuf
    99                 if err := c.Run(); err != nil {
    100                         return "", err
    101                 }
    102         }
     96
     97        err := c.Run()
     98
    10399        if errbuf.Len() > 0 {
    104100                log.Println(errbuf.String())
     101        }
     102
     103        if err != nil {
     104                return err
     105        }
     106        return nil
     107}
     108
     109func eval(cmd []string, vars map[string]string) (string, error) {
     110        outbuf := bytes.NewBuffer(nil)
     111        err := run(path.Join(ZSDIR, cmd[0]), cmd[1:], vars, outbuf)
     112        if err != nil {
     113                log.Println(err)
     114                outbuf = bytes.NewBuffer(nil)
     115                err := run(cmd[0], cmd[1:], vars, outbuf)
     116                if err != nil {
     117                        return "", err
     118                }
    105119        }
    106120        return outbuf.String(), nil
     
    248262                }
    249263        default:
    250                 cmd := exec.Command(path.Join(ZSDIR, cmd), args...)
    251                 cmd.Env = append(cmd.Env, "ZS="+os.Args[0])
    252                 cmd.Stdout = os.Stdout
    253                 cmd.Stderr = os.Stderr
    254                 if err := cmd.Run(); err != nil {
     264                err := run(path.Join(ZSDIR, cmd), args, map[string]string{}, os.Stdout)
     265                if err != nil {
    255266                        log.Println(err)
    256267                }
  • trunk/zs_test.go

    r3 r5  
    11package main
    22
    3 import "testing"
     3import (
     4        "bytes"
     5        "fmt"
     6        "log"
     7        "os"
     8        "strings"
     9        "testing"
     10)
    411
    512func TestSplit2(t *testing.T) {
     
    7683                t.Error()
    7784        }
     85        // Test error case
     86        if s, err := render("a {{greet text ", vars, eval); err == nil || len(s) != 0 {
     87                t.Error()
     88        }
    7889}
     90
     91func TestEnv(t *testing.T) {
     92        e := env(map[string]string{"foo": "bar", "baz": "hello world"})
     93        mustHave := []string{"ZS=" + os.Args[0], "ZS_FOO=bar", "ZS_BAZ=hello world", "PATH="}
     94        for _, s := range mustHave {
     95                found := false
     96                for _, v := range e {
     97                        if strings.HasPrefix(v, s) {
     98                                found = true
     99                                break
     100                        }
     101                }
     102                if !found {
     103                        t.Error("Missing", s)
     104                }
     105        }
     106}
     107
     108func TestRun(t *testing.T) {
     109        out := bytes.NewBuffer(nil)
     110        err := run("some_unbelievable_command_name", []string{}, map[string]string{}, out)
     111        if err == nil {
     112                t.Error()
     113        }
     114
     115        out = bytes.NewBuffer(nil)
     116        err = run(os.Args[0], []string{"-test.run=TestHelperProcess"},
     117                map[string]string{"helper": "1", "out": "foo", "err": "bar"}, out)
     118        if err != nil {
     119                t.Error(err)
     120        }
     121        if out.String() != "foo\n" {
     122                t.Error(out.String())
     123        }
     124}
     125
     126func TestHelperProcess(*testing.T) {
     127        if os.Getenv("ZS_HELPER") != "1" {
     128                return
     129        }
     130        defer os.Exit(0)                 // TODO check exit code
     131        log.Println(os.Getenv("ZS_ERR")) // stderr
     132        fmt.Println(os.Getenv("ZS_OUT")) // stdout
     133}
Note: See TracChangeset for help on using the changeset viewer.