Skip to content

Commit

Permalink
fix: change ignite apps to be able to run in any directory (#3827)
Browse files Browse the repository at this point in the history
* fix: change ignite apps to be able to run in any directory

* chore: update changelog
  • Loading branch information
jeronimoalbi authored Dec 12, 2023
1 parent b0dd6a6 commit c148343
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 28 deletions.
1 change: 1 addition & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

### Fixes

- [#3827](https://github.com/ignite/cli/pull/3827) Change ignite apps to be able to run in any directory
- [#3831](https://github.com/ignite/cli/pull/3831) Correct ignite app gRPC server stop memory issue
- [#3825](https://github.com/ignite/cli/pull/3825) Fix a minor Keplr type-checking bug in TS client
- [#3836](https://github.com/ignite/cli/pull/3836) Add missing IBC commands for scaffolded chain
Expand Down
50 changes: 29 additions & 21 deletions ignite/cmd/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"github.com/ignite/cli/v28/ignite/pkg/cliui"
"github.com/ignite/cli/v28/ignite/pkg/cliui/icons"
"github.com/ignite/cli/v28/ignite/pkg/cosmosanalysis"
"github.com/ignite/cli/v28/ignite/pkg/gomodule"
"github.com/ignite/cli/v28/ignite/pkg/xgit"
"github.com/ignite/cli/v28/ignite/services/plugin"
)
Expand Down Expand Up @@ -197,21 +198,22 @@ func linkPluginHook(rootCmd *cobra.Command, p *plugin.Plugin, hook *plugin.Hook)

preRun := cmd.PreRunE
cmd.PreRunE = func(cmd *cobra.Command, args []string) error {
ctx := cmd.Context()

if preRun != nil {
err := preRun(cmd, args)
if err != nil {
return err
}
}

execHook := newExecutedHook(hook, cmd, args)
// Get chain when the plugin runs inside an blockchain app
c, err := newChainWithHomeFlags(cmd)
if err != nil {
if err != nil && !errors.Is(err, gomodule.ErrGoModNotFound) {
return err
}
err = p.Interface.ExecuteHookPre(ctx, execHook, plugin.NewClientAPI(c))

ctx := cmd.Context()
execHook := newExecutedHook(hook, cmd, args)
err = p.Interface.ExecuteHookPre(ctx, execHook, plugin.NewClientAPI(plugin.WithChain(c)))
if err != nil {
return fmt.Errorf("app %q ExecuteHookPre() error: %w", p.Path, err)
}
Expand All @@ -225,13 +227,15 @@ func linkPluginHook(rootCmd *cobra.Command, p *plugin.Plugin, hook *plugin.Hook)
err := runCmd(cmd, args)
// if the command has failed the `PostRun` will not execute. here we execute the cleanup step before returnning.
if err != nil {
ctx := cmd.Context()
execHook := newExecutedHook(hook, cmd, args)
// Get chain when the plugin runs inside an blockchain app
c, err := newChainWithHomeFlags(cmd)
if err != nil {
if err != nil && !errors.Is(err, gomodule.ErrGoModNotFound) {
return err
}
err = p.Interface.ExecuteHookCleanUp(ctx, execHook, plugin.NewClientAPI(c))

ctx := cmd.Context()
execHook := newExecutedHook(hook, cmd, args)
err = p.Interface.ExecuteHookCleanUp(ctx, execHook, plugin.NewClientAPI(plugin.WithChain(c)))
if err != nil {
cmd.Printf("app %q ExecuteHookCleanUp() error: %v", p.Path, err)
}
Expand All @@ -245,16 +249,17 @@ func linkPluginHook(rootCmd *cobra.Command, p *plugin.Plugin, hook *plugin.Hook)

postCmd := cmd.PostRunE
cmd.PostRunE = func(cmd *cobra.Command, args []string) error {
ctx := cmd.Context()
execHook := newExecutedHook(hook, cmd, args)

// Get chain when the plugin runs inside an blockchain app
c, err := newChainWithHomeFlags(cmd)
if err != nil {
if err != nil && !errors.Is(err, gomodule.ErrGoModNotFound) {
return err
}

ctx := cmd.Context()
execHook := newExecutedHook(hook, cmd, args)

defer func() {
err := p.Interface.ExecuteHookCleanUp(ctx, execHook, plugin.NewClientAPI(c))
err := p.Interface.ExecuteHookCleanUp(ctx, execHook, plugin.NewClientAPI(plugin.WithChain(c)))
if err != nil {
cmd.Printf("app %q ExecuteHookCleanUp() error: %v", p.Path, err)
}
Expand All @@ -268,7 +273,7 @@ func linkPluginHook(rootCmd *cobra.Command, p *plugin.Plugin, hook *plugin.Hook)
}
}

err = p.Interface.ExecuteHookPost(ctx, execHook, plugin.NewClientAPI(c))
err = p.Interface.ExecuteHookPost(ctx, execHook, plugin.NewClientAPI(plugin.WithChain(c)))
if err != nil {
return fmt.Errorf("app %q ExecuteHookPost() error : %w", p.Path, err)
}
Expand Down Expand Up @@ -331,6 +336,13 @@ func linkPluginCmd(rootCmd *cobra.Command, p *plugin.Plugin, pluginCmd *plugin.C
newCmd.RunE = func(cmd *cobra.Command, args []string) error {
ctx := cmd.Context()
return clictx.Do(ctx, func() error {
// Get chain when the plugin runs inside an blockchain app
c, err := newChainWithHomeFlags(cmd)
if err != nil && !errors.Is(err, gomodule.ErrGoModNotFound) {
return err
}

// Call the plugin Execute
execCmd := &plugin.ExecutedCommand{
Use: cmd.Use,
Path: cmd.CommandPath(),
Expand All @@ -339,12 +351,8 @@ func linkPluginCmd(rootCmd *cobra.Command, p *plugin.Plugin, pluginCmd *plugin.C
With: p.With,
}
execCmd.ImportFlags(cmd)
// Call the plugin Execute
c, err := newChainWithHomeFlags(cmd)
if err != nil {
return err
}
err = p.Interface.Execute(ctx, execCmd, plugin.NewClientAPI(c))
err = p.Interface.Execute(ctx, execCmd, plugin.NewClientAPI(plugin.WithChain(c)))

// NOTE(tb): This pause gives enough time for go-plugin to sync the
// output from stdout/stderr of the plugin. Without that pause, this
// output can be discarded and not printed in the user console.
Expand Down
48 changes: 41 additions & 7 deletions ignite/services/plugin/client_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@ package plugin

import (
"context"
"errors"
)

// ErrAppChainNotFound indicates that the plugin command is not running inside a blockchain app.
var ErrAppChainNotFound = errors.New("blockchain app not found")

type Chainer interface {
// AppPath returns the configured App's path.
AppPath() string
Expand All @@ -18,30 +22,60 @@ type Chainer interface {
RPCPublicAddress() (string, error)
}

// APIOption defines options for the client API.
type APIOption func(*apiOptions)

type apiOptions struct {
chain Chainer
}

// WithChain configures the chain to use for the client API.
func WithChain(c Chainer) APIOption {
return func(o *apiOptions) {
o.chain = c
}
}

// NewClientAPI creates a new app ClientAPI.
func NewClientAPI(c Chainer) ClientAPI {
return clientAPI{chain: c}
func NewClientAPI(options ...APIOption) ClientAPI {
o := apiOptions{}
for _, apply := range options {
apply(&o)
}
return clientAPI{o}
}

type clientAPI struct {
chain Chainer
o apiOptions
}

func (api clientAPI) GetChainInfo(context.Context) (*ChainInfo, error) {
chainID, err := api.chain.ID()
chain, err := api.getChain()
if err != nil {
return nil, err
}

chainID, err := chain.ID()
if err != nil {
return nil, err
}

rpc, err := api.chain.RPCPublicAddress()
rpc, err := chain.RPCPublicAddress()
if err != nil {
return nil, err
}

return &ChainInfo{
ChainId: chainID,
AppPath: api.chain.AppPath(),
ConfigPath: api.chain.ConfigPath(),
AppPath: chain.AppPath(),
ConfigPath: chain.ConfigPath(),
RpcAddress: rpc,
}, nil
}

func (api clientAPI) getChain() (Chainer, error) {
if api.o.chain == nil {
return nil, ErrAppChainNotFound
}
return api.o.chain, nil
}

0 comments on commit c148343

Please sign in to comment.