diff --git a/changelog.md b/changelog.md index acce50bda2..199548e5db 100644 --- a/changelog.md +++ b/changelog.md @@ -10,6 +10,7 @@ ### Changes - [#4689](https://github.com/ignite/cli/pull/4689) Revert `HasGenesis` implementation from retracted `core` v1 to SDK `HasGenesis` interface. +- [#4701](https://github.com/ignite/cli/pull/4701) Improve `ignite doctor` by removing manual migration step. Additionally, remove protoc to buf migrations logic. ### Bug Fixes diff --git a/docs/docs/06-migration/v29.0.0.md b/docs/docs/06-migration/v29.0.0.md index bd0c3d50ee..5b3984e13a 100644 --- a/docs/docs/06-migration/v29.0.0.md +++ b/docs/docs/06-migration/v29.0.0.md @@ -8,10 +8,20 @@ description: For chains that were scaffolded with Ignite CLI versions lower than The changes between v28.0.0 and v29.0.0 are not as significant as the changes between v0.27.0 and v28.0.0. -In v29.0.0, the Cosmos SDK version has been upgraded to 0.53.0 and IBC to v10. +In v29.0.0, the Cosmos SDK version has been upgraded to 0.53.0 and IBC to v10. Please see the [Changelog](https://github.com/ignite/cli/commit/1b7f19f08d0fa91e3ae71b4b37b8bb4171a9e320#diff-b027e7b11ff55b21dd50b32abcbdd35d95be87a889f0f6562417fbf0995d402a) for more details. +:::tip +If you wish to keep using a chain scaffolded with Ignite v28, simply run the doctor command: + +```bash +ignite doctor +``` + +Note that some scaffolding commands may not work as expected, and you may need to manually adjust your code, unless you follow the migration steps below. +::: + ## Upgrade Cosmos SDK to v0.53.0 In order to upgrade, please navigate to the `go.mod` file in your blockchain directory and replace an earlier Cosmos-SDK version with v0.53.0. @@ -30,6 +40,7 @@ If you have custom modules, test for deprecated APIs and update as needed. v29 configures preblockers to include the `auth` module (`authtypes.ModuleName`) for transaction processing. Ensure this is set in your v28 scaffold. **Edit PreBlockers**: + - Open `mychain/app/app_config.go`. - Find or add the `preBlockers` slice. Ensure it includes `authtypes.ModuleName`, matching v29’s configuration: @@ -84,4 +95,16 @@ Now start your chain. ignite chain serve ``` +:::tip +If Ignite is unable to detect the chain `app.go`, make sure you have the following methods on the `App` struct: + +```go +func (app *App) AppCodec() codec.Codec +func (app *App) TxConfig() client.TxConfig +func (app *App) RegisterAPIRoutes(apiSvr *api.Server, apiConfig config.APIConfig) +``` + +All recent Ignite v28 scaffolded chains should have these methods. +::: + If you need our help and support, do not hesitate to visit our [Discord](https://discord.com/invite/ignite). diff --git a/ignite/cmd/chain.go b/ignite/cmd/chain.go index b89cc5a359..0a8ce311bc 100644 --- a/ignite/cmd/chain.go +++ b/ignite/cmd/chain.go @@ -17,23 +17,16 @@ import ( "github.com/ignite/cli/v29/ignite/pkg/cosmosgen" "github.com/ignite/cli/v29/ignite/pkg/errors" "github.com/ignite/cli/v29/ignite/pkg/goanalysis" - "github.com/ignite/cli/v29/ignite/pkg/xgenny" - "github.com/ignite/cli/v29/ignite/services/chain" ) const ( - msgMigration = "Migrating blockchain config file from v%d to v%d..." - msgMigrationPrefix = "Your blockchain config version is v%d and the latest is v%d." - msgMigrationPrompt = "Would you like to upgrade your config file to v%d" - msgMigrationBuf = "Now ignite supports the `buf.build` (https://buf.build) registry to manage the protobuf dependencies. The embed protoc binary was deprecated and, your blockchain is still using it. Would you like to upgrade and add the `buf.build` config files to `proto/` folder" - msgMigrationBufProtoDir = "Ignite proto directory path from the chain config doesn't match the proto directory path from the chain `buf.work.yaml`. Do you want to add the proto path `%[1]v` to the directories list from the buf work file" - msgMigrationBufProtoDirs = "Chain `buf.work.yaml` file contains directories that don't exist anymore (%[1]v). Do you want to delete them" - msgMigrationAddTools = "Some required imports are missing in %s file: %s. Would you like to add them" - msgMigrationRemoveTools = "File %s contains deprecated imports: %s. Would you like to remove them" + msgMigration = "Migrating blockchain config file from v%d to v%d..." + msgMigrationPrefix = "Your blockchain config version is v%d and the latest is v%d." + msgMigrationPrompt = "Would you like to upgrade your config file to v%d" + msgMigrationAddTools = "Some required imports are missing in %s file: %s. Would you like to add them" + msgMigrationRemoveTools = "File %s contains deprecated imports: %s. Would you like to remove them" ) -var ErrProtocUnsupported = errors.New("code generation using protoc is only supported by Ignite CLI v0.26.1 or older") - // NewChain returns a command that groups sub commands related to compiling, serving // blockchains and so on. func NewChain() *cobra.Command { @@ -119,7 +112,7 @@ func preRunHandler(cmd *cobra.Command, _ []string) error { return err } - cfg, cfgPath, err := getChainConfig(cmd) + _, cfgPath, err := getChainConfig(cmd) if err != nil { return err } @@ -132,7 +125,7 @@ func preRunHandler(cmd *cobra.Command, _ []string) error { return err } - return bufMigrationPreRunHandler(cmd, session, appPath, cfg.Build.Proto.Path) + return nil } func toolsMigrationPreRunHandler(cmd *cobra.Command, session *cliui.Session, appPath string) error { @@ -189,63 +182,6 @@ func toolsMigrationPreRunHandler(cmd *cobra.Command, session *cliui.Session, app return os.WriteFile(goModPath, buf.Bytes(), 0o600) } -func bufMigrationPreRunHandler(cmd *cobra.Command, session *cliui.Session, appPath, protoDir string) error { - // check if the buf files exist. - hasFiles, err := chain.CheckBufFiles(appPath, protoDir) - if err != nil { - return err - } - - if !hasFiles { - if !getYes(cmd) { - if err := session.AskConfirm(msgMigrationBuf); err != nil { - return ErrProtocUnsupported - } - } - - runner := xgenny.NewRunner(cmd.Context(), appPath) - sm, err := chain.BoxBufFiles(runner, appPath, protoDir) - if err != nil { - return err - } - - session.Print("\nšŸŽ‰ buf.build files added: \n\n") - session.Printf("%s\n\n", strings.Join(sm.CreatedFiles(), "\n")) - } - - // check if the buf.work.yaml has the same proto path from the config file. - hasProtoPath, missingPaths, err := chain.CheckBufProtoDir(appPath, protoDir) - if err != nil { - return err - } - - if !hasProtoPath { - if !getYes(cmd) { - if err := session.AskConfirm(fmt.Sprintf(msgMigrationBufProtoDir, protoDir)); err != nil { - return nil - } - } - - if err := chain.AddBufProtoDir(appPath, protoDir); err != nil { - return err - } - } - - if len(missingPaths) > 0 { - if !getYes(cmd) { - if err := session.AskConfirm(fmt.Sprintf(msgMigrationBufProtoDirs, strings.Join(missingPaths, ", "))); err != nil { - return nil - } - } - - if err := chain.RemoveBufProtoDirs(appPath, missingPaths...); err != nil { - return err - } - } - - return nil -} - func configMigrationPreRunHandler(cmd *cobra.Command, session *cliui.Session, appPath, cfgPath string) error { rawCfg, err := os.ReadFile(cfgPath) if err != nil { diff --git a/ignite/cmd/scaffold.go b/ignite/cmd/scaffold.go index 1bfd202c4e..a83650b431 100644 --- a/ignite/cmd/scaffold.go +++ b/ignite/cmd/scaffold.go @@ -152,11 +152,6 @@ func migrationPreRunHandler(cmd *cobra.Command, args []string) error { session := cliui.New() defer session.End() - cfg, _, err := getChainConfig(cmd) - if err != nil { - return err - } - appPath, err := goModulePath(cmd) if err != nil { return err @@ -175,10 +170,6 @@ func migrationPreRunHandler(cmd *cobra.Command, args []string) error { return err } - if err := bufMigrationPreRunHandler(cmd, session, appPath, cfg.Build.Proto.Path); err != nil { - return err - } - // we go mod tidy in case new dependencies were added or removed if err := gocmd.ModTidy(cmd.Context(), appPath); err != nil { return err diff --git a/ignite/pkg/cosmosbuf/buf.go b/ignite/pkg/cosmosbuf/buf.go index f0de282741..22fd299e4b 100644 --- a/ignite/pkg/cosmosbuf/buf.go +++ b/ignite/pkg/cosmosbuf/buf.go @@ -172,7 +172,11 @@ func (b Buf) Update(ctx context.Context, modDir string) error { // Migrate runs the buf Migrate command for the files in the app directory. func (b Buf) Migrate(ctx context.Context, protoDir string) error { - yamlFiles, err := xos.FindFiles(protoDir, xos.WithExtension(xos.YMLFile), xos.WithExtension(xos.YAMLFile), xos.WithPrefix(bufGenPrefix)) + yamlFiles, err := xos.FindFiles(protoDir, + xos.WithExtension(xos.YMLFile), + xos.WithExtension(xos.YAMLFile), + xos.WithPrefix(bufGenPrefix), + ) if err != nil { return err } diff --git a/ignite/pkg/cosmosbuf/config.go b/ignite/pkg/cosmosbuf/config.go deleted file mode 100644 index 86d35ef25e..0000000000 --- a/ignite/pkg/cosmosbuf/config.go +++ /dev/null @@ -1,92 +0,0 @@ -package cosmosbuf - -import ( - "os" - "path/filepath" - - "gopkg.in/yaml.v3" -) - -const bufConfig = "buf.yaml" - -type ( - // BufWork represents the buf.yaml file. - BufWork struct { - appPath string `yaml:"-"` - filePath string `yaml:"-"` - Version string `yaml:"version"` - Modules []Module `yaml:"modules"` - } - // Module represents the buf.yaml module. - Module struct { - Path string `yaml:"path"` - Name string `yaml:"name"` - } -) - -// ParseBufConfig parse the buf.yaml file at app path. -func ParseBufConfig(appPath string) (BufWork, error) { - path := filepath.Join(appPath, bufConfig) - - f, err := os.Open(path) - if err != nil { - return BufWork{}, err - } - defer f.Close() - - w := BufWork{appPath: appPath, filePath: path} - return w, yaml.NewDecoder(f).Decode(&w) -} - -// MissingDirectories check if the directories inside the buf work exist. -func (w BufWork) MissingDirectories() ([]string, error) { - missingPaths := make([]string, 0) - for _, module := range w.Modules { - protoDir := filepath.Join(w.appPath, module.Path) - if _, err := os.Stat(protoDir); os.IsNotExist(err) { - missingPaths = append(missingPaths, module.Path) - } else if !os.IsNotExist(err) { - return nil, err - } - } - return missingPaths, nil -} - -// AddProtoDir add a proto directory path from the buf work file. -func (w BufWork) AddProtoDir(newPath string) error { - w.Modules = append(w.Modules, Module{Path: newPath}) - return w.save() -} - -// RemoveProtoDirs remove a list a proto directory paths from the buf work file. -func (w BufWork) RemoveProtoDirs(paths ...string) error { - for _, path := range paths { - for i, module := range w.Modules { - if module.Path == path { - w.Modules = append(w.Modules[:i], w.Modules[i+1:]...) - break - } - } - } - return w.save() -} - -// HasProtoDir returns true if the proto path exist into the directories slice. -func (w BufWork) HasProtoDir(path string) bool { - for _, module := range w.Modules { - if path == module.Path { - return true - } - } - return false -} - -// save saves the buf work file. -func (w BufWork) save() error { - file, err := os.OpenFile(w.filePath, os.O_WRONLY|os.O_TRUNC, 0o755) - if err != nil { - return err - } - defer file.Close() - return yaml.NewEncoder(file).Encode(&w) -} diff --git a/ignite/pkg/cosmosgen/generate.go b/ignite/pkg/cosmosgen/generate.go index 28164621f0..3534cd85d2 100644 --- a/ignite/pkg/cosmosgen/generate.go +++ b/ignite/pkg/cosmosgen/generate.go @@ -30,7 +30,7 @@ import ( const ( moduleCacheNamespace = "generate.setup.module" includeProtoCacheNamespace = "generator.includes.proto" - workFilename = "buf.work.yaml" + bufYamlFilename = "buf.yaml" ) var ( @@ -223,7 +223,7 @@ func (g *generator) findBufPath(modpath string) (string, error) { return err } base := filepath.Base(path) - if base == "buf.yaml" || base == "buf.yml" { + if base == bufYamlFilename || base == "buf.yml" { bufPath = path return filepath.SkipAll } @@ -460,21 +460,30 @@ func (g generator) vendorProtoPackage(pkgName, protoPath string) (err error) { return err } - path := filepath.Join(g.appPath, workFilename) + path := filepath.Join(g.appPath, bufYamlFilename) bz, err := os.ReadFile(path) if err != nil { return errors.Errorf("error reading Buf workspace file: %s: %w", path, err) } ws := struct { - Version string `yaml:"version"` - Directories []string `yaml:"directories"` + Version string `yaml:"version"` + Modules []struct { + Path string `yaml:"path"` + } `yaml:"modules"` + Deps []string `yaml:"deps"` + Lint any `yaml:"lint"` + Breaking any `yaml:"breaking"` }{} if err := yaml.Unmarshal(bz, &ws); err != nil { return err } - ws.Directories = append(ws.Directories, vendorRelPath) + ws.Modules = append(ws.Modules, struct { + Path string `yaml:"path"` + }{ + Path: vendorRelPath, + }) f, err := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC, 0o644) if err != nil { diff --git a/ignite/services/chain/proto.go b/ignite/services/chain/proto.go deleted file mode 100644 index a157a1763e..0000000000 --- a/ignite/services/chain/proto.go +++ /dev/null @@ -1,72 +0,0 @@ -package chain - -import ( - "path/filepath" - - "github.com/ignite/cli/v29/ignite/pkg/cosmosbuf" - "github.com/ignite/cli/v29/ignite/pkg/xgenny" - "github.com/ignite/cli/v29/ignite/pkg/xos" - "github.com/ignite/cli/v29/ignite/templates/app" -) - -// CheckBufProtoDir check if the proto path exist into the directory list in the buf.work.yaml file. -func CheckBufProtoDir(appPath, protoDir string) (bool, []string, error) { - bufCfg, err := cosmosbuf.ParseBufConfig(appPath) - if err != nil { - return false, nil, err - } - - missing, err := bufCfg.MissingDirectories() - if err != nil { - return false, nil, err - } - - return bufCfg.HasProtoDir(protoDir), missing, nil -} - -// AddBufProtoDir add the proto path into the directory list in the buf.work.yaml file. -func AddBufProtoDir(appPath, protoDir string) error { - workFile, err := cosmosbuf.ParseBufConfig(appPath) - if err != nil { - return err - } - - return workFile.AddProtoDir(protoDir) -} - -// RemoveBufProtoDirs add the proto path into the directory list in the buf.work.yaml file. -func RemoveBufProtoDirs(appPath string, protoDirs ...string) error { - workFile, err := cosmosbuf.ParseBufConfig(appPath) - if err != nil { - return err - } - - return workFile.RemoveProtoDirs(protoDirs...) -} - -// CheckBufFiles check if the buf files exist. -func CheckBufFiles(appPath, protoDir string) (bool, error) { - files, err := app.BufFiles() - if err != nil { - return false, nil - } - for _, bufFile := range files { - bufFile, ok := app.CutTemplatePrefix(bufFile) - if ok { - bufFile = filepath.Join(protoDir, bufFile) - } - if !xos.FileExists(filepath.Join(appPath, bufFile)) { - return false, nil - } - } - return true, nil -} - -// BoxBufFiles box all buf files. -func BoxBufFiles(runner *xgenny.Runner, appPath, protoDir string) (xgenny.SourceModification, error) { - g, err := app.NewBufGenerator(appPath, protoDir) - if err != nil { - return xgenny.SourceModification{}, err - } - return runner.RunAndApply(g) -} diff --git a/ignite/services/doctor/doctor.go b/ignite/services/doctor/doctor.go index fcd83f5f9a..59abd44254 100644 --- a/ignite/services/doctor/doctor.go +++ b/ignite/services/doctor/doctor.go @@ -18,6 +18,8 @@ import ( "github.com/ignite/cli/v29/ignite/pkg/events" "github.com/ignite/cli/v29/ignite/pkg/goanalysis" "github.com/ignite/cli/v29/ignite/pkg/xast" + "github.com/ignite/cli/v29/ignite/pkg/xgenny" + "github.com/ignite/cli/v29/ignite/templates/app" ) // DONTCOVER: Doctor read and write the filesystem intensively, so it's better @@ -50,14 +52,21 @@ func (d *Doctor) MigrateBufConfig(ctx context.Context, cacheStorage cache.Storag return errors.Errorf("doctor migrate buf config: %w", err) } - d.ev.Send("Checking buf config file version") + d.ev.Send("Checking buf config file version:") // Check if the appPath contains the buf.work.yaml file in the root folder. + // The buf.work.yaml file does not exist in buf v2 config, so it is a good + // indicator that the buf config is already migrated. bufWorkFile := path.Join(appPath, "buf.work.yaml") if _, err := os.Stat(bufWorkFile); os.IsNotExist(err) { + d.ev.Send( + fmt.Sprintf("buf files %s", colors.Success("OK")), + events.Icon(icons.OK), + events.Indent(1), + ) return nil } else if err != nil { - return errf(errors.Errorf("unable to check if buf.work.yaml exists: %w", err)) + return errf(errors.Errorf("unable to check buf files have been migrated: %w", err)) } d.ev.Send("Migrating buf config file to v2") @@ -82,11 +91,11 @@ func (d *Doctor) MigrateBufConfig(ctx context.Context, cacheStorage cache.Storag return errf(err) } - d.ev.Send( - "Important: Update the local field of buf files to use `go tool`", - events.Icon(icons.Announcement), - events.Indent(1), - ) + runner := xgenny.NewRunner(ctx, appPath) + _, err = boxBufFiles(runner, appPath, protoPath) + if err != nil { + return err + } d.ev.Send( "buf config files migrated", @@ -98,6 +107,15 @@ func (d *Doctor) MigrateBufConfig(ctx context.Context, cacheStorage cache.Storag return nil } +// BoxBufFiles box all buf files. +func boxBufFiles(runner *xgenny.Runner, appPath, protoDir string) (xgenny.SourceModification, error) { + g, err := app.NewBufGenerator(appPath, protoDir) + if err != nil { + return xgenny.SourceModification{}, err + } + return runner.RunAndApply(g) +} + // MigrateChainConfig migrates the chain config if required. func (d *Doctor) MigrateChainConfig(configPath string) error { errf := func(err error) error { diff --git a/ignite/templates/app/files/go.mod.plush b/ignite/templates/app/files/go.mod.plush index 36d7ce1504..c0f222ed86 100644 --- a/ignite/templates/app/files/go.mod.plush +++ b/ignite/templates/app/files/go.mod.plush @@ -18,7 +18,7 @@ require ( cosmossdk.io/core v0.11.3 cosmossdk.io/depinject v1.2.0 cosmossdk.io/errors v1.0.2 - cosmossdk.io/log v1.5.1 + cosmossdk.io/log v1.6.0 cosmossdk.io/math v1.5.3 cosmossdk.io/store v1.1.2 cosmossdk.io/tools/confix v0.1.2