diff --git a/cli/smartcontract/smart_contract.go b/cli/smartcontract/smart_contract.go index 14d81da6b..0ae5e2585 100644 --- a/cli/smartcontract/smart_contract.go +++ b/cli/smartcontract/smart_contract.go @@ -1,6 +1,8 @@ package smartcontract import ( + "bufio" + "bytes" "context" "encoding/hex" "encoding/json" @@ -89,6 +91,10 @@ func NewCommand() cli.Command { Name: "name, n", Usage: "name of the smart-contract to be initialized", }, + cli.BoolFlag{ + Name: "skip-details, skip", + Usage: "skip filling in the projects and contract details", + }, }, }, }, @@ -97,31 +103,40 @@ func NewCommand() cli.Command { // initSmartContract initializes a given directory with some boiler plate code. func initSmartContract(ctx *cli.Context) error { - scName := ctx.String("name") - if scName == "" { + contractName := ctx.String("name") + if contractName == "" { return cli.NewExitError(errNoSmartContractName, 1) } // Check if the file already exists, if yes, exit - if _, err := os.Stat(scName); err == nil { + if _, err := os.Stat(contractName); err == nil { return cli.NewExitError(errFileExist, 1) } - basePath := scName + basePath := contractName fileName := "main.go" // create base directory - err := os.Mkdir(basePath, os.ModePerm) - if err != nil { + if err := os.Mkdir(basePath, os.ModePerm); err != nil { return cli.NewExitError(err, 1) } - data := []byte(fmt.Sprintf(smartContractTmpl, scName)) - err = ioutil.WriteFile(filepath.Join(basePath, fileName), data, 0644) - if err != nil { + // Ask contract information and write a storm.yml file unless the -skip-details flag is set. + // TODO: Fix the missing storm.yml file with the `init` command when the package manager is in place. + if !ctx.Bool("skip-details") { + details := parseContractDetails() + if err := ioutil.WriteFile(filepath.Join(basePath, "storm.yml"), details.toStormFile(), 0644); err != nil { + return cli.NewExitError(err, 1) + } + } + + data := []byte(fmt.Sprintf(smartContractTmpl, contractName)) + if err := ioutil.WriteFile(filepath.Join(basePath, fileName), data, 0644); err != nil { return cli.NewExitError(err, 1) } - fmt.Printf("Successfully initialized smart contract [%s]\n", scName) + + fmt.Printf("Successfully initialized smart contract [%s]\n", contractName) + return nil } @@ -190,3 +205,58 @@ func contractDumpOpcode(ctx *cli.Context) error { } return nil } + +type ContractDetails struct { + Author string + Email string + Version string + ProjectName string + Description string +} + +func (d ContractDetails) toStormFile() []byte { + buf := new(bytes.Buffer) + + buf.WriteString("# Storm specific configuration. Do not modify this unless you know what you are doing!\n") + buf.WriteString("storm:\n") + buf.WriteString(" version: 1.0\n") + + buf.WriteString("\n") + + buf.WriteString("# Project section contains information about your smart contract\n") + buf.WriteString("project:\n") + buf.WriteString(" author: " + d.Author) + buf.WriteString(" email: " + d.Email) + buf.WriteString(" version: " + d.Version) + buf.WriteString(" name: " + d.ProjectName) + buf.WriteString(" description: " + d.Description) + + buf.WriteString("\n") + + buf.WriteString("# Module section contains a list of imported modules\n") + buf.WriteString("# This will be automatically managed by the neo-storm package manager\n") + buf.WriteString("modules: \n") + return buf.Bytes() +} + +func parseContractDetails() ContractDetails { + details := ContractDetails{} + reader := bufio.NewReader(os.Stdin) + + fmt.Print("Author: ") + details.Author, _ = reader.ReadString('\n') + + fmt.Print("Email: ") + details.Email, _ = reader.ReadString('\n') + + fmt.Print("Version: ") + details.Version, _ = reader.ReadString('\n') + + fmt.Print("Project name: ") + details.ProjectName, _ = reader.ReadString('\n') + + fmt.Print("Description: ") + details.Description, _ = reader.ReadString('\n') + + return details +}