8000 feat: scaffold empty message by lumtis · Pull Request #823 · ignite/cli · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
8000

feat: scaffold empty message #823

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Mar 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions integration/cmd_message_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// +build !relayer

package integration_test

import (
"testing"

"github.com/tendermint/starport/starport/pkg/cmdrunner/step"
)

func TestGenerateAnAppWithMessage(t *testing.T) {
var (
env = newEnv(t)
path = env.Scaffold("blog", Stargate)
)

env.Must(env.Exec("create a message",
step.NewSteps(step.New(
step.Exec("starport", "message", "foo", "text", "vote:int", "like:bool", "-r", "foo,bar:int,foobar:bool"),
step.Workdir(path),
)),
))

env.Must(env.Exec("should prevent creating an existing message",
step.NewSteps(step.New(
step.Exec("starport", "message", "foo", "bar"),
step.Workdir(path),
)),
ExecShouldError(),
))

env.Must(env.Exec("create a module",
step.NewSteps(step.New(
step.Exec("starport", "module", "create", "foo"),
step.Workdir(path),
)),
))

env.Must(env.Exec("create a message in a module",
step.NewSteps(step.New(
step.Exec("starport", "message", "foo", "text", "--module", "foo", "--desc", "foo bar foobar", "--response", "foo,bar:int,foobar:bool"),
step.Workdir(path),
)),
))

env.EnsureAppIsSteady(path)
}
1 change: 1 addition & 0 deletions starport/interface/cli/starport/cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ func New() *cobra.Command {
c.AddCommand(NewVersion())
c.AddCommand(NewNetwork())
c.AddCommand(NewIBCPacket())
c.AddCommand(NewMessage())
c.Flags().BoolP("toggle", "t", false, "Help message for toggle")
return c
}
Expand Down
69 changes: 69 additions & 0 deletions starport/interface/cli/starport/cmd/message.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package starportcmd

import (
"fmt"

"github.com/spf13/cobra"
"github.com/tendermint/starport/starport/pkg/clispinner"
"github.com/tendermint/starport/starport/services/scaffolder"
)

const (
responseFlag string = "response"
descriptionFlag string = "desc"
)

// NewType command creates a new type command to scaffold types.
func NewMessage() *cobra.Command {
c := &cobra.Command{
Use: "message [name] [field1] [field2] ...",
Short: "Generates an empty message",
Args: cobra.MinimumNArgs(1),
RunE: messageHandler,
}
c.Flags().StringVarP(&appPath, "path", "p", "", "path of the app")
addSdkVersionFlag(c)

c.Flags().String(moduleFlag, "", "Module to add the message into. Default: app's main module")
c.Flags().StringSliceP(responseFlag, "r", []string{}, "Response fields")
c.Flags().StringP(descriptionFlag, "d", "", "Description of the command")

return c
}

func messageHandler(cmd *cobra.Command, args []string) error {
s := clispinner.New().SetText("Scaffolding...")
defer s.Stop()

// Get the module to add the type into
module, err := cmd.Flags().GetString(moduleFlag)
if err != nil {
return err
}

// Get response fields
resFields, err := cmd.Flags().GetStringSlice(responseFlag)
if err != nil {
return err
}

// Get description
desc, err := cmd.Flags().GetString(descriptionFlag)
if err != nil {
return err
}
if desc == "" {
// Use a default description
desc = fmt.Sprintf("Broadcast message %s", args[0])
}

sc := scaffolder.New(appPath)
if err := sc.AddMessage(module, args[0], desc, args[1:], resFields); err != nil {
return err
}

s.Stop()

fmt.Printf("\n🎉 Created a message `%[1]v`.\n\n", args[0])
return nil
}
131 changes: 131 additions & 0 deletions starport/services/scaffolder/message.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
package scaffolder

import (
"context"
"errors"
"fmt"
"os"
"path/filepath"

"github.com/gobuffalo/genny"
"github.com/tendermint/starport/starport/pkg/cosmosver"
"github.com/tendermint/starport/starport/pkg/gomodulepath"
"github.com/tendermint/starport/starport/templates/message"
)

// AddType adds a new type stype to scaffolded app by using optional type fields.
func (s *Scaffolder) AddMessage(moduleName string, msgName string, msgDesc string, fields []string, resField []string) error {
version, err := s.version()
if err != nil {
return err
}
majorVersion := version.Major()
path, err := gomodulepath.ParseAt(s.path)
if err != nil {
return err
}

// If no module is provided, we add the type to the app's module
if moduleName == "" {
moduleName = path.Package
}
ok, err := moduleExists(s.path, moduleName)
if err != nil {
return err
}
if !ok {
return fmt.Errorf("the module %s doesn't exist", moduleName)
}

// Ensure the msg name is not a Go reserved name, it would generate an incorrect code
if isGoReservedWord(msgName) {
return fmt.Errorf("%s can't be used as a type name", msgName)
}

// Check msg is not already created
ok, err = isMsgCreated(s.path, moduleName, msgName)
if err != nil {
return err
}
if ok {
return fmt.Errorf("%s message is already added", msgName)
}

// Parse provided fields
parsedMsgFields, err := parseFields(fields)
if err != nil {
return err
}
parsedResFields, err := parseFields(resField)
if err != nil {
return err
}

var (
g *genny.Generator
opts = &message.Options{
AppName: path.Package,
ModulePath: path.RawPath,
ModuleName: moduleName,
OwnerName: owner(path.RawPath),
MsgName: msgName,
Fields: parsedMsgFields,
ResFields: parsedResFields,
MsgDesc: msgDesc,
}
)
// generate depending on the version
if majorVersion == cosmosver.Launchpad {
return errors.New("message scaffolding not supported on Launchpad")
}
// check if the msgServer convention is used
var msgServerDefined bool
msgServerDefined, err = isMsgServerDefined(s.path, moduleName)
if err != nil {
return err
}
if !msgServerDefined {
// TODO: Determine if we want to support blockchains not using MsgServer convention
return errors.New("the blockchain must use MsgServer convention")
}

// Scaffold
g, err = message.NewStargate(opts)
if err != nil {
return err
}
run := genny.WetRunner(context.Background())
run.With(g)
if err := run.Run(); err != nil {
return err
}
pwd, err := os.Getwd()
if err != nil {
return err
}
if err := s.protoc(pwd, path.RawPath, majorVersion); err != nil {
return err
}
return fmtProject(pwd)
}

func isMsgCreated(appPath, moduleName, msgName string) (isCreated bool, err error) {
absPath, err := filepath.Abs(filepath.Join(
appPath,
moduleDir,
moduleName,
typesDirectory,
"message_"+msgName+".go",
))
if err != nil {
return false, err
}

_, err = os.Stat(absPath)
if os.IsNotExist(err) {
// Packet doesn't exist
return false, nil
}

return true, err
}
1 change: 1 addition & 0 deletions starport/services/scaffolder/packet.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
const (
ibcModuleImplementation = "module_ibc.go"
keeperDirectory = "keeper"
typesDirectory = "types"
)

// AddType adds a new type stype to scaffolded app by using optional type fields.
Expand Down
43 changes: 43 additions & 0 deletions starport/templates/message/message.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package message

import (
"embed"
"strings"

"github.com/gobuffalo/genny"
"github.com/gobuffalo/packd"
"github.com/gobuffalo/plush"
"github.com/gobuffalo/plushgen"
"github.com/tendermint/starport/starport/pkg/xgenny"
)

var (
//go:embed stargate/* stargate/**/*
fsStargate embed.FS

stargateTemplate = xgenny.NewEmbedWalker(fsStargate, "stargate/")
)

func Box(box packd.Walker, opts *Options, g *genny.Generator) error {
if err := g.Box(box); err != nil {
return err
}
ctx := plush.NewContext()
ctx.Set("ModuleName", opts.ModuleName)
ctx.Set("AppName", opts.AppName)
ctx.Set("MsgName", opts.MsgName)
ctx.Set("MsgDesc", opts.MsgDesc)
ctx.Set("OwnerName", opts.OwnerName)
ctx.Set("ModulePath", opts.ModulePath)
ctx.Set("Fields", opts.Fields)
ctx.Set("ResFields", opts.ResFields)
ctx.Set("title", strings.Title)
ctx.Set("nodash", func(s string) string {
return strings.ReplaceAll(s, "-", "")
})
g.Transformer(plushgen.Transformer(ctx))
g.Transformer(genny.Replace("{{moduleName}}", opts.ModuleName))
g.Transformer(genny.Replace("{{msgName}}", opts.MsgName))
g.Transformer(genny.Replace("{{MsgName}}", strings.Title(opts.MsgName)))
return nil
}
Loading
0