-
Notifications
You must be signed in to change notification settings - Fork 558
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(plugin): execute from function (#3899)
- Loading branch information
Showing
19 changed files
with
760 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
package plugininternal | ||
|
||
import ( | ||
"bytes" | ||
"context" | ||
"time" | ||
|
||
"google.golang.org/grpc/status" | ||
|
||
pluginsconfig "github.com/ignite/cli/v28/ignite/config/plugins" | ||
"github.com/ignite/cli/v28/ignite/pkg/errors" | ||
"github.com/ignite/cli/v28/ignite/services/plugin" | ||
) | ||
|
||
// Execute starts and executes a plugin, then shutdowns it. | ||
func Execute(ctx context.Context, path string, args []string, options ...plugin.APIOption) (string, error) { | ||
var buf bytes.Buffer | ||
plugins, err := plugin.Load( | ||
ctx, | ||
[]pluginsconfig.Plugin{{Path: path}}, | ||
plugin.RedirectStdout(&buf), | ||
) | ||
if err != nil { | ||
return "", err | ||
} | ||
defer plugins[0].KillClient() | ||
if plugins[0].Error != nil { | ||
return "", plugins[0].Error | ||
} | ||
err = plugins[0].Interface.Execute( | ||
ctx, | ||
&plugin.ExecutedCommand{Args: args}, | ||
plugin.NewClientAPI(options...), | ||
) | ||
if err != nil { | ||
// Extract the rpc status message and create a simple error from it. | ||
// We don't want Execute to return rpc errors. | ||
err = errors.New(status.Convert(err).Message()) | ||
} | ||
// 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 absent from buf. | ||
time.Sleep(100 * time.Millisecond) | ||
return buf.String(), err | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
package plugininternal | ||
|
||
import ( | ||
"context" | ||
"os" | ||
"path/filepath" | ||
"strings" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/require" | ||
|
||
"github.com/ignite/cli/v28/ignite/services/plugin" | ||
"github.com/ignite/cli/v28/ignite/services/plugin/mocks" | ||
) | ||
|
||
func TestPluginExecute(t *testing.T) { | ||
tests := []struct { | ||
name string | ||
pluginPath string | ||
expectedOut string | ||
expectedError string | ||
}{ | ||
{ | ||
name: "fail: plugin doesnt exist", | ||
pluginPath: "/not/exists", | ||
expectedError: "local app path \"/not/exists\" not found: stat /not/exists: no such file or directory", | ||
}, | ||
{ | ||
name: "ok: plugin execute ok ", | ||
pluginPath: "testdata/execute_ok", | ||
expectedOut: "ok args=[arg1 arg2] chainid=id appPath=apppath configPath=configpath home=home rpcAddress=rpcPublicAddress\n", | ||
}, | ||
{ | ||
name: "ok: plugin execute fail ", | ||
pluginPath: "testdata/execute_fail", | ||
expectedError: "fail", | ||
}, | ||
} | ||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
pluginPath := tt.pluginPath | ||
if !strings.HasPrefix(pluginPath, "/") { | ||
// add working dir to relative paths | ||
wd, err := os.Getwd() | ||
require.NoError(t, err) | ||
pluginPath = filepath.Join(wd, pluginPath) | ||
} | ||
chainer := mocks.NewChainerInterface(t) | ||
chainer.EXPECT().ID().Return("id", nil).Maybe() | ||
chainer.EXPECT().AppPath().Return("apppath").Maybe() | ||
chainer.EXPECT().ConfigPath().Return("configpath").Maybe() | ||
chainer.EXPECT().Home().Return("home", nil).Maybe() | ||
chainer.EXPECT().RPCPublicAddress().Return("rpcPublicAddress", nil).Maybe() | ||
|
||
out, err := Execute( | ||
context.Background(), | ||
pluginPath, | ||
[]string{"arg1", "arg2"}, | ||
plugin.WithChain(chainer), | ||
) | ||
|
||
if tt.expectedError != "" { | ||
require.EqualError(t, err, tt.expectedError) | ||
return | ||
} | ||
require.NoError(t, err) | ||
require.Equal(t, tt.expectedOut, out) | ||
}) | ||
} | ||
} |
1 change: 1 addition & 0 deletions
1
ignite/services/plugin/internal/testdata/execute_fail/.gitignore
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
execute_fail* |
99 changes: 99 additions & 0 deletions
99
ignite/services/plugin/internal/testdata/execute_fail/go.mod
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
module execute_fail | ||
|
||
go 1.21.1 | ||
|
||
toolchain go1.21.5 | ||
|
||
require ( | ||
github.com/hashicorp/go-plugin v1.5.2 | ||
github.com/ignite/cli/v28 v28.0.0 | ||
) | ||
|
||
replace github.com/ignite/cli/v28 => ../../../../../.. | ||
|
||
require ( | ||
dario.cat/mergo v1.0.0 // indirect | ||
github.com/Microsoft/go-winio v0.6.1 // indirect | ||
github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 // indirect | ||
github.com/aymanbagabas/go-osc52 v1.2.1 // indirect | ||
github.com/aymerick/douceur v0.2.0 // indirect | ||
github.com/blang/semver/v4 v4.0.0 // indirect | ||
github.com/charmbracelet/lipgloss v0.6.0 // indirect | ||
github.com/cloudflare/circl v1.3.7 // indirect | ||
github.com/cockroachdb/errors v1.11.1 // indirect | ||
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect | ||
github.com/cockroachdb/redact v1.1.5 // indirect | ||
github.com/cosmos/btcutil v1.0.5 // indirect | ||
github.com/cosmos/cosmos-sdk v0.50.3 // indirect | ||
github.com/cyphar/filepath-securejoin v0.2.4 // indirect | ||
github.com/emirpasic/gods v1.18.1 // indirect | ||
github.com/fatih/color v1.15.0 // indirect | ||
github.com/fatih/structs v1.1.0 // indirect | ||
github.com/getsentry/sentry-go v0.25.0 // indirect | ||
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect | ||
github.com/go-git/go-billy/v5 v5.5.0 // indirect | ||
github.com/go-git/go-git/v5 v5.11.0 // indirect | ||
github.com/gobuffalo/flect v0.3.0 // indirect | ||
github.com/gobuffalo/genny/v2 v2.1.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/packd v1.0.2 // indirect | ||
github.com/gobuffalo/plush/v4 v4.1.19 // indirect | ||
github.com/gobuffalo/tags/v3 v3.1.4 // indirect | ||
github.com/gobuffalo/validate/v3 v3.3.3 // indirect | ||
github.com/goccy/go-yaml v1.11.2 // indirect | ||
github.com/gofrs/uuid v4.4.0+incompatible // indirect | ||
github.com/gogo/protobuf v1.3.2 // indirect | ||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect | ||
github.com/golang/protobuf v1.5.3 // indirect | ||
github.com/google/go-github/v48 v48.2.0 // indirect | ||
github.com/google/go-querystring v1.1.0 // indirect | ||
github.com/gorilla/css v1.0.0 // indirect | ||
github.com/hashicorp/go-hclog v1.5.0 // indirect | ||
github.com/hashicorp/yamux v0.1.1 // indirect | ||
github.com/imdario/mergo v0.3.13 // indirect | ||
github.com/inconshreveable/mousetrap v1.1.0 // indirect | ||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect | ||
github.com/kevinburke/ssh_config v1.2.0 // indirect | ||
github.com/kr/pretty v0.3.1 // indirect | ||
github.com/kr/text v0.2.0 // indirect | ||
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect | ||
github.com/mattn/go-colorable v0.1.13 // indirect | ||
github.com/mattn/go-isatty v0.0.20 // indirect | ||
github.com/mattn/go-runewidth v0.0.14 // indirect | ||
github.com/microcosm-cc/bluemonday v1.0.23 // indirect | ||
github.com/mitchellh/go-testing-interface v1.14.1 // indirect | ||
github.com/mitchellh/mapstructure v1.5.0 // indirect | ||
github.com/muesli/reflow v0.3.0 // indirect | ||
github.com/muesli/termenv v0.14.0 // indirect | ||
github.com/oklog/run v1.1.0 // indirect | ||
github.com/pjbgf/sha1cd v0.3.0 // indirect | ||
github.com/pkg/errors v0.9.1 // indirect | ||
github.com/rivo/uniseg v0.2.0 // indirect | ||
github.com/rogpeppe/go-internal v1.11.0 // indirect | ||
github.com/sergi/go-diff v1.3.1 // indirect | ||
github.com/sirupsen/logrus v1.9.3 // indirect | ||
github.com/skeema/knownhosts v1.2.1 // indirect | ||
github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d // indirect | ||
github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e // indirect | ||
github.com/spf13/cobra v1.8.0 // indirect | ||
github.com/spf13/pflag v1.0.5 // indirect | ||
github.com/xanzy/ssh-agent v0.3.3 // indirect | ||
go.etcd.io/bbolt v1.3.8 // indirect | ||
golang.org/x/crypto v0.17.0 // indirect | ||
golang.org/x/exp v0.0.0-20231108232855-2478ac86f678 // indirect | ||
golang.org/x/mod v0.14.0 // indirect | ||
golang.org/x/net v0.19.0 // indirect | ||
golang.org/x/sync v0.5.0 // indirect | ||
golang.org/x/sys v0.15.0 // indirect | ||
golang.org/x/term v0.15.0 // indirect | ||
golang.org/x/text v0.14.0 // indirect | ||
golang.org/x/tools v0.15.0 // indirect | ||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect | ||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231212172506-995d672761c0 // indirect | ||
google.golang.org/grpc v1.60.1 // indirect | ||
google.golang.org/protobuf v1.32.0 // indirect | ||
gopkg.in/warnings.v0 v0.1.2 // indirect | ||
gopkg.in/yaml.v2 v2.4.0 // indirect | ||
) |
Oops, something went wrong.