refactor cli and gui wrapper code. Details:

- all cli functions shared between ethereum and ethereal abstracted to utils/ cmd.go (should be ethcommon or shared or sth)
- simplify main() now readable stepwise
- rename main wrapper files to main.go
- rename commmand line args definition file from config.go to flags.go
- rename Do -> Start to parallel option names
- register interrupt for rpc server stop
- fix interrupt stopping js repl and ethereum
- register interrupt for mining stop
- custom config file option from command line
- debug option from command line
- loglevel option from command line
- changed ethutil.Config API
- default datadir and default config file set together with other flag defaults in wrappers
- default assetpath set together with other command line flags defaults in gui wrapper (not in ethutil.Config or ui/ui_lib)
- options precedence: default < config file < environment variables < command line
This commit is contained in:
zelig
2014-06-23 12:20:59 +01:00
parent 456167aca0
commit 1024766514
10 changed files with 438 additions and 474 deletions

33
ethereum/cmd.go Normal file
View File

@@ -0,0 +1,33 @@
package main
import (
"github.com/ethereum/eth-go"
"github.com/ethereum/go-ethereum/utils"
"os"
"io/ioutil"
)
func InitJsConsole(ethereum *eth.Ethereum) {
repl := NewJSRepl(ethereum)
go repl.Start()
utils.RegisterInterrupt(func(os.Signal) {
repl.Stop()
ethereum.Stop()
})
}
func ExecJsFile (ethereum *eth.Ethereum, InputFile string) {
file, err := os.Open(InputFile)
if err != nil {
logger.Fatalln(err)
}
content, err := ioutil.ReadAll(file)
if err != nil {
logger.Fatalln(err)
}
re := NewJSRE(ethereum)
utils.RegisterInterrupt(func(os.Signal) {
re.Stop()
})
re.Run(string(content))
}

View File

@@ -1,193 +0,0 @@
package main
import (
"fmt"
"github.com/ethereum/eth-go"
"github.com/ethereum/eth-go/ethutil"
"github.com/ethereum/go-ethereum/utils"
"github.com/rakyll/globalconf"
"io/ioutil"
"log"
"os"
"os/signal"
"path"
"runtime"
"strings"
)
const Debug = true
func RegisterInterrupt(cb func(os.Signal)) {
go func() {
// Buffered chan of one is enough
c := make(chan os.Signal, 1)
// Notify about interrupts for now
signal.Notify(c, os.Interrupt)
for sig := range c {
cb(sig)
}
}()
}
func confirm(message string) bool {
fmt.Println(message, "Are you sure? (y/n)")
var r string
fmt.Scanln(&r)
for ; ; fmt.Scanln(&r) {
if r == "n" || r == "y" {
break
} else {
fmt.Printf("Yes or no?", r)
}
}
return r == "y"
}
func main() {
Init()
runtime.GOMAXPROCS(runtime.NumCPU())
// set logger
var logSys *log.Logger
flags := log.LstdFlags
var lt ethutil.LoggerType
if StartJsConsole || len(InputFile) > 0 {
lt = ethutil.LogFile
} else {
lt = ethutil.LogFile | ethutil.LogStd
}
g, err := globalconf.NewWithOptions(&globalconf.Options{
Filename: path.Join(ethutil.ApplicationFolder(Datadir), "conf.ini"),
})
if err != nil {
fmt.Println(err)
} else {
g.ParseAll()
}
ethutil.ReadConfig(Datadir, lt, g, Identifier)
logger := ethutil.Config.Log
if LogFile != "" {
logfile, err := os.OpenFile(LogFile, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
if err != nil {
panic(fmt.Sprintf("error opening log file '%s': %v", LogFile, err))
}
defer logfile.Close()
log.SetOutput(logfile)
logSys = log.New(logfile, "", flags)
logger.AddLogSystem(logSys)
} else {
logSys = log.New(os.Stdout, "", flags)
}
// Instantiated a eth stack
ethereum, err := eth.New(eth.CapDefault, UseUPnP)
if err != nil {
log.Println("eth start err:", err)
return
}
ethereum.Port = OutboundPort
// bookkeeping tasks
switch {
case GenAddr:
if NonInteractive || confirm("This action overwrites your old private key.") {
utils.CreateKeyPair(true)
}
os.Exit(0)
case len(ImportKey) > 0:
if NonInteractive || confirm("This action overwrites your old private key.") {
mnemonic := strings.Split(ImportKey, " ")
if len(mnemonic) == 24 {
logSys.Println("Got mnemonic key, importing.")
key := ethutil.MnemonicDecode(mnemonic)
utils.ImportPrivateKey(key)
} else if len(mnemonic) == 1 {
logSys.Println("Got hex key, importing.")
utils.ImportPrivateKey(ImportKey)
} else {
logSys.Println("Did not recognise format, exiting.")
}
}
os.Exit(0)
case ExportKey:
keyPair := ethutil.GetKeyRing().Get(0)
fmt.Printf(`
Generating new address and keypair.
Please keep your keys somewhere save.
++++++++++++++++ KeyRing +++++++++++++++++++
addr: %x
prvk: %x
pubk: %x
++++++++++++++++++++++++++++++++++++++++++++
save these words so you can restore your account later: %s
`, keyPair.Address(), keyPair.PrivateKey, keyPair.PublicKey)
os.Exit(0)
case ShowGenesis:
logSys.Println(ethereum.BlockChain().Genesis())
os.Exit(0)
default:
// Creates a keypair if non exists
utils.CreateKeyPair(false)
}
// client
logger.Infoln(fmt.Sprintf("Starting Ethereum v%s", ethutil.Config.Ver))
// Set the max peers
ethereum.MaxPeers = MaxPeer
// Set Mining status
ethereum.Mining = StartMining
if StartMining {
utils.DoMining(ethereum)
}
if StartJsConsole {
repl := NewJSRepl(ethereum)
go repl.Start()
RegisterInterrupt(func(os.Signal) {
repl.Stop()
})
} else if len(InputFile) > 0 {
file, err := os.Open(InputFile)
if err != nil {
ethutil.Config.Log.Fatal(err)
}
content, err := ioutil.ReadAll(file)
if err != nil {
ethutil.Config.Log.Fatal(err)
}
re := NewJSRE(ethereum)
RegisterInterrupt(func(os.Signal) {
re.Stop()
})
re.Run(string(content))
}
if StartRpc {
utils.DoRpc(ethereum, RpcPort)
}
RegisterInterrupt(func(sig os.Signal) {
fmt.Printf("Shutting down (%v) ... \n", sig)
ethereum.Stop()
})
ethereum.Start(UseSeed)
// Wait for shutdown
ethereum.WaitForShutdown()
}

View File

@@ -4,10 +4,12 @@ import (
"flag"
"fmt"
"os"
"os/user"
"path"
"github.com/ethereum/eth-go/ethlog"
)
var Identifier string
var StartMining bool
var StartRpc bool
var RpcPort int
var UseUPnP bool
@@ -19,16 +21,28 @@ var GenAddr bool
var UseSeed bool
var ImportKey string
var ExportKey bool
var LogFile string
var NonInteractive bool
var Datadir string
var LogFile string
var ConfigFile string
var DebugFile string
var LogLevel int
// flags specific to cli client
var StartMining bool
var StartJsConsole bool
var InputFile string
var Datadir string
func defaultDataDir() string {
usr, _ := user.Current()
return path.Join(usr.HomeDir, ".ethereum")
}
var defaultConfigFile = path.Join(defaultDataDir(), "conf.ini")
func Init() {
flag.Usage = func() {
fmt.Fprintf(os.Stderr, "%s [options] [filename]:\n", os.Args[0])
fmt.Fprintf(os.Stderr, "%s [options] [filename]:\noptions precedence: default < config file < environment variables < command line", os.Args[0])
flag.PrintDefaults()
}
@@ -38,17 +52,19 @@ func Init() {
flag.IntVar(&MaxPeer, "maxpeer", 10, "maximum desired peers")
flag.IntVar(&RpcPort, "rpcport", 8080, "port to start json-rpc server on")
flag.BoolVar(&StartRpc, "rpc", false, "start rpc server")
flag.BoolVar(&StartJsConsole, "js", false, "exp")
flag.BoolVar(&StartMining, "mine", false, "start dagger mining")
flag.BoolVar(&NonInteractive, "y", false, "non-interactive mode (say yes to confirmations)")
flag.BoolVar(&UseSeed, "seed", true, "seed peers")
flag.BoolVar(&GenAddr, "genaddr", false, "create a new priv/pub key")
flag.BoolVar(&ExportKey, "export", false, "export private key")
flag.StringVar(&LogFile, "logfile", "", "log file (defaults to standard output)")
flag.StringVar(&ImportKey, "import", "", "imports the given private key (hex)")
flag.StringVar(&Datadir, "datadir", defaultDataDir(), "specifies the datadir to use")
flag.StringVar(&ConfigFile, "conf", defaultConfigFile, "config file")
flag.StringVar(&DebugFile, "debug", "", "debug file (no debugging if not set)")
flag.IntVar(&LogLevel, "loglevel", int(ethlog.InfoLevel), "loglevel: 0-4: silent,error,warn,info,debug)")
flag.StringVar(&Datadir, "datadir", ".ethereum", "specifies the datadir to use. Takes precedence over config file.")
flag.BoolVar(&StartMining, "mine", false, "start dagger mining")
flag.BoolVar(&StartJsConsole, "js", false, "launches javascript console")
flag.Parse()

47
ethereum/main.go Normal file
View File

@@ -0,0 +1,47 @@
package main
import (
"github.com/ethereum/go-ethereum/utils"
"github.com/ethereum/eth-go/ethlog"
"runtime"
)
var logger = ethlog.NewLogger("CLI")
func main() {
runtime.GOMAXPROCS(runtime.NumCPU())
// precedence: code-internal flag default < config file < environment variables < command line
Init() // parsing command line
utils.InitConfig(ConfigFile, Datadir, Identifier, "ETH")
utils.InitDataDir(Datadir)
utils.InitLogging(Datadir, LogFile, LogLevel, DebugFile)
ethereum := utils.NewEthereum(UseUPnP, OutboundPort, MaxPeer)
// create, import, export keys
utils.KeyTasks(GenAddr, ImportKey, ExportKey, NonInteractive)
if ShowGenesis {
utils.ShowGenesis(ethereum)
}
if StartMining {
utils.StartMining(ethereum)
}
// better reworked as cases
if StartJsConsole {
InitJsConsole(ethereum)
} else if len(InputFile) > 0 {
ExecJsFile(ethereum, InputFile)
}
if StartRpc {
utils.StartRpc(ethereum, RpcPort)
}
utils.StartEthereum(ethereum, UseSeed)
}