From 2ad41ee31f9b6dc8550cca5d61c89df6c351e524 Mon Sep 17 00:00:00 2001 From: Danilo Pantani Date: Thu, 28 Mar 2024 22:16:49 +0100 Subject: [PATCH] feat(pkg): improve xgenny dry run (#4001) * run all dry runners before the we runners for the xgenny pkg * add changelog * Improve `xgenny` dry run * replace the last wet runners * create RunAndApply runner function * remove unused parameters from scaffold functions and fix wrong path for scaffold chain * run go mod tidy before go fmt * bump buf build * fix golden files for apps tests * create the runner target path if not exist * update go.mod * fix lint issue * fix doctor absolute path * re-organize xgenny pkg * fix lint warning --------- Co-authored-by: Pantani --- changelog.md | 1 + go.mod | 2 +- ignite/cmd/chain.go | 4 +- ignite/cmd/scaffold.go | 12 +- ignite/cmd/scaffold_chain.go | 26 +++- ignite/cmd/scaffold_configs.go | 12 +- ignite/cmd/scaffold_message.go | 12 +- ignite/cmd/scaffold_module.go | 39 ++--- ...scaffold_package.go => scaffold_packet.go} | 12 +- ignite/cmd/scaffold_params.go | 12 +- ignite/cmd/scaffold_query.go | 12 +- ignite/pkg/xgenny/run.go | 106 ------------- ignite/pkg/xgenny/runner.go | 144 ++++++++++++++++++ ignite/pkg/xgenny/{xgenny.go => walker.go} | 23 ++- .../xgenny/{xgenny_test.go => walker_test.go} | 0 ignite/services/chain/init.go | 2 +- ignite/services/chain/proto.go | 5 +- ignite/services/doctor/doctor.go | 18 +-- ignite/services/plugin/scaffold.go | 11 +- ignite/services/scaffolder/configs.go | 31 +--- ignite/services/scaffolder/init.go | 94 +++++------- ignite/services/scaffolder/message.go | 38 ++--- ignite/services/scaffolder/module.go | 52 +++---- ignite/services/scaffolder/packet.go | 39 ++--- ignite/services/scaffolder/params.go | 31 +--- ignite/services/scaffolder/query.go | 32 ++-- ignite/services/scaffolder/scaffolder.go | 36 ++++- ignite/services/scaffolder/type.go | 40 ++--- 28 files changed, 416 insertions(+), 430 deletions(-) rename ignite/cmd/{scaffold_package.go => scaffold_packet.go} (86%) delete mode 100644 ignite/pkg/xgenny/run.go create mode 100644 ignite/pkg/xgenny/runner.go rename ignite/pkg/xgenny/{xgenny.go => walker.go} (78%) rename ignite/pkg/xgenny/{xgenny_test.go => walker_test.go} (100%) diff --git a/changelog.md b/changelog.md index 0e9bf9fcfb..b21bef4cdc 100644 --- a/changelog.md +++ b/changelog.md @@ -7,6 +7,7 @@ - [#3707](https://github.com/ignite/cli/pull/3707) Add collections support. - [#3977](https://github.com/ignite/cli/pull/3977) Add `chain lint` command to lint the chain's codebase using `golangci-lint` - [#3770](https://github.com/ignite/cli/pull/3770) Add `scaffold configs` and `scaffold params` commands +- [#4001](https://github.com/ignite/cli/pull/4001) Improve `xgenny` dry run - [#3967](https://github.com/ignite/cli/issues/3967) Add HD wallet parameters `address index` and `account number` to the chain account config - [#4004](https://github.com/ignite/cli/pull/4004) Remove all import placeholders using the `xast` pkg diff --git a/go.mod b/go.mod index 31539ae5ba..42a5b2c8b8 100644 --- a/go.mod +++ b/go.mod @@ -43,7 +43,6 @@ require ( github.com/go-delve/delve v1.21.0 github.com/go-git/go-git/v5 v5.11.0 github.com/gobuffalo/genny/v2 v2.1.0 - github.com/gobuffalo/logger v1.0.7 github.com/gobuffalo/packd v1.0.2 github.com/gobuffalo/plush/v4 v4.1.19 github.com/goccy/go-yaml v1.11.2 @@ -243,6 +242,7 @@ require ( github.com/gobuffalo/flect v0.3.0 // indirect github.com/gobuffalo/github_flavored_markdown v1.1.4 // indirect github.com/gobuffalo/helpers v0.6.7 // indirect + github.com/gobuffalo/logger v1.0.7 // indirect github.com/gobuffalo/tags/v3 v3.1.4 // indirect github.com/gobuffalo/validate/v3 v3.3.3 // indirect github.com/gobwas/glob v0.2.3 // indirect diff --git a/ignite/cmd/chain.go b/ignite/cmd/chain.go index 6d157500f4..0ca7bb989a 100644 --- a/ignite/cmd/chain.go +++ b/ignite/cmd/chain.go @@ -19,6 +19,7 @@ import ( "github.com/ignite/cli/v29/ignite/pkg/goanalysis" "github.com/ignite/cli/v29/ignite/pkg/gomodulepath" "github.com/ignite/cli/v29/ignite/pkg/xast" + "github.com/ignite/cli/v29/ignite/pkg/xgenny" "github.com/ignite/cli/v29/ignite/services/chain" "github.com/ignite/cli/v29/ignite/services/doctor" ) @@ -201,7 +202,8 @@ func bufMigrationPreRunHandler(cmd *cobra.Command, session *cliui.Session, appPa } } - sm, err := chain.BoxBufFiles(appPath) + runner := xgenny.NewRunner(cmd.Context(), appPath) + sm, err := chain.BoxBufFiles(runner, appPath) if err != nil { return err } diff --git a/ignite/cmd/scaffold.go b/ignite/cmd/scaffold.go index 625dcddea1..198f59b7c8 100644 --- a/ignite/cmd/scaffold.go +++ b/ignite/cmd/scaffold.go @@ -11,8 +11,6 @@ import ( "github.com/ignite/cli/v29/ignite/pkg/cosmosver" "github.com/ignite/cli/v29/ignite/pkg/errors" "github.com/ignite/cli/v29/ignite/pkg/gomodulepath" - "github.com/ignite/cli/v29/ignite/pkg/placeholder" - "github.com/ignite/cli/v29/ignite/pkg/xgenny" "github.com/ignite/cli/v29/ignite/pkg/xgit" "github.com/ignite/cli/v29/ignite/services/scaffolder" "github.com/ignite/cli/v29/ignite/version" @@ -208,7 +206,7 @@ func scaffoldType( session := cliui.New(cliui.StartSpinnerWithText(statusScaffolding)) defer session.End() - sc, err := scaffolder.New(appPath) + sc, err := scaffolder.New(cmd.Context(), appPath) if err != nil { return err } @@ -218,16 +216,20 @@ func scaffoldType( return err } - sm, err := sc.AddType(cmd.Context(), cacheStorage, typeName, placeholder.New(), kind, options...) + err = sc.AddType(cmd.Context(), typeName, kind, options...) if err != nil { return err } - modificationsStr, err := xgenny.SourceModificationToString(sm) + modificationsStr, err := sc.ApplyModifications() if err != nil { return err } + if err := sc.PostScaffold(cmd.Context(), cacheStorage, false); err != nil { + return err + } + session.Println(modificationsStr) session.Printf("\nšŸŽ‰ %s added. \n\n", typeName) diff --git a/ignite/cmd/scaffold_chain.go b/ignite/cmd/scaffold_chain.go index 5e9c8f066a..480e343f53 100644 --- a/ignite/cmd/scaffold_chain.go +++ b/ignite/cmd/scaffold_chain.go @@ -5,8 +5,9 @@ import ( "github.com/ignite/cli/v29/ignite/pkg/cliui" "github.com/ignite/cli/v29/ignite/pkg/errors" - "github.com/ignite/cli/v29/ignite/pkg/placeholder" "github.com/ignite/cli/v29/ignite/pkg/xfilepath" + "github.com/ignite/cli/v29/ignite/pkg/xgenny" + "github.com/ignite/cli/v29/ignite/pkg/xgit" "github.com/ignite/cli/v29/ignite/services/scaffolder" ) @@ -123,16 +124,14 @@ func scaffoldChainHandler(cmd *cobra.Command, args []string) error { return err } - appDir, err := scaffolder.Init( + runner := xgenny.NewRunner(cmd.Context(), appPath) + appDir, goModule, err := scaffolder.Init( cmd.Context(), - cacheStorage, - placeholder.New(), + runner, appPath, name, addressPrefix, noDefaultModule, - skipGit, - skipProto, minimal, isConsumer, params, @@ -147,5 +146,20 @@ func scaffoldChainHandler(cmd *cobra.Command, args []string) error { return err } + if _, err := runner.ApplyModifications(); err != nil { + return err + } + + if err := scaffolder.PostScaffold(cmd.Context(), cacheStorage, appDir, goModule, skipProto); err != nil { + return err + } + + if !skipGit { + // Initialize git repository and perform the first commit + if err := xgit.InitAndCommit(path); err != nil { + return err + } + } + return session.Printf(tplScaffoldChainSuccess, path) } diff --git a/ignite/cmd/scaffold_configs.go b/ignite/cmd/scaffold_configs.go index c07ecf1c6e..ced6093772 100644 --- a/ignite/cmd/scaffold_configs.go +++ b/ignite/cmd/scaffold_configs.go @@ -6,8 +6,6 @@ import ( "github.com/spf13/cobra" "github.com/ignite/cli/v29/ignite/pkg/cliui" - "github.com/ignite/cli/v29/ignite/pkg/placeholder" - "github.com/ignite/cli/v29/ignite/pkg/xgenny" "github.com/ignite/cli/v29/ignite/services/scaffolder" ) @@ -58,21 +56,25 @@ func scaffoldConfigsHandler(cmd *cobra.Command, args []string) error { return err } - sc, err := scaffolder.New(appPath) + sc, err := scaffolder.New(cmd.Context(), appPath) if err != nil { return err } - sm, err := sc.CreateConfigs(cmd.Context(), cacheStorage, placeholder.New(), moduleName, configs...) + err = sc.CreateConfigs(moduleName, configs...) if err != nil { return err } - modificationsStr, err := xgenny.SourceModificationToString(sm) + modificationsStr, err := sc.ApplyModifications() if err != nil { return err } + if err := sc.PostScaffold(cmd.Context(), cacheStorage, false); err != nil { + return err + } + session.Println(modificationsStr) session.Printf("\nšŸŽ‰ New configs added to the module:\n\n- %s\n\n", strings.Join(configs, "\n- ")) diff --git a/ignite/cmd/scaffold_message.go b/ignite/cmd/scaffold_message.go index f228e3750b..7f2d66c59c 100644 --- a/ignite/cmd/scaffold_message.go +++ b/ignite/cmd/scaffold_message.go @@ -4,8 +4,6 @@ import ( "github.com/spf13/cobra" "github.com/ignite/cli/v29/ignite/pkg/cliui" - "github.com/ignite/cli/v29/ignite/pkg/placeholder" - "github.com/ignite/cli/v29/ignite/pkg/xgenny" "github.com/ignite/cli/v29/ignite/services/scaffolder" ) @@ -115,21 +113,25 @@ func messageHandler(cmd *cobra.Command, args []string) error { options = append(options, scaffolder.WithoutSimulation()) } - sc, err := scaffolder.New(appPath) + sc, err := scaffolder.New(cmd.Context(), appPath) if err != nil { return err } - sm, err := sc.AddMessage(cmd.Context(), cacheStorage, placeholder.New(), module, args[0], args[1:], resFields, options...) + err = sc.AddMessage(cmd.Context(), module, args[0], args[1:], resFields, options...) if err != nil { return err } - modificationsStr, err := xgenny.SourceModificationToString(sm) + modificationsStr, err := sc.ApplyModifications() if err != nil { return err } + if err := sc.PostScaffold(cmd.Context(), cacheStorage, false); err != nil { + return err + } + session.Println(modificationsStr) session.Printf("\nšŸŽ‰ Created a message `%[1]v`.\n\n", args[0]) diff --git a/ignite/cmd/scaffold_module.go b/ignite/cmd/scaffold_module.go index 9d9b63d115..61437d1e0f 100644 --- a/ignite/cmd/scaffold_module.go +++ b/ignite/cmd/scaffold_module.go @@ -10,9 +10,7 @@ import ( "github.com/ignite/cli/v29/ignite/pkg/cliui" "github.com/ignite/cli/v29/ignite/pkg/errors" - "github.com/ignite/cli/v29/ignite/pkg/placeholder" "github.com/ignite/cli/v29/ignite/pkg/validation" - "github.com/ignite/cli/v29/ignite/pkg/xgenny" "github.com/ignite/cli/v29/ignite/services/scaffolder" modulecreate "github.com/ignite/cli/v29/ignite/templates/module/create" ) @@ -29,14 +27,6 @@ const ( flagModuleConfigs = "module-configs" flagIBCOrdering = "ordering" flagRequireRegistration = "require-registration" - - govDependencyWarning = `āš ļø If your app has been scaffolded with Ignite CLI 0.16.x or below -Please make sure that your module keeper definition is defined after gov module keeper definition in app/app.go: - -app.GovKeeper = ... -... -[your module keeper definition] -` ) // NewScaffoldModule returns the command to scaffold a Cosmos SDK module. @@ -181,13 +171,12 @@ func scaffoldModuleHandler(cmd *cobra.Command, args []string) error { var msg bytes.Buffer fmt.Fprintf(&msg, "\nšŸŽ‰ Module created %s.\n\n", name) - sc, err := scaffolder.New(appPath) + sc, err := scaffolder.New(cmd.Context(), appPath) if err != nil { return err } - sm, err := sc.CreateModule(cmd.Context(), cacheStorage, placeholder.New(), name, options...) - if err != nil { + if err := sc.CreateModule(name, options...); err != nil { var validationErr validation.Error if !requireRegistration && errors.As(err, &validationErr) { fmt.Fprintf(&msg, "Can't register module '%s'.\n", name) @@ -195,25 +184,17 @@ func scaffoldModuleHandler(cmd *cobra.Command, args []string) error { } else { return err } - } else { - modificationsStr, err := xgenny.SourceModificationToString(sm) - if err != nil { - return err - } - - session.Println(modificationsStr) + } + modificationsStr, err := sc.ApplyModifications() + if err != nil { + return err } - // in previously scaffolded apps gov keeper is defined below the scaffolded module keeper definition - // therefore we must warn the user to manually move the definition if it's the case - // https://github.com/ignite/cli/issues/818#issuecomment-865736052 - for _, name := range dependencies { - if name == "Gov" { - session.Print(govDependencyWarning) - - break - } + if err := sc.PostScaffold(cmd.Context(), cacheStorage, false); err != nil { + return err } + session.Println(modificationsStr) + return session.Print(msg.String()) } diff --git a/ignite/cmd/scaffold_package.go b/ignite/cmd/scaffold_packet.go similarity index 86% rename from ignite/cmd/scaffold_package.go rename to ignite/cmd/scaffold_packet.go index 3c6267244e..46fad7610d 100644 --- a/ignite/cmd/scaffold_package.go +++ b/ignite/cmd/scaffold_packet.go @@ -5,8 +5,6 @@ import ( "github.com/ignite/cli/v29/ignite/pkg/cliui" "github.com/ignite/cli/v29/ignite/pkg/errors" - "github.com/ignite/cli/v29/ignite/pkg/placeholder" - "github.com/ignite/cli/v29/ignite/pkg/xgenny" "github.com/ignite/cli/v29/ignite/services/scaffolder" ) @@ -68,21 +66,25 @@ func createPacketHandler(cmd *cobra.Command, args []string) error { options = append(options, scaffolder.PacketWithSigner(signer)) } - sc, err := scaffolder.New(appPath) + sc, err := scaffolder.New(cmd.Context(), appPath) if err != nil { return err } - sm, err := sc.AddPacket(cmd.Context(), cacheStorage, placeholder.New(), module, packet, packetFields, ackFields, options...) + err = sc.AddPacket(cmd.Context(), module, packet, packetFields, ackFields, options...) if err != nil { return err } - modificationsStr, err := xgenny.SourceModificationToString(sm) + modificationsStr, err := sc.ApplyModifications() if err != nil { return err } + if err := sc.PostScaffold(cmd.Context(), cacheStorage, false); err != nil { + return err + } + session.Println(modificationsStr) session.Printf("\nšŸŽ‰ Created a packet `%[1]v`.\n\n", args[0]) diff --git a/ignite/cmd/scaffold_params.go b/ignite/cmd/scaffold_params.go index df1992a71f..e1aa27671c 100644 --- a/ignite/cmd/scaffold_params.go +++ b/ignite/cmd/scaffold_params.go @@ -6,8 +6,6 @@ import ( "github.com/spf13/cobra" "github.com/ignite/cli/v29/ignite/pkg/cliui" - "github.com/ignite/cli/v29/ignite/pkg/placeholder" - "github.com/ignite/cli/v29/ignite/pkg/xgenny" "github.com/ignite/cli/v29/ignite/services/scaffolder" ) @@ -60,21 +58,25 @@ func scaffoldParamsHandler(cmd *cobra.Command, args []string) error { return err } - sc, err := scaffolder.New(appPath) + sc, err := scaffolder.New(cmd.Context(), appPath) if err != nil { return err } - sm, err := sc.CreateParams(cmd.Context(), cacheStorage, placeholder.New(), moduleName, params...) + err = sc.CreateParams(moduleName, params...) if err != nil { return err } - modificationsStr, err := xgenny.SourceModificationToString(sm) + modificationsStr, err := sc.ApplyModifications() if err != nil { return err } + if err := sc.PostScaffold(cmd.Context(), cacheStorage, false); err != nil { + return err + } + session.Println(modificationsStr) session.Printf("\nšŸŽ‰ New parameters added to the module:\n\n- %s\n\n", strings.Join(params, "\n- ")) diff --git a/ignite/cmd/scaffold_query.go b/ignite/cmd/scaffold_query.go index 39595f93d6..22ffcd90a4 100644 --- a/ignite/cmd/scaffold_query.go +++ b/ignite/cmd/scaffold_query.go @@ -6,8 +6,6 @@ import ( "github.com/spf13/cobra" "github.com/ignite/cli/v29/ignite/pkg/cliui" - "github.com/ignite/cli/v29/ignite/pkg/placeholder" - "github.com/ignite/cli/v29/ignite/pkg/xgenny" "github.com/ignite/cli/v29/ignite/services/scaffolder" ) @@ -66,21 +64,25 @@ func queryHandler(cmd *cobra.Command, args []string) error { return err } - sc, err := scaffolder.New(appPath) + sc, err := scaffolder.New(cmd.Context(), appPath) if err != nil { return err } - sm, err := sc.AddQuery(cmd.Context(), cacheStorage, placeholder.New(), module, args[0], desc, args[1:], resFields, paginated) + err = sc.AddQuery(cmd.Context(), module, args[0], desc, args[1:], resFields, paginated) if err != nil { return err } - modificationsStr, err := xgenny.SourceModificationToString(sm) + modificationsStr, err := sc.ApplyModifications() if err != nil { return err } + if err := sc.PostScaffold(cmd.Context(), cacheStorage, false); err != nil { + return err + } + session.Println(modificationsStr) session.Printf("\nšŸŽ‰ Created a query `%[1]v`.\n\n", args[0]) diff --git a/ignite/pkg/xgenny/run.go b/ignite/pkg/xgenny/run.go deleted file mode 100644 index c7a898a264..0000000000 --- a/ignite/pkg/xgenny/run.go +++ /dev/null @@ -1,106 +0,0 @@ -package xgenny - -import ( - "context" - "os" - "strings" - - "github.com/gobuffalo/genny/v2" - "github.com/gobuffalo/logger" - "github.com/gobuffalo/packd" - - "github.com/ignite/cli/v29/ignite/pkg/errors" - "github.com/ignite/cli/v29/ignite/pkg/placeholder" - "github.com/ignite/cli/v29/ignite/pkg/validation" -) - -var _ validation.Error = (*dryRunError)(nil) - -type dryRunError struct { - error -} - -// ValidationInfo returns validation info. -func (d *dryRunError) ValidationInfo() string { - return d.Error() -} - -// DryRunner is a genny DryRunner with a logger. -func DryRunner(ctx context.Context) *genny.Runner { - runner := genny.DryRunner(ctx) - runner.Logger = logger.New(genny.DefaultLogLvl) - return runner -} - -// RunWithValidation checks the generators with a dry run and then execute the wet runner to the generators. -func RunWithValidation( - tracer *placeholder.Tracer, - gens ...*genny.Generator, -) (sm SourceModification, err error) { - // run executes the provided runner with the provided generator - run := func(runner *genny.Runner, gens []*genny.Generator) error { - for _, gen := range gens { - if err := runner.With(gen); err != nil { - return err - } - if err := runner.Run(); err != nil { - return err - } - } - return nil - } - // check with a dry runner the generators - dryRunner := DryRunner(context.Background()) - if err := run(dryRunner, gens); err != nil { - if errors.Is(err, os.ErrNotExist) { - return sm, &dryRunError{err} - } - return sm, err - } - if err := tracer.Err(); err != nil { - return sm, err - } - - // fetch the source modification - sm = NewSourceModification() - for _, file := range dryRunner.Results().Files { - fileName := file.Name() - _, err := os.Stat(fileName) - - //nolint:gocritic - if os.IsNotExist(err) { - // if the file doesn't exist in the source, it means it has been created by the runner - sm.AppendCreatedFiles(fileName) - } else if err != nil { - return sm, err - } else { - // the file has been modified by the runner - sm.AppendModifiedFiles(fileName) - } - } - - // execute the modification with a wet runner - if err := run(genny.WetRunner(context.Background()), gens); err != nil { - return sm, err - } - return sm, nil -} - -// Box will mount each file in the Box and wrap it, already existing files are ignored. -func Box(g *genny.Generator, box packd.Walker) error { - return box.Walk(func(path string, bf packd.File) error { - f := genny.NewFile(path, bf) - f, err := g.Transform(f) - if err != nil { - return err - } - filePath := strings.TrimSuffix(f.Name(), ".plush") - _, err = os.Stat(filePath) - if os.IsNotExist(err) { - // path doesn't exist. move on. - g.File(f) - return nil - } - return err - }) -} diff --git a/ignite/pkg/xgenny/runner.go b/ignite/pkg/xgenny/runner.go new file mode 100644 index 0000000000..5b7e2de0fb --- /dev/null +++ b/ignite/pkg/xgenny/runner.go @@ -0,0 +1,144 @@ +package xgenny + +import ( + "context" + "io" + "os" + "path/filepath" + + "github.com/gobuffalo/genny/v2" + + "github.com/ignite/cli/v29/ignite/pkg/placeholder" + "github.com/ignite/cli/v29/ignite/pkg/randstr" + "github.com/ignite/cli/v29/ignite/pkg/xos" +) + +type Runner struct { + *genny.Runner + ctx context.Context + tracer *placeholder.Tracer + results []genny.File + tmpPath string +} + +// NewRunner is a xgenny Runner with a logger. +func NewRunner(ctx context.Context, appPath string) *Runner { + var ( + runner = genny.WetRunner(ctx) + tmpPath = filepath.Join(os.TempDir(), randstr.Runes(5)) + ) + runner.Root = appPath + r := &Runner{ + ctx: ctx, + Runner: runner, + tmpPath: tmpPath, + tracer: placeholder.New(), + results: make([]genny.File, 0), + } + runner.FileFn = func(f genny.File) (genny.File, error) { + return wetFileFn(r, f) + } + return r +} + +func (r *Runner) Tracer() *placeholder.Tracer { + return r.tracer +} + +// ApplyModifications copy all modifications from the temporary folder to the target path. +func (r *Runner) ApplyModifications() (SourceModification, error) { + // fetch the source modification + sm := NewSourceModification() + for _, file := range r.results { + fileName := file.Name() + _, err := os.Stat(fileName) + switch { + case os.IsNotExist(err): + sm.AppendCreatedFiles(fileName) // if the file doesn't exist in the source, it means it has been created by the runner + case err != nil: + return sm, err + default: + sm.AppendModifiedFiles(fileName) // the file has been modified by the runner + } + } + r.results = make([]genny.File, 0) + + if _, err := os.Stat(r.tmpPath); os.IsNotExist(err) { + return sm, nil + } + + // Create the target path and copy the content from the temporary folder. + if err := os.MkdirAll(r.Root, os.ModePerm); err != nil { + return sm, nil + } + err := xos.CopyFolder(r.tmpPath, r.Root) + if err != nil { + return sm, nil + } + + return sm, os.RemoveAll(r.tmpPath) +} + +// RunAndApply run the generators and apply the modifications to the target path. +func (r *Runner) RunAndApply(gens ...*genny.Generator) (SourceModification, error) { + if err := r.Run(gens...); err != nil { + return SourceModification{}, err + } + return r.ApplyModifications() +} + +// Run all generators into a temp folder for we can apply the modifications later. +func (r *Runner) Run(gens ...*genny.Generator) error { + // execute the modification with a wet runner + for _, gen := range gens { + if err := r.With(gen); err != nil { + return err + } + if err := r.Runner.Run(); err != nil { + return err + } + } + r.results = append(r.results, r.Results().Files...) + return r.tracer.Err() +} + +func wetFileFn(runner *Runner, f genny.File) (genny.File, error) { + if d, ok := f.(genny.Dir); ok { + if err := os.MkdirAll(d.Name(), d.Perm); err != nil { + return f, err + } + return d, nil + } + + var err error + if !filepath.IsAbs(runner.Root) { + runner.Root, err = filepath.Abs(runner.Root) + if err != nil { + return f, err + } + } + + name := f.Name() + if !filepath.IsAbs(name) { + name = filepath.Join(runner.Root, name) + } + relPath, err := filepath.Rel(runner.Root, name) + if err != nil { + return f, err + } + + dstPath := filepath.Join(runner.tmpPath, relPath) + dir := filepath.Dir(dstPath) + if err := os.MkdirAll(dir, 0o755); err != nil { + return f, err + } + ff, err := os.Create(dstPath) + if err != nil { + return f, err + } + defer ff.Close() + if _, err := io.Copy(ff, f); err != nil { + return f, err + } + return f, nil +} diff --git a/ignite/pkg/xgenny/xgenny.go b/ignite/pkg/xgenny/walker.go similarity index 78% rename from ignite/pkg/xgenny/xgenny.go rename to ignite/pkg/xgenny/walker.go index b5bc544ae4..9746b0f8c7 100644 --- a/ignite/pkg/xgenny/xgenny.go +++ b/ignite/pkg/xgenny/walker.go @@ -3,13 +3,13 @@ package xgenny import ( "bytes" "embed" + "os" "path/filepath" "strings" "github.com/gobuffalo/genny/v2" - "github.com/gobuffalo/plush/v4" - "github.com/gobuffalo/packd" + "github.com/gobuffalo/plush/v4" "github.com/ignite/cli/v29/ignite/pkg/errors" ) @@ -69,6 +69,25 @@ func (w Walker) walkDir(wl packd.WalkFunc, path string) error { return nil } +// Box will mount each file in the Box and wrap it, already existing files are ignored. +func Box(g *genny.Generator, box packd.Walker) error { + return box.Walk(func(path string, bf packd.File) error { + f := genny.NewFile(path, bf) + f, err := g.Transform(f) + if err != nil { + return err + } + filePath := strings.TrimSuffix(f.Name(), ".plush") + _, err = os.Stat(filePath) + if os.IsNotExist(err) { + // Path doesn't exist. move on. + g.File(f) + return nil + } + return err + }) +} + // Transformer will plush-ify any file that has a ".plush" extension. func Transformer(ctx *plush.Context) genny.Transformer { t := genny.NewTransformer(".plush", func(f genny.File) (genny.File, error) { diff --git a/ignite/pkg/xgenny/xgenny_test.go b/ignite/pkg/xgenny/walker_test.go similarity index 100% rename from ignite/pkg/xgenny/xgenny_test.go rename to ignite/pkg/xgenny/walker_test.go diff --git a/ignite/services/chain/init.go b/ignite/services/chain/init.go index ea89936f63..863b58c6b0 100644 --- a/ignite/services/chain/init.go +++ b/ignite/services/chain/init.go @@ -9,7 +9,7 @@ import ( "github.com/imdario/mergo" chainconfig "github.com/ignite/cli/v29/ignite/config/chain" - "github.com/ignite/cli/v29/ignite/internal/plugin" + plugininternal "github.com/ignite/cli/v29/ignite/internal/plugin" chaincmdrunner "github.com/ignite/cli/v29/ignite/pkg/chaincmd/runner" "github.com/ignite/cli/v29/ignite/pkg/cliui/view/accountview" "github.com/ignite/cli/v29/ignite/pkg/confile" diff --git a/ignite/services/chain/proto.go b/ignite/services/chain/proto.go index cb458ed64e..a38abb7375 100644 --- a/ignite/services/chain/proto.go +++ b/ignite/services/chain/proto.go @@ -3,7 +3,6 @@ package chain import ( "path/filepath" - "github.com/ignite/cli/v29/ignite/pkg/placeholder" "github.com/ignite/cli/v29/ignite/pkg/xgenny" "github.com/ignite/cli/v29/ignite/pkg/xos" "github.com/ignite/cli/v29/ignite/templates/app" @@ -28,10 +27,10 @@ func CheckBufFiles(appPath string) bool { return true } -func BoxBufFiles(appPath string) (xgenny.SourceModification, error) { +func BoxBufFiles(runner *xgenny.Runner, appPath string) (xgenny.SourceModification, error) { g, err := app.NewBufGenerator(appPath) if err != nil { return xgenny.SourceModification{}, err } - return xgenny.RunWithValidation(placeholder.New(), g) + return runner.RunAndApply(g) } diff --git a/ignite/services/doctor/doctor.go b/ignite/services/doctor/doctor.go index be49d67490..ca18adba00 100644 --- a/ignite/services/doctor/doctor.go +++ b/ignite/services/doctor/doctor.go @@ -7,8 +7,6 @@ import ( "os" "path" - "github.com/gobuffalo/genny/v2" - chainconfig "github.com/ignite/cli/v29/ignite/config/chain" "github.com/ignite/cli/v29/ignite/pkg/cliui/colors" "github.com/ignite/cli/v29/ignite/pkg/cliui/icons" @@ -18,6 +16,7 @@ import ( "github.com/ignite/cli/v29/ignite/pkg/goanalysis" "github.com/ignite/cli/v29/ignite/pkg/gomodulepath" "github.com/ignite/cli/v29/ignite/pkg/xast" + "github.com/ignite/cli/v29/ignite/pkg/xgenny" "github.com/ignite/cli/v29/ignite/templates/app" ) @@ -161,7 +160,12 @@ func (d *Doctor) FixDependencyTools(ctx context.Context) error { } func (d Doctor) createToolsFile(ctx context.Context, toolsFilename string) error { - pathInfo, err := gomodulepath.ParseAt(".") + absPath, err := os.Getwd() + if err != nil { + return err + } + + pathInfo, err := gomodulepath.ParseAt(absPath) if err != nil { return err } @@ -176,12 +180,8 @@ func (d Doctor) createToolsFile(ctx context.Context, toolsFilename string) error return err } - runner := genny.WetRunner(ctx) - if err := runner.With(g); err != nil { - return err - } - - if err := runner.Run(); err != nil { + runner := xgenny.NewRunner(ctx, absPath) + if _, err := runner.RunAndApply(g); err != nil { return err } diff --git a/ignite/services/plugin/scaffold.go b/ignite/services/plugin/scaffold.go index da682fc5ce..d9bbe41181 100644 --- a/ignite/services/plugin/scaffold.go +++ b/ignite/services/plugin/scaffold.go @@ -51,14 +51,9 @@ func Scaffold(ctx context.Context, dir, appName string, sharedHost bool) (string pctx.Set("SharedHost", sharedHost) g.Transformer(xgenny.Transformer(pctx)) - r := genny.WetRunner(ctx) - err := r.With(g) - if err != nil { - return "", errors.WithStack(err) - } - - if err := r.Run(); err != nil { - return "", errors.WithStack(err) + r := xgenny.NewRunner(ctx, finalDir) + if _, err := r.RunAndApply(g); err != nil { + return "", err } if err := gocmd.ModTidy(ctx, finalDir); err != nil { diff --git a/ignite/services/scaffolder/configs.go b/ignite/services/scaffolder/configs.go index 566f8c846b..7115187d4d 100644 --- a/ignite/services/scaffolder/configs.go +++ b/ignite/services/scaffolder/configs.go @@ -1,30 +1,21 @@ package scaffolder import ( - "context" "path/filepath" "strings" - "github.com/gobuffalo/genny/v2" - - "github.com/ignite/cli/v29/ignite/pkg/cache" "github.com/ignite/cli/v29/ignite/pkg/errors" "github.com/ignite/cli/v29/ignite/pkg/goanalysis" "github.com/ignite/cli/v29/ignite/pkg/multiformatname" - "github.com/ignite/cli/v29/ignite/pkg/placeholder" - "github.com/ignite/cli/v29/ignite/pkg/xgenny" "github.com/ignite/cli/v29/ignite/templates/field" modulecreate "github.com/ignite/cli/v29/ignite/templates/module/create" ) // CreateConfigs creates a new configs in the scaffolded module. func (s Scaffolder) CreateConfigs( - ctx context.Context, - cacheStorage cache.Storage, - tracer *placeholder.Tracer, moduleName string, configs ...string, -) (sm xgenny.SourceModification, err error) { +) error { appName := s.modpath.Package // If no module is provided, we add the type to the app's module if moduleName == "" { @@ -32,27 +23,27 @@ func (s Scaffolder) CreateConfigs( } mfName, err := multiformatname.NewName(moduleName, multiformatname.NoNumber) if err != nil { - return sm, err + return err } moduleName = mfName.LowerCase // Check if the module already exist ok, err := moduleExists(s.path, moduleName) if err != nil { - return sm, err + return err } if !ok { - return sm, errors.Errorf("the module %v not exist", moduleName) + return errors.Errorf("the module %v not exist", moduleName) } if err := checkConfigCreated(s.path, appName, moduleName, configs); err != nil { - return sm, err + return err } // Parse config with the associated type configsFields, err := field.ParseFields(configs, checkForbiddenTypeIndex) if err != nil { - return sm, err + return err } opts := modulecreate.ConfigsOptions{ @@ -64,16 +55,10 @@ func (s Scaffolder) CreateConfigs( g, err := modulecreate.NewModuleConfigs(opts) if err != nil { - return sm, err - } - gens := []*genny.Generator{g} - - sm, err = xgenny.RunWithValidation(tracer, gens...) - if err != nil { - return sm, err + return err } - return sm, finish(ctx, cacheStorage, opts.AppPath, s.modpath.RawPath, false) + return s.Run(g) } // checkConfigCreated checks if the config has been already created. diff --git a/ignite/services/scaffolder/init.go b/ignite/services/scaffolder/init.go index 70f730dad2..f2de8e367e 100644 --- a/ignite/services/scaffolder/init.go +++ b/ignite/services/scaffolder/init.go @@ -6,13 +6,9 @@ import ( "path/filepath" "strings" - "github.com/gobuffalo/genny/v2" - - "github.com/ignite/cli/v29/ignite/pkg/cache" "github.com/ignite/cli/v29/ignite/pkg/cosmosgen" "github.com/ignite/cli/v29/ignite/pkg/gomodulepath" - "github.com/ignite/cli/v29/ignite/pkg/placeholder" - "github.com/ignite/cli/v29/ignite/pkg/xgit" + "github.com/ignite/cli/v29/ignite/pkg/xgenny" "github.com/ignite/cli/v29/ignite/templates/app" "github.com/ignite/cli/v29/ignite/templates/field" modulecreate "github.com/ignite/cli/v29/ignite/templates/module/create" @@ -22,15 +18,14 @@ import ( // Init initializes a new app with name and given options. func Init( ctx context.Context, - cacheStorage cache.Storage, - tracer *placeholder.Tracer, + runner *xgenny.Runner, root, name, addressPrefix string, - noDefaultModule, skipGit, skipProto, minimal, isConsumerChain bool, + noDefaultModule, minimal, isConsumerChain bool, params, moduleConfigs []string, -) (path string, err error) { +) (string, string, error) { pathInfo, err := gomodulepath.Parse(name) if err != nil { - return "", err + return "", "", err } // Create a new folder named as the blockchain when a custom path is not specified @@ -40,15 +35,17 @@ func Init( } if root, err = filepath.Abs(root); err != nil { - return "", err + return "", "", err } - path = filepath.Join(root, appFolder) - + var ( + path = filepath.Join(root, appFolder) + gomodule = pathInfo.RawPath + ) // create the project - if err := generate( + _, err = generate( ctx, - tracer, + runner, pathInfo, addressPrefix, path, @@ -57,44 +54,30 @@ func Init( isConsumerChain, params, moduleConfigs, - ); err != nil { - return "", err - } - - if err = finish(ctx, cacheStorage, path, pathInfo.RawPath, skipProto); err != nil { - return "", err - } - - if !skipGit { - // Initialize git repository and perform the first commit - if err := xgit.InitAndCommit(path); err != nil { - return "", err - } - } - - return path, nil + ) + return path, gomodule, err } //nolint:interfacer func generate( ctx context.Context, - tracer *placeholder.Tracer, + runner *xgenny.Runner, pathInfo gomodulepath.Path, addressPrefix, absRoot string, noDefaultModule, minimal, isConsumerChain bool, params, moduleConfigs []string, -) error { +) (xgenny.SourceModification, error) { // Parse params with the associated type paramsFields, err := field.ParseFields(params, checkForbiddenTypeIndex) if err != nil { - return err + return xgenny.SourceModification{}, err } // Parse configs with the associated type configsFields, err := field.ParseFields(moduleConfigs, checkForbiddenTypeIndex) if err != nil { - return err + return xgenny.SourceModification{}, err } githubPath := gomodulepath.ExtractAppPath(pathInfo.RawPath) @@ -115,29 +98,24 @@ func generate( IsConsumerChain: isConsumerChain, }) if err != nil { - return err + return xgenny.SourceModification{}, err } // Create the 'testutil' package with the test helpers if err := testutil.Register(g, absRoot); err != nil { - return err + return xgenny.SourceModification{}, err } - run := func(runner *genny.Runner, gen *genny.Generator) error { - if err := runner.With(gen); err != nil { - return err - } - runner.Root = absRoot - return runner.Run() - } - if err := run(genny.WetRunner(ctx), g); err != nil { - return err + // generate module template + runner.Root = absRoot + smc, err := runner.RunAndApply(g) + if err != nil { + return smc, err } if err := cosmosgen.InstallDepTools(ctx, absRoot); err != nil { - return err + return smc, err } - // generate module template if !noDefaultModule { opts := &modulecreate.CreateOptions{ ModuleName: pathInfo.Package, // App name @@ -150,21 +128,21 @@ func generate( } // Check if the module name is valid if err := checkModuleName(opts.AppPath, opts.ModuleName); err != nil { - return err + return smc, err } + g, err = modulecreate.NewGenerator(opts) if err != nil { - return err - } - if err := run(genny.WetRunner(ctx), g); err != nil { - return err - } - g = modulecreate.NewAppModify(tracer, opts) - if err := run(genny.WetRunner(ctx), g); err != nil { - return err + return smc, err } + // generate module template + smm, err := runner.RunAndApply(g, modulecreate.NewAppModify(runner.Tracer(), opts)) + if err != nil { + return smc, err + } + smc.Merge(smm) } - return nil + return smc, err } diff --git a/ignite/services/scaffolder/message.go b/ignite/services/scaffolder/message.go index 163b98a780..371df142bd 100644 --- a/ignite/services/scaffolder/message.go +++ b/ignite/services/scaffolder/message.go @@ -6,11 +6,8 @@ import ( "github.com/gobuffalo/genny/v2" - "github.com/ignite/cli/v29/ignite/pkg/cache" "github.com/ignite/cli/v29/ignite/pkg/errors" "github.com/ignite/cli/v29/ignite/pkg/multiformatname" - "github.com/ignite/cli/v29/ignite/pkg/placeholder" - "github.com/ignite/cli/v29/ignite/pkg/xgenny" "github.com/ignite/cli/v29/ignite/templates/field" "github.com/ignite/cli/v29/ignite/templates/field/datatype" "github.com/ignite/cli/v29/ignite/templates/message" @@ -59,14 +56,12 @@ func WithoutSimulation() MessageOption { // AddMessage adds a new message to scaffolded app. func (s Scaffolder) AddMessage( ctx context.Context, - cacheStorage cache.Storage, - tracer *placeholder.Tracer, moduleName, msgName string, fields, resFields []string, options ...MessageOption, -) (sm xgenny.SourceModification, err error) { +) error { // Create the options scaffoldingOpts := newMessageOptions(msgName) for _, apply := range options { @@ -79,40 +74,40 @@ func (s Scaffolder) AddMessage( } mfName, err := multiformatname.NewName(moduleName, multiformatname.NoNumber) if err != nil { - return sm, err + return err } moduleName = mfName.LowerCase name, err := multiformatname.NewName(msgName) if err != nil { - return sm, err + return err } if err := checkComponentValidity(s.path, moduleName, name, false); err != nil { - return sm, err + return err } // Check and parse provided fields if err := checkCustomTypes(ctx, s.path, s.modpath.Package, moduleName, fields); err != nil { - return sm, err + return err } parsedMsgFields, err := field.ParseFields(fields, checkForbiddenMessageField, scaffoldingOpts.signer) if err != nil { - return sm, err + return err } // Check and parse provided response fields if err := checkCustomTypes(ctx, s.path, s.modpath.Package, moduleName, resFields); err != nil { - return sm, err + return err } parsedResFields, err := field.ParseFields(resFields, checkGoReservedWord, scaffoldingOpts.signer) if err != nil { - return sm, err + return err } mfSigner, err := multiformatname.NewName(scaffoldingOpts.signer) if err != nil { - return sm, err + return err } var ( @@ -135,7 +130,7 @@ func (s Scaffolder) AddMessage( var gens []*genny.Generator gens, err = supportMsgServer( gens, - tracer, + s.Tracer(), s.path, &modulecreate.MsgServerOptions{ ModuleName: opts.ModuleName, @@ -145,20 +140,17 @@ func (s Scaffolder) AddMessage( }, ) if err != nil { - return sm, err + return err } // Scaffold - g, err = message.NewGenerator(tracer, opts) + g, err = message.NewGenerator(s.Tracer(), opts) if err != nil { - return sm, err + return err } gens = append(gens, g) - sm, err = xgenny.RunWithValidation(tracer, gens...) - if err != nil { - return sm, err - } - return sm, finish(ctx, cacheStorage, opts.AppPath, s.modpath.RawPath, false) + + return s.Run(gens...) } // checkForbiddenMessageField returns true if the name is forbidden as a message name. diff --git a/ignite/services/scaffolder/module.go b/ignite/services/scaffolder/module.go index ea54d8cc12..2173112ca0 100644 --- a/ignite/services/scaffolder/module.go +++ b/ignite/services/scaffolder/module.go @@ -1,7 +1,6 @@ package scaffolder import ( - "context" "go/token" "os" "path/filepath" @@ -28,24 +27,18 @@ import ( ibcexported "github.com/cosmos/ibc-go/v8/modules/core/exported" "github.com/gobuffalo/genny/v2" - "github.com/ignite/cli/v29/ignite/pkg/cache" appanalysis "github.com/ignite/cli/v29/ignite/pkg/cosmosanalysis/app" "github.com/ignite/cli/v29/ignite/pkg/errors" "github.com/ignite/cli/v29/ignite/pkg/multiformatname" - "github.com/ignite/cli/v29/ignite/pkg/placeholder" "github.com/ignite/cli/v29/ignite/pkg/validation" - "github.com/ignite/cli/v29/ignite/pkg/xgenny" "github.com/ignite/cli/v29/ignite/templates/field" "github.com/ignite/cli/v29/ignite/templates/module" modulecreate "github.com/ignite/cli/v29/ignite/templates/module/create" ) const ( - extrasImport = "github.com/tendermint/spm-extras" - extrasVersion = "v0.1.0" - appPkg = "app" - moduleDir = "x" - modulePkg = "module" + moduleDir = "x" + modulePkg = "module" ) var ( @@ -169,30 +162,27 @@ func WithDependencies(dependencies []modulecreate.Dependency) ModuleCreationOpti // CreateModule creates a new empty module in the scaffolded app. func (s Scaffolder) CreateModule( - ctx context.Context, - cacheStorage cache.Storage, - tracer *placeholder.Tracer, moduleName string, options ...ModuleCreationOption, -) (sm xgenny.SourceModification, err error) { +) error { mfName, err := multiformatname.NewName(moduleName, multiformatname.NoNumber) if err != nil { - return sm, err + return err } moduleName = mfName.LowerCase // Check if the module name is valid if err := checkModuleName(s.path, moduleName); err != nil { - return sm, err + return err } // Check if the module already exist ok, err := moduleExists(s.path, moduleName) if err != nil { - return sm, err + return err } if ok { - return sm, errors.Errorf("the module %v already exists", moduleName) + return errors.Errorf("the module %v already exists", moduleName) } // Apply the options @@ -204,18 +194,18 @@ func (s Scaffolder) CreateModule( // Parse params with the associated type params, err := field.ParseFields(creationOpts.params, checkForbiddenTypeIndex) if err != nil { - return sm, err + return err } // Parse configs with the associated type configs, err := field.ParseFields(creationOpts.moduleConfigs, checkForbiddenTypeIndex) if err != nil { - return sm, err + return err } // Check dependencies if err := checkDependencies(creationOpts.dependencies, s.path); err != nil { - return sm, err + return err } opts := &modulecreate.CreateOptions{ @@ -232,32 +222,26 @@ func (s Scaffolder) CreateModule( g, err := modulecreate.NewGenerator(opts) if err != nil { - return sm, err + return err } gens := []*genny.Generator{g} // Scaffold IBC module if opts.IsIBC { - g, err = modulecreate.NewIBC(tracer, opts) + g, err = modulecreate.NewIBC(s.Tracer(), opts) if err != nil { - return sm, err + return err } gens = append(gens, g) } - sm, err = xgenny.RunWithValidation(tracer, gens...) - if err != nil { - return sm, err - } + gens = append(gens, modulecreate.NewAppModify(s.Tracer(), opts)) - // Modify app.go to register the module - newSourceModification, runErr := xgenny.RunWithValidation(tracer, modulecreate.NewAppModify(tracer, opts)) - sm.Merge(newSourceModification) + err = s.Run(gens...) var validationErr validation.Error - if runErr != nil && !errors.As(runErr, &validationErr) { - return sm, runErr + if err != nil && !errors.As(err, &validationErr) { + return err } - - return sm, finish(ctx, cacheStorage, opts.AppPath, s.modpath.RawPath, false) + return nil } // moduleExists checks if the module exists in the app. diff --git a/ignite/services/scaffolder/packet.go b/ignite/services/scaffolder/packet.go index 028fc6f88b..5fba16094f 100644 --- a/ignite/services/scaffolder/packet.go +++ b/ignite/services/scaffolder/packet.go @@ -7,11 +7,8 @@ import ( "github.com/gobuffalo/genny/v2" - "github.com/ignite/cli/v29/ignite/pkg/cache" "github.com/ignite/cli/v29/ignite/pkg/errors" "github.com/ignite/cli/v29/ignite/pkg/multiformatname" - "github.com/ignite/cli/v29/ignite/pkg/placeholder" - "github.com/ignite/cli/v29/ignite/pkg/xgenny" "github.com/ignite/cli/v29/ignite/templates/field" "github.com/ignite/cli/v29/ignite/templates/field/datatype" "github.com/ignite/cli/v29/ignite/templates/ibc" @@ -54,14 +51,12 @@ func PacketWithSigner(signer string) PacketOption { // AddPacket adds a new type stype to scaffolded app by using optional type fields. func (s Scaffolder) AddPacket( ctx context.Context, - cacheStorage cache.Storage, - tracer *placeholder.Tracer, moduleName, packetName string, packetFields, ackFields []string, options ...PacketOption, -) (sm xgenny.SourceModification, err error) { +) error { // apply options. o := newPacketOptions() for _, apply := range options { @@ -70,31 +65,31 @@ func (s Scaffolder) AddPacket( mfName, err := multiformatname.NewName(moduleName, multiformatname.NoNumber) if err != nil { - return sm, err + return err } moduleName = mfName.LowerCase name, err := multiformatname.NewName(packetName) if err != nil { - return sm, err + return err } if err := checkComponentValidity(s.path, moduleName, name, o.withoutMessage); err != nil { - return sm, err + return err } mfSigner, err := multiformatname.NewName(o.signer) if err != nil { - return sm, err + return err } // Module must implement IBC ok, err := isIBCModule(s.path, moduleName) if err != nil { - return sm, err + return err } if !ok { - return sm, errors.Errorf("the module %s doesn't implement IBC module interface", moduleName) + return errors.Errorf("the module %s doesn't implement IBC module interface", moduleName) } signer := "" @@ -104,20 +99,20 @@ func (s Scaffolder) AddPacket( // Check and parse packet fields if err := checkCustomTypes(ctx, s.path, s.modpath.Package, moduleName, packetFields); err != nil { - return sm, err + return err } parsedPacketFields, err := field.ParseFields(packetFields, checkForbiddenPacketField, signer) if err != nil { - return sm, err + return err } // check and parse acknowledgment fields if err := checkCustomTypes(ctx, s.path, s.modpath.Package, moduleName, ackFields); err != nil { - return sm, err + return err } parsedAcksFields, err := field.ParseFields(ackFields, checkGoReservedWord, signer) if err != nil { - return sm, err + return err } // Generate the packet @@ -135,15 +130,11 @@ func (s Scaffolder) AddPacket( MsgSigner: mfSigner, } ) - g, err = ibc.NewPacket(tracer, opts) + g, err = ibc.NewPacket(s.Tracer(), opts) if err != nil { - return sm, err - } - sm, err = xgenny.RunWithValidation(tracer, g) - if err != nil { - return sm, err + return err } - return sm, finish(ctx, cacheStorage, opts.AppPath, s.modpath.RawPath, false) + return s.Run(g) } // isIBCModule returns true if the provided module implements the IBC module interface @@ -162,7 +153,7 @@ func isIBCModule(appPath string, moduleName string) (bool, error) { return true, err } - // check the legacy path + // check the legacy Path absPathLegacy, err := filepath.Abs(filepath.Join(appPath, moduleDir, moduleName, ibcModuleImplementation)) if err != nil { return false, err diff --git a/ignite/services/scaffolder/params.go b/ignite/services/scaffolder/params.go index 26bfdbe359..aa3bb7a8b0 100644 --- a/ignite/services/scaffolder/params.go +++ b/ignite/services/scaffolder/params.go @@ -1,57 +1,48 @@ package scaffolder import ( - "context" "path/filepath" "strings" - "github.com/gobuffalo/genny/v2" - - "github.com/ignite/cli/v29/ignite/pkg/cache" "github.com/ignite/cli/v29/ignite/pkg/errors" "github.com/ignite/cli/v29/ignite/pkg/goanalysis" "github.com/ignite/cli/v29/ignite/pkg/multiformatname" - "github.com/ignite/cli/v29/ignite/pkg/placeholder" - "github.com/ignite/cli/v29/ignite/pkg/xgenny" "github.com/ignite/cli/v29/ignite/templates/field" modulecreate "github.com/ignite/cli/v29/ignite/templates/module/create" ) // CreateParams creates a new params in the scaffolded module. func (s Scaffolder) CreateParams( - ctx context.Context, - cacheStorage cache.Storage, - tracer *placeholder.Tracer, moduleName string, params ...string, -) (sm xgenny.SourceModification, err error) { +) error { // 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 sm, err + return err } moduleName = mfName.LowerCase // Check if the module already exist ok, err := moduleExists(s.path, moduleName) if err != nil { - return sm, err + return err } if !ok { - return sm, errors.Errorf("the module %v not exist", moduleName) + return errors.Errorf("the module %v not exist", moduleName) } if err := checkParamCreated(s.path, moduleName, params); err != nil { - return sm, err + return err } // Parse params with the associated type paramsFields, err := field.ParseFields(params, checkForbiddenTypeIndex) if err != nil { - return sm, err + return err } opts := modulecreate.ParamsOptions{ @@ -63,16 +54,10 @@ func (s Scaffolder) CreateParams( g, err := modulecreate.NewModuleParam(opts) if err != nil { - return sm, err - } - gens := []*genny.Generator{g} - - sm, err = xgenny.RunWithValidation(tracer, gens...) - if err != nil { - return sm, err + return err } - return sm, finish(ctx, cacheStorage, opts.AppPath, s.modpath.RawPath, false) + return s.Run(g) } // checkParamCreated checks if the parameter has been already created. diff --git a/ignite/services/scaffolder/query.go b/ignite/services/scaffolder/query.go index 4eadef2aae..fe61736186 100644 --- a/ignite/services/scaffolder/query.go +++ b/ignite/services/scaffolder/query.go @@ -5,11 +5,8 @@ import ( "github.com/gobuffalo/genny/v2" - "github.com/ignite/cli/v29/ignite/pkg/cache" "github.com/ignite/cli/v29/ignite/pkg/errors" "github.com/ignite/cli/v29/ignite/pkg/multiformatname" - "github.com/ignite/cli/v29/ignite/pkg/placeholder" - "github.com/ignite/cli/v29/ignite/pkg/xgenny" "github.com/ignite/cli/v29/ignite/templates/field" "github.com/ignite/cli/v29/ignite/templates/query" ) @@ -17,50 +14,48 @@ import ( // AddQuery adds a new query to scaffolded app. func (s Scaffolder) AddQuery( ctx context.Context, - cacheStorage cache.Storage, - tracer *placeholder.Tracer, moduleName, queryName, description string, reqFields, resFields []string, paginated bool, -) (sm xgenny.SourceModification, err error) { +) error { // 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 sm, err + return err } moduleName = mfName.LowerCase name, err := multiformatname.NewName(queryName) if err != nil { - return sm, err + return err } if err := checkComponentValidity(s.path, moduleName, name, true); err != nil { - return sm, err + return err } // Check and parse provided request fields if ok := containsCustomTypes(reqFields); ok { - return sm, errors.New("query request params can't contain custom type") + return errors.New("query request params can't contain custom type") } parsedReqFields, err := field.ParseFields(reqFields, checkGoReservedWord) if err != nil { - return sm, err + return err } // Check and parse provided response fields if err := checkCustomTypes(ctx, s.path, s.modpath.Package, moduleName, resFields); err != nil { - return sm, err + return err } parsedResFields, err := field.ParseFields(resFields, checkGoReservedWord) if err != nil { - return sm, err + return err } var ( @@ -79,13 +74,10 @@ func (s Scaffolder) AddQuery( ) // Scaffold - g, err = query.NewGenerator(tracer, opts) + g, err = query.NewGenerator(s.Tracer(), opts) if err != nil { - return sm, err + return err } - sm, err = xgenny.RunWithValidation(tracer, g) - if err != nil { - return sm, err - } - return sm, finish(ctx, cacheStorage, opts.AppPath, s.modpath.RawPath, false) + + return s.Run(g) } diff --git a/ignite/services/scaffolder/scaffolder.go b/ignite/services/scaffolder/scaffolder.go index 4dda948a03..5203236485 100644 --- a/ignite/services/scaffolder/scaffolder.go +++ b/ignite/services/scaffolder/scaffolder.go @@ -6,6 +6,8 @@ import ( "context" "path/filepath" + "github.com/gobuffalo/genny/v2" + chainconfig "github.com/ignite/cli/v29/ignite/config/chain" "github.com/ignite/cli/v29/ignite/pkg/cache" "github.com/ignite/cli/v29/ignite/pkg/cosmosanalysis" @@ -13,6 +15,8 @@ import ( "github.com/ignite/cli/v29/ignite/pkg/cosmosver" "github.com/ignite/cli/v29/ignite/pkg/gocmd" "github.com/ignite/cli/v29/ignite/pkg/gomodulepath" + "github.com/ignite/cli/v29/ignite/pkg/placeholder" + "github.com/ignite/cli/v29/ignite/pkg/xgenny" "github.com/ignite/cli/v29/ignite/version" ) @@ -24,12 +28,15 @@ type Scaffolder struct { // path of the app. path string - // modpath represents the go module path of the app. + // modpath represents the go module Path of the app. modpath gomodulepath.Path + + // runner represents the scaffold xgenny runner. + runner *xgenny.Runner } // New creates a new scaffold app. -func New(appPath string) (Scaffolder, error) { +func New(context context.Context, appPath string) (Scaffolder, error) { path, err := filepath.Abs(appPath) if err != nil { return Scaffolder{}, err @@ -58,25 +65,46 @@ func New(appPath string) (Scaffolder, error) { Version: ver, path: path, modpath: modpath, + runner: xgenny.NewRunner(context, path), } return s, nil } -func finish(ctx context.Context, cacheStorage cache.Storage, path, gomodPath string, skipProto bool) error { +func (s Scaffolder) ApplyModifications() (xgenny.SourceModification, error) { + return s.runner.ApplyModifications() +} + +func (s Scaffolder) Tracer() *placeholder.Tracer { + return s.runner.Tracer() +} + +func (s Scaffolder) Run(gens ...*genny.Generator) error { + return s.runner.Run(gens...) +} + +func (s Scaffolder) PostScaffold(ctx context.Context, cacheStorage cache.Storage, skipProto bool) error { + return PostScaffold(ctx, cacheStorage, s.path, s.modpath.RawPath, skipProto) +} + +func PostScaffold(ctx context.Context, cacheStorage cache.Storage, path, gomodPath string, skipProto bool) error { if !skipProto { if err := protoc(ctx, cacheStorage, path, gomodPath); err != nil { return err } } + if err := gocmd.ModTidy(ctx, path); err != nil { + return err + } + if err := gocmd.Fmt(ctx, path); err != nil { return err } _ = gocmd.GoImports(ctx, path) // goimports installation could fail, so ignore the error - return gocmd.ModTidy(ctx, path) + return nil } func protoc(ctx context.Context, cacheStorage cache.Storage, projectPath, gomodPath string) error { diff --git a/ignite/services/scaffolder/type.go b/ignite/services/scaffolder/type.go index 992c3e3d83..fd762bf8e4 100644 --- a/ignite/services/scaffolder/type.go +++ b/ignite/services/scaffolder/type.go @@ -6,11 +6,9 @@ import ( "github.com/gobuffalo/genny/v2" - "github.com/ignite/cli/v29/ignite/pkg/cache" "github.com/ignite/cli/v29/ignite/pkg/errors" "github.com/ignite/cli/v29/ignite/pkg/multiformatname" "github.com/ignite/cli/v29/ignite/pkg/placeholder" - "github.com/ignite/cli/v29/ignite/pkg/xgenny" "github.com/ignite/cli/v29/ignite/templates/field" "github.com/ignite/cli/v29/ignite/templates/field/datatype" modulecreate "github.com/ignite/cli/v29/ignite/templates/module/create" @@ -119,12 +117,10 @@ func TypeWithSigner(signer string) AddTypeOption { // if no module is given, the type will be scaffolded inside the app's default module. func (s Scaffolder) AddType( ctx context.Context, - cacheStorage cache.Storage, typeName string, - tracer *placeholder.Tracer, kind AddTypeKind, options ...AddTypeOption, -) (sm xgenny.SourceModification, err error) { +) error { // apply options. o := newAddTypeOptions(s.modpath.Package) for _, apply := range append(options, AddTypeOption(kind)) { @@ -133,36 +129,36 @@ func (s Scaffolder) AddType( mfName, err := multiformatname.NewName(o.moduleName, multiformatname.NoNumber) if err != nil { - return sm, err + return err } moduleName := mfName.LowerCase name, err := multiformatname.NewName(typeName) if err != nil { - return sm, err + return err } if err := checkComponentValidity(s.path, moduleName, name, o.withoutMessage); err != nil { - return sm, err + return err } // Check and parse provided fields if err := checkCustomTypes(ctx, s.path, s.modpath.Package, moduleName, o.fields); err != nil { - return sm, err + return err } tFields, err := parseTypeFields(o) if err != nil { - return sm, err + return err } mfSigner, err := multiformatname.NewName(o.signer) if err != nil { - return sm, err + return err } isIBC, err := isIBCModule(s.path, moduleName) if err != nil { - return sm, err + return err } var ( @@ -184,7 +180,7 @@ func (s Scaffolder) AddType( // Check and support MsgServer convention gens, err = supportMsgServer( gens, - tracer, + s.runner.Tracer(), s.path, &modulecreate.MsgServerOptions{ ModuleName: opts.ModuleName, @@ -194,32 +190,26 @@ func (s Scaffolder) AddType( }, ) if err != nil { - return sm, err + return err } // create the type generator depending on the model switch { case o.isList: - g, err = list.NewGenerator(tracer, opts) + g, err = list.NewGenerator(s.Tracer(), opts) case o.isMap: - g, err = mapGenerator(tracer, opts, o.indexes) + g, err = mapGenerator(s.Tracer(), opts, o.indexes) case o.isSingleton: - g, err = singleton.NewGenerator(tracer, opts) + g, err = singleton.NewGenerator(s.Tracer(), opts) default: g, err = dry.NewGenerator(opts) } if err != nil { - return sm, err + return err } // run the generation - gens = append(gens, g) - sm, err = xgenny.RunWithValidation(tracer, gens...) - if err != nil { - return sm, err - } - - return sm, finish(ctx, cacheStorage, opts.AppPath, s.modpath.RawPath, false) + return s.Run(append(gens, g)...) } // checkForbiddenTypeIndex returns true if the name is forbidden as a index name.