Skip to content

Commit

Permalink
add migrate buf command to the cli doctor command
Browse files Browse the repository at this point in the history
  • Loading branch information
Pantani committed Feb 5, 2025
1 parent 59595eb commit 5ae7aa4
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 50 deletions.
27 changes: 2 additions & 25 deletions ignite/cmd/chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import (
"github.com/ignite/cli/v29/ignite/pkg/cliui"
"github.com/ignite/cli/v29/ignite/pkg/cliui/colors"
"github.com/ignite/cli/v29/ignite/pkg/cliui/icons"
"github.com/ignite/cli/v29/ignite/pkg/cosmosbuf"
"github.com/ignite/cli/v29/ignite/pkg/cosmosgen"
"github.com/ignite/cli/v29/ignite/pkg/errors"
"github.com/ignite/cli/v29/ignite/pkg/goanalysis"
Expand All @@ -29,17 +28,13 @@ const (
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"
msgMigrationBufV2 = "Now ignite supports the new `buf.build` (https://buf.build) v2 configuration. Would you like to upgrade your buf files to v2 using the `buf config migrate` command"
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"
)

var (
ErrProtocUnsupported = errors.New("code generation using protoc is only supported by Ignite CLI v0.26.1 or older")
ErrBufConfigVersionUnsupported = errors.New("buf config version must be v2")
)
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.
Expand Down Expand Up @@ -197,29 +192,11 @@ func toolsMigrationPreRunHandler(cmd *cobra.Command, session *cliui.Session, app

func bufMigrationPreRunHandler(cmd *cobra.Command, session *cliui.Session, appPath, protoDir string) error {
// check if the buf files exist.
hasFiles, needMigration, err := chain.CheckBufFiles(appPath, protoDir)
hasFiles, err := chain.CheckBufFiles(appPath, protoDir)
if err != nil {
return err
}

if needMigration {
if !getYes(cmd) {
if err := session.AskConfirm(msgMigrationBufV2); err != nil {
return ErrBufConfigVersionUnsupported
}
}

cacheStorage, err := newCache(cmd)
b, err := cosmosbuf.New(cacheStorage, appPath)
if err != nil {
return err
}

if err := b.Migrate(cmd.Context(), protoDir); err != nil {
return err
}
}

if !hasFiles {
if !getYes(cmd) {
if err := session.AskConfirm(msgMigrationBuf); err != nil {
Expand Down
23 changes: 21 additions & 2 deletions ignite/cmd/doctor.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,38 @@ package ignitecmd
import (
"github.com/spf13/cobra"

chainconfig "github.com/ignite/cli/v29/ignite/config/chain"
"github.com/ignite/cli/v29/ignite/pkg/cliui"
"github.com/ignite/cli/v29/ignite/services/doctor"
)

func NewDoctor() *cobra.Command {
return &cobra.Command{
c := &cobra.Command{
Use: "doctor",
Short: "Fix chain configuration",
Hidden: true,
RunE: func(cmd *cobra.Command, _ []string) error {
session := cliui.New()
defer session.End()
appPath := flagGetPath(cmd)

doc := doctor.New(doctor.CollectEvents(session.EventBus()))

if err := doc.MigrateConfig(cmd.Context()); err != nil {
cacheStorage, err := newCache(cmd)
if err != nil {
return err
}

configPath, err := chainconfig.LocateDefault(appPath)
if err != nil {
return err
}

if err := doc.MigrateChainConfig(configPath); err != nil {
return err
}

if err := doc.MigrateBufConfig(cmd.Context(), cacheStorage, appPath, configPath); err != nil {
return err
}

Expand All @@ -29,4 +45,7 @@ func NewDoctor() *cobra.Command {
return doc.FixDependencyTools(cmd.Context())
},
}

flagSetPath(c)
return c
}
17 changes: 17 additions & 0 deletions ignite/config/chain/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

"github.com/cosmos/cosmos-sdk/types/bech32"

"github.com/ignite/cli/v29/ignite/config/chain/defaults"
"github.com/ignite/cli/v29/ignite/config/chain/version"
"github.com/ignite/cli/v29/ignite/pkg/errors"
)
Expand Down Expand Up @@ -103,6 +104,22 @@ func ReadConfigVersion(configFile io.Reader) (version.Version, error) {
return c.Version, err
}

// ReadProtoPath reads the proto path.
func ReadProtoPath(configFile io.Reader) (string, error) {
c := struct {
Build struct {
Proto struct {
Path string `yaml:"path"`
} `yaml:"proto"`
} `yaml:"build"`
}{}

c.Build.Proto.Path = defaults.ProtoDir
err := yaml.NewDecoder(configFile).Decode(&c)

return c.Build.Proto.Path, err
}

func decodeConfig(r io.Reader, version version.Version) (version.Converter, error) {
c, ok := Versions[version]
if !ok {
Expand Down
17 changes: 5 additions & 12 deletions ignite/services/chain/proto.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@ import (
"github.com/ignite/cli/v29/ignite/templates/app"
)

// oldBufWorkFile represents the v1 buf work file, may this check should be remove in v30
const oldBufWorkFile = "buf.work.yaml"

// 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)
Expand Down Expand Up @@ -47,26 +44,22 @@ func RemoveBufProtoDirs(appPath string, protoDirs ...string) error {
return workFile.RemoveProtoDirs(protoDirs...)
}

// CheckBufFiles check if the buf files exist, and if needs a migration to v2.
func CheckBufFiles(appPath, protoDir string) (bool, bool, error) {
// CheckBufFiles check if the buf files exist.
func CheckBufFiles(appPath, protoDir string) (bool, error) {
files, err := app.BufFiles()
if err != nil {
return false, false, nil
}
// if the buf.work.yaml exist, we only need the migration
if xos.FileExists(filepath.Join(appPath, oldBufWorkFile)) {
return true, true, 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, false, nil
return false, nil
}
}
return true, false, nil
return true, nil
}

// BoxBufFiles box all buf files.
Expand Down
65 changes: 54 additions & 11 deletions ignite/services/doctor/doctor.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ import (
"path"

chainconfig "github.com/ignite/cli/v29/ignite/config/chain"
"github.com/ignite/cli/v29/ignite/pkg/cache"
"github.com/ignite/cli/v29/ignite/pkg/cliui/colors"
"github.com/ignite/cli/v29/ignite/pkg/cliui/icons"
"github.com/ignite/cli/v29/ignite/pkg/cosmosbuf"
"github.com/ignite/cli/v29/ignite/pkg/cosmosgen"
"github.com/ignite/cli/v29/ignite/pkg/errors"
"github.com/ignite/cli/v29/ignite/pkg/events"
Expand Down Expand Up @@ -49,41 +51,82 @@ func CollectEvents(ev events.Bus) Option {
}
}

// MigrateConfig migrates the chain config if required.
func (d *Doctor) MigrateConfig(_ context.Context) error {
// MigrateBufConfig migrates the buf chain config if required.
func (d *Doctor) MigrateBufConfig(ctx context.Context, cacheStorage cache.Storage, appPath, configPath string) error {
errf := func(err error) error {
return errors.Errorf("doctor migrate config: %w", err)
return errors.Errorf("doctor migrate buf config: %w", err)
}

d.ev.Send("Checking chain config file:")
d.ev.Send("Checking buf config file version")

// Check if the appPath contains the buf.work.yaml file in the root folder.
bufWorkFile := path.Join(appPath, "buf.work.yaml")
if _, err := os.Stat(bufWorkFile); os.IsNotExist(err) {
return nil
} else if err != nil {
return errf(fmt.Errorf("unable to check if buf.work.yaml exists: %w", err))

Check failure on line 67 in ignite/services/doctor/doctor.go

View workflow job for this annotation

GitHub Actions / Lint Go code

use of `fmt.Errorf` forbidden because "fmt.Errorf should be replaced by '\"github.com/ignite/cli/ignite/pkg/errors\"'" (forbidigo)
}

d.ev.Send("Migrating buf config file to v2")

configFile, err := os.Open(configPath)
if err != nil {
return err
}
defer configFile.Close()

configPath, err := chainconfig.LocateDefault(".")
protoPath, err := chainconfig.ReadProtoPath(configFile)
if err != nil {
return errf(err)
}

f, err := os.Open(configPath)
b, err := cosmosbuf.New(cacheStorage, appPath)
if err != nil {
return errf(err)
}
defer f.Close()

version, err := chainconfig.ReadConfigVersion(f)
if err := b.Migrate(ctx, protoPath); err != nil {
return errf(err)
}

d.ev.Send(
fmt.Sprintf("buf config files migrated"),

Check failure on line 93 in ignite/services/doctor/doctor.go

View workflow job for this annotation

GitHub Actions / Lint Go code

S1039: unnecessary use of fmt.Sprintf (gosimple)
events.Icon(icons.OK),
events.Indent(1),
events.ProgressFinish(),
)

return nil
}

// MigrateChainConfig migrates the chain config if required.
func (d *Doctor) MigrateChainConfig(configPath string) error {
errf := func(err error) error {
return errors.Errorf("doctor migrate config: %w", err)
}

d.ev.Send("Checking chain config file:")
configFile, err := os.Open(configPath)
if err != nil {
return err
}
defer configFile.Close()

version, err := chainconfig.ReadConfigVersion(configFile)
if err != nil {
return errf(err)
}

status := "OK"

if version != chainconfig.LatestVersion {
_, err := f.Seek(0, 0)
_, err := configFile.Seek(0, 0)
if err != nil {
return errf(errors.Errorf("failed to reset the file: %w", err))
}
// migrate config file
// Convert the current config to the latest version and update the YAML file
var buf bytes.Buffer
if err := chainconfig.MigrateLatest(f, &buf); err != nil {
if err := chainconfig.MigrateLatest(configFile, &buf); err != nil {
return errf(err)
}

Expand Down

0 comments on commit 5ae7aa4

Please sign in to comment.