mirror of
https://github.com/danog/liquid.git
synced 2024-11-26 19:24:45 +01:00
Add --env for binding environment in the CLI tool
This commit is contained in:
parent
c68221dd7e
commit
ae6b280abe
@ -9,10 +9,10 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
@ -21,59 +21,79 @@ import (
|
||||
|
||||
// for testing
|
||||
var (
|
||||
stderr = os.Stderr
|
||||
stdout io.Writer = os.Stdout
|
||||
stdin io.Reader = os.Stdin
|
||||
exit = os.Exit
|
||||
stderr io.Writer = os.Stderr
|
||||
stdout io.Writer = os.Stdout
|
||||
stdin io.Reader = os.Stdin
|
||||
exit func(int) = os.Exit
|
||||
env func() []string = os.Environ
|
||||
bindings map[string]interface{} = map[string]interface{}{}
|
||||
)
|
||||
|
||||
func main() {
|
||||
if err := run(os.Args[1:]); err != nil {
|
||||
fmt.Fprintln(stderr, err) // nolint: gas
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
var err error
|
||||
|
||||
func run(args []string) error {
|
||||
switch {
|
||||
case len(args) == 0:
|
||||
buf := new(bytes.Buffer)
|
||||
if _, err := io.Copy(buf, stdin); err != nil {
|
||||
return err
|
||||
cmdLine := flag.NewFlagSet(os.Args[0], flag.ContinueOnError)
|
||||
cmdLine.Usage = func() {
|
||||
fmt.Fprintf(stderr, "usage: %s [OPTIONS] [FILE]\n", cmdLine.Name())
|
||||
fmt.Fprint(stderr, "\nOPTIONS\n")
|
||||
cmdLine.PrintDefaults()
|
||||
}
|
||||
|
||||
var bindEnvs bool
|
||||
cmdLine.BoolVar(&bindEnvs, "env", false, "bind environment variables")
|
||||
|
||||
err = cmdLine.Parse(os.Args[1:])
|
||||
if err != nil {
|
||||
if err == flag.ErrHelp {
|
||||
exit(0)
|
||||
return
|
||||
}
|
||||
return render(buf.Bytes(), "")
|
||||
case args[0] == "-h" || args[0] == "--help":
|
||||
usage()
|
||||
case strings.HasPrefix(args[0], "-"):
|
||||
// undefined flag
|
||||
usage()
|
||||
fmt.Fprintln(stderr, err)
|
||||
exit(1)
|
||||
case len(args) == 1:
|
||||
s, err := ioutil.ReadFile(args[0])
|
||||
if err != nil {
|
||||
return err
|
||||
return
|
||||
}
|
||||
|
||||
if bindEnvs {
|
||||
for _, e := range env() {
|
||||
pair := strings.SplitN(e, "=", 2)
|
||||
bindings[pair[0]] = pair[1]
|
||||
}
|
||||
return render(s, args[0])
|
||||
}
|
||||
|
||||
args := cmdLine.Args()
|
||||
switch len(args) {
|
||||
case 0:
|
||||
// use stdin
|
||||
case 1:
|
||||
stdin, err = os.Open(args[0])
|
||||
default:
|
||||
usage()
|
||||
err = errors.New("too many arguments")
|
||||
}
|
||||
|
||||
if err == nil {
|
||||
err = render()
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
fmt.Fprintln(stderr, err)
|
||||
exit(1)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func render(b []byte, filename string) (err error) {
|
||||
tpl, err := liquid.NewEngine().ParseTemplate(b)
|
||||
func render() error {
|
||||
buf, err := io.ReadAll(stdin)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
out, err := tpl.Render(map[string]interface{}{})
|
||||
|
||||
tpl, err := liquid.NewEngine().ParseTemplate(buf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
out, err := tpl.Render(bindings)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = stdout.Write(out)
|
||||
return err
|
||||
}
|
||||
|
||||
func usage() {
|
||||
fmt.Fprintf(stdout, "usage: %s [FILE]\n", os.Args[0]) // nolint: gas
|
||||
}
|
||||
|
@ -2,47 +2,112 @@ package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestMain(t *testing.T) {
|
||||
exit = func(n int) { t.Fatalf("exit called") }
|
||||
oldArgs := os.Args
|
||||
|
||||
defer func() {
|
||||
os.Args = oldArgs
|
||||
stderr = os.Stderr
|
||||
stdout = os.Stdout
|
||||
stdin = os.Stdin
|
||||
exit = os.Exit
|
||||
env = os.Environ
|
||||
bindings = map[string]interface{}{}
|
||||
}()
|
||||
|
||||
exit = func(n int) {
|
||||
t.Fatalf("exit called")
|
||||
}
|
||||
|
||||
os.Args = []string{"liquid"}
|
||||
|
||||
// stdin
|
||||
src := `{{ "Hello World" | downcase | split: " " | first | append: "!"}}`
|
||||
buf := new(bytes.Buffer)
|
||||
buf := &bytes.Buffer{}
|
||||
stdin = bytes.NewBufferString(src)
|
||||
stdout = buf
|
||||
require.NoError(t, run([]string{}))
|
||||
main()
|
||||
require.Equal(t, "hello!", buf.String())
|
||||
|
||||
// filename
|
||||
buf = new(bytes.Buffer)
|
||||
stdin = bytes.NewBufferString("")
|
||||
// environment binding
|
||||
var envCalled bool
|
||||
env = func() []string {
|
||||
envCalled = true
|
||||
return []string{"TARGET=World"}
|
||||
}
|
||||
src = `Hello, {{ TARGET }}!`
|
||||
// without -e
|
||||
stdin = bytes.NewBufferString(src)
|
||||
buf = &bytes.Buffer{}
|
||||
stdout = buf
|
||||
require.NoError(t, run([]string{"testdata/source.txt"}))
|
||||
os.Args = []string{"liquid"}
|
||||
main()
|
||||
require.False(t, envCalled)
|
||||
require.Equal(t, "Hello, !", buf.String())
|
||||
// with -e
|
||||
stdin = bytes.NewBufferString(src)
|
||||
buf = &bytes.Buffer{}
|
||||
stdout = buf
|
||||
os.Args = []string{"liquid", "--env"}
|
||||
main()
|
||||
require.True(t, envCalled)
|
||||
require.Equal(t, "Hello, World!", buf.String())
|
||||
|
||||
// filename
|
||||
stdin = os.Stdin
|
||||
buf = &bytes.Buffer{}
|
||||
stdout = buf
|
||||
os.Args = []string{"liquid", "testdata/source.txt"}
|
||||
main()
|
||||
require.Contains(t, buf.String(), "file system")
|
||||
|
||||
// missing file
|
||||
require.Error(t, run([]string{"testdata/missing_file"}))
|
||||
// following tests test the exit code
|
||||
var exitCalled bool
|
||||
exitCode := 0
|
||||
exit = func(n int) { exitCalled = true; exitCode = n }
|
||||
|
||||
os.Args = []string{"liquid", "testdata/source.txt"}
|
||||
main()
|
||||
require.Equal(t, 0, exitCode)
|
||||
|
||||
exitCode = 0
|
||||
// missing file
|
||||
buf = &bytes.Buffer{}
|
||||
stderr = buf
|
||||
os.Args = []string{"liquid", "testdata/missing_file"}
|
||||
main()
|
||||
require.Equal(t, 1, exitCode)
|
||||
require.Contains(t, buf.String(), "no such")
|
||||
|
||||
exitCalled = false
|
||||
// --help
|
||||
buf = new(bytes.Buffer)
|
||||
stdout = buf
|
||||
require.NoError(t, run([]string{"--help"}))
|
||||
buf = &bytes.Buffer{}
|
||||
stderr = buf
|
||||
os.Args = []string{"liquid", "--help"}
|
||||
main()
|
||||
require.Contains(t, buf.String(), "usage:")
|
||||
require.True(t, exitCalled)
|
||||
require.Equal(t, 0, exitCode)
|
||||
|
||||
// --undefined-flag
|
||||
exitCode := 0
|
||||
exit = func(n int) { exitCode = n }
|
||||
require.NoError(t, run([]string{"--undefined-flag"}))
|
||||
buf = &bytes.Buffer{}
|
||||
stderr = buf
|
||||
os.Args = []string{"liquid", "--undefined-flag"}
|
||||
main()
|
||||
require.Equal(t, 1, exitCode)
|
||||
require.Contains(t, buf.String(), "defined")
|
||||
|
||||
// multiple args
|
||||
exitCode = 0
|
||||
exit = func(n int) { exitCode = n }
|
||||
require.NoError(t, run([]string{"file1", "file2"}))
|
||||
os.Args = []string{"liquid", "testdata/source.txt", "file2"}
|
||||
buf = &bytes.Buffer{}
|
||||
stderr = buf
|
||||
main()
|
||||
require.Contains(t, buf.String(), "too many")
|
||||
require.Equal(t, 1, exitCode)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user