CLI changes for jeth integration:

cmd/ethereum/js
- remove actual bindings from cmd/ethereum/js (moved to xeth)
- execJsFile and runREPL take assetPath args and pass them on to JEthRE and JSRE
- xeth construction is moved to jethre, repl just passes ethereum object on
- repl struct has no need for xeth or eth fields
- repl now has dataDir field (for history)
cmd/ethereum/main
- set assetPath for js files to path.Join(os.Getenv("GOPATH"), "src", "github.com", "ethereum", "go-ethereum", "cmd", "mist", "assets", "ext")
 (FIXME please)
- pass assetPath to execJsFile and runREPL
This commit is contained in:
zelig 2015-03-09 15:35:56 +07:00
parent 5aed2d2d16
commit 6913cad460
2 changed files with 19 additions and 116 deletions

View file

@ -27,17 +27,12 @@ import (
"strings" "strings"
"github.com/ethereum/go-ethereum/cmd/utils" "github.com/ethereum/go-ethereum/cmd/utils"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/eth" "github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/jethre"
"github.com/ethereum/go-ethereum/javascript"
"github.com/ethereum/go-ethereum/state"
"github.com/ethereum/go-ethereum/xeth"
"github.com/obscuren/otto"
"github.com/peterh/liner" "github.com/peterh/liner"
) )
func execJsFile(ethereum *eth.Ethereum, filename string) { func execJsFile(ethereum *eth.Ethereum, assetPath, filename string) {
file, err := os.Open(filename) file, err := os.Open(filename)
if err != nil { if err != nil {
utils.Fatalf("%v", err) utils.Fatalf("%v", err)
@ -46,29 +41,25 @@ func execJsFile(ethereum *eth.Ethereum, filename string) {
if err != nil { if err != nil {
utils.Fatalf("%v", err) utils.Fatalf("%v", err)
} }
re := javascript.NewJSRE(xeth.New(ethereum)) re := javascript.NewJEthRE(ethereum, assetPath)
if _, err := re.Run(string(content)); err != nil { if _, err := re.Run(string(content)); err != nil {
utils.Fatalf("Javascript Error: %v", err) utils.Fatalf("Javascript Error: %v", err)
} }
} }
type repl struct { type repl struct {
re *javascript.JSRE re *javascript.JEthRE
ethereum *eth.Ethereum prompt string
xeth *xeth.XEth lr *liner.State
prompt string dataDir string
lr *liner.State
} }
func runREPL(ethereum *eth.Ethereum) { func runREPL(ethereum *eth.Ethereum, assetPath string) {
xeth := xeth.New(ethereum)
repl := &repl{ repl := &repl{
re: javascript.NewJSRE(xeth), re: javascript.NewJEthRE(ethereum, assetPath),
xeth: xeth, dataDir: ethereum.DataDir,
ethereum: ethereum, prompt: "> ",
prompt: "> ",
} }
repl.initStdFuncs()
if !liner.TerminalSupported() { if !liner.TerminalSupported() {
repl.dumbRead() repl.dumbRead()
} else { } else {
@ -82,7 +73,7 @@ func runREPL(ethereum *eth.Ethereum) {
} }
func (self *repl) withHistory(op func(*os.File)) { func (self *repl) withHistory(op func(*os.File)) {
hist, err := os.OpenFile(path.Join(self.ethereum.DataDir, "history"), os.O_RDWR|os.O_CREATE, os.ModePerm) hist, err := os.OpenFile(path.Join(self.dataDir, "history"), os.O_RDWR|os.O_CREATE, os.ModePerm)
if err != nil { if err != nil {
fmt.Printf("unable to open history file: %v\n", err) fmt.Printf("unable to open history file: %v\n", err)
return return
@ -181,100 +172,10 @@ func (self *repl) dumbRead() {
} }
func (self *repl) printValue(v interface{}) { func (self *repl) printValue(v interface{}) {
method, _ := self.re.Vm.Get("prettyPrint") val, err := self.re.PrettyPrint(v)
v, err := self.re.Vm.ToValue(v)
if err == nil { if err == nil {
val, err := method.Call(method, v) fmt.Printf("%v", val)
if err == nil {
fmt.Printf("%v", val)
}
}
}
func (self *repl) initStdFuncs() {
t, _ := self.re.Vm.Get("eth")
eth := t.Object()
eth.Set("connect", self.connect)
eth.Set("stopMining", self.stopMining)
eth.Set("startMining", self.startMining)
eth.Set("dump", self.dump)
eth.Set("export", self.export)
}
/*
* The following methods are natively implemented javascript functions.
*/
func (self *repl) dump(call otto.FunctionCall) otto.Value {
var block *types.Block
if len(call.ArgumentList) > 0 {
if call.Argument(0).IsNumber() {
num, _ := call.Argument(0).ToInteger()
block = self.ethereum.ChainManager().GetBlockByNumber(uint64(num))
} else if call.Argument(0).IsString() {
hash, _ := call.Argument(0).ToString()
block = self.ethereum.ChainManager().GetBlock(ethutil.Hex2Bytes(hash))
} else {
fmt.Println("invalid argument for dump. Either hex string or number")
}
if block == nil {
fmt.Println("block not found")
return otto.UndefinedValue()
}
} else { } else {
block = self.ethereum.ChainManager().CurrentBlock() fmt.Printf("print error: %v", err)
} }
statedb := state.New(block.Root(), self.ethereum.StateDb())
v, _ := self.re.Vm.ToValue(statedb.RawDump())
return v
}
func (self *repl) stopMining(call otto.FunctionCall) otto.Value {
self.xeth.Miner().Stop()
return otto.TrueValue()
}
func (self *repl) startMining(call otto.FunctionCall) otto.Value {
self.xeth.Miner().Start()
return otto.TrueValue()
}
func (self *repl) connect(call otto.FunctionCall) otto.Value {
nodeURL, err := call.Argument(0).ToString()
if err != nil {
return otto.FalseValue()
}
if err := self.ethereum.SuggestPeer(nodeURL); err != nil {
return otto.FalseValue()
}
return otto.TrueValue()
}
func (self *repl) export(call otto.FunctionCall) otto.Value {
if len(call.ArgumentList) == 0 {
fmt.Println("err: require file name")
return otto.FalseValue()
}
fn, err := call.Argument(0).ToString()
if err != nil {
fmt.Println(err)
return otto.FalseValue()
}
data := self.ethereum.ChainManager().Export()
if err := ethutil.WriteFile(fn, data); err != nil {
fmt.Println(err)
return otto.FalseValue()
}
return otto.TrueValue()
} }

View file

@ -23,6 +23,7 @@ package main
import ( import (
"fmt" "fmt"
"os" "os"
"path"
"runtime" "runtime"
"strconv" "strconv"
"time" "time"
@ -143,13 +144,14 @@ func run(ctx *cli.Context) {
func runjs(ctx *cli.Context) { func runjs(ctx *cli.Context) {
eth := utils.GetEthereum(ClientIdentifier, Version, ctx) eth := utils.GetEthereum(ClientIdentifier, Version, ctx)
assetPath := path.Join(os.Getenv("GOPATH"), "src", "github.com", "ethereum", "go-ethereum", "cmd", "mist", "assets", "ext")
startEth(ctx, eth) startEth(ctx, eth)
if len(ctx.Args()) == 0 { if len(ctx.Args()) == 0 {
runREPL(eth) runREPL(eth, assetPath)
eth.Stop() eth.Stop()
eth.WaitForShutdown() eth.WaitForShutdown()
} else if len(ctx.Args()) == 1 { } else if len(ctx.Args()) == 1 {
execJsFile(eth, ctx.Args()[0]) execJsFile(eth, assetPath, ctx.Args()[0])
} else { } else {
utils.Fatalf("This command can handle at most one argument.") utils.Fatalf("This command can handle at most one argument.")
} }