Better error messages (#24)
* Print proper error messages while using contract subcommands and also exit with status code 1. * Make -in a flag, also remove dot from avm extension. * Work on feedback by Anthony. * Update README and VERSION
This commit is contained in:
parent
23cfebf621
commit
e93dfe8062
6 changed files with 43 additions and 18 deletions
|
@ -117,20 +117,20 @@ TODO
|
||||||
### Compile a smart contract
|
### Compile a smart contract
|
||||||
|
|
||||||
```
|
```
|
||||||
./bin/neo-go contract compile mycontract.go
|
./bin/neo-go contract compile -i mycontract.go
|
||||||
```
|
```
|
||||||
|
|
||||||
By default the filename will be the name of your .go file with the .avm extension, the file will be located in the same directory where you called the command from. If you want another location for your compiled contract:
|
By default the filename will be the name of your .go file with the .avm extension, the file will be located in the same directory where you called the command from. If you want another location for your compiled contract:
|
||||||
|
|
||||||
```
|
```
|
||||||
./bin/neo-go contract compile mycontract.go --out /Users/foo/bar/contract.avm
|
./bin/neo-go contract compile -i mycontract.go --out /Users/foo/bar/contract.avm
|
||||||
```
|
```
|
||||||
|
|
||||||
### Debugging your smart contract
|
### Debugging your smart contract
|
||||||
You can dump the opcodes generated by the compiler with the following command:
|
You can dump the opcodes generated by the compiler with the following command:
|
||||||
|
|
||||||
```
|
```
|
||||||
./bin/neo-go contract opdump mycontract.go
|
./bin/neo-go contract opdump -i mycontract.go
|
||||||
```
|
```
|
||||||
|
|
||||||
This will result in something like this:
|
This will result in something like this:
|
||||||
|
|
1
cli/.gitignore
vendored
Normal file
1
cli/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
cli
|
|
@ -11,6 +11,7 @@ import (
|
||||||
func main() {
|
func main() {
|
||||||
ctl := cli.NewApp()
|
ctl := cli.NewApp()
|
||||||
ctl.Name = "neo-go"
|
ctl.Name = "neo-go"
|
||||||
|
ctl.Usage = "Official Go client for Neo"
|
||||||
|
|
||||||
ctl.Commands = []cli.Command{
|
ctl.Commands = []cli.Command{
|
||||||
server.NewCommand(),
|
server.NewCommand(),
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
package smartcontract
|
package smartcontract
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
|
|
||||||
"github.com/CityOfZion/neo-go/pkg/vm/compiler"
|
"github.com/CityOfZion/neo-go/pkg/vm/compiler"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
ErrNoInput = "Input file is mandatory and should be passed using -i flag."
|
||||||
|
)
|
||||||
|
|
||||||
// NewCommand returns a new contract command.
|
// NewCommand returns a new contract command.
|
||||||
func NewCommand() cli.Command {
|
func NewCommand() cli.Command {
|
||||||
return cli.Command{
|
return cli.Command{
|
||||||
|
@ -18,6 +20,10 @@ func NewCommand() cli.Command {
|
||||||
Usage: "compile a smart contract to a .avm file",
|
Usage: "compile a smart contract to a .avm file",
|
||||||
Action: contractCompile,
|
Action: contractCompile,
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "in, i",
|
||||||
|
Usage: "Input file for the smart contract to be compiled",
|
||||||
|
},
|
||||||
cli.StringFlag{
|
cli.StringFlag{
|
||||||
Name: "out, o",
|
Name: "out, o",
|
||||||
Usage: "Output of the compiled contract",
|
Usage: "Output of the compiled contract",
|
||||||
|
@ -28,14 +34,21 @@ func NewCommand() cli.Command {
|
||||||
Name: "opdump",
|
Name: "opdump",
|
||||||
Usage: "dump the opcode of a .go file",
|
Usage: "dump the opcode of a .go file",
|
||||||
Action: contractDumpOpcode,
|
Action: contractDumpOpcode,
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "in, i",
|
||||||
|
Usage: "Input file for the smart contract",
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func contractCompile(ctx *cli.Context) error {
|
func contractCompile(ctx *cli.Context) error {
|
||||||
if len(ctx.Args()) == 0 {
|
src := ctx.String("in")
|
||||||
return errors.New("not enough arguments")
|
if len(src) == 0 {
|
||||||
|
return cli.NewExitError(ErrNoInput, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
o := &compiler.Options{
|
o := &compiler.Options{
|
||||||
|
@ -43,14 +56,19 @@ func contractCompile(ctx *cli.Context) error {
|
||||||
Debug: true,
|
Debug: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
src := ctx.Args()[0]
|
if err := compiler.CompileAndSave(src, o); err != nil {
|
||||||
return compiler.CompileAndSave(src, o)
|
return cli.NewExitError(err, 1)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func contractDumpOpcode(ctx *cli.Context) error {
|
func contractDumpOpcode(ctx *cli.Context) error {
|
||||||
if len(ctx.Args()) == 0 {
|
src := ctx.String("in")
|
||||||
return errors.New("not enough arguments")
|
if len(src) == 0 {
|
||||||
|
return cli.NewExitError(ErrNoInput, 1)
|
||||||
}
|
}
|
||||||
src := ctx.Args()[0]
|
if err := compiler.DumpOpcode(src); err != nil {
|
||||||
return compiler.DumpOpcode(src)
|
return cli.NewExitError(err, 1)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,12 @@ The neo-go compiler compiles Go programs to bytecode that the NEO virtual machin
|
||||||
|
|
||||||
> The neo-go compiler is under very active development and will be updated on a weekly basis.
|
> The neo-go compiler is under very active development and will be updated on a weekly basis.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```
|
||||||
|
./bin/neo-go contract compile -i mycontract.go --out /Users/foo/bar/contract.avm
|
||||||
|
```
|
||||||
|
|
||||||
## Currently supported
|
## Currently supported
|
||||||
|
|
||||||
### Go internals
|
### Go internals
|
||||||
|
|
|
@ -3,7 +3,6 @@ package compiler
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"go/ast"
|
"go/ast"
|
||||||
"go/build"
|
"go/build"
|
||||||
|
@ -114,10 +113,10 @@ func resolveImports(f *ast.File) (map[string]*archive, error) {
|
||||||
|
|
||||||
// CompileAndSave will compile and save the file to disk.
|
// CompileAndSave will compile and save the file to disk.
|
||||||
func CompileAndSave(src string, o *Options) error {
|
func CompileAndSave(src string, o *Options) error {
|
||||||
if len(o.Outfile) == 0 {
|
|
||||||
if !strings.HasSuffix(src, ".go") {
|
if !strings.HasSuffix(src, ".go") {
|
||||||
return errors.New("not a Go file")
|
return fmt.Errorf("%s is not a Go file", src)
|
||||||
}
|
}
|
||||||
|
if len(o.Outfile) == 0 {
|
||||||
o.Outfile = strings.TrimSuffix(src, ".go")
|
o.Outfile = strings.TrimSuffix(src, ".go")
|
||||||
}
|
}
|
||||||
if len(o.Ext) == 0 {
|
if len(o.Ext) == 0 {
|
||||||
|
@ -129,7 +128,7 @@ func CompileAndSave(src string, o *Options) error {
|
||||||
}
|
}
|
||||||
b, err = Compile(bytes.NewReader(b), o)
|
b, err = Compile(bytes.NewReader(b), o)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("Error while trying to compile smart contract file: %v", err)
|
||||||
}
|
}
|
||||||
if o.Debug {
|
if o.Debug {
|
||||||
log.Println(hex.EncodeToString(b))
|
log.Println(hex.EncodeToString(b))
|
||||||
|
|
Loading…
Reference in a new issue