Some checks failed
Docs Deploy / build_and_deploy (push) Has been cancelled
Generate Docs / cli (push) Has been cancelled
Generate Config Doc / cli (push) Has been cancelled
Go formatting / go-formatting (push) Has been cancelled
Check links / markdown-link-check (push) Has been cancelled
Integration / pre-test (push) Has been cancelled
Integration / test on (push) Has been cancelled
Integration / status (push) Has been cancelled
Lint / Lint Go code (push) Has been cancelled
Test / test (ubuntu-latest) (push) Has been cancelled
164 lines
3.9 KiB
Go
164 lines
3.9 KiB
Go
package scaffolder
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/gobuffalo/genny/v2"
|
|
|
|
"git.cw.tr/mukan-network/mukan-ignite/ignite/pkg/errors"
|
|
"git.cw.tr/mukan-network/mukan-ignite/ignite/pkg/multiformatname"
|
|
"git.cw.tr/mukan-network/mukan-ignite/ignite/templates/field"
|
|
"git.cw.tr/mukan-network/mukan-ignite/ignite/templates/field/datatype"
|
|
"git.cw.tr/mukan-network/mukan-ignite/ignite/templates/message"
|
|
)
|
|
|
|
// messageOptions represents configuration for the message scaffolding.
|
|
type messageOptions struct {
|
|
description string
|
|
signer string
|
|
withoutSimulation bool
|
|
}
|
|
|
|
// newMessageOptions returns a messageOptions with default options.
|
|
func newMessageOptions(messageName string) messageOptions {
|
|
return messageOptions{
|
|
description: fmt.Sprintf("Broadcast message %s", messageName),
|
|
signer: "creator",
|
|
}
|
|
}
|
|
|
|
// MessageOption configures the message scaffolding.
|
|
type MessageOption func(*messageOptions)
|
|
|
|
// WithDescription provides a custom description for the message CLI command.
|
|
func WithDescription(desc string) MessageOption {
|
|
return func(m *messageOptions) {
|
|
m.description = desc
|
|
}
|
|
}
|
|
|
|
// WithSigner provides a custom signer name for the message.
|
|
func WithSigner(signer string) MessageOption {
|
|
return func(m *messageOptions) {
|
|
m.signer = signer
|
|
}
|
|
}
|
|
|
|
// WithoutSimulation disables generating messages simulation.
|
|
func WithoutSimulation() MessageOption {
|
|
return func(m *messageOptions) {
|
|
m.withoutSimulation = true
|
|
}
|
|
}
|
|
|
|
// AddMessage adds a new message to scaffolded app.
|
|
func (s Scaffolder) AddMessage(
|
|
ctx context.Context,
|
|
moduleName,
|
|
msgName string,
|
|
fields,
|
|
resFields []string,
|
|
options ...MessageOption,
|
|
) error {
|
|
// Create the options
|
|
scaffoldingOpts := newMessageOptions(msgName)
|
|
for _, apply := range options {
|
|
apply(&scaffoldingOpts)
|
|
}
|
|
|
|
// If no module is provided, we add the type to the app's module
|
|
if moduleName == "" {
|
|
moduleName = s.modpath.Package
|
|
}
|
|
mfName, err := multiformatname.NewName(moduleName, multiformatname.NoNumber)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
moduleName = mfName.LowerCase
|
|
|
|
name, err := multiformatname.NewName(msgName)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := checkComponentValidity(s.appPath, moduleName, name, false); err != nil {
|
|
return err
|
|
}
|
|
|
|
// Check and parse provided fields
|
|
if err := checkCustomTypes(
|
|
ctx,
|
|
s.appPath,
|
|
s.modpath.Package,
|
|
s.protoDir,
|
|
moduleName,
|
|
fields,
|
|
); err != nil {
|
|
return err
|
|
}
|
|
parsedMsgFields, err := field.ParseFields(fields, checkForbiddenMessageField, scaffoldingOpts.signer)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Check and parse provided response fields
|
|
if err := checkCustomTypes(
|
|
ctx,
|
|
s.appPath,
|
|
s.modpath.Package,
|
|
s.protoDir,
|
|
moduleName,
|
|
resFields,
|
|
); err != nil {
|
|
return err
|
|
}
|
|
parsedResFields, err := field.ParseFields(resFields, checkGoReservedWord, scaffoldingOpts.signer)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
mfSigner, err := multiformatname.NewName(scaffoldingOpts.signer)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
var (
|
|
g *genny.Generator
|
|
opts = &message.Options{
|
|
AppName: s.modpath.Package,
|
|
ProtoDir: s.protoDir,
|
|
ProtoVer: "v1", // TODO(@julienrbrt): possibly in the future add flag to specify custom proto version.
|
|
ModulePath: s.modpath.RawPath,
|
|
ModuleName: moduleName,
|
|
MsgName: name,
|
|
Fields: parsedMsgFields,
|
|
ResFields: parsedResFields,
|
|
MsgDesc: scaffoldingOpts.description,
|
|
MsgSigner: mfSigner,
|
|
NoSimulation: scaffoldingOpts.withoutSimulation,
|
|
}
|
|
)
|
|
|
|
// Scaffold
|
|
g, err = message.NewGenerator(opts)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return s.Run(g)
|
|
}
|
|
|
|
// checkForbiddenMessageField returns true if the name is forbidden as a message name.
|
|
func checkForbiddenMessageField(name string) error {
|
|
mfName, err := multiformatname.NewName(name)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if mfName.LowerCase == datatype.TypeCustom {
|
|
return errors.Errorf("%s is used by the message scaffolder", name)
|
|
}
|
|
|
|
return checkGoReservedWord(name)
|
|
}
|