mukan-ignite/ignite/services/scaffolder/message.go
Mukan Erkin Törük c32551b6f7
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
refactor: replace all github.com upstream refs with git.cw.tr/mukan-network
2026-05-11 03:36:24 +03:00

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)
}