mukan-ignite/ignite/pkg/cosmosgen/cosmosgen.go
Mukan Erkin Törük 26b204bd04
Some checks are pending
Docs Deploy / build_and_deploy (push) Waiting to run
Generate Docs / cli (push) Waiting to run
Generate Config Doc / cli (push) Waiting to run
Go formatting / go-formatting (push) Waiting to run
Check links / markdown-link-check (push) Waiting to run
Integration / pre-test (push) Waiting to run
Integration / test on (push) Blocked by required conditions
Integration / status (push) Blocked by required conditions
Lint / Lint Go code (push) Waiting to run
Test / test (ubuntu-latest) (push) Waiting to run
feat: fork Ignite CLI v29 as Mukan Ignite — remove cosmos-sdk restrictions
2026-05-11 03:31:37 +03:00

216 lines
6.1 KiB
Go

package cosmosgen
import (
"context"
"os"
"path/filepath"
"strings"
"github.com/iancoleman/strcase"
gomodule "golang.org/x/mod/module"
"github.com/ignite/cli/v29/ignite/pkg/cache"
"github.com/ignite/cli/v29/ignite/pkg/cosmosanalysis/module"
"github.com/ignite/cli/v29/ignite/pkg/cosmosbuf"
"github.com/ignite/cli/v29/ignite/pkg/events"
)
// generateOptions used to configure code generation.
type generateOptions struct {
useCache bool
updateBufModule bool
ev events.Bus
generateProtobuf bool
jsOut func(module.Module) string
tsClientRootPath string
composablesOut func(module.Module) string
composablesRootPath string
openAPISpecOut string
openAPIExcludeList []string
}
// ModulePathFunc defines a function type that returns a path based on a Cosmos SDK module.
type ModulePathFunc func(module.Module) string
// Option configures code generation.
type Option func(*generateOptions)
// WithTSClientGeneration adds Typescript Client code generation.
// The tsClientRootPath is used to determine the root path of generated Typescript classes.
func WithTSClientGeneration(out ModulePathFunc, tsClientRootPath string, useCache bool) Option {
return func(o *generateOptions) {
o.jsOut = out
o.tsClientRootPath = tsClientRootPath
o.useCache = useCache
}
}
func WithComposablesGeneration(out ModulePathFunc, composablesRootPath string) Option {
return func(o *generateOptions) {
o.composablesOut = out
o.composablesRootPath = composablesRootPath
}
}
// WithGoGeneration adds protobuf (gogoproto) code generation.
func WithGoGeneration() Option {
return func(o *generateOptions) {
o.generateProtobuf = true
}
}
// WithOpenAPIGeneration adds OpenAPI spec generation.
func WithOpenAPIGeneration(out string, excludeList []string) Option {
return func(o *generateOptions) {
o.openAPISpecOut = out
o.openAPIExcludeList = excludeList
}
}
// UpdateBufModule enables Buf config proto dependencies update.
// This option updates app's Buf config when proto packages or
// Buf modules are found within the Go dependencies.
func UpdateBufModule() Option {
return func(o *generateOptions) {
o.updateBufModule = true
}
}
// CollectEvents sets an event bus for sending generation feedback events.
func CollectEvents(ev events.Bus) Option {
return func(c *generateOptions) {
c.ev = ev
}
}
// generator generates code for sdk and sdk apps.
type generator struct {
buf cosmosbuf.Buf
cacheStorage cache.Storage
appPath string
protoDir string
goModPath string
frontendPath string
opts *generateOptions
sdkImport string
sdkDir string
deps []gomodule.Version
appModules []module.Module
appIncludes protoIncludes
thirdModules map[string][]module.Module
thirdModuleIncludes map[string]protoIncludes
tmpDirs []string
// caches to avoid repeated operations
bufPathCache map[string]string
bufExportCache map[string]string
bufConfigCache map[string]struct{ Name string }
}
func (g *generator) cleanup() {
// Remove temporary directories created during generation
for _, path := range g.tmpDirs {
_ = os.RemoveAll(path)
}
}
// Generate generates code from protoDir of an SDK app residing at appPath with given options.
// protoDir must be relative to the projectPath.
func Generate(ctx context.Context, cacheStorage cache.Storage, appPath, protoDir, goModPath string, frontendPath string, options ...Option) error {
buf, err := cosmosbuf.New(cacheStorage, goModPath)
if err != nil {
return err
}
g := &generator{
buf: buf,
appPath: appPath,
protoDir: protoDir,
goModPath: goModPath,
frontendPath: frontendPath,
opts: &generateOptions{},
thirdModules: make(map[string][]module.Module),
thirdModuleIncludes: make(map[string]protoIncludes),
cacheStorage: cacheStorage,
bufPathCache: make(map[string]string),
bufExportCache: make(map[string]string),
bufConfigCache: make(map[string]struct{ Name string }),
}
defer g.cleanup()
for _, apply := range options {
apply(g.opts)
}
if err := g.setup(ctx); err != nil {
return err
}
// Update app's Buf config for third party discovered proto modules.
// Go dependency packages might contain proto files which could also
// optionally be using Buf, so for those cases the discovered proto
// files should be available before code generation.
if g.opts.updateBufModule {
if err := g.updateBufModule(ctx); err != nil {
return err
}
}
// Go generation must run first so the types are created before other
// generated code that requires sdk.Msg implementations to be defined
if g.opts.generateProtobuf {
if err := g.generateGoGo(ctx); err != nil {
return err
}
}
if g.opts.openAPISpecOut != "" {
if err := g.generateOpenAPISpec(ctx, g.opts.openAPIExcludeList...); err != nil {
return err
}
}
if g.opts.jsOut != nil {
if err := g.generateTS(ctx); err != nil {
return err
}
}
if g.opts.composablesRootPath != "" {
if err := g.generateComposables(); err != nil {
return err
}
// Update Vue app dependencies when Vue composables are generated.
// This update is required to link the "ts-client" folder so the
// package is available during development before publishing it.
if err := g.updateComposableDependencies(); err != nil {
return err
}
}
return nil
}
// TypescriptModulePath generates TS module paths for Cosmos SDK modules.
// The root path is used as prefix for the generated paths.
func TypescriptModulePath(rootPath string) ModulePathFunc {
return func(m module.Module) string {
return filepath.Join(rootPath, m.Pkg.Name)
}
}
// ComposableModulePath generates useQuery hook/composable module paths for Cosmos SDK modules.
// The root path is used as prefix for the generated paths.
func ComposableModulePath(rootPath string) ModulePathFunc {
return func(m module.Module) string {
replacer := strings.NewReplacer("-", "_", ".", "_")
modPath := strcase.ToCamel(replacer.Replace(m.Pkg.Name))
return filepath.Join(rootPath, "use"+modPath)
}
}