Javascript CLI in Go using Otto

Today, I was playing with Otto and hacked together a small command-line-interface program in Go.

package main

import (
	"bufio"
	"fmt"
	"os"
	"strings"

	"github.com/robertkrimen/otto"
)

var Otto = otto.New()

func main() {
	fmt.Println("otto\n")
	loop()
}

func dispatch(entry string) string {
	if len(entry) == 0 {
		return entry
	}
	value, err := Otto.Run(entry)
	if err != nil {
		return err.Error()
	} else {
		return fmt.Sprintf("%v", value)
	}
}

func loop() {
	for {
		fmt.Print("> ")
		in := bufio.NewReader(os.Stdin)
		entered, err := in.ReadString('\n')
		if err != nil {
			fmt.Println(err)
			break
		}
		entry := strings.TrimLeft(entered[:len(entered)-1], "\t ") // without tabs,spaces and newline
		output := dispatch(entry)
		if len(output) > 0 {
			fmt.Println(output)
		}
	}
}

One cool feature of Otto is the ability to expose your own Go functions in the Javascript namespace. This example below adds the function log to print its arguments using the standard log package.

Otto.Set("log", func(call otto.FunctionCall) otto.Value {
	log.Printf("%v\n",call.ArgumentList())
	return toValue("")
})

With this setup, I can call this function on the command line like this

> log("hi")
> hi