mukan-ignite/ignite/templates/module/create/base.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

173 lines
4.6 KiB
Go

package modulecreate
import (
"fmt"
"io/fs"
"github.com/gobuffalo/genny/v2"
"github.com/gobuffalo/plush/v4"
"github.com/iancoleman/strcase"
"git.cw.tr/mukan-network/mukan-ignite/ignite/pkg/errors"
"git.cw.tr/mukan-network/mukan-ignite/ignite/pkg/gomodulepath"
"git.cw.tr/mukan-network/mukan-ignite/ignite/pkg/xast"
"git.cw.tr/mukan-network/mukan-ignite/ignite/pkg/xgenny"
"git.cw.tr/mukan-network/mukan-ignite/ignite/pkg/xstrings"
"git.cw.tr/mukan-network/mukan-ignite/ignite/templates/field/plushhelpers"
"git.cw.tr/mukan-network/mukan-ignite/ignite/templates/module"
)
// NewGenerator returns the generator to scaffold a module inside an app.
func NewGenerator(opts *CreateOptions) (*genny.Generator, error) {
subBase, err := fs.Sub(fsBase, "files/base")
if err != nil {
return nil, errors.Errorf("fail to generate sub: %w", err)
}
g := genny.New()
if err := g.OnlyFS(subBase, nil, nil); err != nil {
return g, err
}
appModulePath := gomodulepath.ExtractAppPath(opts.ModulePath)
ctx := plush.NewContext()
ctx.Set("moduleName", opts.ModuleName)
ctx.Set("modulePath", opts.ModulePath)
ctx.Set("appName", opts.AppName)
ctx.Set("protoVer", opts.ProtoVer)
ctx.Set("dependencies", opts.Dependencies)
ctx.Set("params", opts.Params)
ctx.Set("configs", opts.Configs)
ctx.Set("isIBC", opts.IsIBC)
ctx.Set("apiPath", fmt.Sprintf("/%s/%s/%s", appModulePath, opts.ModuleName, opts.ProtoVer))
ctx.Set("protoPkgName", module.ProtoPackageName(appModulePath, opts.ModuleName, opts.ProtoVer))
ctx.Set("protoModulePkgName", module.ProtoModulePackageName(appModulePath, opts.ModuleName, opts.ProtoVer))
ctx.Set("toVariableName", strcase.ToLowerCamel)
plushhelpers.ExtendPlushContext(ctx)
g.Transformer(xgenny.Transformer(ctx))
g.Transformer(genny.Replace("{{protoDir}}", opts.ProtoDir))
g.Transformer(genny.Replace("{{appName}}", opts.AppName))
g.Transformer(genny.Replace("{{moduleName}}", opts.ModuleName))
g.Transformer(genny.Replace("{{protoVer}}", opts.ProtoVer))
return g, nil
}
// NewAppModify returns generator with modifications required to register a module in the app.
func NewAppModify(opts *CreateOptions) *genny.Generator {
g := genny.New()
g.RunFn(appModify(opts))
g.RunFn(appConfigModify(opts))
if opts.IsIBC {
g.RunFn(appIBCModify(opts))
}
return g
}
func appConfigModify(opts *CreateOptions) genny.RunFn {
return func(r *genny.Runner) error {
configPath := module.PathAppConfigGo
fConfig, err := r.Disk.Find(configPath)
if err != nil {
return err
}
// Import
content, err := xast.AppendImports(
fConfig.String(),
xast.WithNamedImport(
"_",
fmt.Sprintf("%[1]v/x/%[2]v/module", opts.ModulePath, opts.ModuleName),
),
xast.WithNamedImport(
fmt.Sprintf("%[1]vmoduletypes", opts.ModuleName),
fmt.Sprintf("%[1]v/x/%[2]v/types", opts.ModulePath, opts.ModuleName),
),
)
if err != nil {
return err
}
content, err = AddModuleToAppConfig(content, opts.ModuleName)
if err != nil {
return err
}
// Module dependencies
for _, dep := range opts.Dependencies {
// If bank is a dependency, add account permissions to the module
if dep.Name == "Bank" {
replacement := fmt.Sprintf(
"{Account: %[1]vmoduletypes.ModuleName, Permissions: []string{authtypes.Minter, authtypes.Burner, authtypes.Staking}}",
opts.ModuleName,
)
// Keeper definition
content, err = xast.ModifyGlobalArrayVar(content, "moduleAccPerms", xast.AppendGlobalArrayValue(replacement))
if err != nil {
return err
}
}
}
newFile := genny.NewFileS(configPath, content)
return r.File(newFile)
}
}
// app.go modification when creating a module.
func appModify(opts *CreateOptions) genny.RunFn {
return func(r *genny.Runner) error {
appPath := module.PathAppGo
f, err := r.Disk.Find(appPath)
if err != nil {
return err
}
// Import
content, err := xast.AppendImports(
f.String(),
xast.WithNamedImport(
fmt.Sprintf("%[1]vmodulekeeper", opts.ModuleName),
fmt.Sprintf("%[1]v/x/%[2]v/keeper", opts.ModulePath, opts.ModuleName),
),
)
if err != nil {
return err
}
// Keeper declaration
content, err = xast.ModifyStruct(
content,
"App",
xast.AppendStructValue(
fmt.Sprintf("%[1]vKeeper", xstrings.Title(opts.ModuleName)),
fmt.Sprintf("%[1]vmodulekeeper.Keeper", opts.ModuleName),
),
)
if err != nil {
return err
}
// Keeper definition
content, err = xast.ModifyFunction(
content,
"New",
xast.AppendInsideFuncCall(
"Inject",
fmt.Sprintf("\n&app.%[1]vKeeper", xstrings.Title(opts.ModuleName)),
-1,
),
)
if err != nil {
return err
}
newFile := genny.NewFileS(appPath, content)
return r.File(newFile)
}
}