aboutsummaryrefslogtreecommitdiffstats
path: root/cmd
diff options
context:
space:
mode:
authorgary rong <garyrong0905@gmail.com>2019-07-08 20:59:07 +0800
committerGuillaume Ballet <gballet@gmail.com>2019-07-08 20:59:07 +0800
commit22060611fb4ea9d82af66a86f2effdf969425b03 (patch)
treecc9ca3d66bd500e232c1ee9d7beed0778f1e611d /cmd
parentcdfe9a3a2a257dcd2506e9a0eaf3bf3b0986c43a (diff)
downloadgo-tangerine-22060611fb4ea9d82af66a86f2effdf969425b03.tar
go-tangerine-22060611fb4ea9d82af66a86f2effdf969425b03.tar.gz
go-tangerine-22060611fb4ea9d82af66a86f2effdf969425b03.tar.bz2
go-tangerine-22060611fb4ea9d82af66a86f2effdf969425b03.tar.lz
go-tangerine-22060611fb4ea9d82af66a86f2effdf969425b03.tar.xz
go-tangerine-22060611fb4ea9d82af66a86f2effdf969425b03.tar.zst
go-tangerine-22060611fb4ea9d82af66a86f2effdf969425b03.zip
cmd/abigen: refactor command line interface (#19797)
* cmd, common: refactor abigen command line interface * cmd/abigen: address comment
Diffstat (limited to 'cmd')
-rw-r--r--cmd/abigen/main.go249
-rw-r--r--cmd/utils/flags.go12
2 files changed, 167 insertions, 94 deletions
diff --git a/cmd/abigen/main.go b/cmd/abigen/main.go
index aaf2f9fa8..6af34c5fe 100644
--- a/cmd/abigen/main.go
+++ b/cmd/abigen/main.go
@@ -18,63 +18,129 @@ package main
import (
"encoding/json"
- "flag"
"fmt"
"io/ioutil"
"os"
"strings"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
+ "github.com/ethereum/go-ethereum/cmd/utils"
"github.com/ethereum/go-ethereum/common/compiler"
"github.com/ethereum/go-ethereum/crypto"
+ "github.com/ethereum/go-ethereum/log"
+ "gopkg.in/urfave/cli.v1"
)
-var (
- abiFlag = flag.String("abi", "", "Path to the Ethereum contract ABI json to bind, - for STDIN")
- binFlag = flag.String("bin", "", "Path to the Ethereum contract bytecode (generate deploy method)")
- typFlag = flag.String("type", "", "Struct name for the binding (default = package name)")
+const (
+ commandHelperTemplate = `{{.Name}}{{if .Subcommands}} command{{end}}{{if .Flags}} [command options]{{end}} [arguments...]
+{{if .Description}}{{.Description}}
+{{end}}{{if .Subcommands}}
+SUBCOMMANDS:
+ {{range .Subcommands}}{{.Name}}{{with .ShortName}}, {{.}}{{end}}{{ "\t" }}{{.Usage}}
+ {{end}}{{end}}{{if .Flags}}
+OPTIONS:
+{{range $.Flags}}{{"\t"}}{{.}}
+{{end}}
+{{end}}`
+)
- solFlag = flag.String("sol", "", "Path to the Ethereum contract Solidity source to build and bind")
- solcFlag = flag.String("solc", "solc", "Solidity compiler to use if source builds are requested")
- excFlag = flag.String("exc", "", "Comma separated types to exclude from binding")
+var (
+ // Git SHA1 commit hash of the release (set via linker flags)
+ gitCommit = ""
+ gitDate = ""
- vyFlag = flag.String("vy", "", "Path to the Ethereum contract Vyper source to build and bind")
- vyperFlag = flag.String("vyper", "vyper", "Vyper compiler to use if source builds are requested")
+ app *cli.App
- pkgFlag = flag.String("pkg", "", "Package name to generate the binding into")
- outFlag = flag.String("out", "", "Output file for the generated binding (default = stdout)")
- langFlag = flag.String("lang", "go", "Destination language for the bindings (go, java, objc)")
+ // Flags needed by abigen
+ abiFlag = cli.StringFlag{
+ Name: "abi",
+ Usage: "Path to the Ethereum contract ABI json to bind, - for STDIN",
+ }
+ binFlag = cli.StringFlag{
+ Name: "bin",
+ Usage: "Path to the Ethereum contract bytecode (generate deploy method)",
+ }
+ typeFlag = cli.StringFlag{
+ Name: "type",
+ Usage: "Struct name for the binding (default = package name)",
+ }
+ jsonFlag = cli.StringFlag{
+ Name: "combined-json",
+ Usage: "Path to the combined-json file generated by compiler",
+ }
+ solFlag = cli.StringFlag{
+ Name: "sol",
+ Usage: "Path to the Ethereum contract Solidity source to build and bind",
+ }
+ solcFlag = cli.StringFlag{
+ Name: "solc",
+ Usage: "Solidity compiler to use if source builds are requested",
+ Value: "solc",
+ }
+ vyFlag = cli.StringFlag{
+ Name: "vy",
+ Usage: "Path to the Ethereum contract Vyper source to build and bind",
+ }
+ vyperFlag = cli.StringFlag{
+ Name: "vyper",
+ Usage: "Vyper compiler to use if source builds are requested",
+ Value: "vyper",
+ }
+ excFlag = cli.StringFlag{
+ Name: "exc",
+ Usage: "Comma separated types to exclude from binding",
+ }
+ pkgFlag = cli.StringFlag{
+ Name: "pkg",
+ Usage: "Package name to generate the binding into",
+ }
+ outFlag = cli.StringFlag{
+ Name: "out",
+ Usage: "Output file for the generated binding (default = stdout)",
+ }
+ langFlag = cli.StringFlag{
+ Name: "lang",
+ Usage: "Destination language for the bindings (go, java, objc)",
+ Value: "go",
+ }
)
-func main() {
- // Parse and ensure all needed inputs are specified
- flag.Parse()
+func init() {
+ app = utils.NewApp(gitCommit, gitDate, "ethereum checkpoint helper tool")
+ app.Flags = []cli.Flag{
+ abiFlag,
+ binFlag,
+ typeFlag,
+ jsonFlag,
+ solFlag,
+ solcFlag,
+ vyFlag,
+ vyperFlag,
+ excFlag,
+ pkgFlag,
+ outFlag,
+ langFlag,
+ }
+ app.Action = utils.MigrateFlags(abigen)
+ cli.CommandHelpTemplate = commandHelperTemplate
+}
- if *abiFlag == "" && *solFlag == "" && *vyFlag == "" {
- fmt.Printf("No contract ABI (--abi), Solidity source (--sol), or Vyper source (--vy) specified\n")
- os.Exit(-1)
- } else if (*abiFlag != "" || *binFlag != "" || *typFlag != "") && (*solFlag != "" || *vyFlag != "") {
- fmt.Printf("Contract ABI (--abi), bytecode (--bin) and type (--type) flags are mutually exclusive with the Solidity (--sol) and Vyper (--vy) flags\n")
- os.Exit(-1)
- } else if *solFlag != "" && *vyFlag != "" {
- fmt.Printf("Solidity (--sol) and Vyper (--vy) flags are mutually exclusive\n")
- os.Exit(-1)
- }
- if *pkgFlag == "" {
- fmt.Printf("No destination package specified (--pkg)\n")
- os.Exit(-1)
+func abigen(c *cli.Context) error {
+ utils.CheckExclusive(c, abiFlag, jsonFlag, solFlag, vyFlag) // Only one source can be selected.
+ if c.GlobalString(pkgFlag.Name) == "" {
+ utils.Fatalf("No destination package specified (--pkg)")
}
var lang bind.Lang
- switch *langFlag {
+ switch c.GlobalString(langFlag.Name) {
case "go":
lang = bind.LangGo
case "java":
lang = bind.LangJava
case "objc":
lang = bind.LangObjC
+ utils.Fatalf("Objc binding generation is uncompleted")
default:
- fmt.Printf("Unsupported destination language \"%s\" (--lang)\n", *langFlag)
- os.Exit(-1)
+ utils.Fatalf("Unsupported destination language \"%s\" (--lang)", c.GlobalString(langFlag.Name))
}
// If the entire solidity code was specified, build and bind based on that
var (
@@ -84,34 +150,67 @@ func main() {
sigs []map[string]string
libs = make(map[string]string)
)
- if *solFlag != "" || *vyFlag != "" || *abiFlag == "-" {
+ if c.GlobalString(abiFlag.Name) != "" {
+ // Load up the ABI, optional bytecode and type name from the parameters
+ var (
+ abi []byte
+ err error
+ )
+ input := c.GlobalString(abiFlag.Name)
+ if input == "-" {
+ abi, err = ioutil.ReadAll(os.Stdin)
+ } else {
+ abi, err = ioutil.ReadFile(input)
+ }
+ if err != nil {
+ utils.Fatalf("Failed to read input ABI: %v", err)
+ }
+ abis = append(abis, string(abi))
+
+ var bin []byte
+ if binFile := c.GlobalString(binFlag.Name); binFile != "" {
+ if bin, err = ioutil.ReadFile(binFile); err != nil {
+ utils.Fatalf("Failed to read input bytecode: %v", err)
+ }
+ if strings.Contains(string(bin), "//") {
+ utils.Fatalf("Contract has additional library references, please use other mode(e.g. --combined-json) to catch library infos")
+ }
+ }
+ bins = append(bins, string(bin))
+
+ kind := c.GlobalString(typeFlag.Name)
+ if kind == "" {
+ kind = c.GlobalString(pkgFlag.Name)
+ }
+ types = append(types, kind)
+ } else {
// Generate the list of types to exclude from binding
exclude := make(map[string]bool)
- for _, kind := range strings.Split(*excFlag, ",") {
+ for _, kind := range strings.Split(c.GlobalString(excFlag.Name), ",") {
exclude[strings.ToLower(kind)] = true
}
-
- var contracts map[string]*compiler.Contract
var err error
+ var contracts map[string]*compiler.Contract
switch {
- case *solFlag != "":
- contracts, err = compiler.CompileSolidity(*solcFlag, *solFlag)
+ case c.GlobalIsSet(solFlag.Name):
+ contracts, err = compiler.CompileSolidity(c.GlobalString(solcFlag.Name), c.GlobalString(solFlag.Name))
+ if err != nil {
+ utils.Fatalf("Failed to build Solidity contract: %v", err)
+ }
+ case c.GlobalIsSet(vyFlag.Name):
+ contracts, err = compiler.CompileVyper(c.GlobalString(vyperFlag.Name), c.GlobalString(vyFlag.Name))
if err != nil {
- fmt.Printf("Failed to build Solidity contract: %v\n", err)
- os.Exit(-1)
+ utils.Fatalf("Failed to build Vyper contract: %v", err)
}
- case *vyFlag != "":
- contracts, err = compiler.CompileVyper(*vyperFlag, *vyFlag)
+ case c.GlobalIsSet(jsonFlag.Name):
+ jsonOutput, err := ioutil.ReadFile(c.GlobalString(jsonFlag.Name))
if err != nil {
- fmt.Printf("Failed to build Vyper contract: %v\n", err)
- os.Exit(-1)
+ utils.Fatalf("Failed to read combined-json from compiler: %v", err)
}
- default:
- contracts, err = contractsFromStdin()
+ contracts, err = compiler.ParseCombinedJSON(jsonOutput, "", "", "", "")
if err != nil {
- fmt.Printf("Failed to read input ABIs from STDIN: %v\n", err)
- os.Exit(-1)
+ utils.Fatalf("Failed to read contract information from json output: %v", err)
}
}
// Gather all non-excluded contract for binding
@@ -121,65 +220,39 @@ func main() {
}
abi, err := json.Marshal(contract.Info.AbiDefinition) // Flatten the compiler parse
if err != nil {
- fmt.Printf("Failed to parse ABIs from compiler output: %v\n", err)
- os.Exit(-1)
+ utils.Fatalf("Failed to parse ABIs from compiler output: %v", err)
}
abis = append(abis, string(abi))
bins = append(bins, contract.Code)
sigs = append(sigs, contract.Hashes)
-
nameParts := strings.Split(name, ":")
types = append(types, nameParts[len(nameParts)-1])
libPattern := crypto.Keccak256Hash([]byte(name)).String()[2:36]
libs[libPattern] = nameParts[len(nameParts)-1]
}
- } else {
- // Otherwise load up the ABI, optional bytecode and type name from the parameters
- abi, err := ioutil.ReadFile(*abiFlag)
-
- if err != nil {
- fmt.Printf("Failed to read input ABI: %v\n", err)
- os.Exit(-1)
- }
- abis = append(abis, string(abi))
-
- var bin []byte
- if *binFlag != "" {
- if bin, err = ioutil.ReadFile(*binFlag); err != nil {
- fmt.Printf("Failed to read input bytecode: %v\n", err)
- os.Exit(-1)
- }
- }
- bins = append(bins, string(bin))
-
- kind := *typFlag
- if kind == "" {
- kind = *pkgFlag
- }
- types = append(types, kind)
}
// Generate the contract binding
- code, err := bind.Bind(types, abis, bins, sigs, *pkgFlag, lang, libs)
+ code, err := bind.Bind(types, abis, bins, sigs, c.GlobalString(pkgFlag.Name), lang, libs)
if err != nil {
- fmt.Printf("Failed to generate ABI binding: %v\n", err)
- os.Exit(-1)
+ utils.Fatalf("Failed to generate ABI binding: %v", err)
}
// Either flush it out to a file or display on the standard output
- if *outFlag == "" {
+ if !c.GlobalIsSet(outFlag.Name) {
fmt.Printf("%s\n", code)
- return
+ return nil
}
- if err := ioutil.WriteFile(*outFlag, []byte(code), 0600); err != nil {
- fmt.Printf("Failed to write ABI binding: %v\n", err)
- os.Exit(-1)
+ if err := ioutil.WriteFile(c.GlobalString(outFlag.Name), []byte(code), 0600); err != nil {
+ utils.Fatalf("Failed to write ABI binding: %v", err)
}
+ return nil
}
-func contractsFromStdin() (map[string]*compiler.Contract, error) {
- bytes, err := ioutil.ReadAll(os.Stdin)
- if err != nil {
- return nil, err
+func main() {
+ log.Root().SetHandler(log.LvlFilterHandler(log.LvlInfo, log.StreamHandler(os.Stderr, log.TerminalFormat(true))))
+
+ if err := app.Run(os.Args); err != nil {
+ fmt.Fprintln(os.Stderr, err)
+ os.Exit(1)
}
- return compiler.ParseCombinedJSON(bytes, "", "", "", "")
}
diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go
index f928edc0f..9a92e21fe 100644
--- a/cmd/utils/flags.go
+++ b/cmd/utils/flags.go
@@ -944,7 +944,7 @@ func setWS(ctx *cli.Context, cfg *node.Config) {
// setIPC creates an IPC path configuration from the set command line flags,
// returning an empty string if IPC was explicitly disabled, or the set path.
func setIPC(ctx *cli.Context, cfg *node.Config) {
- checkExclusive(ctx, IPCDisabledFlag, IPCPathFlag)
+ CheckExclusive(ctx, IPCDisabledFlag, IPCPathFlag)
switch {
case ctx.GlobalBool(IPCDisabledFlag.Name):
cfg.IPCPath = ""
@@ -1329,10 +1329,10 @@ func setWhitelist(ctx *cli.Context, cfg *eth.Config) {
}
}
-// checkExclusive verifies that only a single instance of the provided flags was
+// CheckExclusive verifies that only a single instance of the provided flags was
// set by the user. Each flag might optionally be followed by a string type to
// specialize it further.
-func checkExclusive(ctx *cli.Context, args ...interface{}) {
+func CheckExclusive(ctx *cli.Context, args ...interface{}) {
set := make([]string, 0, 1)
for i := 0; i < len(args); i++ {
// Make sure the next argument is a flag and skip if not set
@@ -1386,10 +1386,10 @@ func SetShhConfig(ctx *cli.Context, stack *node.Node, cfg *whisper.Config) {
// SetEthConfig applies eth-related command line flags to the config.
func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) {
// Avoid conflicting network flags
- checkExclusive(ctx, DeveloperFlag, TestnetFlag, RinkebyFlag, GoerliFlag)
- checkExclusive(ctx, LightServFlag, SyncModeFlag, "light")
+ CheckExclusive(ctx, DeveloperFlag, TestnetFlag, RinkebyFlag, GoerliFlag)
+ CheckExclusive(ctx, LightServFlag, SyncModeFlag, "light")
// Can't use both ephemeral unlocked and external signer
- checkExclusive(ctx, DeveloperFlag, ExternalSignerFlag)
+ CheckExclusive(ctx, DeveloperFlag, ExternalSignerFlag)
var ks *keystore.KeyStore
if keystores := stack.AccountManager().Backends(keystore.KeyStoreType); len(keystores) > 0 {
ks = keystores[0].(*keystore.KeyStore)