mirror of
https://github.com/danog/liquid.git
synced 2024-11-30 05:58:59 +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
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"errors"
|
||||||
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@ -21,59 +21,79 @@ import (
|
|||||||
|
|
||||||
// for testing
|
// for testing
|
||||||
var (
|
var (
|
||||||
stderr = os.Stderr
|
stderr io.Writer = os.Stderr
|
||||||
stdout io.Writer = os.Stdout
|
stdout io.Writer = os.Stdout
|
||||||
stdin io.Reader = os.Stdin
|
stdin io.Reader = os.Stdin
|
||||||
exit = os.Exit
|
exit func(int) = os.Exit
|
||||||
|
env func() []string = os.Environ
|
||||||
|
bindings map[string]interface{} = map[string]interface{}{}
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
if err := run(os.Args[1:]); err != nil {
|
var err error
|
||||||
fmt.Fprintln(stderr, err) // nolint: gas
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func run(args []string) error {
|
cmdLine := flag.NewFlagSet(os.Args[0], flag.ContinueOnError)
|
||||||
switch {
|
cmdLine.Usage = func() {
|
||||||
case len(args) == 0:
|
fmt.Fprintf(stderr, "usage: %s [OPTIONS] [FILE]\n", cmdLine.Name())
|
||||||
buf := new(bytes.Buffer)
|
fmt.Fprint(stderr, "\nOPTIONS\n")
|
||||||
if _, err := io.Copy(buf, stdin); err != nil {
|
cmdLine.PrintDefaults()
|
||||||
return err
|
}
|
||||||
|
|
||||||
|
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(), "")
|
fmt.Fprintln(stderr, err)
|
||||||
case args[0] == "-h" || args[0] == "--help":
|
|
||||||
usage()
|
|
||||||
case strings.HasPrefix(args[0], "-"):
|
|
||||||
// undefined flag
|
|
||||||
usage()
|
|
||||||
exit(1)
|
exit(1)
|
||||||
case len(args) == 1:
|
return
|
||||||
s, err := ioutil.ReadFile(args[0])
|
}
|
||||||
if err != nil {
|
|
||||||
return err
|
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:
|
default:
|
||||||
usage()
|
err = errors.New("too many arguments")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
err = render()
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintln(stderr, err)
|
||||||
exit(1)
|
exit(1)
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func render(b []byte, filename string) (err error) {
|
func render() error {
|
||||||
tpl, err := liquid.NewEngine().ParseTemplate(b)
|
buf, err := io.ReadAll(stdin)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
_, err = stdout.Write(out)
|
_, err = stdout.Write(out)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func usage() {
|
|
||||||
fmt.Fprintf(stdout, "usage: %s [FILE]\n", os.Args[0]) // nolint: gas
|
|
||||||
}
|
|
||||||
|
@ -2,47 +2,112 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(t *testing.T) {
|
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
|
// stdin
|
||||||
src := `{{ "Hello World" | downcase | split: " " | first | append: "!"}}`
|
src := `{{ "Hello World" | downcase | split: " " | first | append: "!"}}`
|
||||||
buf := new(bytes.Buffer)
|
buf := &bytes.Buffer{}
|
||||||
stdin = bytes.NewBufferString(src)
|
stdin = bytes.NewBufferString(src)
|
||||||
stdout = buf
|
stdout = buf
|
||||||
require.NoError(t, run([]string{}))
|
main()
|
||||||
require.Equal(t, "hello!", buf.String())
|
require.Equal(t, "hello!", buf.String())
|
||||||
|
|
||||||
// filename
|
// environment binding
|
||||||
buf = new(bytes.Buffer)
|
var envCalled bool
|
||||||
stdin = bytes.NewBufferString("")
|
env = func() []string {
|
||||||
|
envCalled = true
|
||||||
|
return []string{"TARGET=World"}
|
||||||
|
}
|
||||||
|
src = `Hello, {{ TARGET }}!`
|
||||||
|
// without -e
|
||||||
|
stdin = bytes.NewBufferString(src)
|
||||||
|
buf = &bytes.Buffer{}
|
||||||
stdout = buf
|
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")
|
require.Contains(t, buf.String(), "file system")
|
||||||
|
|
||||||
// missing file
|
// following tests test the exit code
|
||||||
require.Error(t, run([]string{"testdata/missing_file"}))
|
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
|
// --help
|
||||||
buf = new(bytes.Buffer)
|
buf = &bytes.Buffer{}
|
||||||
stdout = buf
|
stderr = buf
|
||||||
require.NoError(t, run([]string{"--help"}))
|
os.Args = []string{"liquid", "--help"}
|
||||||
|
main()
|
||||||
require.Contains(t, buf.String(), "usage:")
|
require.Contains(t, buf.String(), "usage:")
|
||||||
|
require.True(t, exitCalled)
|
||||||
|
require.Equal(t, 0, exitCode)
|
||||||
|
|
||||||
// --undefined-flag
|
// --undefined-flag
|
||||||
exitCode := 0
|
buf = &bytes.Buffer{}
|
||||||
exit = func(n int) { exitCode = n }
|
stderr = buf
|
||||||
require.NoError(t, run([]string{"--undefined-flag"}))
|
os.Args = []string{"liquid", "--undefined-flag"}
|
||||||
|
main()
|
||||||
require.Equal(t, 1, exitCode)
|
require.Equal(t, 1, exitCode)
|
||||||
|
require.Contains(t, buf.String(), "defined")
|
||||||
|
|
||||||
// multiple args
|
// multiple args
|
||||||
exitCode = 0
|
os.Args = []string{"liquid", "testdata/source.txt", "file2"}
|
||||||
exit = func(n int) { exitCode = n }
|
buf = &bytes.Buffer{}
|
||||||
require.NoError(t, run([]string{"file1", "file2"}))
|
stderr = buf
|
||||||
|
main()
|
||||||
|
require.Contains(t, buf.String(), "too many")
|
||||||
require.Equal(t, 1, exitCode)
|
require.Equal(t, 1, exitCode)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user