From 718f27cb581da755435961085658ad087beefcd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jer=C3=B3nimo=20Albi?= Date: Fri, 10 Nov 2023 15:49:02 +0100 Subject: [PATCH] refactor: change plugin system to use gRPC (#3529) * chore: update plugin template Go version to 1.20 * docs: add documentation to clarify the plugin cache purpose * chore: improve plugins code spacing for better redability * chore: add context support to plugin scaffold * refactor: move plugin RPC implementation to an `rpc.go` file * refactor: simplify RPC plugin implementation * feat: add proto buffer files for the gRPC plugins * chore: generate plugin files from proto * chore: remove extra blank line * chore: add Flags to ExecutedCommand proto definition * refactor: remove rpc plugin implementation * refactor: move interface types methods to the generated types * refactor: move plugin interface into grpc package * feat: add gRPC plugin implementation * refactor: change plugin to use gRPC for communication * refactor: change plugin command to use the new gRPC interface * refactor: add context to gRPC plugin client communication * refactor: move plugin interface and gRPC implementation Done to have a better package API. * chore: add plugin flag type aliases for v1 * refactor: add flag contructor methods to executed command * refactor: update plugin template to use gRPC * test: fixed tests * chore: move proto flag type enum definition into flag message * chore: add changelog entry * chore: correct flag type reference in plugin service tests * test: improve plugin scaffold test * test: change flag types * chore: lower plugin template Go version to 1.19 This is temporary until CI/CD allows Go v1.20 * chore: use `hplugin` alias go hashicorp's go-plugin package To keep consistency between imports in the plugin package. * test: fix issue that killed plugins when testing * test: fix plugin command tests * fix: correct issue in plugin load * chore: update plugin documentation * chore: fix changelog * chore: add buf to tool dependencies * feat: add make file targets to generate code from proto * fix: correct proto file linting issue * chore: proto file format fix * ci: add GitHub workflow to check and lint proto files * ci: disable proto breaking change It must be disabled until proto files are available in the main branch. * fix: correct Buf repository name * test: change plugin integration test to use a local example folder This was done to allow CI to pass the test without the requirement of merging the changes into the example plugin repository. * chore: update Go and CLI versions Co-authored-by: Danilo Pantani * ci: update GitHub workflows to use Go version 1.20 * fix: beam me up Scotty * test: move command and manifest test to the right location * test: add plugin gRPC types tests * ci: correct CI issue with naked return * fix: correct plugin command path issue * chore: remove deprecated replace from Go mod Co-authored-by: Julien Robert * chore: change Ignite App handshake config Co-authored-by: Danilo Pantani * feat: add bidirectional communication to plugin system (#3544) * chore: rename `types.proto`to `interface.proto` * feat: add code analizer support Adds initial analizer support to allow bidirectional communication between the CLI and the plugins. The analizer features should be defined and implemented on top of these changes. * feat: add analizer support to plugin's interface * chore: add proto generated code * chore: generate interface mocks * refactor: change protocol implementation to support analizer * chore: fix issue with missing return * refactor: change plugin command to add analizer to calls * feat: add proto types required for the cosmos/proto analysis packages These types allows the implementation of the dependencies analyzer. * chore: update plugin template to include analizer arguments * fix: correct type in Analyzer name * chore: update plugin documentation * chore: rename analyzer file name because of typo * fix: correct typo for analyzer names * chore: update changelog * test: fix plugin integration test * test: fix plugin cmd unit tests * test: fix plugin service unit test * ci: fix unused argument warning * refactor: Add basic GetChainInfo method to plugin API (#3561) * refactor: Analyzer/analizer -> ClientAPI * refactor: rename proto files and rebuild * refactor: Add json tags * wip/refactor: Module analysis * feat: Add chain reference to plugin ClientAPI * feat: Complete Dependencies ClientAPI method * fix: Address review comments * feat: Remove services/chain dep from pkg/cosmosanalysis as per discussion * wip: remove deptools install * feat: package-specific includes * fix: Replace Module List call with Chain Info call * chore: Remove chain analysis code * feat: ChainInfo API example template * chore: Update template cli reference * chore: clean up PR * fix: Address review comments * fix: address review comments * fix: address review comments * fix: Tests and linting * chore: add changelog * fix: linting issues * tests: fix issue with client api in plugin tests * tests: fix plugin template for integration tests --------- Co-authored-by: jeronimoalbi * chore: correct typos and simplify code * chore: update pseudo version for plugin's `go.mod` template * chore: fix typos * fix: correct call to module dependency resolution * chore: remove proto file comment --------- Co-authored-by: Danilo Pantani Co-authored-by: Clockwork --------- Co-authored-by: Danilo Pantani Co-authored-by: Julien Robert Co-authored-by: Clockwork --- .github/workflows/proto-checker.yml | 31 + .gitignore | 1 - Makefile | 20 + buf.work.yaml | 3 + changelog.md | 11 + docs/docs/apps/02-developing-apps.md | 108 ++- go.mod | 29 +- go.sum | 70 +- ignite/cmd/plugin.go | 101 +- ignite/cmd/plugin_default.go | 2 +- ignite/cmd/plugin_test.go | 401 ++++---- ignite/config/chain/config.go | 1 - ignite/internal/tools/tools.go | 1 + ignite/pkg/cosmosanalysis/module/module.go | 37 +- .../cosmosclient/mocks/account_retriever.go | 2 +- .../cosmosclient/mocks/bank_query_client.go | 2 +- .../pkg/cosmosclient/mocks/faucet_client.go | 12 +- ignite/pkg/cosmosclient/mocks/gasometer.go | 14 +- ignite/pkg/cosmosclient/mocks/rpc_client.go | 2 +- ignite/pkg/cosmosclient/mocks/signer.go | 7 +- ignite/pkg/cosmostxcollector/mocks/saver.go | 10 +- .../cosmostxcollector/mocks/txs_collector.go | 7 +- ignite/pkg/protoanalysis/package.go | 76 +- ignite/services/chain/chain.go | 5 + ignite/services/plugin/cache.go | 3 + ignite/services/plugin/cache_test.go | 10 +- ignite/services/plugin/client_api.go | 47 + .../services/plugin/grpc/v1/client_api.pb.go | 178 ++++ .../services/plugin/grpc/v1/interface.pb.go | 856 ++++++++++++++++ .../plugin/grpc/v1/interface_command.go | 92 ++ .../services/plugin/grpc/v1/interface_flag.go | 129 +++ .../services/plugin/grpc/v1/interface_hook.go | 6 + .../plugin/grpc/v1/interface_manifest.go | 27 + ignite/services/plugin/grpc/v1/service.pb.go | 914 ++++++++++++++++++ .../plugin/grpc/v1/service_grpc.pb.go | 383 ++++++++ .../plugin/grpc/v1/types_command_test.go | 343 +++++++ .../plugin/grpc/v1/types_hook_test.go | 45 + .../plugin/grpc/v1/types_manifest_test.go | 110 +++ ignite/services/plugin/interface.go | 483 +-------- ignite/services/plugin/interface_test.go | 169 ---- ignite/services/plugin/mocks/client_api.go | 93 ++ ignite/services/plugin/mocks/interface.go | 140 +-- ignite/services/plugin/plugin.go | 78 +- ignite/services/plugin/plugin_test.go | 79 +- ignite/services/plugin/protocol.go | 233 +++++ ignite/services/plugin/scaffold.go | 20 +- ignite/services/plugin/scaffold_test.go | 10 +- ignite/services/plugin/template/go.mod.plush | 4 +- ignite/services/plugin/template/main.go.plush | 85 +- integration/plugin/plugin_test.go | 16 +- .../plugin/testdata/example-plugin/go.mod | 82 ++ .../plugin/testdata/example-plugin/go.sum | 288 ++++++ .../plugin/testdata/example-plugin/main.go | 74 ++ proto/buf.gen.yaml | 8 + proto/buf.md | 3 + proto/buf.yaml | 15 + .../services/plugin/grpc/v1/client_api.proto | 12 + .../services/plugin/grpc/v1/interface.proto | 147 +++ .../services/plugin/grpc/v1/service.proto | 84 ++ 59 files changed, 5093 insertions(+), 1126 deletions(-) create mode 100644 .github/workflows/proto-checker.yml create mode 100644 buf.work.yaml create mode 100644 ignite/services/plugin/client_api.go create mode 100644 ignite/services/plugin/grpc/v1/client_api.pb.go create mode 100644 ignite/services/plugin/grpc/v1/interface.pb.go create mode 100644 ignite/services/plugin/grpc/v1/interface_command.go create mode 100644 ignite/services/plugin/grpc/v1/interface_flag.go create mode 100644 ignite/services/plugin/grpc/v1/interface_hook.go create mode 100644 ignite/services/plugin/grpc/v1/interface_manifest.go create mode 100644 ignite/services/plugin/grpc/v1/service.pb.go create mode 100644 ignite/services/plugin/grpc/v1/service_grpc.pb.go create mode 100644 ignite/services/plugin/grpc/v1/types_command_test.go create mode 100644 ignite/services/plugin/grpc/v1/types_hook_test.go create mode 100644 ignite/services/plugin/grpc/v1/types_manifest_test.go delete mode 100644 ignite/services/plugin/interface_test.go create mode 100644 ignite/services/plugin/mocks/client_api.go create mode 100644 ignite/services/plugin/protocol.go create mode 100644 integration/plugin/testdata/example-plugin/go.mod create mode 100644 integration/plugin/testdata/example-plugin/go.sum create mode 100644 integration/plugin/testdata/example-plugin/main.go create mode 100644 proto/buf.gen.yaml create mode 100644 proto/buf.md create mode 100644 proto/buf.yaml create mode 100644 proto/ignite/services/plugin/grpc/v1/client_api.proto create mode 100644 proto/ignite/services/plugin/grpc/v1/interface.proto create mode 100644 proto/ignite/services/plugin/grpc/v1/service.proto diff --git a/.github/workflows/proto-checker.yml b/.github/workflows/proto-checker.yml new file mode 100644 index 0000000000..1abdd37c38 --- /dev/null +++ b/.github/workflows/proto-checker.yml @@ -0,0 +1,31 @@ +name: Protobuf Files + +on: + pull_request: + paths: + - "proto/**" + +permissions: + contents: read + +jobs: + lint: + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - uses: actions/checkout@v3 + - uses: bufbuild/buf-setup-action@v1.22.0 + - uses: bufbuild/buf-lint-action@v1 + with: + input: "proto" + + # TODO: Uncomment after PR#3529 is merged + # break-check: + # runs-on: ubuntu-latest + # steps: + # - uses: actions/checkout@v3 + # - uses: bufbuild/buf-setup-action@v1.22.0 + # - uses: bufbuild/buf-breaking-action@v1 + # with: + # input: "proto" + # against: "https://github.com/${{ github.repository }}.git#branch=${{ github.event.pull_request.base.ref }},ref=HEAD~1,subdir=proto" diff --git a/.gitignore b/.gitignore index 9f3c28161b..671a36b808 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,6 @@ scripts/**/nodetime-* dist/ node_modules .DS_Store -apps/ .idea .vscode docs/.vuepress/dist diff --git a/Makefile b/Makefile index 7347759283..7292ecdc66 100644 --- a/Makefile +++ b/Makefile @@ -59,6 +59,26 @@ lint: .PHONY: govet format lint +## proto-all: Format, lint and generate code from proto files using buf. +proto-all: proto-format proto-lint proto-gen + +## proto-gen: Run buf generate. +proto-gen: + @echo Generating code from proto... + @buf generate --template ./proto/buf.gen.yaml --output ./ + +## proto-format: Run buf format and update files with invalid proto format> +proto-format: + @echo Formatting proto files... + @buf format --write + +## proto-lint: Run buf lint. +proto-lint: + @echo Linting proto files... + @buf lint + +.PHONY: proto-all proto-gen proto-format proto-lint + ## test-unit: Run the unit tests. test-unit: @echo Running unit tests... diff --git a/buf.work.yaml b/buf.work.yaml new file mode 100644 index 0000000000..1878b341be --- /dev/null +++ b/buf.work.yaml @@ -0,0 +1,3 @@ +version: v1 +directories: + - proto diff --git a/changelog.md b/changelog.md index c8c2957409..1dc1d03e52 100644 --- a/changelog.md +++ b/changelog.md @@ -4,6 +4,17 @@ ### Features +- [#3544](https://github.com/ignite/cli/pull/3544) Add bidirectional communication to plugin system +- [#3561](https://github.com/ignite/cli/pull/3561) Add GetChainInfo method to plugin system API + +### Changes + +- [#3529](https://github.com/ignite/cli/pull/3529) Refactor plugin system to use gRPC + +## [`v0.27.1`](https://github.com/ignite/cli/releases/tag/v0.27.1) + +### Features + - [#3476](https://github.com/ignite/cli/pull/3476) Use `buf.build` binary to code generate from proto files - [#3614](https://github.com/ignite/cli/pull/3614) feat: use DefaultBaseappOptions for app.New method - [#3536](https://github.com/ignite/cli/pull/3536) Change app.go to v2 and add AppWiring feature diff --git a/docs/docs/apps/02-developing-apps.md b/docs/docs/apps/02-developing-apps.md index 1f5a13a508..57d1fdd58b 100644 --- a/docs/docs/apps/02-developing-apps.md +++ b/docs/docs/apps/02-developing-apps.md @@ -43,31 +43,35 @@ All apps must implement a predefined interface: ```go title=ignite/services/plugin/interface.go type Interface interface { // Manifest declares app's Command(s) and Hook(s). - Manifest() (Manifest, error) + Manifest(context.Context) (*Manifest, error) // Execute will be invoked by ignite when an app Command is executed. // It is global for all commands declared in Manifest, if you have declared // multiple commands, use cmd.Path to distinguish them. - Execute(cmd ExecutedCommand) error + // The ClientAPI argument can be used by plugins to get chain app analysis info. + Execute(context.Context, *ExecutedCommand, ClientAPI) error // ExecuteHookPre is invoked by ignite when a command specified by the Hook // path is invoked. // It is global for all hooks declared in Manifest, if you have declared // multiple hooks, use hook.Name to distinguish them. - ExecuteHookPre(hook ExecutedHook) error + // The ClientAPI argument can be used by plugins to get chain app analysis info. + ExecuteHookPre(context.Context, *ExecutedHook, ClientAPI) error // ExecuteHookPost is invoked by ignite when a command specified by the hook // path is invoked. // It is global for all hooks declared in Manifest, if you have declared // multiple hooks, use hook.Name to distinguish them. - ExecuteHookPost(hook ExecutedHook) error + // The ClientAPI argument can be used by plugins to get chain app analysis info. + ExecuteHookPost(context.Context, *ExecutedHook, ClientAPI) error // ExecuteHookCleanUp is invoked by ignite when a command specified by the // hook path is invoked. Unlike ExecuteHookPost, it is invoked regardless of // execution status of the command and hooks. // It is global for all hooks declared in Manifest, if you have declared // multiple hooks, use hook.Name to distinguish them. - ExecuteHookCleanUp(hook ExecutedHook) error + // The ClientAPI argument can be used by plugins to get chain app analysis info. + ExecuteHookCleanUp(context.Context, *ExecutedHook, ClientAPI) error } ``` @@ -76,35 +80,34 @@ the method's body. ## Defining app's manifest -Here is the `Manifest` struct: - -```go title=ignite/services/plugin/interface.go -type Manifest struct { - Name string - - // Commands contains the commands that will be added to the list of ignite - // commands. Each commands are independent, for nested commands use the - // inner Commands field. - Commands []Command - - // Hooks contains the hooks that will be attached to the existing ignite - // commands. - Hooks []Hook - - // SharedHost enables sharing a single app server across all running instances - // of an app. Useful if an app adds or extends long running commands - // - // Example: if an app defines a hook on `ignite chain serve`, a server is instanciated - // when the command is run. Now if you want to interact with that instance from commands - // defined in that app, you need to enable `SharedHost`, or else the commands will just - // instantiate separate app servers. - // - // When enabled, all apps of the same `Path` loaded from the same configuration will - // attach it's gRPC client to a an existing gRPC server. - // - // If an app instance has no other running app servers, it will create one and it - // will be the host. - SharedHost bool `yaml:"shared_host"` +Here is the `Manifest` proto message definition: + +```protobuf title=proto/ignite/services/plugin/grpc/v1/types.proto +message Manifest { + // App name. + string name = 1; + + // Commands contains the commands that will be added to the list of ignite commands. + // Each commands are independent, for nested commands use the inner Commands field. + bool shared_host = 2; + + // Hooks contains the hooks that will be attached to the existing ignite commands. + repeated Command commands = 3; + + // Enables sharing a single app server across all running instances of an Ignite App. + // Useful if an app adds or extends long running commands. + // + // Example: if an app defines a hook on `ignite chain serve`, a server is instanciated + // when the command is run. Now if you want to interact with that instance + // from commands defined in that app, you need to enable shared host, or else the + // commands will just instantiate separate app servers. + // + // When enabled, all apps of the same path loaded from the same configuration will + // attach it's RPC client to a an existing RPC server. + // + // If an app instance has no other running app servers, it will create one and it + // will be the host. + repeated Hook hooks = 4; } ``` @@ -132,16 +135,16 @@ For instance, let's say your app adds a new `oracle` command to `ignite scaffold`, then the `Manifest` method will look like : ```go -func (app) Manifest() (plugin.Manifest, error) { - return plugin.Manifest{ +func (app) Manifest(context.Context) (*plugin.Manifest, error) { + return &plugin.Manifest{ Name: "oracle", - Commands: []plugin.Command{ + Commands: []*plugin.Command{ { Use: "oracle [name]", Short: "Scaffold an oracle module", Long: "Long description goes here...", // Optionnal flags is required - Flags: []plugin.Flag{ + Flags: []*plugin.Flag{ {Name: "source", Type: plugin.FlagTypeString, Usage: "the oracle source"}, }, // Attach the command to `scaffold` @@ -156,14 +159,21 @@ To update the app execution, you have to change the `Execute` command. For example: ```go -func (app) Execute(cmd plugin.ExecutedCommand) error { +func (app) Execute(_ context.Context, cmd *plugin.ExecutedCommand, _ plugin.ClientAPI) error { if len(cmd.Args) == 0 { return fmt.Errorf("oracle name missing") } + + flags, err := cmd.NewFlags() + if err != nil { + return err + } + var ( name = cmd.Args[0] - source, _ = cmd.Flags().GetString("source") + source, _ = flags.GetString("source") ) + // Read chain information c, err := getChain(cmd) if err != nil { @@ -199,10 +209,10 @@ resulting in `post` and `clean up` not executing. The following is an example of a `hook` definition. ```go -func (app) Manifest() (plugin.Manifest, error) { - return plugin.Manifest{ +func (app) Manifest(context.Context) (*plugin.Manifest, error) { + return &plugin.Manifest{ Name: "oracle", - Hooks: []plugin.Hook{ + Hooks: []*plugin.Hook{ { Name: "my-hook", PlaceHookOn: "ignite chain build", @@ -211,8 +221,8 @@ func (app) Manifest() (plugin.Manifest, error) { }, nil } -func (app) ExecuteHookPre(hook plugin.ExecutedHook) error { - switch hook.Name { +func (app) ExecuteHookPre(_ context.Context, h *plugin.ExecutedHook, _ plugin.ClientAPI) error { + switch h.Hook.GetName() { case "my-hook": fmt.Println("I'm executed before ignite chain build") default: @@ -221,8 +231,8 @@ func (app) ExecuteHookPre(hook plugin.ExecutedHook) error { return nil } -func (app) ExecuteHookPost(hook plugin.ExecutedHook) error { - switch hook.Name { +func (app) ExecuteHookPost(_ context.Context, h *plugin.ExecutedHook, _ plugin.ClientAPI) error { + switch h.Hook.GetName() { case "my-hook": fmt.Println("I'm executed after ignite chain build (if no error)") default: @@ -231,8 +241,8 @@ func (app) ExecuteHookPost(hook plugin.ExecutedHook) error { return nil } -func (app) ExecuteHookCleanUp(hook plugin.ExecutedHook) error { - switch hook.Name { +func (app) ExecuteHookCleanUp(_ context.Context, h *plugin.ExecutedHook, _ plugin.ClientAPI) error { + switch h.Hook.GetName() { case "my-hook": fmt.Println("I'm executed after ignite chain build (regardless errors)") default: diff --git a/go.mod b/go.mod index 8492f9534f..be043fe2b4 100644 --- a/go.mod +++ b/go.mod @@ -11,6 +11,7 @@ require ( github.com/DATA-DOG/go-sqlmock v1.5.0 github.com/blang/semver/v4 v4.0.0 github.com/briandowns/spinner v1.23.0 + github.com/bufbuild/buf v1.7.0 github.com/buger/jsonparser v1.1.1 github.com/cenkalti/backoff v2.2.1+incompatible github.com/charmbracelet/bubbles v0.7.6 @@ -70,6 +71,7 @@ require ( golang.org/x/tools v0.9.1 golang.org/x/vuln v0.1.0 google.golang.org/grpc v1.56.3 + google.golang.org/protobuf v1.30.0 gopkg.in/yaml.v2 v2.4.0 mvdan.cc/gofumpt v0.5.0 sigs.k8s.io/yaml v1.3.0 @@ -93,6 +95,7 @@ require ( github.com/Abirdcfly/dupword v0.0.7 // indirect github.com/Antonboom/errname v0.1.7 // indirect github.com/Antonboom/nilnil v0.1.1 // indirect + github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect github.com/BurntSushi/toml v1.2.1 // indirect github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d // indirect github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 // indirect @@ -125,6 +128,8 @@ require ( github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect github.com/btcsuite/btcd/btcutil v1.1.3 // indirect github.com/btcsuite/btcd/chaincfg/chainhash v1.0.2 // indirect + github.com/bufbuild/connect-go v1.0.0 // indirect + github.com/bufbuild/protocompile v0.4.0 // indirect github.com/butuzov/ireturn v0.1.1 // indirect github.com/calmh/randomart v1.1.0 // indirect github.com/cespare/xxhash v1.1.0 // indirect @@ -142,6 +147,7 @@ require ( github.com/confio/ics23/go v0.9.0 // indirect github.com/containerd/console v1.0.4-0.20230508195404-8d3c090fd31c // indirect github.com/containerd/containerd v1.7.0-beta.2 // indirect + github.com/containerd/typeurl v1.0.3-0.20220422153119-7f6e6d160d67 // indirect github.com/cosiner/argv v0.1.0 // indirect github.com/cosmos/btcutil v1.0.5 // indirect github.com/cosmos/cosmos-proto v1.0.0-beta.2 // indirect @@ -162,7 +168,10 @@ require ( github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect github.com/dlclark/regexp2 v1.2.0 // indirect + github.com/docker/distribution v2.8.1+incompatible // indirect github.com/docker/docker v24.0.7+incompatible // indirect + github.com/docker/go-connections v0.4.0 // indirect + github.com/docker/go-units v0.5.0 // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/dvsekhvalnov/jose2go v1.5.0 // indirect github.com/emirpasic/gods v1.18.1 // indirect @@ -174,6 +183,7 @@ require ( github.com/firefart/nonamedreturns v1.0.4 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/fzipp/gocyclo v0.6.0 // indirect + github.com/go-chi/chi/v5 v5.0.7 // indirect github.com/go-critic/go-critic v0.6.5 // indirect github.com/go-delve/liner v1.2.3-0.20220127212407-d32d89dd2a5d // indirect github.com/go-git/gcfg v1.5.0 // indirect @@ -181,6 +191,8 @@ require ( github.com/go-kit/kit v0.12.0 // indirect github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.6.0 // indirect + github.com/go-logr/logr v1.2.3 // indirect + github.com/go-logr/stdr v1.2.2 // indirect github.com/go-playground/locales v0.14.0 // indirect github.com/go-toolsmith/astcast v1.0.0 // indirect github.com/go-toolsmith/astcopy v1.0.2 // indirect @@ -201,6 +213,7 @@ require ( github.com/gofrs/uuid v4.3.0+incompatible // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/glog v1.1.0 // indirect + github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2 // indirect @@ -241,7 +254,10 @@ require ( github.com/huandu/skiplist v1.2.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect + github.com/jdxcode/netrc v0.0.0-20210204082910-926c7f70242a // indirect github.com/jgautheron/goconst v1.5.1 // indirect + github.com/jhump/protocompile v0.0.0-20220216033700-d705409f108f // indirect + github.com/jhump/protoreflect v1.15.1 // indirect github.com/jingyugao/rowserrcheck v1.1.1 // indirect github.com/jinzhu/copier v0.3.5 // indirect github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af // indirect @@ -257,6 +273,7 @@ require ( github.com/kisielk/gotool v1.0.0 // indirect github.com/kkHAIKE/contextcheck v1.1.3 // indirect github.com/klauspost/compress v1.16.5 // indirect + github.com/klauspost/pgzip v1.2.5 // indirect github.com/kulti/thelper v0.6.3 // indirect github.com/kunwardeep/paralleltest v1.0.6 // indirect github.com/kyoh86/exportloopref v0.1.8 // indirect @@ -284,9 +301,12 @@ require ( github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/go-testing-interface v1.14.1 // indirect + github.com/moby/buildkit v0.10.4 // indirect github.com/moby/patternmatcher v0.5.0 // indirect github.com/moby/sys/sequential v0.5.0 // indirect + github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae // indirect github.com/moricho/tparallel v0.2.1 // indirect + github.com/morikuni/aec v1.0.0 // indirect github.com/mtibben/percent v0.2.1 // indirect github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect github.com/muesli/cancelreader v0.2.2 // indirect @@ -300,11 +320,15 @@ require ( github.com/nishanths/predeclared v0.2.2 // indirect github.com/oklog/run v1.0.0 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect + github.com/opencontainers/go-digest v1.0.0 // indirect + github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b // indirect github.com/opencontainers/runc v1.1.7 // indirect github.com/pelletier/go-toml/v2 v2.0.7 // indirect github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08 // indirect github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d // indirect github.com/pjbgf/sha1cd v0.3.0 // indirect + github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect + github.com/pkg/profile v1.6.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/polyfloyd/go-errorlint v1.0.5 // indirect github.com/prometheus/client_golang v1.14.0 // indirect @@ -371,6 +395,10 @@ require ( github.com/zondax/hid v0.9.1 // indirect github.com/zondax/ledger-go v0.14.1 // indirect gitlab.com/bosi/decorder v0.2.3 // indirect + go.opencensus.io v0.24.0 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.36.4 // indirect + go.opentelemetry.io/otel v1.11.1 // indirect + go.opentelemetry.io/otel/trace v1.11.1 // indirect go.starlark.net v0.0.0-20220816155156-cfacd8902214 // indirect go.uber.org/atomic v1.10.0 // indirect go.uber.org/goleak v1.1.12 // indirect @@ -383,7 +411,6 @@ require ( golang.org/x/sys v0.13.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect - google.golang.org/protobuf v1.30.0 // indirect; indir ect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 893dbdfea9..b1f35cadd6 100644 --- a/go.sum +++ b/go.sum @@ -77,6 +77,8 @@ github.com/Antonboom/errname v0.1.7 h1:mBBDKvEYwPl4WFFNwec1CZO096G6vzK9vvDQzAwka github.com/Antonboom/errname v0.1.7/go.mod h1:g0ONh16msHIPgJSGsecu1G/dcF2hlYR/0SddnIAGavU= github.com/Antonboom/nilnil v0.1.1 h1:PHhrh5ANKFWRBh7TdYmyyq2gyT2lotnvFvvFbylF81Q= github.com/Antonboom/nilnil v0.1.1/go.mod h1:L1jBqoWM7AOeTD+tSquifKSesRHs4ZdaxvZR+xdJEaI= +github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= +github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak= github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= @@ -159,8 +161,8 @@ github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiE github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= -github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= -github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= +github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -209,6 +211,10 @@ github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/bufbuild/buf v1.7.0 h1:uWRjhIXcrWkzIkA5TqXGyJbF51VW54QJsQZ3nwaes5Q= +github.com/bufbuild/buf v1.7.0/go.mod h1:Go40fMAF46PnPLC7jJgTQhAI95pmC0+VtxFKVC0qLq0= +github.com/bufbuild/connect-go v1.0.0 h1:htSflKUT8y1jxhoPhPYTZMrsY3ipUXjjrbcZR5O2cVo= +github.com/bufbuild/connect-go v1.0.0/go.mod h1:9iNvh/NOsfhNBUH5CtvXeVUskQO1xsrEviH7ZArwZ3I= github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA= github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8= github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs= @@ -273,6 +279,8 @@ github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUK github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 h1:/inchEIKaYC1Akx+H+gqO04wryn5h75LSazbRlnya1k= +github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cockroachdb/apd/v2 v2.0.2 h1:weh8u7Cneje73dDh+2tEVLUvyBc89iwepWCD8b8034E= github.com/cockroachdb/apd/v2 v2.0.2/go.mod h1:DDxRlzC2lo3/vSlmSoS7JkqbbrARPuFOGr0B9pvN3Gw= github.com/cockroachdb/apd/v3 v3.1.0 h1:MK3Ow7LH0W8zkd5GMKA1PvS9qG3bWFI95WaVNfyZJ/w= @@ -291,6 +299,8 @@ github.com/containerd/console v1.0.4-0.20230508195404-8d3c090fd31c h1:sgmd9/Gm5S github.com/containerd/console v1.0.4-0.20230508195404-8d3c090fd31c/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk= github.com/containerd/containerd v1.7.0-beta.2 h1:GWmC96y8j7jlFJX0Wh+covft0M1hHBqQL7lo+N6qvxg= github.com/containerd/containerd v1.7.0-beta.2/go.mod h1:RR01Jsm/jovDKK48sFCVqWyKAH2APMPi88Aeu1on63I= +github.com/containerd/typeurl v1.0.3-0.20220422153119-7f6e6d160d67 h1:rQvjv7gRi6Ki/NS/U9oLZFhqyk4dh/GH2M3o/4BRkMM= +github.com/containerd/typeurl v1.0.3-0.20220422153119-7f6e6d160d67/go.mod h1:HDkcKOXRnX6yKnXv3P0QrogFi0DoiauK/LpQi961f0A= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= @@ -334,6 +344,7 @@ github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46t github.com/creachadair/taskgroup v0.4.2 h1:jsBLdAJE42asreGss2xZGZ8fJra7WtwnHWeJFxv2Li8= github.com/creachadair/taskgroup v0.4.2/go.mod h1:qiXUOSrbwAY3u0JPGTzObbE3yf9hcXHDKBZ2ZjpCbgM= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.17 h1:QeVUsEDNrLBW4tMgZHvxy18sKtr6VI492kBhUfhDJNI= github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/cristalhq/acmd v0.8.1/go.mod h1:LG5oa43pE/BbxtfMoImHCQN++0Su7dzipdgBjMCBVDQ= @@ -379,8 +390,14 @@ github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUn github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/dlclark/regexp2 v1.2.0 h1:8sAhBGEM0dRWogWqWyQeIJnxjWO6oIjl8FKqREDsGfk= github.com/dlclark/regexp2 v1.2.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= +github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68= +github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/docker v24.0.7+incompatible h1:Wo6l37AuwP3JaMnZa226lzVXGA3F9Ig1seQen0cKYlM= github.com/docker/docker v24.0.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= +github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= +github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= +github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.1-0.20200219035652-afde56e7acac/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= @@ -400,6 +417,8 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/envoyproxy/protoc-gen-validate v0.10.1 h1:c0g45+xCJhdgFGw7a5QAfdS4byAbud7miNWJ1WwEVf8= +github.com/envoyproxy/protoc-gen-validate v0.10.1/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss= github.com/esimonov/ifshort v1.0.4 h1:6SID4yGWfRae/M7hkVDVVyppy8q/v9OuxNdmjLQStBA= github.com/esimonov/ifshort v1.0.4/go.mod h1:Pe8zjlRrJ80+q2CxHLfEOfTwxCZ4O+MuhcHcfgNWTk0= github.com/ettle/strcase v0.1.1 h1:htFueZyVeE1XNnMEfbqp5r67qAN/4r6ya1ysq8Q+Zcw= @@ -436,6 +455,8 @@ github.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlya github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gliderlabs/ssh v0.3.5 h1:OcaySEmAQJgyYcArR+gGGTHCyE7nvhEMTlYY+Dp8CpY= github.com/gliderlabs/ssh v0.3.5/go.mod h1:8XB4KraRrX39qHhT6yxPsHedjA08I/uBVwj4xC+/+z4= +github.com/go-chi/chi/v5 v5.0.7 h1:rDTPXLDHGATaeHvVlLcR4Qe0zftYethFucbjVQ1PxU8= +github.com/go-chi/chi/v5 v5.0.7/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= github.com/go-critic/go-critic v0.6.5 h1:fDaR/5GWURljXwF8Eh31T2GZNz9X4jeboS912mWF8Uo= github.com/go-critic/go-critic v0.6.5/go.mod h1:ezfP/Lh7MA6dBNn4c6ab5ALv3sKnZVLx37tr00uuaOY= github.com/go-delve/delve v1.20.2 h1:rgPK7Iqb1oQk+i2Ilg0fpH6p5LqyixYiAt4N3Lhx4/Y= @@ -466,6 +487,11 @@ github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU= @@ -533,8 +559,8 @@ github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7a github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang-jwt/jwt/v4 v4.0.0 h1:RAqyYixv1p7uEnocuy8P1nru5wprCh/MH2BIlW5z5/o= -github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= +github.com/golang-jwt/jwt/v4 v4.1.0 h1:XUgk2Ex5veyVFVeLm0xhusUTQybEbexJXrvPNOKkSY0= +github.com/golang-jwt/jwt/v4 v4.1.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= github.com/golang-jwt/jwt/v4 v4.4.2 h1:rcc4lwaZgFMCZ5jxF9ABolDcIHdBytAFgqFPbSJQAYs= github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -611,6 +637,7 @@ github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= @@ -782,11 +809,15 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= +github.com/jdxcode/netrc v0.0.0-20210204082910-926c7f70242a h1:d4+I1YEKVmWZrgkt6jpXBnLgV2ZjO0YxEtLDdfIZfH4= +github.com/jdxcode/netrc v0.0.0-20210204082910-926c7f70242a/go.mod h1:Zi/ZFkEqFHTm7qkjyNJjaWH4LQA9LQhGJyF0lTYGpxw= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= github.com/jgautheron/goconst v1.5.1 h1:HxVbL1MhydKs8R8n/HE5NPvzfaYmQJA3o879lE4+WcM= github.com/jgautheron/goconst v1.5.1/go.mod h1:aAosetZ5zaeC/2EfMeRswtxUFBpe2Hr7HzkgX4fanO4= +github.com/jhump/protocompile v0.0.0-20220216033700-d705409f108f h1:BNuUg9k2EiJmlMwjoef3e8vZLHplbVw6DrjGFjLL+Yo= +github.com/jhump/protocompile v0.0.0-20220216033700-d705409f108f/go.mod h1:qr2b5kx4HbFS7/g4uYO5qv9ei8303JMsC7ESbYiqr2Q= github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c= github.com/jhump/protoreflect v1.15.1/go.mod h1:jD/2GMKKE6OqX8qTjhADU1e6DShO+gavG9e0Q693nKo= github.com/jingyugao/rowserrcheck v1.1.1 h1:zibz55j/MJtLsjP1OF4bSdgXxwL1b+Vn7Tjzq7gFzUs= @@ -841,6 +872,8 @@ github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6 github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.16.5 h1:IFV2oUNUzZaz+XyusxpLzpzS8Pt5rh0Z16For/djlyI= github.com/klauspost/compress v1.16.5/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/pgzip v1.2.5 h1:qnWYvvKqedOF2ulHpMG72XQol4ILEJ8k2wwRl/Km8oE= +github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= @@ -959,12 +992,16 @@ github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mmcloughlin/avo v0.5.0/go.mod h1:ChHFdoV7ql95Wi7vuq2YT1bwCJqiWdZrQ1im3VujLYM= +github.com/moby/buildkit v0.10.4 h1:FvC+buO8isGpUFZ1abdSLdGHZVqg9sqI4BbFL8tlzP4= +github.com/moby/buildkit v0.10.4/go.mod h1:Yajz9vt1Zw5q9Pp4pdb3TCSUXJBIroIQGQ3TTs/sLug= github.com/moby/moby v24.0.1+incompatible h1:VzcmrGPwKZLMsjylQP6yqYz3D+MTwFnPt2BDAPYuzQE= github.com/moby/moby v24.0.1+incompatible/go.mod h1:fDXVQ6+S340veQPv35CzDahGBmHsiclFwfEygB/TWMc= github.com/moby/patternmatcher v0.5.0 h1:YCZgJOeULcxLw1Q+sVR636pmS7sPEn1Qo2iAN6M7DBo= github.com/moby/patternmatcher v0.5.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc= github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc= github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo= +github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae h1:O4SWKdcHVCvYqyDV+9CJA1fcDN2L11Bule0iFy3YlAI= +github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae/go.mod h1:E2VnQOmVuvZB6UYnnDB0qG5Nq/1tD9acaOpo6xmt0Kw= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= @@ -972,6 +1009,8 @@ github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3Rllmb github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/moricho/tparallel v0.2.1 h1:95FytivzT6rYzdJLdtfn6m1bfFJylOJK41+lgv/EHf4= github.com/moricho/tparallel v0.2.1/go.mod h1:fXEIZxG2vdfl0ZF8b42f5a78EhjjD5mX8qUplsoSU4k= +github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= +github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/mtibben/percent v0.2.1 h1:5gssi8Nqo8QU/r2pynCm+hBQHpkB/uNK7BJCFogWdzs= github.com/mtibben/percent v0.2.1/go.mod h1:KG9uO+SZkUp+VkRHsCdYQV3XSZrrSpR3O9ibNBTZrns= github.com/muesli/ansi v0.0.0-20211018074035-2e021307bc4b/go.mod h1:fQuZ0gauxyBcmsdE3ZT4NasjaRdxmbCS0jRHsrWu3Ho= @@ -1032,6 +1071,10 @@ github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7J github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.20.0 h1:8W0cWlwFkflGPLltQvLRB7ZVD5HuP6ng320w2IS245Q= github.com/onsi/gomega v1.20.0/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo= +github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= +github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= +github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b h1:YWuSjZCQAPM8UUBLkYUk1e+rZcvWHJmFb6i6rM44Xs8= +github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b/go.mod h1:3OVijpioIKYWTqjiG0zfF6wvoJ4fAXGbjdZuI2NgsRQ= github.com/opencontainers/runc v1.1.7 h1:y2EZDS8sNng4Ksf0GUYNhKbTShZJPJg1FiXJNH/uoCk= github.com/opencontainers/runc v1.1.7/go.mod h1:CbUumNnWCuTGFukNXahoo/RFBZvDAgRh/smNYNOhA50= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= @@ -1059,10 +1102,14 @@ github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d h1:CdDQnGF8Nq9oc github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d/go.mod h1:3OzsM7FXDQlpCiw2j81fOmAwQLnZnLGXVKUzeKQXIAw= github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI= +github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU= +github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/profile v1.6.0 h1:hUDfIISABYI59DyeB3OTay/HxSRwTQ8rB/H83k6r5dM= +github.com/pkg/profile v1.6.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18= github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -1331,6 +1378,12 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.36.4 h1:PRXhsszxTt5bbPriTjmaweWUsAnJYeWBhUMLRetUgBU= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.36.4/go.mod h1:05eWWy6ZWzmpeImD3UowLTB3VjDMU1yxQ+ENuVWDM3c= +go.opentelemetry.io/otel v1.11.1 h1:4WLLAmcfkmDk2ukNXJyq3/kiz/3UzCaYq6PskJsaou4= +go.opentelemetry.io/otel v1.11.1/go.mod h1:1nNhXBbWSD0nsL38H6btgnFN2k4i0sNLHNNMZMSbUGE= +go.opentelemetry.io/otel/trace v1.11.1 h1:ofxdnzsNrGBYXbP7t7zpUK281+go5rF7dvdIZXF8gdQ= +go.opentelemetry.io/otel/trace v1.11.1/go.mod h1:f/Q9G7vzk5u91PhbmKbg1Qn0rzH1LJ4vbPHFGkTPtOk= go.starlark.net v0.0.0-20220816155156-cfacd8902214 h1:MqijAN3S61c7KWasOk+zIqIjHQPN6WUra/X3+YAkQxQ= go.starlark.net v0.0.0-20220816155156-cfacd8902214/go.mod h1:VZcBMdr3cT3PnBoWunTabuSEXwVAH+ZJ5zxfs3AdASk= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= @@ -1459,6 +1512,7 @@ golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= @@ -1571,6 +1625,8 @@ golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1627,6 +1683,8 @@ golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.1.0 h1:xYY+Bajn2a7VBmTM5GikTmnK8ZuX8YgnQCqZpbBNtmA= +golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -1645,6 +1703,7 @@ golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190910044552-dd2b5c81c578/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -1825,6 +1884,8 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= @@ -1861,6 +1922,7 @@ gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= +gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= gotest.tools/v3 v3.4.0 h1:ZazjZUfuVeZGLAmlKKuyv3IKP5orXcwtOwDQH6YVr6o= gotest.tools/v3 v3.4.0/go.mod h1:CtbdzLSsqVhDgMtKsx03ird5YTGB3ar27v0u/yKBW5g= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/ignite/cmd/plugin.go b/ignite/cmd/plugin.go index eb51cfb319..21078b9318 100644 --- a/ignite/cmd/plugin.go +++ b/ignite/cmd/plugin.go @@ -64,7 +64,7 @@ func LoadPlugins(ctx context.Context, cmd *cobra.Command) error { return nil } - return linkPlugins(rootCmd, plugins) + return linkPlugins(ctx, rootCmd, plugins) } func parseLocalPlugins(cmd *cobra.Command) (*pluginsconfig.Config, error) { @@ -103,7 +103,7 @@ func parseGlobalPlugins() (cfg *pluginsconfig.Config, err error) { return } -func linkPlugins(rootCmd *cobra.Command, plugins []*plugin.Plugin) error { +func linkPlugins(ctx context.Context, rootCmd *cobra.Command, plugins []*plugin.Plugin) error { // Link plugins to related commands var linkErrors []*plugin.Plugin for _, p := range plugins { @@ -111,30 +111,37 @@ func linkPlugins(rootCmd *cobra.Command, plugins []*plugin.Plugin) error { linkErrors = append(linkErrors, p) continue } - manifest, err := p.Interface.Manifest() + + manifest, err := p.Interface.Manifest(ctx) if err != nil { - p.Error = fmt.Errorf("Manifest() error: %w", err) + p.Error = err + linkErrors = append(linkErrors, p) continue } + linkPluginHooks(rootCmd, p, manifest.Hooks) if p.Error != nil { linkErrors = append(linkErrors, p) continue } + linkPluginCmds(rootCmd, p, manifest.Commands) if p.Error != nil { linkErrors = append(linkErrors, p) continue } } + if len(linkErrors) > 0 { // unload any plugin that could have been loaded defer UnloadPlugins() - if err := printPlugins(cliui.New(cliui.WithStdout(os.Stdout))); err != nil { + + if err := printPlugins(ctx, cliui.New(cliui.WithStdout(os.Stdout))); err != nil { // content of loadErrors is more important than a print error, so we don't // return here, just print the error. fmt.Printf("fail to print: %v\n", err) } + var s strings.Builder for _, p := range linkErrors { fmt.Fprintf(&s, "%s: %v", p.Path, p.Error) @@ -152,7 +159,7 @@ func UnloadPlugins() { } } -func linkPluginHooks(rootCmd *cobra.Command, p *plugin.Plugin, hooks []plugin.Hook) { +func linkPluginHooks(rootCmd *cobra.Command, p *plugin.Plugin, hooks []*plugin.Hook) { if p.Error != nil { return } @@ -161,8 +168,8 @@ func linkPluginHooks(rootCmd *cobra.Command, p *plugin.Plugin, hooks []plugin.Ho } } -func linkPluginHook(rootCmd *cobra.Command, p *plugin.Plugin, hook plugin.Hook) { - cmdPath := hook.PlaceHookOnFull() +func linkPluginHook(rootCmd *cobra.Command, p *plugin.Plugin, hook *plugin.Hook) { + cmdPath := hook.CommandPath() cmd := findCommandByPath(rootCmd, cmdPath) if cmd == nil { p.Error = errors.Errorf("unable to find command path %q for app hook %q", cmdPath, hook.Name) @@ -173,30 +180,38 @@ func linkPluginHook(rootCmd *cobra.Command, p *plugin.Plugin, hook plugin.Hook) return } - newExecutedHook := func(hook plugin.Hook, cmd *cobra.Command, args []string) plugin.ExecutedHook { - execHook := plugin.ExecutedHook{ + newExecutedHook := func(hook *plugin.Hook, cmd *cobra.Command, args []string) *plugin.ExecutedHook { + execHook := &plugin.ExecutedHook{ Hook: hook, - ExecutedCommand: plugin.ExecutedCommand{ + ExecutedCommand: &plugin.ExecutedCommand{ Use: cmd.Use, Path: cmd.CommandPath(), Args: args, - OSArgs: os.Args, + OsArgs: os.Args, With: p.With, }, } - execHook.ExecutedCommand.SetFlags(cmd) + execHook.ExecutedCommand.ImportFlags(cmd) return execHook } 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 } } - err := p.Interface.ExecuteHookPre(newExecutedHook(hook, cmd, args)) + + execHook := newExecutedHook(hook, cmd, args) + c, err := newChainWithHomeFlags(cmd) + if err != nil { + return err + } + err = p.Interface.ExecuteHookPre(ctx, execHook, plugin.NewClientAPI(c)) if err != nil { return fmt.Errorf("app %q ExecuteHookPre() error: %w", p.Path, err) } @@ -210,7 +225,13 @@ 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 { - err := p.Interface.ExecuteHookCleanUp(newExecutedHook(hook, cmd, args)) + ctx := cmd.Context() + execHook := newExecutedHook(hook, cmd, args) + c, err := newChainWithHomeFlags(cmd) + if err != nil { + return err + } + err = p.Interface.ExecuteHookCleanUp(ctx, execHook, plugin.NewClientAPI(c)) if err != nil { cmd.Printf("app %q ExecuteHookCleanUp() error: %v", p.Path, err) } @@ -224,10 +245,16 @@ 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) + c, err := newChainWithHomeFlags(cmd) + if err != nil { + return err + } + defer func() { - err := p.Interface.ExecuteHookCleanUp(execHook) + err := p.Interface.ExecuteHookCleanUp(ctx, execHook, plugin.NewClientAPI(c)) if err != nil { cmd.Printf("app %q ExecuteHookCleanUp() error: %v", p.Path, err) } @@ -241,7 +268,7 @@ func linkPluginHook(rootCmd *cobra.Command, p *plugin.Plugin, hook plugin.Hook) } } - err := p.Interface.ExecuteHookPost(execHook) + err = p.Interface.ExecuteHookPost(ctx, execHook, plugin.NewClientAPI(c)) if err != nil { return fmt.Errorf("app %q ExecuteHookPost() error : %w", p.Path, err) } @@ -251,7 +278,7 @@ func linkPluginHook(rootCmd *cobra.Command, p *plugin.Plugin, hook plugin.Hook) // linkPluginCmds tries to add the plugin commands to the legacy ignite // commands. -func linkPluginCmds(rootCmd *cobra.Command, p *plugin.Plugin, pluginCmds []plugin.Command) { +func linkPluginCmds(rootCmd *cobra.Command, p *plugin.Plugin, pluginCmds []*plugin.Command) { if p.Error != nil { return } @@ -263,8 +290,8 @@ func linkPluginCmds(rootCmd *cobra.Command, p *plugin.Plugin, pluginCmds []plugi } } -func linkPluginCmd(rootCmd *cobra.Command, p *plugin.Plugin, pluginCmd plugin.Command) { - cmdPath := pluginCmd.PlaceCommandUnderFull() +func linkPluginCmd(rootCmd *cobra.Command, p *plugin.Plugin, pluginCmd *plugin.Command) { + cmdPath := pluginCmd.Path() cmd := findCommandByPath(rootCmd, cmdPath) if cmd == nil { p.Error = errors.Errorf("unable to find command path %q for app %q", cmdPath, p.Path) @@ -302,17 +329,22 @@ func linkPluginCmd(rootCmd *cobra.Command, p *plugin.Plugin, pluginCmd plugin.Co if len(pluginCmd.Commands) == 0 { // pluginCmd has no sub commands, so it's runnable newCmd.RunE = func(cmd *cobra.Command, args []string) error { - return clictx.Do(cmd.Context(), func() error { - execCmd := plugin.ExecutedCommand{ + ctx := cmd.Context() + return clictx.Do(ctx, func() error { + execCmd := &plugin.ExecutedCommand{ Use: cmd.Use, Path: cmd.CommandPath(), Args: args, - OSArgs: os.Args, + OsArgs: os.Args, With: p.With, } - execCmd.SetFlags(cmd) + execCmd.ImportFlags(cmd) // Call the plugin Execute - err := p.Interface.Execute(execCmd) + c, err := newChainWithHomeFlags(cmd) + if err != nil { + return err + } + err = p.Interface.Execute(ctx, execCmd, plugin.NewClientAPI(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. @@ -369,7 +401,7 @@ func NewAppList() *cobra.Command { Long: "Prints status and information of all installed Ignite Apps.", RunE: func(cmd *cobra.Command, args []string) error { s := cliui.New(cliui.WithStdout(os.Stdout)) - return printPlugins(s) + return printPlugins(cmd.Context(), s) }, } return lstCmd @@ -568,7 +600,7 @@ A git repository will be created with the given module name, unless the current return err } moduleName := args[0] - path, err := plugin.Scaffold(wd, moduleName, false) + path, err := plugin.Scaffold(cmd.Context(), wd, moduleName, false) if err != nil { return err } @@ -605,10 +637,11 @@ func NewAppDescribe() *cobra.Command { Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { s := cliui.New(cliui.WithStdout(os.Stdout)) + ctx := cmd.Context() for _, p := range plugins { if p.Path == args[0] { - manifest, err := p.Interface.Manifest() + manifest, err := p.Interface.Manifest(ctx) if err != nil { return fmt.Errorf("error while loading app manifest: %w", err) } @@ -616,7 +649,7 @@ func NewAppDescribe() *cobra.Command { if len(manifest.Commands) > 0 { s.Println("Commands:") for i, c := range manifest.Commands { - cmdPath := fmt.Sprintf("%s %s", c.PlaceCommandUnderFull(), c.Use) + cmdPath := fmt.Sprintf("%s %s", c.Path(), c.Use) s.Printf(" %d) %s\n", i+1, cmdPath) } } @@ -624,7 +657,7 @@ func NewAppDescribe() *cobra.Command { if len(manifest.Hooks) > 0 { s.Println("Hooks:") for i, h := range manifest.Hooks { - s.Printf(" %d) '%s' on command '%s'\n", i+1, h.Name, h.PlaceHookOnFull()) + s.Printf(" %d) '%s' on command '%s'\n", i+1, h.Name, h.CommandPath()) } } @@ -644,12 +677,12 @@ func getPluginLocationName(p *plugin.Plugin) string { return "local" } -func getPluginStatus(p *plugin.Plugin) string { +func getPluginStatus(ctx context.Context, p *plugin.Plugin) string { if p.Error != nil { return fmt.Sprintf("%s Error: %v", icons.NotOK, p.Error) } - _, err := p.Interface.Manifest() + _, err := p.Interface.Manifest(ctx) if err != nil { return fmt.Sprintf("%s Error: Manifest() returned %v", icons.NotOK, err) } @@ -657,10 +690,10 @@ func getPluginStatus(p *plugin.Plugin) string { return fmt.Sprintf("%s Loaded", icons.OK) } -func printPlugins(session *cliui.Session) error { +func printPlugins(ctx context.Context, session *cliui.Session) error { var entries [][]string for _, p := range plugins { - entries = append(entries, []string{p.Path, getPluginLocationName(p), getPluginStatus(p)}) + entries = append(entries, []string{p.Path, getPluginLocationName(p), getPluginStatus(ctx, p)}) } if err := session.PrintTable([]string{"Path", "Config", "Status"}, entries...); err != nil { diff --git a/ignite/cmd/plugin_default.go b/ignite/cmd/plugin_default.go index 6d9b995704..9ffcc189ad 100644 --- a/ignite/cmd/plugin_default.go +++ b/ignite/cmd/plugin_default.go @@ -90,7 +90,7 @@ func newPluginInstallCmd(dp defaultPlugin) *cobra.Command { // Remove this command before call to linkPlugins because a plugin is // usually not allowed to override an existing command. rootCmd.RemoveCommand(cmd) - if err := linkPlugins(rootCmd, plugins); err != nil { + if err := linkPlugins(cmd.Context(), rootCmd, plugins); err != nil { return err } // Execute the command diff --git a/ignite/cmd/plugin_test.go b/ignite/cmd/plugin_test.go index e8e154f62f..c0e4e13eca 100644 --- a/ignite/cmd/plugin_test.go +++ b/ignite/cmd/plugin_test.go @@ -1,6 +1,7 @@ package ignitecmd import ( + "context" "fmt" "io" "os" @@ -18,7 +19,7 @@ import ( "github.com/ignite/cli/ignite/services/plugin/mocks" ) -func buildRootCmd() *cobra.Command { +func buildRootCmd(ctx context.Context) *cobra.Command { var ( rootCmd = &cobra.Command{ Use: "ignite", @@ -39,24 +40,34 @@ func buildRootCmd() *cobra.Command { scaffoldCmd.AddCommand(scaffoldChainCmd) scaffoldCmd.AddCommand(scaffoldModuleCmd) rootCmd.AddCommand(scaffoldCmd) + rootCmd.SetContext(ctx) return rootCmd } -func assertFlags(t *testing.T, expectedFlags []plugin.Flag, execCmd plugin.ExecutedCommand) { +func assertFlags(t *testing.T, expectedFlags []*plugin.Flag, execCmd *plugin.ExecutedCommand) { var ( have []string expected []string ) - execCmd.Flags().VisitAll(func(f *pflag.Flag) { + + t.Helper() + + flags, err := execCmd.NewFlags() + assert.NoError(t, err) + + flags.VisitAll(func(f *pflag.Flag) { if f.Name == "help" { // ignore help flag return } + have = append(have, f.Name) }) + for _, f := range expectedFlags { expected = append(expected, f.Name) } + assert.Equal(t, expected, have) } @@ -65,49 +76,53 @@ func TestLinkPluginCmds(t *testing.T) { args = []string{"arg1", "arg2"} pluginParams = map[string]string{"key": "val"} // define a plugin with command flags - pluginWithFlags = plugin.Command{ + pluginWithFlags = &plugin.Command{ Use: "flaggy", - Flags: []plugin.Flag{ + Flags: []*plugin.Flag{ {Name: "flag1", Type: plugin.FlagTypeString}, - {Name: "flag2", Type: plugin.FlagTypeInt}, + {Name: "flag2", Type: plugin.FlagTypeInt, DefaultValue: "0"}, }, } ) // helper to assert pluginInterface.Execute() calls - expectExecute := func(t *testing.T, p *mocks.PluginInterface, cmd plugin.Command) { - p.EXPECT().Execute( - mock.MatchedBy(func(execCmd plugin.ExecutedCommand) bool { - return cmd.Use == execCmd.Use - }), - ).Run(func(execCmd plugin.ExecutedCommand) { - // Assert execCmd is populated correctly - assert.True(t, strings.HasSuffix(execCmd.Path, cmd.Use), "wrong path %s", execCmd.Path) - assert.Equal(t, args, execCmd.Args) - assertFlags(t, cmd.Flags, execCmd) - assert.Equal(t, pluginParams, execCmd.With) - }).Return(nil) + expectExecute := func(t *testing.T, ctx context.Context, p *mocks.PluginInterface, cmd *plugin.Command) { + t.Helper() + p.EXPECT(). + Execute( + mock.Anything, + mock.MatchedBy(func(execCmd *plugin.ExecutedCommand) bool { + fmt.Println(cmd.Use == execCmd.Use, cmd.Use, execCmd.Use) + return cmd.Use == execCmd.Use + }), + mock.Anything, + ). + Run(func(_ context.Context, execCmd *plugin.ExecutedCommand, _ plugin.ClientAPI) { + // Assert execCmd is populated correctly + assert.True(t, strings.HasSuffix(execCmd.Path, cmd.Use), "wrong path %s", execCmd.Path) + assert.Equal(t, args, execCmd.Args) + assertFlags(t, cmd.Flags, execCmd) + assert.Equal(t, pluginParams, execCmd.With) + }). + Return(nil) } tests := []struct { name string - setup func(*testing.T, *mocks.PluginInterface) + setup func(*testing.T, context.Context, *mocks.PluginInterface) expectedDumpCmd string expectedError string }{ { name: "ok: link foo at root", - setup: func(t *testing.T, p *mocks.PluginInterface) { - cmd := plugin.Command{ + setup: func(t *testing.T, ctx context.Context, p *mocks.PluginInterface) { + cmd := &plugin.Command{ Use: "foo", } - p.EXPECT().Manifest().Return( - plugin.Manifest{ - Commands: []plugin.Command{cmd}, - }, - nil, - ) - expectExecute(t, p, cmd) + p.EXPECT(). + Manifest(ctx). + Return(&plugin.Manifest{Commands: []*plugin.Command{cmd}}, nil) + expectExecute(t, ctx, p, cmd) }, expectedDumpCmd: ` ignite @@ -119,13 +134,15 @@ ignite }, { name: "ok: link foo at subcommand", - setup: func(t *testing.T, p *mocks.PluginInterface) { - cmd := plugin.Command{ + setup: func(t *testing.T, ctx context.Context, p *mocks.PluginInterface) { + cmd := &plugin.Command{ Use: "foo", PlaceCommandUnder: "ignite scaffold", } - p.EXPECT().Manifest().Return(plugin.Manifest{Commands: []plugin.Command{cmd}}, nil) - expectExecute(t, p, cmd) + p.EXPECT(). + Manifest(ctx). + Return(&plugin.Manifest{Commands: []*plugin.Command{cmd}}, nil) + expectExecute(t, ctx, p, cmd) }, expectedDumpCmd: ` ignite @@ -137,13 +154,15 @@ ignite }, { name: "ok: link foo at subcommand with incomplete PlaceCommandUnder", - setup: func(t *testing.T, p *mocks.PluginInterface) { - cmd := plugin.Command{ + setup: func(t *testing.T, ctx context.Context, p *mocks.PluginInterface) { + cmd := &plugin.Command{ Use: "foo", PlaceCommandUnder: "scaffold", } - p.EXPECT().Manifest().Return(plugin.Manifest{Commands: []plugin.Command{cmd}}, nil) - expectExecute(t, p, cmd) + p.EXPECT(). + Manifest(ctx). + Return(&plugin.Manifest{Commands: []*plugin.Command{cmd}}, nil) + expectExecute(t, ctx, p, cmd) }, expectedDumpCmd: ` ignite @@ -155,99 +174,111 @@ ignite }, { name: "fail: link to runnable command", - setup: func(t *testing.T, p *mocks.PluginInterface) { - p.EXPECT().Manifest().Return(plugin.Manifest{ - Commands: []plugin.Command{ - { - Use: "foo", - PlaceCommandUnder: "ignite scaffold chain", + setup: func(t *testing.T, ctx context.Context, p *mocks.PluginInterface) { + p.EXPECT(). + Manifest(ctx). + Return(&plugin.Manifest{ + Commands: []*plugin.Command{ + { + Use: "foo", + PlaceCommandUnder: "ignite scaffold chain", + }, }, }, - }, - nil, - ) + nil, + ) }, expectedError: `can't attach app command "foo" to runnable command "ignite scaffold chain"`, }, { name: "fail: link to unknown command", - setup: func(t *testing.T, p *mocks.PluginInterface) { - p.EXPECT().Manifest().Return(plugin.Manifest{ - Commands: []plugin.Command{ - { - Use: "foo", - PlaceCommandUnder: "ignite unknown", + setup: func(t *testing.T, ctx context.Context, p *mocks.PluginInterface) { + p.EXPECT(). + Manifest(ctx). + Return(&plugin.Manifest{ + Commands: []*plugin.Command{ + { + Use: "foo", + PlaceCommandUnder: "ignite unknown", + }, }, }, - }, - nil, - ) + nil, + ) }, expectedError: `unable to find command path "ignite unknown" for app "foo"`, }, { name: "fail: plugin name exists in legacy commands", - setup: func(t *testing.T, p *mocks.PluginInterface) { - p.EXPECT().Manifest().Return(plugin.Manifest{ - Commands: []plugin.Command{ - { - Use: "scaffold", + setup: func(t *testing.T, ctx context.Context, p *mocks.PluginInterface) { + p.EXPECT(). + Manifest(ctx). + Return(&plugin.Manifest{ + Commands: []*plugin.Command{ + { + Use: "scaffold", + }, }, }, - }, - nil, - ) + nil, + ) }, expectedError: `app command "scaffold" already exists in Ignite's commands`, }, { name: "fail: plugin name with args exists in legacy commands", - setup: func(t *testing.T, p *mocks.PluginInterface) { - p.EXPECT().Manifest().Return(plugin.Manifest{ - Commands: []plugin.Command{ - { - Use: "scaffold [args]", + setup: func(t *testing.T, ctx context.Context, p *mocks.PluginInterface) { + p.EXPECT(). + Manifest(ctx). + Return(&plugin.Manifest{ + Commands: []*plugin.Command{ + { + Use: "scaffold [args]", + }, }, }, - }, - nil, - ) + nil, + ) }, expectedError: `app command "scaffold" already exists in Ignite's commands`, }, { name: "fail: plugin name exists in legacy sub commands", - setup: func(t *testing.T, p *mocks.PluginInterface) { - p.EXPECT().Manifest().Return(plugin.Manifest{ - Commands: []plugin.Command{ - { - Use: "chain", - PlaceCommandUnder: "scaffold", + setup: func(t *testing.T, ctx context.Context, p *mocks.PluginInterface) { + p.EXPECT(). + Manifest(ctx). + Return(&plugin.Manifest{ + Commands: []*plugin.Command{ + { + Use: "chain", + PlaceCommandUnder: "scaffold", + }, }, }, - }, - nil, - ) + nil, + ) }, expectedError: `app command "chain" already exists in Ignite's commands`, }, { name: "ok: link multiple at root", - setup: func(t *testing.T, p *mocks.PluginInterface) { - fooCmd := plugin.Command{ + setup: func(t *testing.T, ctx context.Context, p *mocks.PluginInterface) { + fooCmd := &plugin.Command{ Use: "foo", } - barCmd := plugin.Command{ + barCmd := &plugin.Command{ Use: "bar", } - p.EXPECT().Manifest().Return(plugin.Manifest{ - Commands: []plugin.Command{ - fooCmd, barCmd, pluginWithFlags, - }, - }, nil) - expectExecute(t, p, fooCmd) - expectExecute(t, p, barCmd) - expectExecute(t, p, pluginWithFlags) + p.EXPECT(). + Manifest(ctx). + Return(&plugin.Manifest{ + Commands: []*plugin.Command{ + fooCmd, barCmd, pluginWithFlags, + }, + }, nil) + expectExecute(t, ctx, p, fooCmd) + expectExecute(t, ctx, p, barCmd) + expectExecute(t, ctx, p, pluginWithFlags) }, expectedDumpCmd: ` ignite @@ -261,21 +292,23 @@ ignite }, { name: "ok: link with subcommands", - setup: func(t *testing.T, p *mocks.PluginInterface) { - cmd := plugin.Command{ + setup: func(t *testing.T, ctx context.Context, p *mocks.PluginInterface) { + cmd := &plugin.Command{ Use: "foo", - Commands: []plugin.Command{ + Commands: []*plugin.Command{ {Use: "bar"}, {Use: "baz"}, pluginWithFlags, }, } - p.EXPECT().Manifest().Return(plugin.Manifest{Commands: []plugin.Command{cmd}}, nil) + p.EXPECT(). + Manifest(ctx). + Return(&plugin.Manifest{Commands: []*plugin.Command{cmd}}, nil) // cmd is not executed because it's not runnable, only sub-commands // are executed. - expectExecute(t, p, cmd.Commands[0]) - expectExecute(t, p, cmd.Commands[1]) - expectExecute(t, p, cmd.Commands[2]) + expectExecute(t, ctx, p, cmd.Commands[0]) + expectExecute(t, ctx, p, cmd.Commands[1]) + expectExecute(t, ctx, p, cmd.Commands[2]) }, expectedDumpCmd: ` ignite @@ -290,18 +323,20 @@ ignite }, { name: "ok: link with multiple subcommands", - setup: func(t *testing.T, p *mocks.PluginInterface) { - cmd := plugin.Command{ + setup: func(t *testing.T, ctx context.Context, p *mocks.PluginInterface) { + cmd := &plugin.Command{ Use: "foo", - Commands: []plugin.Command{ - {Use: "bar", Commands: []plugin.Command{{Use: "baz"}}}, - {Use: "qux", Commands: []plugin.Command{{Use: "quux"}, {Use: "corge"}}}, + Commands: []*plugin.Command{ + {Use: "bar", Commands: []*plugin.Command{{Use: "baz"}}}, + {Use: "qux", Commands: []*plugin.Command{{Use: "quux"}, {Use: "corge"}}}, }, } - p.EXPECT().Manifest().Return(plugin.Manifest{Commands: []plugin.Command{cmd}}, nil) - expectExecute(t, p, cmd.Commands[0].Commands[0]) - expectExecute(t, p, cmd.Commands[1].Commands[0]) - expectExecute(t, p, cmd.Commands[1].Commands[1]) + p.EXPECT(). + Manifest(ctx). + Return(&plugin.Manifest{Commands: []*plugin.Command{cmd}}, nil) + expectExecute(t, ctx, p, cmd.Commands[0].Commands[0]) + expectExecute(t, ctx, p, cmd.Commands[1].Commands[0]) + expectExecute(t, ctx, p, cmd.Commands[1].Commands[1]) }, expectedDumpCmd: ` ignite @@ -319,6 +354,9 @@ ignite } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + require := require.New(t) assert := assert.New(t) pi := mocks.NewPluginInterface(t) @@ -329,10 +367,10 @@ ignite }, Interface: pi, } - rootCmd := buildRootCmd() - tt.setup(t, pi) + rootCmd := buildRootCmd(ctx) + tt.setup(t, ctx, pi) - _ = linkPlugins(rootCmd, []*plugin.Plugin{p}) + _ = linkPlugins(ctx, rootCmd, []*plugin.Plugin{p}) if tt.expectedError != "" { require.Error(p.Error) @@ -370,18 +408,19 @@ func TestLinkPluginHooks(t *testing.T) { var ( args = []string{"arg1", "arg2"} pluginParams = map[string]string{"key": "val"} + ctx = context.Background() // helper to assert pluginInterface.ExecuteHook*() calls in expected order // (pre, then post, then cleanup) - expectExecuteHook = func(t *testing.T, p *mocks.PluginInterface, expectedFlags []plugin.Flag, hooks ...plugin.Hook) { - matcher := func(hook plugin.Hook) any { - return mock.MatchedBy(func(execHook plugin.ExecutedHook) bool { - return hook.Name == execHook.Name && - hook.PlaceHookOn == execHook.PlaceHookOn + expectExecuteHook = func(t *testing.T, p *mocks.PluginInterface, expectedFlags []*plugin.Flag, hooks ...*plugin.Hook) { + matcher := func(hook *plugin.Hook) any { + return mock.MatchedBy(func(execHook *plugin.ExecutedHook) bool { + return hook.Name == execHook.Hook.Name && + hook.PlaceHookOn == execHook.Hook.PlaceHookOn }) } - asserter := func(hook plugin.Hook) func(hook plugin.ExecutedHook) { - return func(execHook plugin.ExecutedHook) { + asserter := func(hook *plugin.Hook) func(_ context.Context, hook *plugin.ExecutedHook, _ plugin.ClientAPI) { + return func(_ context.Context, execHook *plugin.ExecutedHook, _ plugin.ClientAPI) { assert.True(t, strings.HasSuffix(execHook.ExecutedCommand.Path, hook.PlaceHookOn), "wrong path %q want %q", execHook.ExecutedCommand.Path, hook.PlaceHookOn) assert.Equal(t, args, execHook.ExecutedCommand.Args) assertFlags(t, expectedFlags, execHook.ExecutedCommand) @@ -390,18 +429,27 @@ func TestLinkPluginHooks(t *testing.T) { } var lastPre *mock.Call for _, hook := range hooks { - pre := p.EXPECT().ExecuteHookPre(matcher(hook)). - Run(asserter(hook)).Return(nil).Call + pre := p.EXPECT(). + ExecuteHookPre(ctx, matcher(hook), mock.Anything). + Run(asserter(hook)). + Return(nil). + Call if lastPre != nil { pre.NotBefore(lastPre) } lastPre = pre } for _, hook := range hooks { - post := p.EXPECT().ExecuteHookPost(matcher(hook)). - Run(asserter(hook)).Return(nil).Call - cleanup := p.EXPECT().ExecuteHookCleanUp(matcher(hook)). - Run(asserter(hook)).Return(nil).Call + post := p.EXPECT(). + ExecuteHookPost(ctx, matcher(hook), mock.Anything). + Run(asserter(hook)). + Return(nil). + Call + cleanup := p.EXPECT(). + ExecuteHookCleanUp(ctx, matcher(hook), mock.Anything). + Run(asserter(hook)). + Return(nil). + Call post.NotBefore(lastPre) cleanup.NotBefore(post) } @@ -410,90 +458,100 @@ func TestLinkPluginHooks(t *testing.T) { tests := []struct { name string expectedError string - setup func(*testing.T, *mocks.PluginInterface) + setup func(*testing.T, context.Context, *mocks.PluginInterface) }{ { name: "fail: command not runnable", - setup: func(t *testing.T, p *mocks.PluginInterface) { - p.EXPECT().Manifest().Return(plugin.Manifest{ - Hooks: []plugin.Hook{ - { - Name: "test-hook", - PlaceHookOn: "ignite scaffold", + setup: func(t *testing.T, ctx context.Context, p *mocks.PluginInterface) { + p.EXPECT(). + Manifest(ctx). + Return(&plugin.Manifest{ + Hooks: []*plugin.Hook{ + { + Name: "test-hook", + PlaceHookOn: "ignite scaffold", + }, }, }, - }, - nil, - ) + nil, + ) }, expectedError: `can't attach app hook "test-hook" to non executable command "ignite scaffold"`, }, { name: "fail: command doesn't exists", - setup: func(t *testing.T, p *mocks.PluginInterface) { - p.EXPECT().Manifest().Return(plugin.Manifest{ - Hooks: []plugin.Hook{ - { - Name: "test-hook", - PlaceHookOn: "ignite chain", + setup: func(t *testing.T, ctx context.Context, p *mocks.PluginInterface) { + p.EXPECT(). + Manifest(ctx). + Return(&plugin.Manifest{ + Hooks: []*plugin.Hook{ + { + Name: "test-hook", + PlaceHookOn: "ignite chain", + }, }, }, - }, - nil, - ) + nil, + ) }, expectedError: `unable to find command path "ignite chain" for app hook "test-hook"`, }, { name: "ok: single hook", - setup: func(t *testing.T, p *mocks.PluginInterface) { - hook := plugin.Hook{ + setup: func(t *testing.T, ctx context.Context, p *mocks.PluginInterface) { + hook := &plugin.Hook{ Name: "test-hook", PlaceHookOn: "scaffold chain", } - p.EXPECT().Manifest().Return(plugin.Manifest{Hooks: []plugin.Hook{hook}}, nil) - expectExecuteHook(t, p, []plugin.Flag{{Name: "path"}}, hook) + p.EXPECT(). + Manifest(ctx). + Return(&plugin.Manifest{Hooks: []*plugin.Hook{hook}}, nil) + expectExecuteHook(t, p, []*plugin.Flag{{Name: "path"}}, hook) }, }, { name: "ok: multiple hooks on same command", - setup: func(t *testing.T, p *mocks.PluginInterface) { - hook1 := plugin.Hook{ + setup: func(t *testing.T, ctx context.Context, p *mocks.PluginInterface) { + hook1 := &plugin.Hook{ Name: "test-hook-1", PlaceHookOn: "scaffold chain", } - hook2 := plugin.Hook{ + hook2 := &plugin.Hook{ Name: "test-hook-2", PlaceHookOn: "scaffold chain", } - p.EXPECT().Manifest().Return(plugin.Manifest{Hooks: []plugin.Hook{hook1, hook2}}, nil) - expectExecuteHook(t, p, []plugin.Flag{{Name: "path"}}, hook1, hook2) + p.EXPECT(). + Manifest(ctx). + Return(&plugin.Manifest{Hooks: []*plugin.Hook{hook1, hook2}}, nil) + expectExecuteHook(t, p, []*plugin.Flag{{Name: "path"}}, hook1, hook2) }, }, { name: "ok: multiple hooks on different commands", - setup: func(t *testing.T, p *mocks.PluginInterface) { - hookChain1 := plugin.Hook{ + setup: func(t *testing.T, ctx context.Context, p *mocks.PluginInterface) { + hookChain1 := &plugin.Hook{ Name: "test-hook-1", PlaceHookOn: "scaffold chain", } - hookChain2 := plugin.Hook{ + hookChain2 := &plugin.Hook{ Name: "test-hook-2", PlaceHookOn: "scaffold chain", } - hookModule := plugin.Hook{ + hookModule := &plugin.Hook{ Name: "test-hook-3", PlaceHookOn: "scaffold module", } - p.EXPECT().Manifest().Return(plugin.Manifest{Hooks: []plugin.Hook{hookChain1, hookChain2, hookModule}}, nil) - expectExecuteHook(t, p, []plugin.Flag{{Name: "path"}}, hookChain1, hookChain2) + p.EXPECT(). + Manifest(ctx). + Return(&plugin.Manifest{Hooks: []*plugin.Hook{hookChain1, hookChain2, hookModule}}, nil) + expectExecuteHook(t, p, []*plugin.Flag{{Name: "path"}}, hookChain1, hookChain2) expectExecuteHook(t, p, nil, hookModule) }, }, { name: "ok: duplicate hook names on same command", - setup: func(t *testing.T, p *mocks.PluginInterface) { - hooks := []plugin.Hook{ + setup: func(t *testing.T, ctx context.Context, p *mocks.PluginInterface) { + hooks := []*plugin.Hook{ { Name: "test-hook", PlaceHookOn: "ignite scaffold chain", @@ -503,23 +561,27 @@ func TestLinkPluginHooks(t *testing.T) { PlaceHookOn: "ignite scaffold chain", }, } - p.EXPECT().Manifest().Return(plugin.Manifest{Hooks: hooks}, nil) - expectExecuteHook(t, p, []plugin.Flag{{Name: "path"}}, hooks...) + p.EXPECT(). + Manifest(ctx). + Return(&plugin.Manifest{Hooks: hooks}, nil) + expectExecuteHook(t, p, []*plugin.Flag{{Name: "path"}}, hooks...) }, }, { name: "ok: duplicate hook names on different commands", - setup: func(t *testing.T, p *mocks.PluginInterface) { - hookChain := plugin.Hook{ + setup: func(t *testing.T, ctx context.Context, p *mocks.PluginInterface) { + hookChain := &plugin.Hook{ Name: "test-hook", PlaceHookOn: "ignite scaffold chain", } - hookModule := plugin.Hook{ + hookModule := &plugin.Hook{ Name: "test-hook", PlaceHookOn: "ignite scaffold module", } - p.EXPECT().Manifest().Return(plugin.Manifest{Hooks: []plugin.Hook{hookChain, hookModule}}, nil) - expectExecuteHook(t, p, []plugin.Flag{{Name: "path"}}, hookChain) + p.EXPECT(). + Manifest(ctx). + Return(&plugin.Manifest{Hooks: []*plugin.Hook{hookChain, hookModule}}, nil) + expectExecuteHook(t, p, []*plugin.Flag{{Name: "path"}}, hookChain) expectExecuteHook(t, p, nil, hookModule) }, }, @@ -527,6 +589,9 @@ func TestLinkPluginHooks(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + require := require.New(t) // assert := assert.New(t) pi := mocks.NewPluginInterface(t) @@ -537,10 +602,10 @@ func TestLinkPluginHooks(t *testing.T) { }, Interface: pi, } - rootCmd := buildRootCmd() - tt.setup(t, pi) + rootCmd := buildRootCmd(ctx) + tt.setup(t, ctx, pi) - _ = linkPlugins(rootCmd, []*plugin.Plugin{p}) + _ = linkPlugins(ctx, rootCmd, []*plugin.Plugin{p}) if tt.expectedError != "" { require.EqualError(p.Error, tt.expectedError) diff --git a/ignite/config/chain/config.go b/ignite/config/chain/config.go index b19cc7fbe3..3724442cbf 100644 --- a/ignite/config/chain/config.go +++ b/ignite/config/chain/config.go @@ -15,7 +15,6 @@ import ( ) var ( - // ConfigFilenames is a list of recognized names as Ignite's chain config file. ConfigFilenames = []string{"config.yml", "config.yaml"} diff --git a/ignite/internal/tools/tools.go b/ignite/internal/tools/tools.go index ce7e689a69..dbc2316bd9 100644 --- a/ignite/internal/tools/tools.go +++ b/ignite/internal/tools/tools.go @@ -4,6 +4,7 @@ package tools import ( + _ "github.com/bufbuild/buf/cmd/buf" _ "github.com/golangci/golangci-lint/cmd/golangci-lint" _ "github.com/tbruyelle/mdgofmt/cmd/mdgofmt" _ "github.com/vektra/mockery/v2" diff --git a/ignite/pkg/cosmosanalysis/module/module.go b/ignite/pkg/cosmosanalysis/module/module.go index 1f73179ecb..0b506cb393 100644 --- a/ignite/pkg/cosmosanalysis/module/module.go +++ b/ignite/pkg/cosmosanalysis/module/module.go @@ -22,57 +22,58 @@ type Msgs map[string][]string // Module keeps metadata about a Cosmos SDK module. type Module struct { // Name of the module. - Name string + Name string `json:"name,omitempty"` // GoModulePath of the app where the module is defined. - GoModulePath string + GoModulePath string `json:"go_module_path,omitempty"` // Pkg holds the proto package info. - Pkg protoanalysis.Package + Pkg protoanalysis.Package `json:"package,omitempty"` - // Msg is a list of sdk.Msg implementation of the module. - Msgs []Msg + // Msgs is a list of sdk.Msg implementation of the module. + Msgs []Msg `json:"messages,omitempty"` // HTTPQueries is a list of module queries. - HTTPQueries []HTTPQuery + HTTPQueries []HTTPQuery `json:"http_queries,omitempty"` // Types is a list of proto types that might be used by module. - Types []Type + Types []Type `json:"types,omitempty"` } // Msg keeps metadata about an sdk.Msg implementation. type Msg struct { // Name of the type. - Name string + Name string `json:"name,omitempty"` // URI of the type. - URI string + URI string `json:"uri,omitempty"` - // FilePath is the path of the .proto file where message is defined at. - FilePath string + // FilePath is the path of the proto file where message is defined. + FilePath string `json:"file_path,omitempty"` } // HTTPQuery is an sdk Query. type HTTPQuery struct { // Name of the RPC func. - Name string + Name string `json:"name,omitempty"` // FullName of the query with service name and rpc func name. - FullName string + FullName string `json:"full_name,omitempty"` - // HTTPAnnotations keeps info about http annotations of query. - Rules []protoanalysis.HTTPRule + // Rules keeps info about configured HTTP rules of RPC functions. + Rules []protoanalysis.HTTPRule `json:"rules,omitempty"` // Paginated indicates that the query is using pagination. - Paginated bool + Paginated bool `json:"paginated,omitempty"` } // Type is a proto type that might be used by module. type Type struct { - Name string + // Name of the type. + Name string `json:"name,omitempty"` // FilePath is the path of the .proto file where message is defined at. - FilePath string + FilePath string `json:"file_path,omitempty"` } type moduleDiscoverer struct { diff --git a/ignite/pkg/cosmosclient/mocks/account_retriever.go b/ignite/pkg/cosmosclient/mocks/account_retriever.go index c5ed1de1f6..d01a5c6f6a 100644 --- a/ignite/pkg/cosmosclient/mocks/account_retriever.go +++ b/ignite/pkg/cosmosclient/mocks/account_retriever.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.22.1. DO NOT EDIT. +// Code generated by mockery v2.27.1. DO NOT EDIT. package mocks diff --git a/ignite/pkg/cosmosclient/mocks/bank_query_client.go b/ignite/pkg/cosmosclient/mocks/bank_query_client.go index 76793e1c4b..32b4722b69 100644 --- a/ignite/pkg/cosmosclient/mocks/bank_query_client.go +++ b/ignite/pkg/cosmosclient/mocks/bank_query_client.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.22.1. DO NOT EDIT. +// Code generated by mockery v2.27.1. DO NOT EDIT. package mocks diff --git a/ignite/pkg/cosmosclient/mocks/faucet_client.go b/ignite/pkg/cosmosclient/mocks/faucet_client.go index 6c808dce58..12ac46772e 100644 --- a/ignite/pkg/cosmosclient/mocks/faucet_client.go +++ b/ignite/pkg/cosmosclient/mocks/faucet_client.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.16.0. DO NOT EDIT. +// Code generated by mockery v2.27.1. DO NOT EDIT. package mocks @@ -28,13 +28,16 @@ func (_m *FaucetClient) Transfer(_a0 context.Context, _a1 cosmosfaucet.TransferR ret := _m.Called(_a0, _a1) var r0 cosmosfaucet.TransferResponse + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, cosmosfaucet.TransferRequest) (cosmosfaucet.TransferResponse, error)); ok { + return rf(_a0, _a1) + } if rf, ok := ret.Get(0).(func(context.Context, cosmosfaucet.TransferRequest) cosmosfaucet.TransferResponse); ok { r0 = rf(_a0, _a1) } else { r0 = ret.Get(0).(cosmosfaucet.TransferResponse) } - var r1 error if rf, ok := ret.Get(1).(func(context.Context, cosmosfaucet.TransferRequest) error); ok { r1 = rf(_a0, _a1) } else { @@ -68,6 +71,11 @@ func (_c *FaucetClient_Transfer_Call) Return(_a0 cosmosfaucet.TransferResponse, return _c } +func (_c *FaucetClient_Transfer_Call) RunAndReturn(run func(context.Context, cosmosfaucet.TransferRequest) (cosmosfaucet.TransferResponse, error)) *FaucetClient_Transfer_Call { + _c.Call.Return(run) + return _c +} + type mockConstructorTestingTNewFaucetClient interface { mock.TestingT Cleanup(func()) diff --git a/ignite/pkg/cosmosclient/mocks/gasometer.go b/ignite/pkg/cosmosclient/mocks/gasometer.go index 26b8149585..2bb356b37e 100644 --- a/ignite/pkg/cosmosclient/mocks/gasometer.go +++ b/ignite/pkg/cosmosclient/mocks/gasometer.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.16.0. DO NOT EDIT. +// Code generated by mockery v2.27.1. DO NOT EDIT. package mocks @@ -38,6 +38,11 @@ func (_m *Gasometer) CalculateGas(clientCtx grpc.ClientConn, txf tx.Factory, msg ret := _m.Called(_ca...) var r0 *typestx.SimulateResponse + var r1 uint64 + var r2 error + if rf, ok := ret.Get(0).(func(grpc.ClientConn, tx.Factory, ...types.Msg) (*typestx.SimulateResponse, uint64, error)); ok { + return rf(clientCtx, txf, msgs...) + } if rf, ok := ret.Get(0).(func(grpc.ClientConn, tx.Factory, ...types.Msg) *typestx.SimulateResponse); ok { r0 = rf(clientCtx, txf, msgs...) } else { @@ -46,14 +51,12 @@ func (_m *Gasometer) CalculateGas(clientCtx grpc.ClientConn, txf tx.Factory, msg } } - var r1 uint64 if rf, ok := ret.Get(1).(func(grpc.ClientConn, tx.Factory, ...types.Msg) uint64); ok { r1 = rf(clientCtx, txf, msgs...) } else { r1 = ret.Get(1).(uint64) } - var r2 error if rf, ok := ret.Get(2).(func(grpc.ClientConn, tx.Factory, ...types.Msg) error); ok { r2 = rf(clientCtx, txf, msgs...) } else { @@ -95,6 +98,11 @@ func (_c *Gasometer_CalculateGas_Call) Return(_a0 *typestx.SimulateResponse, _a1 return _c } +func (_c *Gasometer_CalculateGas_Call) RunAndReturn(run func(grpc.ClientConn, tx.Factory, ...types.Msg) (*typestx.SimulateResponse, uint64, error)) *Gasometer_CalculateGas_Call { + _c.Call.Return(run) + return _c +} + type mockConstructorTestingTNewGasometer interface { mock.TestingT Cleanup(func()) diff --git a/ignite/pkg/cosmosclient/mocks/rpc_client.go b/ignite/pkg/cosmosclient/mocks/rpc_client.go index d76eae984d..a8b39d43ee 100644 --- a/ignite/pkg/cosmosclient/mocks/rpc_client.go +++ b/ignite/pkg/cosmosclient/mocks/rpc_client.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.22.1. DO NOT EDIT. +// Code generated by mockery v2.27.1. DO NOT EDIT. package mocks diff --git a/ignite/pkg/cosmosclient/mocks/signer.go b/ignite/pkg/cosmosclient/mocks/signer.go index b199b10fcf..53914d8a73 100644 --- a/ignite/pkg/cosmosclient/mocks/signer.go +++ b/ignite/pkg/cosmosclient/mocks/signer.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.16.0. DO NOT EDIT. +// Code generated by mockery v2.27.1. DO NOT EDIT. package mocks @@ -63,6 +63,11 @@ func (_c *Signer_Sign_Call) Return(_a0 error) *Signer_Sign_Call { return _c } +func (_c *Signer_Sign_Call) RunAndReturn(run func(tx.Factory, string, client.TxBuilder, bool) error) *Signer_Sign_Call { + _c.Call.Return(run) + return _c +} + type mockConstructorTestingTNewSigner interface { mock.TestingT Cleanup(func()) diff --git a/ignite/pkg/cosmostxcollector/mocks/saver.go b/ignite/pkg/cosmostxcollector/mocks/saver.go index 734e1f1c11..0f28067f30 100644 --- a/ignite/pkg/cosmostxcollector/mocks/saver.go +++ b/ignite/pkg/cosmostxcollector/mocks/saver.go @@ -1,13 +1,12 @@ -// Code generated by mockery v2.16.0. DO NOT EDIT. +// Code generated by mockery v2.27.1. DO NOT EDIT. package mocks import ( context "context" - mock "github.com/stretchr/testify/mock" - cosmosclient "github.com/ignite/cli/ignite/pkg/cosmosclient" + mock "github.com/stretchr/testify/mock" ) // Saver is an autogenerated mock type for the Saver type @@ -61,6 +60,11 @@ func (_c *Saver_Save_Call) Return(_a0 error) *Saver_Save_Call { return _c } +func (_c *Saver_Save_Call) RunAndReturn(run func(context.Context, []cosmosclient.TX) error) *Saver_Save_Call { + _c.Call.Return(run) + return _c +} + type mockConstructorTestingTNewSaver interface { mock.TestingT Cleanup(func()) diff --git a/ignite/pkg/cosmostxcollector/mocks/txs_collector.go b/ignite/pkg/cosmostxcollector/mocks/txs_collector.go index a80ee11808..9ee77bed6e 100644 --- a/ignite/pkg/cosmostxcollector/mocks/txs_collector.go +++ b/ignite/pkg/cosmostxcollector/mocks/txs_collector.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.16.0. DO NOT EDIT. +// Code generated by mockery v2.27.1. DO NOT EDIT. package mocks @@ -62,6 +62,11 @@ func (_c *TXsCollector_CollectTXs_Call) Return(_a0 error) *TXsCollector_CollectT return _c } +func (_c *TXsCollector_CollectTXs_Call) RunAndReturn(run func(context.Context, int64, chan<- []cosmosclient.TX) error) *TXsCollector_CollectTXs_Call { + _c.Call.Return(run) + return _c +} + type mockConstructorTestingTNewTXsCollector interface { mock.TestingT Cleanup(func()) diff --git a/ignite/pkg/protoanalysis/package.go b/ignite/pkg/protoanalysis/package.go index 3e139c164d..9beb7122cc 100644 --- a/ignite/pkg/protoanalysis/package.go +++ b/ignite/pkg/protoanalysis/package.go @@ -17,35 +17,27 @@ type ( // Package represents a proto pkg. Package struct { // Name of the proto pkg. - Name string + Name string `json:"name,omitempty"` // Path of the package in the fs. - Path string + Path string `json:"path,omitempty"` // Files is a list of .proto files in the package. - Files Files + Files Files `json:"files,omitempty"` // GoImportName is the go package name of proto package. - GoImportName string + GoImportName string `json:"go_import_name,omitempty"` // Messages is a list of proto messages defined in the package. - Messages []Message + Messages []Message `json:"messages,omitempty"` // Services is a list of RPC services. - Services []Service + Services []Service `json:"services,omitempty"` } ) var regexBetaVersion = regexp.MustCompile("^v[0-9]+(beta|alpha)[0-9]+") -func (p Packages) Files() Files { - var files []File - for _, pkg := range p { - files = append(files, pkg.Files...) - } - return files -} - // ModuleName retrieves the single module name of the package. func (p Package) ModuleName() (name string) { names := strings.Split(p.Name, ".") @@ -73,18 +65,28 @@ func (p Package) GoImportPath() string { return strings.Split(p.GoImportName, ";")[0] } +// Files retrieves the files from the package list. +func (p Packages) Files() Files { + var files []File + for _, pkg := range p { + files = append(files, pkg.Files...) + } + return files +} + type ( Files []File File struct { // Path of the file. - Path string + Path string `json:"path,omitempty"` - // Dependencies is a list of imported .proto files in this package. - Dependencies []string + // Dependencies is a list of imported proto packages. + Dependencies []string `json:"dependencies,omitempty"` } ) +// Paths retrieves the list of paths from the files. func (f Files) Paths() []string { var paths []string for _, ff := range f { @@ -97,57 +99,57 @@ type ( // Message represents a proto message. Message struct { // Name of the message. - Name string + Name string `json:"name,omitempty"` - // Path of the file where message is defined at. - Path string + // Path of the proto file where the message is defined. + Path string `json:"path,omitempty"` - // HighestFieldNumber is the highest field number among fields of the message - // This allows to determine new field number when writing to proto message - HighestFieldNumber int + // HighestFieldNumber is the highest field number among fields of the message. + // This allows to determine new field number when writing to proto message. + HighestFieldNumber int `json:"highest_field_number,omitempty"` - // Fields contains message's field names and types - Fields map[string]string + // Fields contains message's field names and types. + Fields map[string]string `json:"fields,omitempty"` } // Service is an RPC service. Service struct { // Name of the services. - Name string + Name string `json:"name,omitempty"` - // RPC is a list of RPC funcs of the service. - RPCFuncs []RPCFunc + // RPCFuncs is a list of RPC funcs of the service. + RPCFuncs []RPCFunc `json:"functions,omitempty"` } // RPCFunc is an RPC func. RPCFunc struct { // Name of the RPC func. - Name string + Name string `json:"name,omitempty"` // RequestType is the request type of RPC func. - RequestType string + RequestType string `json:"request_type,omitempty"` // ReturnsType is the response type of RPC func. - ReturnsType string + ReturnsType string `json:"return_type,omitempty"` // HTTPRules keeps info about http rules of an RPC func. // spec: // https://github.com/googleapis/googleapis/blob/master/google/api/http.proto. - HTTPRules []HTTPRule + HTTPRules []HTTPRule `json:"http_rules,omitempty"` // Paginated indicates that the RPC function is using pagination. - Paginated bool + Paginated bool `json:"paginated,omitempty"` } // HTTPRule keeps info about a configured http rule of an RPC func. HTTPRule struct { - // Params is a list of parameters defined in the http endpoint itself. - Params []string + // Params is a list of parameters defined in the HTTP endpoint itself. + Params []string `json:"params,omitempty"` // HasQuery indicates if there is a request query. - HasQuery bool + HasQuery bool `json:"has_query,omitempty"` // HasBody indicates if there is a request payload. - HasBody bool + HasBody bool `json:"has_body,omitempty"` } ) diff --git a/ignite/services/chain/chain.go b/ignite/services/chain/chain.go index 2bc222ab57..4e8af01382 100644 --- a/ignite/services/chain/chain.go +++ b/ignite/services/chain/chain.go @@ -314,6 +314,11 @@ func (c *Chain) Home() (string, error) { return home, nil } +// AppPath returns the configured App's path. +func (c *Chain) AppPath() string { + return c.app.Path +} + // DefaultHome returns the blockchain node's default home dir when not specified in the app. func (c *Chain) DefaultHome() (string, error) { // check if home is defined in config diff --git a/ignite/services/plugin/cache.go b/ignite/services/plugin/cache.go index a0832da6ce..bcdce5fa28 100644 --- a/ignite/services/plugin/cache.go +++ b/ignite/services/plugin/cache.go @@ -16,6 +16,9 @@ const ( cacheNamespace = "plugin.rpc.context" ) +// Caches configuration for shared plugin hosts. +// The cached configuration can be used to re-attach to running plugins. +// These type of plugins must have "shared_host: true" in their manifest. var storageCache *cache.Cache[hplugin.ReattachConfig] func init() { diff --git a/ignite/services/plugin/cache_test.go b/ignite/services/plugin/cache_test.go index c11ca8b033..44dbb9ec4e 100644 --- a/ignite/services/plugin/cache_test.go +++ b/ignite/services/plugin/cache_test.go @@ -14,7 +14,7 @@ func TestReadWriteConfigCache(t *testing.T) { unixFD, _ := net.ResolveUnixAddr("unix", "/var/folders/5k/sv4bxrs102n_6rr7430jc7j80000gn/T/plugin193424090") rc := hplugin.ReattachConfig{ - Protocol: hplugin.ProtocolNetRPC, + Protocol: hplugin.ProtocolGRPC, ProtocolVersion: hplugin.CoreProtocolVersion, Addr: unixFD, Pid: 24464, @@ -31,7 +31,7 @@ func TestReadWriteConfigCache(t *testing.T) { t.Run("Should error writing bad plugin config to cache", func(t *testing.T) { const path = "/path/to/awesome/plugin" rc := hplugin.ReattachConfig{ - Protocol: hplugin.ProtocolNetRPC, + Protocol: hplugin.ProtocolGRPC, ProtocolVersion: hplugin.CoreProtocolVersion, Addr: nil, Pid: 24464, @@ -44,7 +44,7 @@ func TestReadWriteConfigCache(t *testing.T) { t.Run("Should error with invalid plugin path", func(t *testing.T) { const path = "" rc := hplugin.ReattachConfig{ - Protocol: hplugin.ProtocolNetRPC, + Protocol: hplugin.ProtocolGRPC, ProtocolVersion: hplugin.CoreProtocolVersion, Addr: nil, Pid: 24464, @@ -61,7 +61,7 @@ func TestDeleteConfCache(t *testing.T) { unixFD, _ := net.ResolveUnixAddr("unix", "/var/folders/5k/sv4bxrs102n_6rr7430jc7j80000gn/T/plugin193424090") rc := hplugin.ReattachConfig{ - Protocol: hplugin.ProtocolNetRPC, + Protocol: hplugin.ProtocolGRPC, ProtocolVersion: hplugin.CoreProtocolVersion, Addr: unixFD, Pid: 24464, @@ -90,7 +90,7 @@ func TestCheckConfCache(t *testing.T) { unixFD, _ := net.ResolveUnixAddr("unix", "/var/folders/5k/sv4bxrs102n_6rr7430jc7j80000gn/T/plugin193424090") rc := hplugin.ReattachConfig{ - Protocol: hplugin.ProtocolNetRPC, + Protocol: hplugin.ProtocolGRPC, ProtocolVersion: hplugin.CoreProtocolVersion, Addr: unixFD, Pid: 24464, diff --git a/ignite/services/plugin/client_api.go b/ignite/services/plugin/client_api.go new file mode 100644 index 0000000000..6bfde13ccf --- /dev/null +++ b/ignite/services/plugin/client_api.go @@ -0,0 +1,47 @@ +package plugin + +import ( + "context" +) + +type Chainer interface { + // AppPath returns the configured App's path. + AppPath() string + + // ID returns the configured App's chain id. + ID() (string, error) + + // ConfigPath returns the path to the App's config file. + ConfigPath() string + + // RPCPublicAddress returns the configured App's rpc endpoint. + RPCPublicAddress() (string, error) +} + +// NewClientAPI creates a new app ClientAPI. +func NewClientAPI(c Chainer) ClientAPI { + return clientAPI{chain: c} +} + +type clientAPI struct { + chain Chainer +} + +func (api clientAPI) GetChainInfo(context.Context) (*ChainInfo, error) { + chainID, err := api.chain.ID() + if err != nil { + return nil, err + } + + rpc, err := api.chain.RPCPublicAddress() + if err != nil { + return nil, err + } + + return &ChainInfo{ + ChainId: chainID, + AppPath: api.chain.AppPath(), + ConfigPath: api.chain.ConfigPath(), + RpcAddress: rpc, + }, nil +} diff --git a/ignite/services/plugin/grpc/v1/client_api.pb.go b/ignite/services/plugin/grpc/v1/client_api.pb.go new file mode 100644 index 0000000000..d0a5a00f68 --- /dev/null +++ b/ignite/services/plugin/grpc/v1/client_api.pb.go @@ -0,0 +1,178 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.31.0 +// protoc (unknown) +// source: ignite/services/plugin/grpc/v1/client_api.proto + +package v1 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type ChainInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ChainId string `protobuf:"bytes,1,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` + AppPath string `protobuf:"bytes,2,opt,name=app_path,json=appPath,proto3" json:"app_path,omitempty"` + ConfigPath string `protobuf:"bytes,3,opt,name=config_path,json=configPath,proto3" json:"config_path,omitempty"` + RpcAddress string `protobuf:"bytes,4,opt,name=rpc_address,json=rpcAddress,proto3" json:"rpc_address,omitempty"` +} + +func (x *ChainInfo) Reset() { + *x = ChainInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_ignite_services_plugin_grpc_v1_client_api_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ChainInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ChainInfo) ProtoMessage() {} + +func (x *ChainInfo) ProtoReflect() protoreflect.Message { + mi := &file_ignite_services_plugin_grpc_v1_client_api_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ChainInfo.ProtoReflect.Descriptor instead. +func (*ChainInfo) Descriptor() ([]byte, []int) { + return file_ignite_services_plugin_grpc_v1_client_api_proto_rawDescGZIP(), []int{0} +} + +func (x *ChainInfo) GetChainId() string { + if x != nil { + return x.ChainId + } + return "" +} + +func (x *ChainInfo) GetAppPath() string { + if x != nil { + return x.AppPath + } + return "" +} + +func (x *ChainInfo) GetConfigPath() string { + if x != nil { + return x.ConfigPath + } + return "" +} + +func (x *ChainInfo) GetRpcAddress() string { + if x != nil { + return x.RpcAddress + } + return "" +} + +var File_ignite_services_plugin_grpc_v1_client_api_proto protoreflect.FileDescriptor + +var file_ignite_services_plugin_grpc_v1_client_api_proto_rawDesc = []byte{ + 0x0a, 0x2f, 0x69, 0x67, 0x6e, 0x69, 0x74, 0x65, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x73, 0x2f, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x76, 0x31, + 0x2f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x12, 0x1e, 0x69, 0x67, 0x6e, 0x69, 0x74, 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x73, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, + 0x31, 0x22, 0x83, 0x01, 0x0a, 0x09, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, + 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x70, + 0x70, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x70, + 0x70, 0x50, 0x61, 0x74, 0x68, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, + 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x50, 0x61, 0x74, 0x68, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x70, 0x63, 0x5f, 0x61, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x70, 0x63, + 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x42, 0x36, 0x5a, 0x34, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x67, 0x6e, 0x69, 0x74, 0x65, 0x2f, 0x63, 0x6c, 0x69, + 0x2f, 0x69, 0x67, 0x6e, 0x69, 0x74, 0x65, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, + 0x2f, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x76, 0x31, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_ignite_services_plugin_grpc_v1_client_api_proto_rawDescOnce sync.Once + file_ignite_services_plugin_grpc_v1_client_api_proto_rawDescData = file_ignite_services_plugin_grpc_v1_client_api_proto_rawDesc +) + +func file_ignite_services_plugin_grpc_v1_client_api_proto_rawDescGZIP() []byte { + file_ignite_services_plugin_grpc_v1_client_api_proto_rawDescOnce.Do(func() { + file_ignite_services_plugin_grpc_v1_client_api_proto_rawDescData = protoimpl.X.CompressGZIP(file_ignite_services_plugin_grpc_v1_client_api_proto_rawDescData) + }) + return file_ignite_services_plugin_grpc_v1_client_api_proto_rawDescData +} + +var file_ignite_services_plugin_grpc_v1_client_api_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_ignite_services_plugin_grpc_v1_client_api_proto_goTypes = []interface{}{ + (*ChainInfo)(nil), // 0: ignite.services.plugin.grpc.v1.ChainInfo +} +var file_ignite_services_plugin_grpc_v1_client_api_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_ignite_services_plugin_grpc_v1_client_api_proto_init() } +func file_ignite_services_plugin_grpc_v1_client_api_proto_init() { + if File_ignite_services_plugin_grpc_v1_client_api_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_ignite_services_plugin_grpc_v1_client_api_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ChainInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_ignite_services_plugin_grpc_v1_client_api_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_ignite_services_plugin_grpc_v1_client_api_proto_goTypes, + DependencyIndexes: file_ignite_services_plugin_grpc_v1_client_api_proto_depIdxs, + MessageInfos: file_ignite_services_plugin_grpc_v1_client_api_proto_msgTypes, + }.Build() + File_ignite_services_plugin_grpc_v1_client_api_proto = out.File + file_ignite_services_plugin_grpc_v1_client_api_proto_rawDesc = nil + file_ignite_services_plugin_grpc_v1_client_api_proto_goTypes = nil + file_ignite_services_plugin_grpc_v1_client_api_proto_depIdxs = nil +} diff --git a/ignite/services/plugin/grpc/v1/interface.pb.go b/ignite/services/plugin/grpc/v1/interface.pb.go new file mode 100644 index 0000000000..2c294ad841 --- /dev/null +++ b/ignite/services/plugin/grpc/v1/interface.pb.go @@ -0,0 +1,856 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.31.0 +// protoc (unknown) +// source: ignite/services/plugin/grpc/v1/interface.proto + +package v1 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// Type represents the flag type. +type Flag_Type int32 + +const ( + Flag_TYPE_FLAG_STRING_UNSPECIFIED Flag_Type = 0 + Flag_TYPE_FLAG_INT Flag_Type = 1 + Flag_TYPE_FLAG_UINT Flag_Type = 2 + Flag_TYPE_FLAG_INT64 Flag_Type = 3 + Flag_TYPE_FLAG_UINT64 Flag_Type = 4 + Flag_TYPE_FLAG_BOOL Flag_Type = 5 + Flag_TYPE_FLAG_STRING_SLICE Flag_Type = 6 +) + +// Enum value maps for Flag_Type. +var ( + Flag_Type_name = map[int32]string{ + 0: "TYPE_FLAG_STRING_UNSPECIFIED", + 1: "TYPE_FLAG_INT", + 2: "TYPE_FLAG_UINT", + 3: "TYPE_FLAG_INT64", + 4: "TYPE_FLAG_UINT64", + 5: "TYPE_FLAG_BOOL", + 6: "TYPE_FLAG_STRING_SLICE", + } + Flag_Type_value = map[string]int32{ + "TYPE_FLAG_STRING_UNSPECIFIED": 0, + "TYPE_FLAG_INT": 1, + "TYPE_FLAG_UINT": 2, + "TYPE_FLAG_INT64": 3, + "TYPE_FLAG_UINT64": 4, + "TYPE_FLAG_BOOL": 5, + "TYPE_FLAG_STRING_SLICE": 6, + } +) + +func (x Flag_Type) Enum() *Flag_Type { + p := new(Flag_Type) + *p = x + return p +} + +func (x Flag_Type) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Flag_Type) Descriptor() protoreflect.EnumDescriptor { + return file_ignite_services_plugin_grpc_v1_interface_proto_enumTypes[0].Descriptor() +} + +func (Flag_Type) Type() protoreflect.EnumType { + return &file_ignite_services_plugin_grpc_v1_interface_proto_enumTypes[0] +} + +func (x Flag_Type) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Flag_Type.Descriptor instead. +func (Flag_Type) EnumDescriptor() ([]byte, []int) { + return file_ignite_services_plugin_grpc_v1_interface_proto_rawDescGZIP(), []int{4, 0} +} + +// ExecutedCommand represents a plugin command under execution. +type ExecutedCommand struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Use is the one-line usage message. + Use string `protobuf:"bytes,1,opt,name=use,proto3" json:"use,omitempty"` + // Path contains the command path, e.g. `ignite scaffold foo`. + Path string `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"` + // Args are the command arguments. + Args []string `protobuf:"bytes,3,rep,name=args,proto3" json:"args,omitempty"` + // Full list of args taken from the command line. + OsArgs []string `protobuf:"bytes,4,rep,name=os_args,json=osArgs,proto3" json:"os_args,omitempty"` + // With contains the plugin config parameters. + With map[string]string `protobuf:"bytes,5,rep,name=with,proto3" json:"with,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + // Flags holds the list of command flags. + Flags []*Flag `protobuf:"bytes,6,rep,name=flags,proto3" json:"flags,omitempty"` +} + +func (x *ExecutedCommand) Reset() { + *x = ExecutedCommand{} + if protoimpl.UnsafeEnabled { + mi := &file_ignite_services_plugin_grpc_v1_interface_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ExecutedCommand) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExecutedCommand) ProtoMessage() {} + +func (x *ExecutedCommand) ProtoReflect() protoreflect.Message { + mi := &file_ignite_services_plugin_grpc_v1_interface_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ExecutedCommand.ProtoReflect.Descriptor instead. +func (*ExecutedCommand) Descriptor() ([]byte, []int) { + return file_ignite_services_plugin_grpc_v1_interface_proto_rawDescGZIP(), []int{0} +} + +func (x *ExecutedCommand) GetUse() string { + if x != nil { + return x.Use + } + return "" +} + +func (x *ExecutedCommand) GetPath() string { + if x != nil { + return x.Path + } + return "" +} + +func (x *ExecutedCommand) GetArgs() []string { + if x != nil { + return x.Args + } + return nil +} + +func (x *ExecutedCommand) GetOsArgs() []string { + if x != nil { + return x.OsArgs + } + return nil +} + +func (x *ExecutedCommand) GetWith() map[string]string { + if x != nil { + return x.With + } + return nil +} + +func (x *ExecutedCommand) GetFlags() []*Flag { + if x != nil { + return x.Flags + } + return nil +} + +// ExecutedHook represents a plugin hook under execution. +type ExecutedHook struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Hook is a copy of the original Hook defined in the Manifest. + Hook *Hook `protobuf:"bytes,1,opt,name=hook,proto3" json:"hook,omitempty"` + // ExecutedCommand gives access to the command attached by the hook. + ExecutedCommand *ExecutedCommand `protobuf:"bytes,2,opt,name=executed_command,json=executedCommand,proto3" json:"executed_command,omitempty"` +} + +func (x *ExecutedHook) Reset() { + *x = ExecutedHook{} + if protoimpl.UnsafeEnabled { + mi := &file_ignite_services_plugin_grpc_v1_interface_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ExecutedHook) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExecutedHook) ProtoMessage() {} + +func (x *ExecutedHook) ProtoReflect() protoreflect.Message { + mi := &file_ignite_services_plugin_grpc_v1_interface_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ExecutedHook.ProtoReflect.Descriptor instead. +func (*ExecutedHook) Descriptor() ([]byte, []int) { + return file_ignite_services_plugin_grpc_v1_interface_proto_rawDescGZIP(), []int{1} +} + +func (x *ExecutedHook) GetHook() *Hook { + if x != nil { + return x.Hook + } + return nil +} + +func (x *ExecutedHook) GetExecutedCommand() *ExecutedCommand { + if x != nil { + return x.ExecutedCommand + } + return nil +} + +// Manifest represents the plugin behavior. +type Manifest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Plugin name. + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // Commands contains the commands that will be added to the list of ignite commands. + // Each commands are independent, for nested commands use the inner Commands field. + SharedHost bool `protobuf:"varint,2,opt,name=shared_host,json=sharedHost,proto3" json:"shared_host,omitempty"` + // Hooks contains the hooks that will be attached to the existing ignite commands. + Commands []*Command `protobuf:"bytes,3,rep,name=commands,proto3" json:"commands,omitempty"` + // Enables sharing a single plugin server across all running instances of a plugin. + // Useful if a plugin adds or extends long running commands. + // + // Example: if a plugin defines a hook on `ignite chain serve`, a plugin server is + // instanciated when the command is run. Now if you want to interact with that instance + // from commands defined in that plugin, you need to enable shared host, or else the + // commands will just instantiate separate plugin servers. + // + // When enabled, all plugins of the same path loaded from the same configuration will + // attach it's RPC client to a an existing RPC server. + // + // If a plugin instance has no other running plugin servers, it will create one and it + // will be the host. + Hooks []*Hook `protobuf:"bytes,4,rep,name=hooks,proto3" json:"hooks,omitempty"` +} + +func (x *Manifest) Reset() { + *x = Manifest{} + if protoimpl.UnsafeEnabled { + mi := &file_ignite_services_plugin_grpc_v1_interface_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Manifest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Manifest) ProtoMessage() {} + +func (x *Manifest) ProtoReflect() protoreflect.Message { + mi := &file_ignite_services_plugin_grpc_v1_interface_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Manifest.ProtoReflect.Descriptor instead. +func (*Manifest) Descriptor() ([]byte, []int) { + return file_ignite_services_plugin_grpc_v1_interface_proto_rawDescGZIP(), []int{2} +} + +func (x *Manifest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Manifest) GetSharedHost() bool { + if x != nil { + return x.SharedHost + } + return false +} + +func (x *Manifest) GetCommands() []*Command { + if x != nil { + return x.Commands + } + return nil +} + +func (x *Manifest) GetHooks() []*Hook { + if x != nil { + return x.Hooks + } + return nil +} + +// Command represents a plugin command. +type Command struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Use is the one-line usage message. + // + // Recommended syntax is as follow: + // + // [ ] identifies an optional argument. Arguments that are not enclosed in brackets are required. + // ... indicates that you can specify multiple values for the previous argument. + // | indicates mutually exclusive information. You can use the argument to the left of the separator or the + // argument to the right of the separator. You cannot use both arguments in a single use of the command. + // { } delimits a set of mutually exclusive arguments when one of the arguments is required. If the arguments are + // optional, they are enclosed in brackets ([ ]). + // + // Example: add [-F file | -D dir]... [-f format] profile + Use string `protobuf:"bytes,1,opt,name=use,proto3" json:"use,omitempty"` + // Aliases is an array of aliases that can be used instead of the first word in Use. + Aliases []string `protobuf:"bytes,2,rep,name=aliases,proto3" json:"aliases,omitempty"` + // Short is the short description shown in the 'help' output. + Short string `protobuf:"bytes,3,opt,name=short,proto3" json:"short,omitempty"` + // Long is the long message shown in the 'help ' output. + Long string `protobuf:"bytes,4,opt,name=long,proto3" json:"long,omitempty"` + // Hidden defines, if this command is hidden and should NOT show up in the list of available commands. + Hidden bool `protobuf:"varint,5,opt,name=hidden,proto3" json:"hidden,omitempty"` + // Flags holds the list of command flags. + Flags []*Flag `protobuf:"bytes,6,rep,name=flags,proto3" json:"flags,omitempty"` + // Indicates where the command should be placed. + // For instance `ignite scaffold` will place the command at the `scaffold` command. + // An empty value is interpreted as `ignite` (==root). + PlaceCommandUnder string `protobuf:"bytes,7,opt,name=place_command_under,json=placeCommandUnder,proto3" json:"place_command_under,omitempty"` + // List of sub commands. + Commands []*Command `protobuf:"bytes,8,rep,name=commands,proto3" json:"commands,omitempty"` +} + +func (x *Command) Reset() { + *x = Command{} + if protoimpl.UnsafeEnabled { + mi := &file_ignite_services_plugin_grpc_v1_interface_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Command) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Command) ProtoMessage() {} + +func (x *Command) ProtoReflect() protoreflect.Message { + mi := &file_ignite_services_plugin_grpc_v1_interface_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Command.ProtoReflect.Descriptor instead. +func (*Command) Descriptor() ([]byte, []int) { + return file_ignite_services_plugin_grpc_v1_interface_proto_rawDescGZIP(), []int{3} +} + +func (x *Command) GetUse() string { + if x != nil { + return x.Use + } + return "" +} + +func (x *Command) GetAliases() []string { + if x != nil { + return x.Aliases + } + return nil +} + +func (x *Command) GetShort() string { + if x != nil { + return x.Short + } + return "" +} + +func (x *Command) GetLong() string { + if x != nil { + return x.Long + } + return "" +} + +func (x *Command) GetHidden() bool { + if x != nil { + return x.Hidden + } + return false +} + +func (x *Command) GetFlags() []*Flag { + if x != nil { + return x.Flags + } + return nil +} + +func (x *Command) GetPlaceCommandUnder() string { + if x != nil { + return x.PlaceCommandUnder + } + return "" +} + +func (x *Command) GetCommands() []*Command { + if x != nil { + return x.Commands + } + return nil +} + +// Flag represents of a command line flag. +type Flag struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Name as it appears in the command line. + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // One letter abbreviation of the flag. + Shorthand string `protobuf:"bytes,2,opt,name=shorthand,proto3" json:"shorthand,omitempty"` + // Help message. + Usage string `protobuf:"bytes,3,opt,name=usage,proto3" json:"usage,omitempty"` + // Default flag value. + DefaultValue string `protobuf:"bytes,4,opt,name=default_value,json=defaultValue,proto3" json:"default_value,omitempty"` + // Flag type. + Type Flag_Type `protobuf:"varint,5,opt,name=type,proto3,enum=ignite.services.plugin.grpc.v1.Flag_Type" json:"type,omitempty"` + // Flag value. + Value string `protobuf:"bytes,6,opt,name=value,proto3" json:"value,omitempty"` + // Indicates wether or not the flag is propagated on children commands. + Persistent bool `protobuf:"varint,7,opt,name=persistent,proto3" json:"persistent,omitempty"` +} + +func (x *Flag) Reset() { + *x = Flag{} + if protoimpl.UnsafeEnabled { + mi := &file_ignite_services_plugin_grpc_v1_interface_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Flag) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Flag) ProtoMessage() {} + +func (x *Flag) ProtoReflect() protoreflect.Message { + mi := &file_ignite_services_plugin_grpc_v1_interface_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Flag.ProtoReflect.Descriptor instead. +func (*Flag) Descriptor() ([]byte, []int) { + return file_ignite_services_plugin_grpc_v1_interface_proto_rawDescGZIP(), []int{4} +} + +func (x *Flag) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Flag) GetShorthand() string { + if x != nil { + return x.Shorthand + } + return "" +} + +func (x *Flag) GetUsage() string { + if x != nil { + return x.Usage + } + return "" +} + +func (x *Flag) GetDefaultValue() string { + if x != nil { + return x.DefaultValue + } + return "" +} + +func (x *Flag) GetType() Flag_Type { + if x != nil { + return x.Type + } + return Flag_TYPE_FLAG_STRING_UNSPECIFIED +} + +func (x *Flag) GetValue() string { + if x != nil { + return x.Value + } + return "" +} + +func (x *Flag) GetPersistent() bool { + if x != nil { + return x.Persistent + } + return false +} + +// Hook represents a user defined action within a plugin. +type Hook struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Identifies the hook for the client to invoke the correct hook. + // It must be unique. + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // Indicates the command where to register the hooks. + PlaceHookOn string `protobuf:"bytes,2,opt,name=place_hook_on,json=placeHookOn,proto3" json:"place_hook_on,omitempty"` +} + +func (x *Hook) Reset() { + *x = Hook{} + if protoimpl.UnsafeEnabled { + mi := &file_ignite_services_plugin_grpc_v1_interface_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Hook) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Hook) ProtoMessage() {} + +func (x *Hook) ProtoReflect() protoreflect.Message { + mi := &file_ignite_services_plugin_grpc_v1_interface_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Hook.ProtoReflect.Descriptor instead. +func (*Hook) Descriptor() ([]byte, []int) { + return file_ignite_services_plugin_grpc_v1_interface_proto_rawDescGZIP(), []int{5} +} + +func (x *Hook) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Hook) GetPlaceHookOn() string { + if x != nil { + return x.PlaceHookOn + } + return "" +} + +var File_ignite_services_plugin_grpc_v1_interface_proto protoreflect.FileDescriptor + +var file_ignite_services_plugin_grpc_v1_interface_proto_rawDesc = []byte{ + 0x0a, 0x2e, 0x69, 0x67, 0x6e, 0x69, 0x74, 0x65, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x73, 0x2f, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x76, 0x31, + 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x12, 0x1e, 0x69, 0x67, 0x6e, 0x69, 0x74, 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x73, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, + 0x22, 0xa8, 0x02, 0x0a, 0x0f, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x6d, + 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x75, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x72, + 0x67, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x61, 0x72, 0x67, 0x73, 0x12, 0x17, + 0x0a, 0x07, 0x6f, 0x73, 0x5f, 0x61, 0x72, 0x67, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x06, 0x6f, 0x73, 0x41, 0x72, 0x67, 0x73, 0x12, 0x4d, 0x0a, 0x04, 0x77, 0x69, 0x74, 0x68, 0x18, + 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x69, 0x67, 0x6e, 0x69, 0x74, 0x65, 0x2e, 0x73, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x67, + 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x64, 0x43, + 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x57, 0x69, 0x74, 0x68, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x52, 0x04, 0x77, 0x69, 0x74, 0x68, 0x12, 0x3a, 0x0a, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x18, + 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x69, 0x67, 0x6e, 0x69, 0x74, 0x65, 0x2e, 0x73, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x67, + 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x6c, 0x61, 0x67, 0x52, 0x05, 0x66, 0x6c, 0x61, + 0x67, 0x73, 0x1a, 0x37, 0x0a, 0x09, 0x57, 0x69, 0x74, 0x68, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, + 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, + 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xa4, 0x01, 0x0a, 0x0c, + 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x64, 0x48, 0x6f, 0x6f, 0x6b, 0x12, 0x38, 0x0a, 0x04, + 0x68, 0x6f, 0x6f, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x69, 0x67, 0x6e, + 0x69, 0x74, 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x70, 0x6c, 0x75, + 0x67, 0x69, 0x6e, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x6f, 0x6f, 0x6b, + 0x52, 0x04, 0x68, 0x6f, 0x6f, 0x6b, 0x12, 0x5a, 0x0a, 0x10, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, + 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x2f, 0x2e, 0x69, 0x67, 0x6e, 0x69, 0x74, 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x73, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, + 0x31, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, + 0x64, 0x52, 0x0f, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x61, + 0x6e, 0x64, 0x22, 0xc0, 0x01, 0x0a, 0x08, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x12, + 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x5f, 0x68, 0x6f, + 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, + 0x48, 0x6f, 0x73, 0x74, 0x12, 0x43, 0x0a, 0x08, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, + 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x69, 0x67, 0x6e, 0x69, 0x74, 0x65, 0x2e, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, + 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, + 0x08, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x12, 0x3a, 0x0a, 0x05, 0x68, 0x6f, 0x6f, + 0x6b, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x69, 0x67, 0x6e, 0x69, 0x74, + 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, + 0x6e, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x6f, 0x6f, 0x6b, 0x52, 0x05, + 0x68, 0x6f, 0x6f, 0x6b, 0x73, 0x22, 0xa8, 0x02, 0x0a, 0x07, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, + 0x64, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, + 0x75, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x18, 0x02, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x12, 0x14, 0x0a, + 0x05, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, + 0x6f, 0x72, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x6f, 0x6e, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x6c, 0x6f, 0x6e, 0x67, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x69, 0x64, 0x64, 0x65, + 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x12, + 0x3a, 0x0a, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, + 0x2e, 0x69, 0x67, 0x6e, 0x69, 0x74, 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, + 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, + 0x46, 0x6c, 0x61, 0x67, 0x52, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x12, 0x2e, 0x0a, 0x13, 0x70, + 0x6c, 0x61, 0x63, 0x65, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x5f, 0x75, 0x6e, 0x64, + 0x65, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x43, + 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x55, 0x6e, 0x64, 0x65, 0x72, 0x12, 0x43, 0x0a, 0x08, 0x63, + 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, + 0x69, 0x67, 0x6e, 0x69, 0x74, 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, + 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x43, + 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x08, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, + 0x22, 0x95, 0x03, 0x0a, 0x04, 0x46, 0x6c, 0x61, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, + 0x09, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x68, 0x61, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x09, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x68, 0x61, 0x6e, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x75, + 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x75, 0x73, 0x61, 0x67, + 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, + 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x3d, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x29, 0x2e, 0x69, 0x67, 0x6e, 0x69, 0x74, 0x65, 0x2e, 0x73, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x67, 0x72, + 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x6c, 0x61, 0x67, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, + 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x70, + 0x65, 0x72, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x0a, 0x70, 0x65, 0x72, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x74, 0x22, 0xaa, 0x01, 0x0a, 0x04, + 0x54, 0x79, 0x70, 0x65, 0x12, 0x20, 0x0a, 0x1c, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x46, 0x4c, 0x41, + 0x47, 0x5f, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, + 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x46, + 0x4c, 0x41, 0x47, 0x5f, 0x49, 0x4e, 0x54, 0x10, 0x01, 0x12, 0x12, 0x0a, 0x0e, 0x54, 0x59, 0x50, + 0x45, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x5f, 0x55, 0x49, 0x4e, 0x54, 0x10, 0x02, 0x12, 0x13, 0x0a, + 0x0f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x5f, 0x49, 0x4e, 0x54, 0x36, 0x34, + 0x10, 0x03, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x5f, + 0x55, 0x49, 0x4e, 0x54, 0x36, 0x34, 0x10, 0x04, 0x12, 0x12, 0x0a, 0x0e, 0x54, 0x59, 0x50, 0x45, + 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x5f, 0x42, 0x4f, 0x4f, 0x4c, 0x10, 0x05, 0x12, 0x1a, 0x0a, 0x16, + 0x54, 0x59, 0x50, 0x45, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x5f, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, + 0x5f, 0x53, 0x4c, 0x49, 0x43, 0x45, 0x10, 0x06, 0x22, 0x3e, 0x0a, 0x04, 0x48, 0x6f, 0x6f, 0x6b, + 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x22, 0x0a, 0x0d, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x5f, 0x68, 0x6f, + 0x6f, 0x6b, 0x5f, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x6c, 0x61, + 0x63, 0x65, 0x48, 0x6f, 0x6f, 0x6b, 0x4f, 0x6e, 0x42, 0x36, 0x5a, 0x34, 0x67, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x67, 0x6e, 0x69, 0x74, 0x65, 0x2f, 0x63, 0x6c, + 0x69, 0x2f, 0x69, 0x67, 0x6e, 0x69, 0x74, 0x65, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x73, 0x2f, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x76, 0x31, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_ignite_services_plugin_grpc_v1_interface_proto_rawDescOnce sync.Once + file_ignite_services_plugin_grpc_v1_interface_proto_rawDescData = file_ignite_services_plugin_grpc_v1_interface_proto_rawDesc +) + +func file_ignite_services_plugin_grpc_v1_interface_proto_rawDescGZIP() []byte { + file_ignite_services_plugin_grpc_v1_interface_proto_rawDescOnce.Do(func() { + file_ignite_services_plugin_grpc_v1_interface_proto_rawDescData = protoimpl.X.CompressGZIP(file_ignite_services_plugin_grpc_v1_interface_proto_rawDescData) + }) + return file_ignite_services_plugin_grpc_v1_interface_proto_rawDescData +} + +var file_ignite_services_plugin_grpc_v1_interface_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_ignite_services_plugin_grpc_v1_interface_proto_msgTypes = make([]protoimpl.MessageInfo, 7) +var file_ignite_services_plugin_grpc_v1_interface_proto_goTypes = []interface{}{ + (Flag_Type)(0), // 0: ignite.services.plugin.grpc.v1.Flag.Type + (*ExecutedCommand)(nil), // 1: ignite.services.plugin.grpc.v1.ExecutedCommand + (*ExecutedHook)(nil), // 2: ignite.services.plugin.grpc.v1.ExecutedHook + (*Manifest)(nil), // 3: ignite.services.plugin.grpc.v1.Manifest + (*Command)(nil), // 4: ignite.services.plugin.grpc.v1.Command + (*Flag)(nil), // 5: ignite.services.plugin.grpc.v1.Flag + (*Hook)(nil), // 6: ignite.services.plugin.grpc.v1.Hook + nil, // 7: ignite.services.plugin.grpc.v1.ExecutedCommand.WithEntry +} +var file_ignite_services_plugin_grpc_v1_interface_proto_depIdxs = []int32{ + 7, // 0: ignite.services.plugin.grpc.v1.ExecutedCommand.with:type_name -> ignite.services.plugin.grpc.v1.ExecutedCommand.WithEntry + 5, // 1: ignite.services.plugin.grpc.v1.ExecutedCommand.flags:type_name -> ignite.services.plugin.grpc.v1.Flag + 6, // 2: ignite.services.plugin.grpc.v1.ExecutedHook.hook:type_name -> ignite.services.plugin.grpc.v1.Hook + 1, // 3: ignite.services.plugin.grpc.v1.ExecutedHook.executed_command:type_name -> ignite.services.plugin.grpc.v1.ExecutedCommand + 4, // 4: ignite.services.plugin.grpc.v1.Manifest.commands:type_name -> ignite.services.plugin.grpc.v1.Command + 6, // 5: ignite.services.plugin.grpc.v1.Manifest.hooks:type_name -> ignite.services.plugin.grpc.v1.Hook + 5, // 6: ignite.services.plugin.grpc.v1.Command.flags:type_name -> ignite.services.plugin.grpc.v1.Flag + 4, // 7: ignite.services.plugin.grpc.v1.Command.commands:type_name -> ignite.services.plugin.grpc.v1.Command + 0, // 8: ignite.services.plugin.grpc.v1.Flag.type:type_name -> ignite.services.plugin.grpc.v1.Flag.Type + 9, // [9:9] is the sub-list for method output_type + 9, // [9:9] is the sub-list for method input_type + 9, // [9:9] is the sub-list for extension type_name + 9, // [9:9] is the sub-list for extension extendee + 0, // [0:9] is the sub-list for field type_name +} + +func init() { file_ignite_services_plugin_grpc_v1_interface_proto_init() } +func file_ignite_services_plugin_grpc_v1_interface_proto_init() { + if File_ignite_services_plugin_grpc_v1_interface_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_ignite_services_plugin_grpc_v1_interface_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ExecutedCommand); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ignite_services_plugin_grpc_v1_interface_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ExecutedHook); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ignite_services_plugin_grpc_v1_interface_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Manifest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ignite_services_plugin_grpc_v1_interface_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Command); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ignite_services_plugin_grpc_v1_interface_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Flag); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ignite_services_plugin_grpc_v1_interface_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Hook); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_ignite_services_plugin_grpc_v1_interface_proto_rawDesc, + NumEnums: 1, + NumMessages: 7, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_ignite_services_plugin_grpc_v1_interface_proto_goTypes, + DependencyIndexes: file_ignite_services_plugin_grpc_v1_interface_proto_depIdxs, + EnumInfos: file_ignite_services_plugin_grpc_v1_interface_proto_enumTypes, + MessageInfos: file_ignite_services_plugin_grpc_v1_interface_proto_msgTypes, + }.Build() + File_ignite_services_plugin_grpc_v1_interface_proto = out.File + file_ignite_services_plugin_grpc_v1_interface_proto_rawDesc = nil + file_ignite_services_plugin_grpc_v1_interface_proto_goTypes = nil + file_ignite_services_plugin_grpc_v1_interface_proto_depIdxs = nil +} diff --git a/ignite/services/plugin/grpc/v1/interface_command.go b/ignite/services/plugin/grpc/v1/interface_command.go new file mode 100644 index 0000000000..c396c75146 --- /dev/null +++ b/ignite/services/plugin/grpc/v1/interface_command.go @@ -0,0 +1,92 @@ +package v1 + +import ( + "strings" + + "github.com/spf13/cobra" + "github.com/spf13/pflag" +) + +const igniteBinaryName = "ignite" + +// Path returns the absolute command path including the binary name as prefix. +func (c *Command) Path() string { + return ensureFullCommandPath(c.PlaceCommandUnder) +} + +// ToCobraCommand returns a new Cobra command that matches the current command. +func (c *Command) ToCobraCommand() (*cobra.Command, error) { + cmd := &cobra.Command{ + Use: c.Use, + Aliases: c.Aliases, + Short: c.Short, + Long: c.Long, + Hidden: c.Hidden, + } + + for _, f := range c.Flags { + var fs *pflag.FlagSet + if f.Persistent { + fs = cmd.PersistentFlags() + } else { + fs = cmd.Flags() + } + + if err := f.exportToFlagSet(fs); err != nil { + return nil, err + } + } + + return cmd, nil +} + +// ImportFlags imports flags from a Cobra command. +func (c *ExecutedCommand) ImportFlags(cmd *cobra.Command) { + c.Flags = extractCobraFlags(cmd) +} + +// NewFlags creates a new flags set initialized with the executed command's flags. +func (c *ExecutedCommand) NewFlags() (*pflag.FlagSet, error) { + fs := pflag.NewFlagSet(igniteBinaryName, pflag.ContinueOnError) + + for _, f := range c.Flags { + if f.Persistent { + continue + } + + if err := f.exportToFlagSet(fs); err != nil { + return nil, err + } + } + + return fs, nil +} + +// NewPersistentFlags creates a new flags set initialized with the executed command's persistent flags. +func (c *ExecutedCommand) NewPersistentFlags() (*pflag.FlagSet, error) { + fs := pflag.NewFlagSet(igniteBinaryName, pflag.ContinueOnError) + + for _, f := range c.Flags { + if !f.Persistent { + continue + } + + if err := f.exportToFlagSet(fs); err != nil { + return nil, err + } + } + + return fs, nil +} + +func ensureFullCommandPath(path string) string { + path = strings.TrimSpace(path) + if path == "" { + return igniteBinaryName + } + + if !strings.HasPrefix(path, igniteBinaryName) { + path = igniteBinaryName + " " + path + } + return path +} diff --git a/ignite/services/plugin/grpc/v1/interface_flag.go b/ignite/services/plugin/grpc/v1/interface_flag.go new file mode 100644 index 0000000000..c458315760 --- /dev/null +++ b/ignite/services/plugin/grpc/v1/interface_flag.go @@ -0,0 +1,129 @@ +package v1 + +import ( + "fmt" + "strconv" + "strings" + + "github.com/spf13/pflag" +) + +const ( + cobraFlagTypeBool = "bool" + cobraFlagTypeInt = "int" + cobraFlagTypeInt64 = "int64" + cobraFlagTypeString = "string" + cobraFlagTypeStringSlice = "stringSlice" + cobraFlagTypeUint = "uint" + cobraFlagTypeUint64 = "uint64" +) + +var flagTypes = map[string]Flag_Type{ + cobraFlagTypeBool: Flag_TYPE_FLAG_BOOL, + cobraFlagTypeInt: Flag_TYPE_FLAG_INT, + cobraFlagTypeInt64: Flag_TYPE_FLAG_INT64, + cobraFlagTypeString: Flag_TYPE_FLAG_STRING_UNSPECIFIED, + cobraFlagTypeStringSlice: Flag_TYPE_FLAG_STRING_SLICE, + cobraFlagTypeUint: Flag_TYPE_FLAG_UINT, + cobraFlagTypeUint64: Flag_TYPE_FLAG_UINT64, +} + +func newDefaultFlagValueError(typeName, value string) error { + return fmt.Errorf("invalid default value for plugin command %s flag: %s", typeName, value) +} + +func (f *Flag) exportToFlagSet(fs *pflag.FlagSet) error { + switch f.Type { + case Flag_TYPE_FLAG_BOOL: + v, err := strconv.ParseBool(f.DefaultValue) + if err != nil { + return newDefaultFlagValueError(cobraFlagTypeBool, f.DefaultValue) + } + + fs.BoolP(f.Name, f.Shorthand, v, f.Usage) + fs.Set(f.Name, f.Value) + case Flag_TYPE_FLAG_INT: + v, err := strconv.Atoi(f.DefaultValue) + if err != nil { + return newDefaultFlagValueError(cobraFlagTypeInt, f.DefaultValue) + } + + fs.IntP(f.Name, f.Shorthand, v, f.Usage) + fs.Set(f.Name, f.Value) + case Flag_TYPE_FLAG_UINT: + v, err := strconv.ParseUint(f.DefaultValue, 10, 64) + if err != nil { + return newDefaultFlagValueError(cobraFlagTypeUint, f.DefaultValue) + } + + fs.UintP(f.Name, f.Shorthand, uint(v), f.Usage) + fs.Set(f.Name, f.Value) + case Flag_TYPE_FLAG_INT64: + v, err := strconv.ParseInt(f.DefaultValue, 10, 64) + if err != nil { + return newDefaultFlagValueError(cobraFlagTypeInt64, f.DefaultValue) + } + + fs.Int64P(f.Name, f.Shorthand, v, f.Usage) + fs.Set(f.Name, f.Value) + case Flag_TYPE_FLAG_UINT64: + v, err := strconv.ParseUint(f.DefaultValue, 10, 64) + if err != nil { + return newDefaultFlagValueError(cobraFlagTypeInt64, f.DefaultValue) + } + + fs.Uint64P(f.Name, f.Shorthand, v, f.Usage) + fs.Set(f.Name, f.Value) + case Flag_TYPE_FLAG_STRING_SLICE: + s := strings.Trim(f.DefaultValue, "[]") + fs.StringSliceP(f.Name, f.Shorthand, strings.Fields(s), f.Usage) + fs.Set(f.Name, strings.Trim(f.Value, "[]")) + case Flag_TYPE_FLAG_STRING_UNSPECIFIED: + fs.StringP(f.Name, f.Shorthand, f.DefaultValue, f.Usage) + fs.Set(f.Name, f.Value) + } + return nil +} + +type flagger interface { + Flags() *pflag.FlagSet + PersistentFlags() *pflag.FlagSet +} + +func extractCobraFlags(cmd flagger) []*Flag { + var flags []*Flag + + if cmd.Flags() != nil { + cmd.Flags().VisitAll(func(pf *pflag.Flag) { + // Skip persistent flags + if cmd.PersistentFlags().Lookup(pf.Name) != nil { + return + } + + flags = append(flags, &Flag{ + Name: pf.Name, + Shorthand: pf.Shorthand, + Usage: pf.Usage, + DefaultValue: pf.DefValue, + Value: pf.Value.String(), + Type: flagTypes[pf.Value.Type()], + }) + }) + } + + if cmd.PersistentFlags() != nil { + cmd.PersistentFlags().VisitAll(func(pf *pflag.Flag) { + flags = append(flags, &Flag{ + Name: pf.Name, + Shorthand: pf.Shorthand, + Usage: pf.Usage, + DefaultValue: pf.DefValue, + Value: pf.Value.String(), + Type: flagTypes[pf.Value.Type()], + Persistent: true, + }) + }) + } + + return flags +} diff --git a/ignite/services/plugin/grpc/v1/interface_hook.go b/ignite/services/plugin/grpc/v1/interface_hook.go new file mode 100644 index 0000000000..db5d02484a --- /dev/null +++ b/ignite/services/plugin/grpc/v1/interface_hook.go @@ -0,0 +1,6 @@ +package v1 + +// CommandPath returns the absolute command path including the binary name as prefix. +func (h *Hook) CommandPath() string { + return ensureFullCommandPath(h.PlaceHookOn) +} diff --git a/ignite/services/plugin/grpc/v1/interface_manifest.go b/ignite/services/plugin/grpc/v1/interface_manifest.go new file mode 100644 index 0000000000..1c67f579cf --- /dev/null +++ b/ignite/services/plugin/grpc/v1/interface_manifest.go @@ -0,0 +1,27 @@ +package v1 + +import "github.com/spf13/cobra" + +// ImportCobraCommand appends Cobra command definitions to the list of plugin commands. +// This method can be used in cases where a plugin defines the commands using Cobra. +func (m *Manifest) ImportCobraCommand(cmd *cobra.Command, placeCommandUnder string) { + m.Commands = append(m.Commands, convertCobraCommand(cmd, placeCommandUnder)) +} + +func convertCobraCommand(c *cobra.Command, placeCommandUnder string) *Command { + cmd := &Command{ + Use: c.Use, + Aliases: c.Aliases, + Short: c.Short, + Long: c.Long, + Hidden: c.Hidden, + PlaceCommandUnder: placeCommandUnder, + Flags: extractCobraFlags(c), + } + + for _, c := range c.Commands() { + cmd.Commands = append(cmd.Commands, convertCobraCommand(c, "")) + } + + return cmd +} diff --git a/ignite/services/plugin/grpc/v1/service.pb.go b/ignite/services/plugin/grpc/v1/service.pb.go new file mode 100644 index 0000000000..7cd54c135e --- /dev/null +++ b/ignite/services/plugin/grpc/v1/service.pb.go @@ -0,0 +1,914 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.31.0 +// protoc (unknown) +// source: ignite/services/plugin/grpc/v1/service.proto + +package v1 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type ManifestRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ManifestRequest) Reset() { + *x = ManifestRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ignite_services_plugin_grpc_v1_service_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ManifestRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ManifestRequest) ProtoMessage() {} + +func (x *ManifestRequest) ProtoReflect() protoreflect.Message { + mi := &file_ignite_services_plugin_grpc_v1_service_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ManifestRequest.ProtoReflect.Descriptor instead. +func (*ManifestRequest) Descriptor() ([]byte, []int) { + return file_ignite_services_plugin_grpc_v1_service_proto_rawDescGZIP(), []int{0} +} + +type ManifestResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Manifest *Manifest `protobuf:"bytes,1,opt,name=manifest,proto3" json:"manifest,omitempty"` +} + +func (x *ManifestResponse) Reset() { + *x = ManifestResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ignite_services_plugin_grpc_v1_service_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ManifestResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ManifestResponse) ProtoMessage() {} + +func (x *ManifestResponse) ProtoReflect() protoreflect.Message { + mi := &file_ignite_services_plugin_grpc_v1_service_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ManifestResponse.ProtoReflect.Descriptor instead. +func (*ManifestResponse) Descriptor() ([]byte, []int) { + return file_ignite_services_plugin_grpc_v1_service_proto_rawDescGZIP(), []int{1} +} + +func (x *ManifestResponse) GetManifest() *Manifest { + if x != nil { + return x.Manifest + } + return nil +} + +type ExecuteRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Cmd *ExecutedCommand `protobuf:"bytes,1,opt,name=cmd,proto3" json:"cmd,omitempty"` + ClientApi uint32 `protobuf:"varint,2,opt,name=client_api,json=clientApi,proto3" json:"client_api,omitempty"` +} + +func (x *ExecuteRequest) Reset() { + *x = ExecuteRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ignite_services_plugin_grpc_v1_service_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ExecuteRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExecuteRequest) ProtoMessage() {} + +func (x *ExecuteRequest) ProtoReflect() protoreflect.Message { + mi := &file_ignite_services_plugin_grpc_v1_service_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ExecuteRequest.ProtoReflect.Descriptor instead. +func (*ExecuteRequest) Descriptor() ([]byte, []int) { + return file_ignite_services_plugin_grpc_v1_service_proto_rawDescGZIP(), []int{2} +} + +func (x *ExecuteRequest) GetCmd() *ExecutedCommand { + if x != nil { + return x.Cmd + } + return nil +} + +func (x *ExecuteRequest) GetClientApi() uint32 { + if x != nil { + return x.ClientApi + } + return 0 +} + +type ExecuteResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ExecuteResponse) Reset() { + *x = ExecuteResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ignite_services_plugin_grpc_v1_service_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ExecuteResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExecuteResponse) ProtoMessage() {} + +func (x *ExecuteResponse) ProtoReflect() protoreflect.Message { + mi := &file_ignite_services_plugin_grpc_v1_service_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ExecuteResponse.ProtoReflect.Descriptor instead. +func (*ExecuteResponse) Descriptor() ([]byte, []int) { + return file_ignite_services_plugin_grpc_v1_service_proto_rawDescGZIP(), []int{3} +} + +type ExecuteHookPreRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Hook *ExecutedHook `protobuf:"bytes,1,opt,name=hook,proto3" json:"hook,omitempty"` + ClientApi uint32 `protobuf:"varint,2,opt,name=client_api,json=clientApi,proto3" json:"client_api,omitempty"` +} + +func (x *ExecuteHookPreRequest) Reset() { + *x = ExecuteHookPreRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ignite_services_plugin_grpc_v1_service_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ExecuteHookPreRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExecuteHookPreRequest) ProtoMessage() {} + +func (x *ExecuteHookPreRequest) ProtoReflect() protoreflect.Message { + mi := &file_ignite_services_plugin_grpc_v1_service_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ExecuteHookPreRequest.ProtoReflect.Descriptor instead. +func (*ExecuteHookPreRequest) Descriptor() ([]byte, []int) { + return file_ignite_services_plugin_grpc_v1_service_proto_rawDescGZIP(), []int{4} +} + +func (x *ExecuteHookPreRequest) GetHook() *ExecutedHook { + if x != nil { + return x.Hook + } + return nil +} + +func (x *ExecuteHookPreRequest) GetClientApi() uint32 { + if x != nil { + return x.ClientApi + } + return 0 +} + +type ExecuteHookPreResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ExecuteHookPreResponse) Reset() { + *x = ExecuteHookPreResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ignite_services_plugin_grpc_v1_service_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ExecuteHookPreResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExecuteHookPreResponse) ProtoMessage() {} + +func (x *ExecuteHookPreResponse) ProtoReflect() protoreflect.Message { + mi := &file_ignite_services_plugin_grpc_v1_service_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ExecuteHookPreResponse.ProtoReflect.Descriptor instead. +func (*ExecuteHookPreResponse) Descriptor() ([]byte, []int) { + return file_ignite_services_plugin_grpc_v1_service_proto_rawDescGZIP(), []int{5} +} + +type ExecuteHookPostRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Hook *ExecutedHook `protobuf:"bytes,1,opt,name=hook,proto3" json:"hook,omitempty"` + ClientApi uint32 `protobuf:"varint,2,opt,name=client_api,json=clientApi,proto3" json:"client_api,omitempty"` +} + +func (x *ExecuteHookPostRequest) Reset() { + *x = ExecuteHookPostRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ignite_services_plugin_grpc_v1_service_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ExecuteHookPostRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExecuteHookPostRequest) ProtoMessage() {} + +func (x *ExecuteHookPostRequest) ProtoReflect() protoreflect.Message { + mi := &file_ignite_services_plugin_grpc_v1_service_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ExecuteHookPostRequest.ProtoReflect.Descriptor instead. +func (*ExecuteHookPostRequest) Descriptor() ([]byte, []int) { + return file_ignite_services_plugin_grpc_v1_service_proto_rawDescGZIP(), []int{6} +} + +func (x *ExecuteHookPostRequest) GetHook() *ExecutedHook { + if x != nil { + return x.Hook + } + return nil +} + +func (x *ExecuteHookPostRequest) GetClientApi() uint32 { + if x != nil { + return x.ClientApi + } + return 0 +} + +type ExecuteHookPostResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ExecuteHookPostResponse) Reset() { + *x = ExecuteHookPostResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ignite_services_plugin_grpc_v1_service_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ExecuteHookPostResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExecuteHookPostResponse) ProtoMessage() {} + +func (x *ExecuteHookPostResponse) ProtoReflect() protoreflect.Message { + mi := &file_ignite_services_plugin_grpc_v1_service_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ExecuteHookPostResponse.ProtoReflect.Descriptor instead. +func (*ExecuteHookPostResponse) Descriptor() ([]byte, []int) { + return file_ignite_services_plugin_grpc_v1_service_proto_rawDescGZIP(), []int{7} +} + +type ExecuteHookCleanUpRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Hook *ExecutedHook `protobuf:"bytes,1,opt,name=hook,proto3" json:"hook,omitempty"` + ClientApi uint32 `protobuf:"varint,2,opt,name=client_api,json=clientApi,proto3" json:"client_api,omitempty"` +} + +func (x *ExecuteHookCleanUpRequest) Reset() { + *x = ExecuteHookCleanUpRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ignite_services_plugin_grpc_v1_service_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ExecuteHookCleanUpRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExecuteHookCleanUpRequest) ProtoMessage() {} + +func (x *ExecuteHookCleanUpRequest) ProtoReflect() protoreflect.Message { + mi := &file_ignite_services_plugin_grpc_v1_service_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ExecuteHookCleanUpRequest.ProtoReflect.Descriptor instead. +func (*ExecuteHookCleanUpRequest) Descriptor() ([]byte, []int) { + return file_ignite_services_plugin_grpc_v1_service_proto_rawDescGZIP(), []int{8} +} + +func (x *ExecuteHookCleanUpRequest) GetHook() *ExecutedHook { + if x != nil { + return x.Hook + } + return nil +} + +func (x *ExecuteHookCleanUpRequest) GetClientApi() uint32 { + if x != nil { + return x.ClientApi + } + return 0 +} + +type ExecuteHookCleanUpResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ExecuteHookCleanUpResponse) Reset() { + *x = ExecuteHookCleanUpResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ignite_services_plugin_grpc_v1_service_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ExecuteHookCleanUpResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExecuteHookCleanUpResponse) ProtoMessage() {} + +func (x *ExecuteHookCleanUpResponse) ProtoReflect() protoreflect.Message { + mi := &file_ignite_services_plugin_grpc_v1_service_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ExecuteHookCleanUpResponse.ProtoReflect.Descriptor instead. +func (*ExecuteHookCleanUpResponse) Descriptor() ([]byte, []int) { + return file_ignite_services_plugin_grpc_v1_service_proto_rawDescGZIP(), []int{9} +} + +type GetChainInfoRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *GetChainInfoRequest) Reset() { + *x = GetChainInfoRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ignite_services_plugin_grpc_v1_service_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetChainInfoRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetChainInfoRequest) ProtoMessage() {} + +func (x *GetChainInfoRequest) ProtoReflect() protoreflect.Message { + mi := &file_ignite_services_plugin_grpc_v1_service_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetChainInfoRequest.ProtoReflect.Descriptor instead. +func (*GetChainInfoRequest) Descriptor() ([]byte, []int) { + return file_ignite_services_plugin_grpc_v1_service_proto_rawDescGZIP(), []int{10} +} + +type GetChainInfoResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ChainInfo *ChainInfo `protobuf:"bytes,1,opt,name=chain_info,json=chainInfo,proto3" json:"chain_info,omitempty"` +} + +func (x *GetChainInfoResponse) Reset() { + *x = GetChainInfoResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ignite_services_plugin_grpc_v1_service_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetChainInfoResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetChainInfoResponse) ProtoMessage() {} + +func (x *GetChainInfoResponse) ProtoReflect() protoreflect.Message { + mi := &file_ignite_services_plugin_grpc_v1_service_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetChainInfoResponse.ProtoReflect.Descriptor instead. +func (*GetChainInfoResponse) Descriptor() ([]byte, []int) { + return file_ignite_services_plugin_grpc_v1_service_proto_rawDescGZIP(), []int{11} +} + +func (x *GetChainInfoResponse) GetChainInfo() *ChainInfo { + if x != nil { + return x.ChainInfo + } + return nil +} + +var File_ignite_services_plugin_grpc_v1_service_proto protoreflect.FileDescriptor + +var file_ignite_services_plugin_grpc_v1_service_proto_rawDesc = []byte{ + 0x0a, 0x2c, 0x69, 0x67, 0x6e, 0x69, 0x74, 0x65, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x73, 0x2f, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x76, 0x31, + 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1e, + 0x69, 0x67, 0x6e, 0x69, 0x74, 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, + 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x1a, 0x2f, + 0x69, 0x67, 0x6e, 0x69, 0x74, 0x65, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, + 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x76, 0x31, 0x2f, 0x63, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, + 0x2e, 0x69, 0x67, 0x6e, 0x69, 0x74, 0x65, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, + 0x2f, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x76, 0x31, 0x2f, + 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, + 0x11, 0x0a, 0x0f, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x22, 0x58, 0x0a, 0x10, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, 0x0a, 0x08, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, + 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x69, 0x67, 0x6e, 0x69, 0x74, + 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, + 0x6e, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, + 0x73, 0x74, 0x52, 0x08, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x22, 0x72, 0x0a, 0x0e, + 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x41, + 0x0a, 0x03, 0x63, 0x6d, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x69, 0x67, + 0x6e, 0x69, 0x74, 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x70, 0x6c, + 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x65, + 0x63, 0x75, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x03, 0x63, 0x6d, + 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x61, 0x70, 0x69, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x41, 0x70, 0x69, + 0x22, 0x11, 0x0a, 0x0f, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x78, 0x0a, 0x15, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x48, 0x6f, + 0x6f, 0x6b, 0x50, 0x72, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x40, 0x0a, 0x04, + 0x68, 0x6f, 0x6f, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x69, 0x67, 0x6e, + 0x69, 0x74, 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x70, 0x6c, 0x75, + 0x67, 0x69, 0x6e, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x65, 0x63, + 0x75, 0x74, 0x65, 0x64, 0x48, 0x6f, 0x6f, 0x6b, 0x52, 0x04, 0x68, 0x6f, 0x6f, 0x6b, 0x12, 0x1d, + 0x0a, 0x0a, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x61, 0x70, 0x69, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x41, 0x70, 0x69, 0x22, 0x18, 0x0a, + 0x16, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x48, 0x6f, 0x6f, 0x6b, 0x50, 0x72, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x79, 0x0a, 0x16, 0x45, 0x78, 0x65, 0x63, 0x75, + 0x74, 0x65, 0x48, 0x6f, 0x6f, 0x6b, 0x50, 0x6f, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x40, 0x0a, 0x04, 0x68, 0x6f, 0x6f, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x2c, 0x2e, 0x69, 0x67, 0x6e, 0x69, 0x74, 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x73, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, + 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x64, 0x48, 0x6f, 0x6f, 0x6b, 0x52, 0x04, 0x68, + 0x6f, 0x6f, 0x6b, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x61, 0x70, + 0x69, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x41, + 0x70, 0x69, 0x22, 0x19, 0x0a, 0x17, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x48, 0x6f, 0x6f, + 0x6b, 0x50, 0x6f, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x7c, 0x0a, + 0x19, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x48, 0x6f, 0x6f, 0x6b, 0x43, 0x6c, 0x65, 0x61, + 0x6e, 0x55, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x40, 0x0a, 0x04, 0x68, 0x6f, + 0x6f, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x69, 0x67, 0x6e, 0x69, 0x74, + 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, + 0x6e, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, + 0x65, 0x64, 0x48, 0x6f, 0x6f, 0x6b, 0x52, 0x04, 0x68, 0x6f, 0x6f, 0x6b, 0x12, 0x1d, 0x0a, 0x0a, + 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x61, 0x70, 0x69, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x09, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x41, 0x70, 0x69, 0x22, 0x1c, 0x0a, 0x1a, 0x45, + 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x48, 0x6f, 0x6f, 0x6b, 0x43, 0x6c, 0x65, 0x61, 0x6e, 0x55, + 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x15, 0x0a, 0x13, 0x47, 0x65, 0x74, + 0x43, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x22, 0x60, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x6e, 0x66, 0x6f, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x48, 0x0a, 0x0a, 0x63, 0x68, 0x61, 0x69, + 0x6e, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x69, + 0x67, 0x6e, 0x69, 0x74, 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x70, + 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, + 0x61, 0x69, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x09, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x6e, + 0x66, 0x6f, 0x32, 0x81, 0x05, 0x0a, 0x10, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x6d, 0x0a, 0x08, 0x4d, 0x61, 0x6e, 0x69, 0x66, + 0x65, 0x73, 0x74, 0x12, 0x2f, 0x2e, 0x69, 0x67, 0x6e, 0x69, 0x74, 0x65, 0x2e, 0x73, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x67, 0x72, 0x70, + 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x69, 0x67, 0x6e, 0x69, 0x74, 0x65, 0x2e, 0x73, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x67, 0x72, + 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6a, 0x0a, 0x07, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, + 0x65, 0x12, 0x2e, 0x2e, 0x69, 0x67, 0x6e, 0x69, 0x74, 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x73, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, + 0x76, 0x31, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x2f, 0x2e, 0x69, 0x67, 0x6e, 0x69, 0x74, 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x73, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, + 0x76, 0x31, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x7f, 0x0a, 0x0e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x48, 0x6f, 0x6f, + 0x6b, 0x50, 0x72, 0x65, 0x12, 0x35, 0x2e, 0x69, 0x67, 0x6e, 0x69, 0x74, 0x65, 0x2e, 0x73, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x67, 0x72, + 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x48, 0x6f, 0x6f, + 0x6b, 0x50, 0x72, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x36, 0x2e, 0x69, 0x67, + 0x6e, 0x69, 0x74, 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x70, 0x6c, + 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x65, + 0x63, 0x75, 0x74, 0x65, 0x48, 0x6f, 0x6f, 0x6b, 0x50, 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x82, 0x01, 0x0a, 0x0f, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x48, + 0x6f, 0x6f, 0x6b, 0x50, 0x6f, 0x73, 0x74, 0x12, 0x36, 0x2e, 0x69, 0x67, 0x6e, 0x69, 0x74, 0x65, + 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, + 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, + 0x48, 0x6f, 0x6f, 0x6b, 0x50, 0x6f, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x37, 0x2e, 0x69, 0x67, 0x6e, 0x69, 0x74, 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x73, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, + 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x48, 0x6f, 0x6f, 0x6b, 0x50, 0x6f, 0x73, 0x74, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x8b, 0x01, 0x0a, 0x12, 0x45, 0x78, 0x65, + 0x63, 0x75, 0x74, 0x65, 0x48, 0x6f, 0x6f, 0x6b, 0x43, 0x6c, 0x65, 0x61, 0x6e, 0x55, 0x70, 0x12, + 0x39, 0x2e, 0x69, 0x67, 0x6e, 0x69, 0x74, 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x73, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, + 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x48, 0x6f, 0x6f, 0x6b, 0x43, 0x6c, 0x65, 0x61, + 0x6e, 0x55, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3a, 0x2e, 0x69, 0x67, 0x6e, + 0x69, 0x74, 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x70, 0x6c, 0x75, + 0x67, 0x69, 0x6e, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x65, 0x63, + 0x75, 0x74, 0x65, 0x48, 0x6f, 0x6f, 0x6b, 0x43, 0x6c, 0x65, 0x61, 0x6e, 0x55, 0x70, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x8d, 0x01, 0x0a, 0x10, 0x43, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x41, 0x50, 0x49, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x79, 0x0a, 0x0c, 0x47, + 0x65, 0x74, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x33, 0x2e, 0x69, 0x67, + 0x6e, 0x69, 0x74, 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x70, 0x6c, + 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, + 0x43, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x34, 0x2e, 0x69, 0x67, 0x6e, 0x69, 0x74, 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x73, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x76, + 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x36, 0x5a, 0x34, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x67, 0x6e, 0x69, 0x74, 0x65, 0x2f, 0x63, 0x6c, 0x69, 0x2f, + 0x69, 0x67, 0x6e, 0x69, 0x74, 0x65, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, + 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x76, 0x31, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_ignite_services_plugin_grpc_v1_service_proto_rawDescOnce sync.Once + file_ignite_services_plugin_grpc_v1_service_proto_rawDescData = file_ignite_services_plugin_grpc_v1_service_proto_rawDesc +) + +func file_ignite_services_plugin_grpc_v1_service_proto_rawDescGZIP() []byte { + file_ignite_services_plugin_grpc_v1_service_proto_rawDescOnce.Do(func() { + file_ignite_services_plugin_grpc_v1_service_proto_rawDescData = protoimpl.X.CompressGZIP(file_ignite_services_plugin_grpc_v1_service_proto_rawDescData) + }) + return file_ignite_services_plugin_grpc_v1_service_proto_rawDescData +} + +var file_ignite_services_plugin_grpc_v1_service_proto_msgTypes = make([]protoimpl.MessageInfo, 12) +var file_ignite_services_plugin_grpc_v1_service_proto_goTypes = []interface{}{ + (*ManifestRequest)(nil), // 0: ignite.services.plugin.grpc.v1.ManifestRequest + (*ManifestResponse)(nil), // 1: ignite.services.plugin.grpc.v1.ManifestResponse + (*ExecuteRequest)(nil), // 2: ignite.services.plugin.grpc.v1.ExecuteRequest + (*ExecuteResponse)(nil), // 3: ignite.services.plugin.grpc.v1.ExecuteResponse + (*ExecuteHookPreRequest)(nil), // 4: ignite.services.plugin.grpc.v1.ExecuteHookPreRequest + (*ExecuteHookPreResponse)(nil), // 5: ignite.services.plugin.grpc.v1.ExecuteHookPreResponse + (*ExecuteHookPostRequest)(nil), // 6: ignite.services.plugin.grpc.v1.ExecuteHookPostRequest + (*ExecuteHookPostResponse)(nil), // 7: ignite.services.plugin.grpc.v1.ExecuteHookPostResponse + (*ExecuteHookCleanUpRequest)(nil), // 8: ignite.services.plugin.grpc.v1.ExecuteHookCleanUpRequest + (*ExecuteHookCleanUpResponse)(nil), // 9: ignite.services.plugin.grpc.v1.ExecuteHookCleanUpResponse + (*GetChainInfoRequest)(nil), // 10: ignite.services.plugin.grpc.v1.GetChainInfoRequest + (*GetChainInfoResponse)(nil), // 11: ignite.services.plugin.grpc.v1.GetChainInfoResponse + (*Manifest)(nil), // 12: ignite.services.plugin.grpc.v1.Manifest + (*ExecutedCommand)(nil), // 13: ignite.services.plugin.grpc.v1.ExecutedCommand + (*ExecutedHook)(nil), // 14: ignite.services.plugin.grpc.v1.ExecutedHook + (*ChainInfo)(nil), // 15: ignite.services.plugin.grpc.v1.ChainInfo +} +var file_ignite_services_plugin_grpc_v1_service_proto_depIdxs = []int32{ + 12, // 0: ignite.services.plugin.grpc.v1.ManifestResponse.manifest:type_name -> ignite.services.plugin.grpc.v1.Manifest + 13, // 1: ignite.services.plugin.grpc.v1.ExecuteRequest.cmd:type_name -> ignite.services.plugin.grpc.v1.ExecutedCommand + 14, // 2: ignite.services.plugin.grpc.v1.ExecuteHookPreRequest.hook:type_name -> ignite.services.plugin.grpc.v1.ExecutedHook + 14, // 3: ignite.services.plugin.grpc.v1.ExecuteHookPostRequest.hook:type_name -> ignite.services.plugin.grpc.v1.ExecutedHook + 14, // 4: ignite.services.plugin.grpc.v1.ExecuteHookCleanUpRequest.hook:type_name -> ignite.services.plugin.grpc.v1.ExecutedHook + 15, // 5: ignite.services.plugin.grpc.v1.GetChainInfoResponse.chain_info:type_name -> ignite.services.plugin.grpc.v1.ChainInfo + 0, // 6: ignite.services.plugin.grpc.v1.InterfaceService.Manifest:input_type -> ignite.services.plugin.grpc.v1.ManifestRequest + 2, // 7: ignite.services.plugin.grpc.v1.InterfaceService.Execute:input_type -> ignite.services.plugin.grpc.v1.ExecuteRequest + 4, // 8: ignite.services.plugin.grpc.v1.InterfaceService.ExecuteHookPre:input_type -> ignite.services.plugin.grpc.v1.ExecuteHookPreRequest + 6, // 9: ignite.services.plugin.grpc.v1.InterfaceService.ExecuteHookPost:input_type -> ignite.services.plugin.grpc.v1.ExecuteHookPostRequest + 8, // 10: ignite.services.plugin.grpc.v1.InterfaceService.ExecuteHookCleanUp:input_type -> ignite.services.plugin.grpc.v1.ExecuteHookCleanUpRequest + 10, // 11: ignite.services.plugin.grpc.v1.ClientAPIService.GetChainInfo:input_type -> ignite.services.plugin.grpc.v1.GetChainInfoRequest + 1, // 12: ignite.services.plugin.grpc.v1.InterfaceService.Manifest:output_type -> ignite.services.plugin.grpc.v1.ManifestResponse + 3, // 13: ignite.services.plugin.grpc.v1.InterfaceService.Execute:output_type -> ignite.services.plugin.grpc.v1.ExecuteResponse + 5, // 14: ignite.services.plugin.grpc.v1.InterfaceService.ExecuteHookPre:output_type -> ignite.services.plugin.grpc.v1.ExecuteHookPreResponse + 7, // 15: ignite.services.plugin.grpc.v1.InterfaceService.ExecuteHookPost:output_type -> ignite.services.plugin.grpc.v1.ExecuteHookPostResponse + 9, // 16: ignite.services.plugin.grpc.v1.InterfaceService.ExecuteHookCleanUp:output_type -> ignite.services.plugin.grpc.v1.ExecuteHookCleanUpResponse + 11, // 17: ignite.services.plugin.grpc.v1.ClientAPIService.GetChainInfo:output_type -> ignite.services.plugin.grpc.v1.GetChainInfoResponse + 12, // [12:18] is the sub-list for method output_type + 6, // [6:12] is the sub-list for method input_type + 6, // [6:6] is the sub-list for extension type_name + 6, // [6:6] is the sub-list for extension extendee + 0, // [0:6] is the sub-list for field type_name +} + +func init() { file_ignite_services_plugin_grpc_v1_service_proto_init() } +func file_ignite_services_plugin_grpc_v1_service_proto_init() { + if File_ignite_services_plugin_grpc_v1_service_proto != nil { + return + } + file_ignite_services_plugin_grpc_v1_client_api_proto_init() + file_ignite_services_plugin_grpc_v1_interface_proto_init() + if !protoimpl.UnsafeEnabled { + file_ignite_services_plugin_grpc_v1_service_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ManifestRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ignite_services_plugin_grpc_v1_service_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ManifestResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ignite_services_plugin_grpc_v1_service_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ExecuteRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ignite_services_plugin_grpc_v1_service_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ExecuteResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ignite_services_plugin_grpc_v1_service_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ExecuteHookPreRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ignite_services_plugin_grpc_v1_service_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ExecuteHookPreResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ignite_services_plugin_grpc_v1_service_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ExecuteHookPostRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ignite_services_plugin_grpc_v1_service_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ExecuteHookPostResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ignite_services_plugin_grpc_v1_service_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ExecuteHookCleanUpRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ignite_services_plugin_grpc_v1_service_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ExecuteHookCleanUpResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ignite_services_plugin_grpc_v1_service_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetChainInfoRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ignite_services_plugin_grpc_v1_service_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetChainInfoResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_ignite_services_plugin_grpc_v1_service_proto_rawDesc, + NumEnums: 0, + NumMessages: 12, + NumExtensions: 0, + NumServices: 2, + }, + GoTypes: file_ignite_services_plugin_grpc_v1_service_proto_goTypes, + DependencyIndexes: file_ignite_services_plugin_grpc_v1_service_proto_depIdxs, + MessageInfos: file_ignite_services_plugin_grpc_v1_service_proto_msgTypes, + }.Build() + File_ignite_services_plugin_grpc_v1_service_proto = out.File + file_ignite_services_plugin_grpc_v1_service_proto_rawDesc = nil + file_ignite_services_plugin_grpc_v1_service_proto_goTypes = nil + file_ignite_services_plugin_grpc_v1_service_proto_depIdxs = nil +} diff --git a/ignite/services/plugin/grpc/v1/service_grpc.pb.go b/ignite/services/plugin/grpc/v1/service_grpc.pb.go new file mode 100644 index 0000000000..f369c94a1e --- /dev/null +++ b/ignite/services/plugin/grpc/v1/service_grpc.pb.go @@ -0,0 +1,383 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.3.0 +// - protoc (unknown) +// source: ignite/services/plugin/grpc/v1/service.proto + +package v1 + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +const ( + InterfaceService_Manifest_FullMethodName = "/ignite.services.plugin.grpc.v1.InterfaceService/Manifest" + InterfaceService_Execute_FullMethodName = "/ignite.services.plugin.grpc.v1.InterfaceService/Execute" + InterfaceService_ExecuteHookPre_FullMethodName = "/ignite.services.plugin.grpc.v1.InterfaceService/ExecuteHookPre" + InterfaceService_ExecuteHookPost_FullMethodName = "/ignite.services.plugin.grpc.v1.InterfaceService/ExecuteHookPost" + InterfaceService_ExecuteHookCleanUp_FullMethodName = "/ignite.services.plugin.grpc.v1.InterfaceService/ExecuteHookCleanUp" +) + +// InterfaceServiceClient is the client API for InterfaceService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type InterfaceServiceClient interface { + // Manifest declares the plugin's Command(s) and Hook(s). + Manifest(ctx context.Context, in *ManifestRequest, opts ...grpc.CallOption) (*ManifestResponse, error) + // Execute will be invoked by ignite when a plugin Command is executed. + // It is global for all commands declared in Manifest, if you have declared + // multiple commands, use cmd.Path to distinguish them. + Execute(ctx context.Context, in *ExecuteRequest, opts ...grpc.CallOption) (*ExecuteResponse, error) + // ExecuteHookPre is invoked by ignite when a command specified by the Hook + // path is invoked. + // It is global for all hooks declared in Manifest, if you have declared + // multiple hooks, use hook.Name to distinguish them. + ExecuteHookPre(ctx context.Context, in *ExecuteHookPreRequest, opts ...grpc.CallOption) (*ExecuteHookPreResponse, error) + // ExecuteHookPost is invoked by ignite when a command specified by the hook + // path is invoked. + // It is global for all hooks declared in Manifest, if you have declared + // multiple hooks, use hook.Name to distinguish them. + ExecuteHookPost(ctx context.Context, in *ExecuteHookPostRequest, opts ...grpc.CallOption) (*ExecuteHookPostResponse, error) + // ExecuteHookCleanUp is invoked by ignite when a command specified by the + // hook path is invoked. Unlike ExecuteHookPost, it is invoked regardless of + // execution status of the command and hooks. + // It is global for all hooks declared in Manifest, if you have declared + // multiple hooks, use hook.Name to distinguish them. + ExecuteHookCleanUp(ctx context.Context, in *ExecuteHookCleanUpRequest, opts ...grpc.CallOption) (*ExecuteHookCleanUpResponse, error) +} + +type interfaceServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewInterfaceServiceClient(cc grpc.ClientConnInterface) InterfaceServiceClient { + return &interfaceServiceClient{cc} +} + +func (c *interfaceServiceClient) Manifest(ctx context.Context, in *ManifestRequest, opts ...grpc.CallOption) (*ManifestResponse, error) { + out := new(ManifestResponse) + err := c.cc.Invoke(ctx, InterfaceService_Manifest_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *interfaceServiceClient) Execute(ctx context.Context, in *ExecuteRequest, opts ...grpc.CallOption) (*ExecuteResponse, error) { + out := new(ExecuteResponse) + err := c.cc.Invoke(ctx, InterfaceService_Execute_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *interfaceServiceClient) ExecuteHookPre(ctx context.Context, in *ExecuteHookPreRequest, opts ...grpc.CallOption) (*ExecuteHookPreResponse, error) { + out := new(ExecuteHookPreResponse) + err := c.cc.Invoke(ctx, InterfaceService_ExecuteHookPre_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *interfaceServiceClient) ExecuteHookPost(ctx context.Context, in *ExecuteHookPostRequest, opts ...grpc.CallOption) (*ExecuteHookPostResponse, error) { + out := new(ExecuteHookPostResponse) + err := c.cc.Invoke(ctx, InterfaceService_ExecuteHookPost_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *interfaceServiceClient) ExecuteHookCleanUp(ctx context.Context, in *ExecuteHookCleanUpRequest, opts ...grpc.CallOption) (*ExecuteHookCleanUpResponse, error) { + out := new(ExecuteHookCleanUpResponse) + err := c.cc.Invoke(ctx, InterfaceService_ExecuteHookCleanUp_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// InterfaceServiceServer is the server API for InterfaceService service. +// All implementations must embed UnimplementedInterfaceServiceServer +// for forward compatibility +type InterfaceServiceServer interface { + // Manifest declares the plugin's Command(s) and Hook(s). + Manifest(context.Context, *ManifestRequest) (*ManifestResponse, error) + // Execute will be invoked by ignite when a plugin Command is executed. + // It is global for all commands declared in Manifest, if you have declared + // multiple commands, use cmd.Path to distinguish them. + Execute(context.Context, *ExecuteRequest) (*ExecuteResponse, error) + // ExecuteHookPre is invoked by ignite when a command specified by the Hook + // path is invoked. + // It is global for all hooks declared in Manifest, if you have declared + // multiple hooks, use hook.Name to distinguish them. + ExecuteHookPre(context.Context, *ExecuteHookPreRequest) (*ExecuteHookPreResponse, error) + // ExecuteHookPost is invoked by ignite when a command specified by the hook + // path is invoked. + // It is global for all hooks declared in Manifest, if you have declared + // multiple hooks, use hook.Name to distinguish them. + ExecuteHookPost(context.Context, *ExecuteHookPostRequest) (*ExecuteHookPostResponse, error) + // ExecuteHookCleanUp is invoked by ignite when a command specified by the + // hook path is invoked. Unlike ExecuteHookPost, it is invoked regardless of + // execution status of the command and hooks. + // It is global for all hooks declared in Manifest, if you have declared + // multiple hooks, use hook.Name to distinguish them. + ExecuteHookCleanUp(context.Context, *ExecuteHookCleanUpRequest) (*ExecuteHookCleanUpResponse, error) + mustEmbedUnimplementedInterfaceServiceServer() +} + +// UnimplementedInterfaceServiceServer must be embedded to have forward compatible implementations. +type UnimplementedInterfaceServiceServer struct { +} + +func (UnimplementedInterfaceServiceServer) Manifest(context.Context, *ManifestRequest) (*ManifestResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Manifest not implemented") +} +func (UnimplementedInterfaceServiceServer) Execute(context.Context, *ExecuteRequest) (*ExecuteResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Execute not implemented") +} +func (UnimplementedInterfaceServiceServer) ExecuteHookPre(context.Context, *ExecuteHookPreRequest) (*ExecuteHookPreResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ExecuteHookPre not implemented") +} +func (UnimplementedInterfaceServiceServer) ExecuteHookPost(context.Context, *ExecuteHookPostRequest) (*ExecuteHookPostResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ExecuteHookPost not implemented") +} +func (UnimplementedInterfaceServiceServer) ExecuteHookCleanUp(context.Context, *ExecuteHookCleanUpRequest) (*ExecuteHookCleanUpResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ExecuteHookCleanUp not implemented") +} +func (UnimplementedInterfaceServiceServer) mustEmbedUnimplementedInterfaceServiceServer() {} + +// UnsafeInterfaceServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to InterfaceServiceServer will +// result in compilation errors. +type UnsafeInterfaceServiceServer interface { + mustEmbedUnimplementedInterfaceServiceServer() +} + +func RegisterInterfaceServiceServer(s grpc.ServiceRegistrar, srv InterfaceServiceServer) { + s.RegisterService(&InterfaceService_ServiceDesc, srv) +} + +func _InterfaceService_Manifest_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ManifestRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(InterfaceServiceServer).Manifest(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: InterfaceService_Manifest_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(InterfaceServiceServer).Manifest(ctx, req.(*ManifestRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _InterfaceService_Execute_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ExecuteRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(InterfaceServiceServer).Execute(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: InterfaceService_Execute_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(InterfaceServiceServer).Execute(ctx, req.(*ExecuteRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _InterfaceService_ExecuteHookPre_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ExecuteHookPreRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(InterfaceServiceServer).ExecuteHookPre(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: InterfaceService_ExecuteHookPre_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(InterfaceServiceServer).ExecuteHookPre(ctx, req.(*ExecuteHookPreRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _InterfaceService_ExecuteHookPost_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ExecuteHookPostRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(InterfaceServiceServer).ExecuteHookPost(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: InterfaceService_ExecuteHookPost_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(InterfaceServiceServer).ExecuteHookPost(ctx, req.(*ExecuteHookPostRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _InterfaceService_ExecuteHookCleanUp_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ExecuteHookCleanUpRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(InterfaceServiceServer).ExecuteHookCleanUp(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: InterfaceService_ExecuteHookCleanUp_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(InterfaceServiceServer).ExecuteHookCleanUp(ctx, req.(*ExecuteHookCleanUpRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// InterfaceService_ServiceDesc is the grpc.ServiceDesc for InterfaceService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var InterfaceService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "ignite.services.plugin.grpc.v1.InterfaceService", + HandlerType: (*InterfaceServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Manifest", + Handler: _InterfaceService_Manifest_Handler, + }, + { + MethodName: "Execute", + Handler: _InterfaceService_Execute_Handler, + }, + { + MethodName: "ExecuteHookPre", + Handler: _InterfaceService_ExecuteHookPre_Handler, + }, + { + MethodName: "ExecuteHookPost", + Handler: _InterfaceService_ExecuteHookPost_Handler, + }, + { + MethodName: "ExecuteHookCleanUp", + Handler: _InterfaceService_ExecuteHookCleanUp_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "ignite/services/plugin/grpc/v1/service.proto", +} + +const ( + ClientAPIService_GetChainInfo_FullMethodName = "/ignite.services.plugin.grpc.v1.ClientAPIService/GetChainInfo" +) + +// ClientAPIServiceClient is the client API for ClientAPIService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type ClientAPIServiceClient interface { + // GetChainInfo returns basic chain info for the configured app + GetChainInfo(ctx context.Context, in *GetChainInfoRequest, opts ...grpc.CallOption) (*GetChainInfoResponse, error) +} + +type clientAPIServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewClientAPIServiceClient(cc grpc.ClientConnInterface) ClientAPIServiceClient { + return &clientAPIServiceClient{cc} +} + +func (c *clientAPIServiceClient) GetChainInfo(ctx context.Context, in *GetChainInfoRequest, opts ...grpc.CallOption) (*GetChainInfoResponse, error) { + out := new(GetChainInfoResponse) + err := c.cc.Invoke(ctx, ClientAPIService_GetChainInfo_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// ClientAPIServiceServer is the server API for ClientAPIService service. +// All implementations must embed UnimplementedClientAPIServiceServer +// for forward compatibility +type ClientAPIServiceServer interface { + // GetChainInfo returns basic chain info for the configured app + GetChainInfo(context.Context, *GetChainInfoRequest) (*GetChainInfoResponse, error) + mustEmbedUnimplementedClientAPIServiceServer() +} + +// UnimplementedClientAPIServiceServer must be embedded to have forward compatible implementations. +type UnimplementedClientAPIServiceServer struct { +} + +func (UnimplementedClientAPIServiceServer) GetChainInfo(context.Context, *GetChainInfoRequest) (*GetChainInfoResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetChainInfo not implemented") +} +func (UnimplementedClientAPIServiceServer) mustEmbedUnimplementedClientAPIServiceServer() {} + +// UnsafeClientAPIServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to ClientAPIServiceServer will +// result in compilation errors. +type UnsafeClientAPIServiceServer interface { + mustEmbedUnimplementedClientAPIServiceServer() +} + +func RegisterClientAPIServiceServer(s grpc.ServiceRegistrar, srv ClientAPIServiceServer) { + s.RegisterService(&ClientAPIService_ServiceDesc, srv) +} + +func _ClientAPIService_GetChainInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetChainInfoRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ClientAPIServiceServer).GetChainInfo(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ClientAPIService_GetChainInfo_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ClientAPIServiceServer).GetChainInfo(ctx, req.(*GetChainInfoRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// ClientAPIService_ServiceDesc is the grpc.ServiceDesc for ClientAPIService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var ClientAPIService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "ignite.services.plugin.grpc.v1.ClientAPIService", + HandlerType: (*ClientAPIServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GetChainInfo", + Handler: _ClientAPIService_GetChainInfo_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "ignite/services/plugin/grpc/v1/service.proto", +} diff --git a/ignite/services/plugin/grpc/v1/types_command_test.go b/ignite/services/plugin/grpc/v1/types_command_test.go new file mode 100644 index 0000000000..c74034e656 --- /dev/null +++ b/ignite/services/plugin/grpc/v1/types_command_test.go @@ -0,0 +1,343 @@ +package v1_test + +import ( + "fmt" + "testing" + + "github.com/spf13/cobra" + "github.com/spf13/pflag" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + v1 "github.com/ignite/cli/ignite/services/plugin/grpc/v1" +) + +func TestCommandToCobraCommand(t *testing.T) { + var ( + require = require.New(t) + assert = assert.New(t) + pcmd = v1.Command{ + Use: "new", + Aliases: []string{"n"}, + Short: "short", + Long: "long", + Hidden: true, + Flags: []*v1.Flag{ + { + Name: "bool", + Shorthand: "b", + DefaultValue: "true", + Value: "true", + Usage: "a bool", + Type: v1.Flag_TYPE_FLAG_BOOL, + }, + { + Name: "string", + DefaultValue: "hello", + Value: "hello", + Usage: "a string", + Type: v1.Flag_TYPE_FLAG_STRING_UNSPECIFIED, + Persistent: true, + }, + }, + Commands: []*v1.Command{ + { + Use: "sub", + Aliases: []string{"s"}, + Short: "sub short", + Long: "sub long", + }, + }, + } + ) + + cmd, err := pcmd.ToCobraCommand() + + require.NoError(err) + require.NotNil(cmd) + assert.Empty(cmd.Commands()) // subcommands aren't converted + assert.Equal(pcmd.Use, cmd.Use) + assert.Equal(pcmd.Short, cmd.Short) + assert.Equal(pcmd.Long, cmd.Long) + assert.Equal(pcmd.Aliases, cmd.Aliases) + assert.Equal(pcmd.Hidden, cmd.Hidden) + for _, f := range pcmd.Flags { + if f.Persistent { + assert.NotNil(cmd.PersistentFlags().Lookup(f.Name), "missing pflag %s", f.Name) + } else { + assert.NotNil(cmd.Flags().Lookup(f.Name), "missing flag %s", f.Name) + } + } +} + +func TestCommandPath(t *testing.T) { + cases := []struct { + name, wantPath string + cmd *v1.Command + }{ + { + name: "relative path", + cmd: &v1.Command{ + PlaceCommandUnder: "chain", + }, + wantPath: "ignite chain", + }, + { + name: "full path", + cmd: &v1.Command{ + PlaceCommandUnder: "ignite chain", + }, + wantPath: "ignite chain", + }, + { + name: "path with spaces", + cmd: &v1.Command{ + PlaceCommandUnder: " ignite scaffold ", + }, + wantPath: "ignite scaffold", + }, + } + + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + path := tc.cmd.Path() + require.Equal(t, tc.wantPath, path) + }) + } +} + +func TestExecutedCommandImportFlags(t *testing.T) { + // Arrange + execCmd := &v1.ExecutedCommand{} + wantFlags := []*v1.Flag{ + { + Name: "foo", + Shorthand: "f", + Usage: "foo usage", + DefaultValue: "bar", + Value: "baz", + Type: v1.Flag_TYPE_FLAG_STRING_UNSPECIFIED, + }, { + Name: "test", + Shorthand: "t", + Usage: "test usage", + DefaultValue: "1", + Value: "42", + Type: v1.Flag_TYPE_FLAG_INT, + Persistent: true, + }, + } + + cmd := cobra.Command{} + cmd.Flags().StringP("foo", "f", "bar", "foo usage") + cmd.PersistentFlags().IntP("test", "t", 1, "test usage") + cmd.ParseFlags([]string{"--foo", "baz", "--test", "42"}) + + // Act + execCmd.ImportFlags(&cmd) + + // Assert + require.Equal(t, wantFlags, execCmd.Flags) +} + +func TestExecutedCommandNewFlags(t *testing.T) { + // Arrange + execCmd := &v1.ExecutedCommand{ + Flags: []*v1.Flag{ + { + Name: "bool", + Shorthand: "b", + Usage: "bool usage", + DefaultValue: "false", + Type: v1.Flag_TYPE_FLAG_BOOL, + }, + { + Name: "int", + Shorthand: "i", + Usage: "int usage", + DefaultValue: "0", + Type: v1.Flag_TYPE_FLAG_INT, + }, + { + Name: "uint", + Shorthand: "u", + Usage: "uint usage", + DefaultValue: "0", + Type: v1.Flag_TYPE_FLAG_UINT, + }, + { + Name: "int64", + Shorthand: "j", + Usage: "int64 usage", + DefaultValue: "0", + Type: v1.Flag_TYPE_FLAG_INT64, + }, + { + Name: "uint64", + Shorthand: "k", + Usage: "uint64 usage", + DefaultValue: "0", + Type: v1.Flag_TYPE_FLAG_UINT64, + }, + { + Name: "string", + Shorthand: "s", + Usage: "string usage", + DefaultValue: "", + Type: v1.Flag_TYPE_FLAG_STRING_UNSPECIFIED, + }, + { + Name: "string-slice", + Shorthand: "l", + Usage: "string slice usage", + DefaultValue: "[]", + Type: v1.Flag_TYPE_FLAG_STRING_SLICE, + }, + { + Name: "persistent", + Persistent: true, + }, + }, + } + + wantFlags := make(map[string]pflag.Flag) + for _, f := range execCmd.Flags { + wantFlags[f.Name] = pflag.Flag{ + Name: f.Name, + Shorthand: f.Shorthand, + Usage: f.Usage, + DefValue: f.DefaultValue, + } + } + + var ( + flagCount int + + // Persistent flag should not be included + wantFlagCount = len(execCmd.Flags) - 1 + ) + + // Act + flags, err := execCmd.NewFlags() + + // Assert + require.NoError(t, err) + + flags.VisitAll(func(f *pflag.Flag) { + flag, ok := wantFlags[f.Name] + + require.True(t, ok, fmt.Sprintf("missing flag: %s", f.Name)) + require.Equal(t, flag.Name, f.Name) + require.Equal(t, flag.Shorthand, f.Shorthand) + require.Equal(t, flag.Usage, f.Usage) + require.Equal(t, flag.DefValue, f.DefValue) + + flagCount++ + }) + + require.Equal(t, wantFlagCount, flagCount) +} + +func TestExecutedCommandNewPersistentFlags(t *testing.T) { + // Arrange + execCmd := &v1.ExecutedCommand{ + Flags: []*v1.Flag{ + { + Name: "bool", + Shorthand: "b", + Usage: "bool usage", + DefaultValue: "false", + Type: v1.Flag_TYPE_FLAG_BOOL, + Persistent: true, + }, + { + Name: "int", + Shorthand: "i", + Usage: "int usage", + DefaultValue: "0", + Type: v1.Flag_TYPE_FLAG_INT, + Persistent: true, + }, + { + Name: "uint", + Shorthand: "u", + Usage: "uint usage", + DefaultValue: "0", + Type: v1.Flag_TYPE_FLAG_UINT, + Persistent: true, + }, + { + Name: "int64", + Shorthand: "j", + Usage: "int64 usage", + DefaultValue: "0", + Type: v1.Flag_TYPE_FLAG_INT64, + Persistent: true, + }, + { + Name: "uint64", + Shorthand: "k", + Usage: "uint64 usage", + DefaultValue: "0", + Type: v1.Flag_TYPE_FLAG_UINT64, + Persistent: true, + }, + { + Name: "string", + Shorthand: "s", + Usage: "string usage", + DefaultValue: "", + Type: v1.Flag_TYPE_FLAG_STRING_UNSPECIFIED, + Persistent: true, + }, + { + Name: "string-slice", + Shorthand: "l", + Usage: "string slice usage", + DefaultValue: "[]", + Type: v1.Flag_TYPE_FLAG_STRING_SLICE, + Persistent: true, + }, + { + Name: "non-persistent", + }, + }, + } + + wantFlags := make(map[string]pflag.Flag) + for _, f := range execCmd.Flags { + wantFlags[f.Name] = pflag.Flag{ + Name: f.Name, + Shorthand: f.Shorthand, + Usage: f.Usage, + DefValue: f.DefaultValue, + } + } + + var ( + flagCount int + + // Non persistent flag should not be included + wantFlagCount = len(execCmd.Flags) - 1 + ) + + // Act + flags, err := execCmd.NewPersistentFlags() + + // Assert + require.NoError(t, err) + + flags.VisitAll(func(f *pflag.Flag) { + flag, ok := wantFlags[f.Name] + + require.True(t, ok, fmt.Sprintf("missing flag: %s", f.Name)) + require.Equal(t, flag.Name, f.Name) + require.Equal(t, flag.Shorthand, f.Shorthand) + require.Equal(t, flag.Usage, f.Usage) + require.Equal(t, flag.DefValue, f.DefValue) + + flagCount++ + }) + + require.Equal(t, wantFlagCount, flagCount) +} diff --git a/ignite/services/plugin/grpc/v1/types_hook_test.go b/ignite/services/plugin/grpc/v1/types_hook_test.go new file mode 100644 index 0000000000..4fed09ed08 --- /dev/null +++ b/ignite/services/plugin/grpc/v1/types_hook_test.go @@ -0,0 +1,45 @@ +package v1_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + + v1 "github.com/ignite/cli/ignite/services/plugin/grpc/v1" +) + +func TestHookCommandPath(t *testing.T) { + cases := []struct { + name, wantPath string + hook *v1.Hook + }{ + { + name: "relative path", + hook: &v1.Hook{ + PlaceHookOn: "chain", + }, + wantPath: "ignite chain", + }, + { + name: "full path", + hook: &v1.Hook{ + PlaceHookOn: "ignite chain", + }, + wantPath: "ignite chain", + }, + { + name: "path with spaces", + hook: &v1.Hook{ + PlaceHookOn: " ignite scaffold ", + }, + wantPath: "ignite scaffold", + }, + } + + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + path := tc.hook.CommandPath() + require.Equal(t, tc.wantPath, path) + }) + } +} diff --git a/ignite/services/plugin/grpc/v1/types_manifest_test.go b/ignite/services/plugin/grpc/v1/types_manifest_test.go new file mode 100644 index 0000000000..73246d9c93 --- /dev/null +++ b/ignite/services/plugin/grpc/v1/types_manifest_test.go @@ -0,0 +1,110 @@ +package v1_test + +import ( + "testing" + + "github.com/spf13/cobra" + "github.com/stretchr/testify/assert" + + v1 "github.com/ignite/cli/ignite/services/plugin/grpc/v1" +) + +func TestManifestImportCobraCommand(t *testing.T) { + manifest := &v1.Manifest{ + Name: "hey", + Commands: []*v1.Command{ + {Use: "existing"}, + }, + } + cmd := &cobra.Command{ + Use: "new", + Aliases: []string{"n"}, + Short: "short", + Long: "long", + Hidden: true, + } + cmd.Flags().BoolP("bool", "b", true, "a bool") + cmd.Flags().String("string", "hello", "a string") + cmd.PersistentFlags().String("persistent", "hello", "a persistent string") + subcmd := &cobra.Command{ + Use: "sub", + Aliases: []string{"s"}, + Short: "sub short", + Long: "sub long", + } + subcmd.Flags().BoolP("subbool", "b", true, "a bool") + subcmd.Flags().String("substring", "hello", "a string") + subcmd.AddCommand(&cobra.Command{ + Use: "subsub", + }) + cmd.AddCommand(subcmd) + + manifest.ImportCobraCommand(cmd, "under") + + expectedManifest := &v1.Manifest{ + Name: "hey", + Commands: []*v1.Command{ + {Use: "existing"}, + { + Use: "new", + Aliases: []string{"n"}, + Short: "short", + Long: "long", + Hidden: true, + PlaceCommandUnder: "under", + Flags: []*v1.Flag{ + { + Name: "bool", + Shorthand: "b", + DefaultValue: "true", + Value: "true", + Usage: "a bool", + Type: v1.Flag_TYPE_FLAG_BOOL, + }, + { + Name: "string", + DefaultValue: "hello", + Value: "hello", + Usage: "a string", + Type: v1.Flag_TYPE_FLAG_STRING_UNSPECIFIED, + }, + { + Name: "persistent", + DefaultValue: "hello", + Value: "hello", + Usage: "a persistent string", + Type: v1.Flag_TYPE_FLAG_STRING_UNSPECIFIED, + Persistent: true, + }, + }, + Commands: []*v1.Command{ + { + Use: "sub", + Aliases: []string{"s"}, + Short: "sub short", + Long: "sub long", + Flags: []*v1.Flag{ + { + Name: "subbool", + Shorthand: "b", + DefaultValue: "true", + Value: "true", + Usage: "a bool", + Type: v1.Flag_TYPE_FLAG_BOOL, + }, + { + Name: "substring", + DefaultValue: "hello", + Value: "hello", + Usage: "a string", + Type: v1.Flag_TYPE_FLAG_STRING_UNSPECIFIED, + }, + }, + Commands: []*v1.Command{{Use: "subsub"}}, + }, + }, + }, + }, + } + assert.Equal(t, expectedManifest, manifest) +} diff --git a/ignite/services/plugin/interface.go b/ignite/services/plugin/interface.go index 9a735d1fad..9eb44b008c 100644 --- a/ignite/services/plugin/interface.go +++ b/ignite/services/plugin/interface.go @@ -1,481 +1,74 @@ package plugin import ( - "bytes" - "encoding/gob" - "fmt" - "net/rpc" - "os" - "strconv" - "strings" + "context" - "github.com/hashicorp/go-plugin" - "github.com/spf13/cobra" - "github.com/spf13/pflag" + v1 "github.com/ignite/cli/ignite/services/plugin/grpc/v1" ) -func init() { - gob.Register(Manifest{}) - gob.Register(ExecutedCommand{}) - gob.Register(ExecutedHook{}) -} +// Flag type aliases. +const ( + FlagTypeString = v1.Flag_TYPE_FLAG_STRING_UNSPECIFIED + FlagTypeInt = v1.Flag_TYPE_FLAG_INT + FlagTypeUint = v1.Flag_TYPE_FLAG_UINT + FlagTypeInt64 = v1.Flag_TYPE_FLAG_INT64 + FlagTypeUint64 = v1.Flag_TYPE_FLAG_UINT64 + FlagTypeBool = v1.Flag_TYPE_FLAG_BOOL + FlagTypeStringSlice = v1.Flag_TYPE_FLAG_STRING_SLICE +) + +// Type aliases for the current plugin version. +type ( + Command = v1.Command + ChainInfo = v1.ChainInfo + ExecutedCommand = v1.ExecutedCommand + ExecutedHook = v1.ExecutedHook + Flag = v1.Flag + FlagType = v1.Flag_Type + Hook = v1.Hook + Manifest = v1.Manifest +) // Interface defines the interface that all Ignite App must implement. // //go:generate mockery --srcpkg . --name Interface --structname PluginInterface --filename interface.go --with-expecter type Interface interface { // Manifest declares the app's Command(s) and Hook(s). - Manifest() (Manifest, error) + Manifest(context.Context) (*Manifest, error) // Execute will be invoked by ignite when an app Command is executed. // It is global for all commands declared in Manifest, if you have declared // multiple commands, use cmd.Path to distinguish them. - Execute(cmd ExecutedCommand) error + // The clientAPI argument can be used by plugins to get chain app analysis info. + Execute(context.Context, *ExecutedCommand, ClientAPI) error // ExecuteHookPre is invoked by ignite when a command specified by the Hook // path is invoked. // It is global for all hooks declared in Manifest, if you have declared // multiple hooks, use hook.Name to distinguish them. - ExecuteHookPre(hook ExecutedHook) error + // The clientAPI argument can be used by plugins to get chain app analysis info. + ExecuteHookPre(context.Context, *ExecutedHook, ClientAPI) error // ExecuteHookPost is invoked by ignite when a command specified by the hook // path is invoked. // It is global for all hooks declared in Manifest, if you have declared // multiple hooks, use hook.Name to distinguish them. - ExecuteHookPost(hook ExecutedHook) error + // The clientAPI argument can be used by plugins to get chain app analysis info. + ExecuteHookPost(context.Context, *ExecutedHook, ClientAPI) error // ExecuteHookCleanUp is invoked by ignite when a command specified by the // hook path is invoked. Unlike ExecuteHookPost, it is invoked regardless of // execution status of the command and hooks. // It is global for all hooks declared in Manifest, if you have declared // multiple hooks, use hook.Name to distinguish them. - ExecuteHookCleanUp(hook ExecutedHook) error -} - -// Manifest represents the Ignite App behavior. -type Manifest struct { - Name string - - // Commands contains the commands that will be added to the list of ignite - // commands. Each commands are independent, for nested commands use the - // inner Commands field. - Commands []Command - - // Hooks contains the hooks that will be attached to the existing ignite - // commands. - Hooks []Hook - - // SharedHost enables sharing a single app server across all running instances - // of an app. Useful if an app adds or extends long running commands - // - // Example: if an app defines a hook on `ignite chain serve`, a server is instanciated - // when the command is run. Now if you want to interact with that instance from commands - // defined in that app, you need to enable `SharedHost`, or else the commands will just - // instantiate separate app servers. - // - // When enabled, all apps of the same `Path` loaded from the same configuration will - // attach it's RPC client to a an existing RPC server. - // - // If an app instance has no other running app servers, it will create one and it - // will be the host. - SharedHost bool `yaml:"shared_host"` -} - -// ImportCobraCommand allows to hydrate m with a standard root cobra commands. -func (m *Manifest) ImportCobraCommand(c *cobra.Command, placeCommandUnder string) { - m.Commands = append(m.Commands, convertCobraCommand(c, placeCommandUnder)) -} - -func convertCobraCommand(c *cobra.Command, placeCommandUnder string) Command { - cmd := Command{ - Use: c.Use, - Aliases: c.Aliases, - Short: c.Short, - Long: c.Long, - Hidden: c.Hidden, - PlaceCommandUnder: placeCommandUnder, - Flags: convertPFlags(c), - } - for _, c := range c.Commands() { - cmd.Commands = append(cmd.Commands, convertCobraCommand(c, "")) - } - return cmd + // The clientAPI argument can be used by plugins to get chain app analysis info. + ExecuteHookCleanUp(context.Context, *ExecutedHook, ClientAPI) error } -// Command represents an app command. -type Command struct { - // Same as cobra.Command.Use - Use string - - // Same as cobra.Command.Aliases - Aliases []string - - // Same as cobra.Command.Short - Short string - - // Same as cobra.Command.Long - Long string - - // Same as cobra.Command.Hidden - Hidden bool - - // Flags holds the list of command flags - Flags []Flag - - // PlaceCommandUnder indicates where the command should be placed. - // For instance `ignite scaffold` will place the command at the - // `scaffold` command. - // An empty value is interpreted as `ignite` (==root). - PlaceCommandUnder string - - // List of sub commands - Commands []Command -} - -// PlaceCommandUnderFull returns a normalized p.PlaceCommandUnder, -// by adding the `ignite ` prefix if not present. -func (c Command) PlaceCommandUnderFull() string { - return commandFull(c.PlaceCommandUnder) -} - -func commandFull(cmdPath string) string { - const rootCmdName = "ignite" - if !strings.HasPrefix(cmdPath, rootCmdName) { - cmdPath = rootCmdName + " " + cmdPath - } - return strings.TrimSpace(cmdPath) -} - -// ToCobraCommand turns Command into a cobra.Command so it can be added to a parent command. -func (c Command) ToCobraCommand() (*cobra.Command, error) { - cmd := &cobra.Command{ - Use: c.Use, - Aliases: c.Aliases, - Short: c.Short, - Long: c.Long, - Hidden: c.Hidden, - } - for _, f := range c.Flags { - err := f.feedFlagSet(cmd) - if err != nil { - return nil, err - } - } - return cmd, nil -} - -// Hook represents a user defined action within an app. -type Hook struct { - // Name identifies the hook for the client to invoke the correct hook - // must be unique - Name string - - // PlaceHookOn indicates the command to register the hooks for - PlaceHookOn string -} - -// PlaceHookOnFull returns a normalized p.PlaceCommandUnder, by adding the -// `ignite ` prefix if not present. -func (h Hook) PlaceHookOnFull() string { - return commandFull(h.PlaceHookOn) -} - -// ExecutedCommand represents an app command under execution. -type ExecutedCommand struct { - // Use is copied from Command.Use - Use string - - // Path contains the command path, e.g. `ignite scaffold foo` - Path string - - // Args are the command arguments - Args []string - - // Full list of args taken from os.Args - OSArgs []string - - // With contains the app config parameters - With map[string]string - - flags *pflag.FlagSet - pflags *pflag.FlagSet -} - -// ExecutedHook represents an app hook under execution. -type ExecutedHook struct { - // ExecutedCommand gives access to the command attached by the hook. - ExecutedCommand ExecutedCommand - // Hook is a copy of the original Hook defined in the Manifest. - Hook -} - -// Flags gives access to the commands' flags, like cobra.Command.Flags. -func (c *ExecutedCommand) Flags() *pflag.FlagSet { - if c.flags == nil { - c.flags = pflag.NewFlagSet(os.Args[0], pflag.ContinueOnError) - } - return c.flags -} - -// PersistentFlags gives access to the commands' persistent flags, like -// cobra.Command.PersistentFlags. -func (c *ExecutedCommand) PersistentFlags() *pflag.FlagSet { - if c.pflags == nil { - c.pflags = pflag.NewFlagSet(os.Args[0], pflag.ContinueOnError) - } - return c.pflags -} - -// SetFlags set the flags. -// As an app developer, you probably don't need to use it. -func (c *ExecutedCommand) SetFlags(cmd *cobra.Command) { - c.flags = cmd.Flags() - c.pflags = cmd.PersistentFlags() -} - -// Flag is a serializable representation of pflag.Flag. -type Flag struct { - Name string // name as it appears on command line - Shorthand string // one-letter abbreviated flag - Usage string // help message - DefValue string // default value (as text); for usage message - Type FlagType - Value string - - // Persistent indicates wether or not the flag is propagated on children commands - Persistent bool -} - -// FlagType represents the pflag.Flag.Value.Type(). -type FlagType string - -const ( - // NOTE(tb): we declare only the main used cobra flag types for simplicity - // If an app receives an unhandled type, it will output an error. - FlagTypeString FlagType = "string" - FlagTypeInt FlagType = "int" - FlagTypeUint FlagType = "uint" - FlagTypeInt64 FlagType = "int64" - FlagTypeUint64 FlagType = "uint64" - FlagTypeBool FlagType = "bool" - FlagTypeStringSlice FlagType = "stringSlice" -) - -// feedFlagSet fills flagger with f. -func (f Flag) feedFlagSet(fgr flagger) error { - fs := fgr.Flags() - if f.Persistent { - fs = fgr.PersistentFlags() - } - switch f.Type { - case FlagTypeBool: - defVal, _ := strconv.ParseBool(f.DefValue) - fs.BoolP(f.Name, f.Shorthand, defVal, f.Usage) - _ = fs.Set(f.Name, f.Value) - case FlagTypeInt: - defVal, _ := strconv.Atoi(f.DefValue) - fs.IntP(f.Name, f.Shorthand, defVal, f.Usage) - _ = fs.Set(f.Name, f.Value) - case FlagTypeUint: - defVal, _ := strconv.ParseUint(f.DefValue, 10, 64) - fs.UintP(f.Name, f.Shorthand, uint(defVal), f.Usage) - _ = fs.Set(f.Name, f.Value) - case FlagTypeInt64: - defVal, _ := strconv.ParseInt(f.DefValue, 10, 64) - fs.Int64P(f.Name, f.Shorthand, defVal, f.Usage) - _ = fs.Set(f.Name, f.Value) - case FlagTypeUint64: - defVal, _ := strconv.ParseUint(f.DefValue, 10, 64) - fs.Uint64P(f.Name, f.Shorthand, defVal, f.Usage) - _ = fs.Set(f.Name, f.Value) - case FlagTypeString: - fs.StringP(f.Name, f.Shorthand, f.DefValue, f.Usage) - _ = fs.Set(f.Name, f.Value) - case FlagTypeStringSlice: - s := strings.Trim(f.DefValue, "[]") - defValue := strings.Fields(s) - fs.StringSliceP(f.Name, f.Shorthand, defValue, f.Usage) - _ = fs.Set(f.Name, strings.Trim(f.Value, "[]")) - default: - return fmt.Errorf("flagset unmarshal: unhandled flag type %q in flag %#v", f.Type, f) - } - return nil -} - -// gobCommandFlags is used to gob encode/decode Command. -// Command can't be encoded because : -// - flags is unexported (because we want to expose it via the Flags() method, -// like a regular cobra.Command) -// - flags type is *pflag.FlagSet which is also full of unexported fields. -type gobCommandContextFlags struct { - CommandContext gobCommandContext - Flags []Flag -} - -// gobCommandContext is the same as ExecutedCommand but without GobDecode -// attached, which avoids infinite loops. -type gobCommandContext ExecutedCommand - -// GobEncode implements gob.Encoder. -// It actually encodes a gobCommandContext struct built from c. -func (c ExecutedCommand) GobEncode() ([]byte, error) { - var b bytes.Buffer - err := gob.NewEncoder(&b).Encode(gobCommandContextFlags{ - CommandContext: gobCommandContext(c), - Flags: convertPFlags(&c), - }) - return b.Bytes(), err -} - -// flagger matches both cobra.Command and Command. -type flagger interface { - Flags() *pflag.FlagSet - PersistentFlags() *pflag.FlagSet -} - -func convertPFlags(fgr flagger) []Flag { - var ff []Flag - if fgr.Flags() != nil { - fgr.Flags().VisitAll(func(pf *pflag.Flag) { - ff = append(ff, Flag{ - Name: pf.Name, - Shorthand: pf.Shorthand, - Usage: pf.Usage, - DefValue: pf.DefValue, - Value: pf.Value.String(), - Type: FlagType(pf.Value.Type()), - }) - }) - } - if fgr.PersistentFlags() != nil { - fgr.PersistentFlags().VisitAll(func(pf *pflag.Flag) { - ff = append(ff, Flag{ - Name: pf.Name, - Shorthand: pf.Shorthand, - Usage: pf.Usage, - DefValue: pf.DefValue, - Value: pf.Value.String(), - Type: FlagType(pf.Value.Type()), - Persistent: true, - }) - }) - } - return ff -} - -// GobDecode implements gob.Decoder. -// It actually decodes a gobCommandContext struct and fills c with it. -func (c *ExecutedCommand) GobDecode(bz []byte) error { - var gb gobCommandContextFlags - err := gob.NewDecoder(bytes.NewReader(bz)).Decode(&gb) - if err != nil { - return err - } - *c = ExecutedCommand(gb.CommandContext) - for _, f := range gb.Flags { - err := f.feedFlagSet(c) - if err != nil { - return err - } - } - return nil -} - -// handshakeConfigs are used to just do a basic handshake between -// an app and host. If the handshake fails, a user friendly error is shown. -// This prevents users from executing bad apps or executing an app -// directory. It is a UX feature, not a security feature. -var handshakeConfig = plugin.HandshakeConfig{ - ProtocolVersion: 1, - MagicCookieKey: "BASIC_PLUGIN", - MagicCookieValue: "hello", -} - -func HandshakeConfig() plugin.HandshakeConfig { - return handshakeConfig -} - -// InterfaceRPC is an implementation that talks over RPC. -type InterfaceRPC struct{ client *rpc.Client } - -// Manifest implements Interface.Manifest. -func (g *InterfaceRPC) Manifest() (Manifest, error) { - var resp Manifest - return resp, g.client.Call("Plugin.Manifest", new(interface{}), &resp) -} - -// Execute implements Interface.Commands. -func (g *InterfaceRPC) Execute(c ExecutedCommand) error { - var resp interface{} - return g.client.Call("Plugin.Execute", map[string]interface{}{ - "executedCommand": c, - }, &resp) -} - -func (g *InterfaceRPC) ExecuteHookPre(hook ExecutedHook) error { - var resp interface{} - return g.client.Call("Plugin.ExecuteHookPre", map[string]interface{}{ - "executedHook": hook, - }, &resp) -} - -func (g *InterfaceRPC) ExecuteHookPost(hook ExecutedHook) error { - var resp interface{} - return g.client.Call("Plugin.ExecuteHookPost", map[string]interface{}{ - "executedHook": hook, - }, &resp) -} - -func (g *InterfaceRPC) ExecuteHookCleanUp(hook ExecutedHook) error { - var resp interface{} - return g.client.Call("Plugin.ExecuteHookCleanUp", map[string]interface{}{ - "executedHook": hook, - }, &resp) -} - -// InterfaceRPCServer is the RPC server that InterfaceRPC talks to, conforming to -// the requirements of net/rpc. -type InterfaceRPCServer struct { - Impl Interface -} - -func (s *InterfaceRPCServer) Manifest(_ interface{}, resp *Manifest) error { - var err error - *resp, err = s.Impl.Manifest() - return err -} - -func (s *InterfaceRPCServer) Execute(args map[string]interface{}, _ *interface{}) error { - return s.Impl.Execute(args["executedCommand"].(ExecutedCommand)) -} - -func (s *InterfaceRPCServer) ExecuteHookPre(args map[string]interface{}, _ *interface{}) error { - return s.Impl.ExecuteHookPre(args["executedHook"].(ExecutedHook)) -} - -func (s *InterfaceRPCServer) ExecuteHookPost(args map[string]interface{}, _ *interface{}) error { - return s.Impl.ExecuteHookPost(args["executedHook"].(ExecutedHook)) -} - -func (s *InterfaceRPCServer) ExecuteHookCleanUp(args map[string]interface{}, _ *interface{}) error { - return s.Impl.ExecuteHookCleanUp(args["executedHook"].(ExecutedHook)) -} - -// InterfacePlugin is the implementation of Interface. -// -// This has two methods: Server must return an RPC server for this plugin -// type. We construct a InterfaceRPCServer for this. +// ClientAPI defines the interface for plugins to get chain app code analysis info. // -// Client must return an implementation of our interface that communicates -// over an RPC client. We return InterfaceRPC for this. -type InterfacePlugin struct { - Impl Interface -} - -func (p *InterfacePlugin) Server(*plugin.MuxBroker) (interface{}, error) { - return &InterfaceRPCServer{Impl: p.Impl}, nil -} - -func (InterfacePlugin) Client(_ *plugin.MuxBroker, c *rpc.Client) (interface{}, error) { - return &InterfaceRPC{client: c}, nil +//go:generate mockery --srcpkg . --name ClientAPI --structname PluginClientAPI --filename client_api.go --with-expecter +type ClientAPI interface { + // GetChainInfo returns basic info for the configured blockchain app. + GetChainInfo(context.Context) (*ChainInfo, error) } diff --git a/ignite/services/plugin/interface_test.go b/ignite/services/plugin/interface_test.go deleted file mode 100644 index f36fb9f89d..0000000000 --- a/ignite/services/plugin/interface_test.go +++ /dev/null @@ -1,169 +0,0 @@ -package plugin_test - -import ( - "testing" - - "github.com/spf13/cobra" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - - "github.com/ignite/cli/ignite/services/plugin" -) - -func TestCommandToCobraCommand(t *testing.T) { - var ( - require = require.New(t) - assert = assert.New(t) - pcmd = plugin.Command{ - Use: "new", - Aliases: []string{"n"}, - Short: "short", - Long: "long", - Hidden: true, - Flags: []plugin.Flag{ - { - Name: "bool", - Shorthand: "b", - DefValue: "true", - Value: "true", - Usage: "a bool", - Type: plugin.FlagTypeBool, - }, - { - Name: "string", - DefValue: "hello", - Value: "hello", - Usage: "a string", - Type: plugin.FlagTypeString, - Persistent: true, - }, - }, - Commands: []plugin.Command{ - { - Use: "sub", - Aliases: []string{"s"}, - Short: "sub short", - Long: "sub long", - }, - }, - } - ) - - cmd, err := pcmd.ToCobraCommand() - - require.NoError(err) - require.NotNil(cmd) - assert.Empty(cmd.Commands()) // subcommands aren't converted - assert.Equal(pcmd.Use, cmd.Use) - assert.Equal(pcmd.Short, cmd.Short) - assert.Equal(pcmd.Long, cmd.Long) - assert.Equal(pcmd.Aliases, cmd.Aliases) - assert.Equal(pcmd.Hidden, cmd.Hidden) - for _, f := range pcmd.Flags { - if f.Persistent { - assert.NotNil(cmd.PersistentFlags().Lookup(f.Name), "missing pflag %s", f.Name) - } else { - assert.NotNil(cmd.Flags().Lookup(f.Name), "missing flag %s", f.Name) - } - } -} - -func TestManifestImportCobraCommand(t *testing.T) { - manifest := plugin.Manifest{ - Name: "hey", - Commands: []plugin.Command{ - {Use: "existing"}, - }, - } - cmd := &cobra.Command{ - Use: "new", - Aliases: []string{"n"}, - Short: "short", - Long: "long", - Hidden: true, - } - cmd.Flags().BoolP("bool", "b", true, "a bool") - cmd.Flags().String("string", "hello", "a string") - cmd.PersistentFlags().String("persistent", "hello", "a persistent string") - subcmd := &cobra.Command{ - Use: "sub", - Aliases: []string{"s"}, - Short: "sub short", - Long: "sub long", - } - subcmd.Flags().BoolP("subbool", "b", true, "a bool") - subcmd.Flags().String("substring", "hello", "a string") - subcmd.AddCommand(&cobra.Command{ - Use: "subsub", - }) - cmd.AddCommand(subcmd) - - manifest.ImportCobraCommand(cmd, "under") - - expectedManifest := plugin.Manifest{ - Name: "hey", - Commands: []plugin.Command{ - {Use: "existing"}, - { - Use: "new", - Aliases: []string{"n"}, - Short: "short", - Long: "long", - Hidden: true, - PlaceCommandUnder: "under", - Flags: []plugin.Flag{ - { - Name: "bool", - Shorthand: "b", - DefValue: "true", - Value: "true", - Usage: "a bool", - Type: plugin.FlagTypeBool, - }, - { - Name: "string", - DefValue: "hello", - Value: "hello", - Usage: "a string", - Type: plugin.FlagTypeString, - }, - { - Name: "persistent", - DefValue: "hello", - Value: "hello", - Usage: "a persistent string", - Type: plugin.FlagTypeString, - Persistent: true, - }, - }, - Commands: []plugin.Command{ - { - Use: "sub", - Aliases: []string{"s"}, - Short: "sub short", - Long: "sub long", - Flags: []plugin.Flag{ - { - Name: "subbool", - Shorthand: "b", - DefValue: "true", - Value: "true", - Usage: "a bool", - Type: plugin.FlagTypeBool, - }, - { - Name: "substring", - DefValue: "hello", - Value: "hello", - Usage: "a string", - Type: plugin.FlagTypeString, - }, - }, - Commands: []plugin.Command{{Use: "subsub"}}, - }, - }, - }, - }, - } - assert.Equal(t, expectedManifest, manifest) -} diff --git a/ignite/services/plugin/mocks/client_api.go b/ignite/services/plugin/mocks/client_api.go new file mode 100644 index 0000000000..c9bffda3e3 --- /dev/null +++ b/ignite/services/plugin/mocks/client_api.go @@ -0,0 +1,93 @@ +// Code generated by mockery v2.27.1. DO NOT EDIT. + +package mocks + +import ( + context "context" + + mock "github.com/stretchr/testify/mock" + + v1 "github.com/ignite/cli/ignite/services/plugin/grpc/v1" +) + +// PluginClientAPI is an autogenerated mock type for the ClientAPI type +type PluginClientAPI struct { + mock.Mock +} + +type PluginClientAPI_Expecter struct { + mock *mock.Mock +} + +func (_m *PluginClientAPI) EXPECT() *PluginClientAPI_Expecter { + return &PluginClientAPI_Expecter{mock: &_m.Mock} +} + +// GetChainInfo provides a mock function with given fields: _a0 +func (_m *PluginClientAPI) GetChainInfo(_a0 context.Context) (*v1.ChainInfo, error) { + ret := _m.Called(_a0) + + var r0 *v1.ChainInfo + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (*v1.ChainInfo, error)); ok { + return rf(_a0) + } + if rf, ok := ret.Get(0).(func(context.Context) *v1.ChainInfo); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*v1.ChainInfo) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PluginClientAPI_GetChainInfo_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetChainInfo' +type PluginClientAPI_GetChainInfo_Call struct { + *mock.Call +} + +// GetChainInfo is a helper method to define mock.On call +// - _a0 context.Context +func (_e *PluginClientAPI_Expecter) GetChainInfo(_a0 interface{}) *PluginClientAPI_GetChainInfo_Call { + return &PluginClientAPI_GetChainInfo_Call{Call: _e.mock.On("GetChainInfo", _a0)} +} + +func (_c *PluginClientAPI_GetChainInfo_Call) Run(run func(_a0 context.Context)) *PluginClientAPI_GetChainInfo_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *PluginClientAPI_GetChainInfo_Call) Return(_a0 *v1.ChainInfo, _a1 error) *PluginClientAPI_GetChainInfo_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *PluginClientAPI_GetChainInfo_Call) RunAndReturn(run func(context.Context) (*v1.ChainInfo, error)) *PluginClientAPI_GetChainInfo_Call { + _c.Call.Return(run) + return _c +} + +type mockConstructorTestingTNewPluginClientAPI interface { + mock.TestingT + Cleanup(func()) +} + +// NewPluginClientAPI creates a new instance of PluginClientAPI. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func NewPluginClientAPI(t mockConstructorTestingTNewPluginClientAPI) *PluginClientAPI { + mock := &PluginClientAPI{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/ignite/services/plugin/mocks/interface.go b/ignite/services/plugin/mocks/interface.go index cdf4f810df..e03d029aa8 100644 --- a/ignite/services/plugin/mocks/interface.go +++ b/ignite/services/plugin/mocks/interface.go @@ -1,11 +1,14 @@ -// Code generated by mockery v2.22.1. DO NOT EDIT. +// Code generated by mockery v2.27.1. DO NOT EDIT. package mocks import ( - mock "github.com/stretchr/testify/mock" + context "context" plugin "github.com/ignite/cli/ignite/services/plugin" + mock "github.com/stretchr/testify/mock" + + v1 "github.com/ignite/cli/ignite/services/plugin/grpc/v1" ) // PluginInterface is an autogenerated mock type for the Interface type @@ -21,13 +24,13 @@ func (_m *PluginInterface) EXPECT() *PluginInterface_Expecter { return &PluginInterface_Expecter{mock: &_m.Mock} } -// Execute provides a mock function with given fields: cmd -func (_m *PluginInterface) Execute(cmd plugin.ExecutedCommand) error { - ret := _m.Called(cmd) +// Execute provides a mock function with given fields: _a0, _a1, _a2 +func (_m *PluginInterface) Execute(_a0 context.Context, _a1 *v1.ExecutedCommand, _a2 plugin.ClientAPI) error { + ret := _m.Called(_a0, _a1, _a2) var r0 error - if rf, ok := ret.Get(0).(func(plugin.ExecutedCommand) error); ok { - r0 = rf(cmd) + if rf, ok := ret.Get(0).(func(context.Context, *v1.ExecutedCommand, plugin.ClientAPI) error); ok { + r0 = rf(_a0, _a1, _a2) } else { r0 = ret.Error(0) } @@ -41,14 +44,16 @@ type PluginInterface_Execute_Call struct { } // Execute is a helper method to define mock.On call -// - cmd plugin.ExecutedCommand -func (_e *PluginInterface_Expecter) Execute(cmd interface{}) *PluginInterface_Execute_Call { - return &PluginInterface_Execute_Call{Call: _e.mock.On("Execute", cmd)} +// - _a0 context.Context +// - _a1 *v1.ExecutedCommand +// - _a2 plugin.ClientAPI +func (_e *PluginInterface_Expecter) Execute(_a0 interface{}, _a1 interface{}, _a2 interface{}) *PluginInterface_Execute_Call { + return &PluginInterface_Execute_Call{Call: _e.mock.On("Execute", _a0, _a1, _a2)} } -func (_c *PluginInterface_Execute_Call) Run(run func(cmd plugin.ExecutedCommand)) *PluginInterface_Execute_Call { +func (_c *PluginInterface_Execute_Call) Run(run func(_a0 context.Context, _a1 *v1.ExecutedCommand, _a2 plugin.ClientAPI)) *PluginInterface_Execute_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(plugin.ExecutedCommand)) + run(args[0].(context.Context), args[1].(*v1.ExecutedCommand), args[2].(plugin.ClientAPI)) }) return _c } @@ -58,18 +63,18 @@ func (_c *PluginInterface_Execute_Call) Return(_a0 error) *PluginInterface_Execu return _c } -func (_c *PluginInterface_Execute_Call) RunAndReturn(run func(plugin.ExecutedCommand) error) *PluginInterface_Execute_Call { +func (_c *PluginInterface_Execute_Call) RunAndReturn(run func(context.Context, *v1.ExecutedCommand, plugin.ClientAPI) error) *PluginInterface_Execute_Call { _c.Call.Return(run) return _c } -// ExecuteHookCleanUp provides a mock function with given fields: hook -func (_m *PluginInterface) ExecuteHookCleanUp(hook plugin.ExecutedHook) error { - ret := _m.Called(hook) +// ExecuteHookCleanUp provides a mock function with given fields: _a0, _a1, _a2 +func (_m *PluginInterface) ExecuteHookCleanUp(_a0 context.Context, _a1 *v1.ExecutedHook, _a2 plugin.ClientAPI) error { + ret := _m.Called(_a0, _a1, _a2) var r0 error - if rf, ok := ret.Get(0).(func(plugin.ExecutedHook) error); ok { - r0 = rf(hook) + if rf, ok := ret.Get(0).(func(context.Context, *v1.ExecutedHook, plugin.ClientAPI) error); ok { + r0 = rf(_a0, _a1, _a2) } else { r0 = ret.Error(0) } @@ -83,14 +88,16 @@ type PluginInterface_ExecuteHookCleanUp_Call struct { } // ExecuteHookCleanUp is a helper method to define mock.On call -// - hook plugin.ExecutedHook -func (_e *PluginInterface_Expecter) ExecuteHookCleanUp(hook interface{}) *PluginInterface_ExecuteHookCleanUp_Call { - return &PluginInterface_ExecuteHookCleanUp_Call{Call: _e.mock.On("ExecuteHookCleanUp", hook)} +// - _a0 context.Context +// - _a1 *v1.ExecutedHook +// - _a2 plugin.ClientAPI +func (_e *PluginInterface_Expecter) ExecuteHookCleanUp(_a0 interface{}, _a1 interface{}, _a2 interface{}) *PluginInterface_ExecuteHookCleanUp_Call { + return &PluginInterface_ExecuteHookCleanUp_Call{Call: _e.mock.On("ExecuteHookCleanUp", _a0, _a1, _a2)} } -func (_c *PluginInterface_ExecuteHookCleanUp_Call) Run(run func(hook plugin.ExecutedHook)) *PluginInterface_ExecuteHookCleanUp_Call { +func (_c *PluginInterface_ExecuteHookCleanUp_Call) Run(run func(_a0 context.Context, _a1 *v1.ExecutedHook, _a2 plugin.ClientAPI)) *PluginInterface_ExecuteHookCleanUp_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(plugin.ExecutedHook)) + run(args[0].(context.Context), args[1].(*v1.ExecutedHook), args[2].(plugin.ClientAPI)) }) return _c } @@ -100,18 +107,18 @@ func (_c *PluginInterface_ExecuteHookCleanUp_Call) Return(_a0 error) *PluginInte return _c } -func (_c *PluginInterface_ExecuteHookCleanUp_Call) RunAndReturn(run func(plugin.ExecutedHook) error) *PluginInterface_ExecuteHookCleanUp_Call { +func (_c *PluginInterface_ExecuteHookCleanUp_Call) RunAndReturn(run func(context.Context, *v1.ExecutedHook, plugin.ClientAPI) error) *PluginInterface_ExecuteHookCleanUp_Call { _c.Call.Return(run) return _c } -// ExecuteHookPost provides a mock function with given fields: hook -func (_m *PluginInterface) ExecuteHookPost(hook plugin.ExecutedHook) error { - ret := _m.Called(hook) +// ExecuteHookPost provides a mock function with given fields: _a0, _a1, _a2 +func (_m *PluginInterface) ExecuteHookPost(_a0 context.Context, _a1 *v1.ExecutedHook, _a2 plugin.ClientAPI) error { + ret := _m.Called(_a0, _a1, _a2) var r0 error - if rf, ok := ret.Get(0).(func(plugin.ExecutedHook) error); ok { - r0 = rf(hook) + if rf, ok := ret.Get(0).(func(context.Context, *v1.ExecutedHook, plugin.ClientAPI) error); ok { + r0 = rf(_a0, _a1, _a2) } else { r0 = ret.Error(0) } @@ -125,14 +132,16 @@ type PluginInterface_ExecuteHookPost_Call struct { } // ExecuteHookPost is a helper method to define mock.On call -// - hook plugin.ExecutedHook -func (_e *PluginInterface_Expecter) ExecuteHookPost(hook interface{}) *PluginInterface_ExecuteHookPost_Call { - return &PluginInterface_ExecuteHookPost_Call{Call: _e.mock.On("ExecuteHookPost", hook)} +// - _a0 context.Context +// - _a1 *v1.ExecutedHook +// - _a2 plugin.ClientAPI +func (_e *PluginInterface_Expecter) ExecuteHookPost(_a0 interface{}, _a1 interface{}, _a2 interface{}) *PluginInterface_ExecuteHookPost_Call { + return &PluginInterface_ExecuteHookPost_Call{Call: _e.mock.On("ExecuteHookPost", _a0, _a1, _a2)} } -func (_c *PluginInterface_ExecuteHookPost_Call) Run(run func(hook plugin.ExecutedHook)) *PluginInterface_ExecuteHookPost_Call { +func (_c *PluginInterface_ExecuteHookPost_Call) Run(run func(_a0 context.Context, _a1 *v1.ExecutedHook, _a2 plugin.ClientAPI)) *PluginInterface_ExecuteHookPost_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(plugin.ExecutedHook)) + run(args[0].(context.Context), args[1].(*v1.ExecutedHook), args[2].(plugin.ClientAPI)) }) return _c } @@ -142,18 +151,18 @@ func (_c *PluginInterface_ExecuteHookPost_Call) Return(_a0 error) *PluginInterfa return _c } -func (_c *PluginInterface_ExecuteHookPost_Call) RunAndReturn(run func(plugin.ExecutedHook) error) *PluginInterface_ExecuteHookPost_Call { +func (_c *PluginInterface_ExecuteHookPost_Call) RunAndReturn(run func(context.Context, *v1.ExecutedHook, plugin.ClientAPI) error) *PluginInterface_ExecuteHookPost_Call { _c.Call.Return(run) return _c } -// ExecuteHookPre provides a mock function with given fields: hook -func (_m *PluginInterface) ExecuteHookPre(hook plugin.ExecutedHook) error { - ret := _m.Called(hook) +// ExecuteHookPre provides a mock function with given fields: _a0, _a1, _a2 +func (_m *PluginInterface) ExecuteHookPre(_a0 context.Context, _a1 *v1.ExecutedHook, _a2 plugin.ClientAPI) error { + ret := _m.Called(_a0, _a1, _a2) var r0 error - if rf, ok := ret.Get(0).(func(plugin.ExecutedHook) error); ok { - r0 = rf(hook) + if rf, ok := ret.Get(0).(func(context.Context, *v1.ExecutedHook, plugin.ClientAPI) error); ok { + r0 = rf(_a0, _a1, _a2) } else { r0 = ret.Error(0) } @@ -167,14 +176,16 @@ type PluginInterface_ExecuteHookPre_Call struct { } // ExecuteHookPre is a helper method to define mock.On call -// - hook plugin.ExecutedHook -func (_e *PluginInterface_Expecter) ExecuteHookPre(hook interface{}) *PluginInterface_ExecuteHookPre_Call { - return &PluginInterface_ExecuteHookPre_Call{Call: _e.mock.On("ExecuteHookPre", hook)} +// - _a0 context.Context +// - _a1 *v1.ExecutedHook +// - _a2 plugin.ClientAPI +func (_e *PluginInterface_Expecter) ExecuteHookPre(_a0 interface{}, _a1 interface{}, _a2 interface{}) *PluginInterface_ExecuteHookPre_Call { + return &PluginInterface_ExecuteHookPre_Call{Call: _e.mock.On("ExecuteHookPre", _a0, _a1, _a2)} } -func (_c *PluginInterface_ExecuteHookPre_Call) Run(run func(hook plugin.ExecutedHook)) *PluginInterface_ExecuteHookPre_Call { +func (_c *PluginInterface_ExecuteHookPre_Call) Run(run func(_a0 context.Context, _a1 *v1.ExecutedHook, _a2 plugin.ClientAPI)) *PluginInterface_ExecuteHookPre_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(plugin.ExecutedHook)) + run(args[0].(context.Context), args[1].(*v1.ExecutedHook), args[2].(plugin.ClientAPI)) }) return _c } @@ -184,28 +195,30 @@ func (_c *PluginInterface_ExecuteHookPre_Call) Return(_a0 error) *PluginInterfac return _c } -func (_c *PluginInterface_ExecuteHookPre_Call) RunAndReturn(run func(plugin.ExecutedHook) error) *PluginInterface_ExecuteHookPre_Call { +func (_c *PluginInterface_ExecuteHookPre_Call) RunAndReturn(run func(context.Context, *v1.ExecutedHook, plugin.ClientAPI) error) *PluginInterface_ExecuteHookPre_Call { _c.Call.Return(run) return _c } -// Manifest provides a mock function with given fields: -func (_m *PluginInterface) Manifest() (plugin.Manifest, error) { - ret := _m.Called() +// Manifest provides a mock function with given fields: _a0 +func (_m *PluginInterface) Manifest(_a0 context.Context) (*v1.Manifest, error) { + ret := _m.Called(_a0) - var r0 plugin.Manifest + var r0 *v1.Manifest var r1 error - if rf, ok := ret.Get(0).(func() (plugin.Manifest, error)); ok { - return rf() + if rf, ok := ret.Get(0).(func(context.Context) (*v1.Manifest, error)); ok { + return rf(_a0) } - if rf, ok := ret.Get(0).(func() plugin.Manifest); ok { - r0 = rf() + if rf, ok := ret.Get(0).(func(context.Context) *v1.Manifest); ok { + r0 = rf(_a0) } else { - r0 = ret.Get(0).(plugin.Manifest) + if ret.Get(0) != nil { + r0 = ret.Get(0).(*v1.Manifest) + } } - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(_a0) } else { r1 = ret.Error(1) } @@ -219,23 +232,24 @@ type PluginInterface_Manifest_Call struct { } // Manifest is a helper method to define mock.On call -func (_e *PluginInterface_Expecter) Manifest() *PluginInterface_Manifest_Call { - return &PluginInterface_Manifest_Call{Call: _e.mock.On("Manifest")} +// - _a0 context.Context +func (_e *PluginInterface_Expecter) Manifest(_a0 interface{}) *PluginInterface_Manifest_Call { + return &PluginInterface_Manifest_Call{Call: _e.mock.On("Manifest", _a0)} } -func (_c *PluginInterface_Manifest_Call) Run(run func()) *PluginInterface_Manifest_Call { +func (_c *PluginInterface_Manifest_Call) Run(run func(_a0 context.Context)) *PluginInterface_Manifest_Call { _c.Call.Run(func(args mock.Arguments) { - run() + run(args[0].(context.Context)) }) return _c } -func (_c *PluginInterface_Manifest_Call) Return(_a0 plugin.Manifest, _a1 error) *PluginInterface_Manifest_Call { +func (_c *PluginInterface_Manifest_Call) Return(_a0 *v1.Manifest, _a1 error) *PluginInterface_Manifest_Call { _c.Call.Return(_a0, _a1) return _c } -func (_c *PluginInterface_Manifest_Call) RunAndReturn(run func() (plugin.Manifest, error)) *PluginInterface_Manifest_Call { +func (_c *PluginInterface_Manifest_Call) RunAndReturn(run func(context.Context) (*v1.Manifest, error)) *PluginInterface_Manifest_Call { _c.Call.Return(run) return _c } diff --git a/ignite/services/plugin/plugin.go b/ignite/services/plugin/plugin.go index 240effab4d..b23a46711b 100644 --- a/ignite/services/plugin/plugin.go +++ b/ignite/services/plugin/plugin.go @@ -37,11 +37,13 @@ var PluginsPath = xfilepath.Mkdir(xfilepath.Join( // Plugin represents a ignite plugin. type Plugin struct { - // Embed the plugin configuration + // Embed the plugin configuration. pluginsconfig.Plugin - // Interface allows to communicate with the plugin via net/rpc. + + // Interface allows to communicate with the plugin via RPC. Interface Interface - // If any error occurred during the plugin load, it's stored here + + // If any error occurred during the plugin load, it's stored here. Error error name string @@ -53,11 +55,13 @@ type Plugin struct { client *hplugin.Client - // holds a cache of the plugin manifest to prevent mant calls over the rpc boundary - manifest Manifest + // Holds a cache of the plugin manifest to prevent mant calls over the rpc boundary. + manifest *Manifest + // If a plugin's ShareHost flag is set to true, isHost is used to discern if a // plugin instance is controlling the rpc server. - isHost bool + isHost bool + isSharedHost bool ev events.Bus } @@ -100,8 +104,7 @@ func Load(ctx context.Context, plugins []pluginsconfig.Plugin, options ...Option // Update removes the cache directory of plugins and fetch them again. func Update(plugins ...*Plugin) error { for _, p := range plugins { - err := p.clean() - if err != nil { + if err := p.clean(); err != nil { return err } p.fetch() @@ -176,7 +179,7 @@ func newPlugin(pluginsDir string, cp pluginsconfig.Plugin, options ...Option) *P // KillClient kills the running plugin client. func (p *Plugin) KillClient() { - if p.manifest.SharedHost && !p.isHost { + if p.isSharedHost && !p.isHost { // Don't send kill signal to a shared-host plugin when this process isn't // the one who initiated it. return @@ -192,6 +195,12 @@ func (p *Plugin) KillClient() { } } +// Manifest returns plugin's manigest. +// The manifest is available after the plugin has been loaded. +func (p Plugin) Manifest() *Manifest { + return p.manifest +} + func (p Plugin) binaryName() string { return fmt.Sprintf("%s.app", p.name) } @@ -232,7 +241,7 @@ func (p *Plugin) load(ctx context.Context) { } // pluginMap is the map of plugins we can dispense. pluginMap := map[string]hplugin.Plugin{ - p.name: &InterfacePlugin{}, + p.name: NewGRPC(nil), } // Create an hclog.Logger logLevel := hclog.Error @@ -245,6 +254,16 @@ func (p *Plugin) load(ctx context.Context) { Level: logLevel, }) + // Common plugin client configuration values + cfg := &hplugin.ClientConfig{ + HandshakeConfig: HandshakeConfig(), + Plugins: pluginMap, + Logger: logger, + SyncStderr: os.Stderr, + SyncStdout: os.Stdout, + AllowedProtocols: []hplugin.Protocol{hplugin.ProtocolGRPC}, + } + if checkConfCache(p.Path) { rconf, err := readConfigCache(p.Path) if err != nil { @@ -252,29 +271,16 @@ func (p *Plugin) load(ctx context.Context) { return } - // We're attaching to an existing server, supply attachment configuration - p.client = hplugin.NewClient(&hplugin.ClientConfig{ - HandshakeConfig: handshakeConfig, - Plugins: pluginMap, - Logger: logger, - Reattach: &rconf, - SyncStderr: os.Stderr, - SyncStdout: os.Stdout, - }) - + // Attach to an existing plugin process + cfg.Reattach = &rconf + p.client = hplugin.NewClient(cfg) } else { - // We're a host! Start by launching the plugin process. - p.client = hplugin.NewClient(&hplugin.ClientConfig{ - HandshakeConfig: handshakeConfig, - Plugins: pluginMap, - Logger: logger, - Cmd: exec.Command(p.binaryPath()), - SyncStderr: os.Stderr, - SyncStdout: os.Stdout, - }) - } - - // :Connect via RPC + // Launch a new plugin process + cfg.Cmd = exec.Command(p.binaryPath()) + p.client = hplugin.NewClient(cfg) + } + + // Connect via gRPC rpcClient, err := p.client.Client() if err != nil { p.Error = errors.Wrapf(err, "connecting") @@ -289,14 +295,18 @@ func (p *Plugin) load(ctx context.Context) { } // We should have an Interface now! This feels like a normal interface - // implementation but is in fact over an RPC connection. + // implementation but is in fact over an gRPC connection. p.Interface = raw.(Interface) - m, err := p.Interface.Manifest() + m, err := p.Interface.Manifest(ctx) if err != nil { p.Error = errors.Wrapf(err, "manifest load") + return } + p.isSharedHost = m.SharedHost + + // Cache the manifest to avoid extra plugin requests p.manifest = m // write the rpc context to cache if the plugin is declared as host. diff --git a/ignite/services/plugin/plugin_test.go b/ignite/services/plugin/plugin_test.go index b3e6682dd0..7ddca88daf 100644 --- a/ignite/services/plugin/plugin_test.go +++ b/ignite/services/plugin/plugin_test.go @@ -157,33 +157,47 @@ func TestNewPlugin(t *testing.T) { } } +// Helper to make a local git repository with gofile committed. +// Returns the repo directory and the git.Repository +func makeGitRepo(t *testing.T, name string) (string, *git.Repository) { + t.Helper() + + require := require.New(t) + repoDir := t.TempDir() + scaffoldPlugin(t, repoDir, "github.com/ignite/"+name, false) + + repo, err := git.PlainInit(repoDir, false) + require.NoError(err) + + w, err := repo.Worktree() + require.NoError(err) + + _, err = w.Add(".") + require.NoError(err) + + _, err = w.Commit("msg", &git.CommitOptions{ + Author: &object.Signature{ + Name: "bob", + Email: "bob@example.com", + When: time.Now(), + }, + }) + require.NoError(err) + return repoDir, repo +} + +type TestClientAPI struct{ ClientAPI } + +func (TestClientAPI) GetChainInfo(context.Context) (*ChainInfo, error) { + return &ChainInfo{}, nil +} + func TestPluginLoad(t *testing.T) { wd, err := os.Getwd() require.NoError(t, err) - // Helper to make a local git repository with gofile committed. - // Returns the repo directory and the git.Repository - makeGitRepo := func(t *testing.T, name string) (string, *git.Repository) { - require := require.New(t) - repoDir := t.TempDir() - scaffoldPlugin(t, repoDir, "github.com/ignite/"+name, false) - require.NoError(err) - repo, err := git.PlainInit(repoDir, false) - require.NoError(err) - w, err := repo.Worktree() - require.NoError(err) - _, err = w.Add(".") - require.NoError(err) - _, err = w.Commit("msg", &git.CommitOptions{ - Author: &object.Signature{ - Name: "bob", - Email: "bob@example.com", - When: time.Now(), - }, - }) - require.NoError(err) - return repoDir, repo - } + clientAPI := &TestClientAPI{} + tests := []struct { name string buildPlugin func(t *testing.T) Plugin @@ -330,6 +344,7 @@ func TestPluginLoad(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { + ctx := context.Background() require := require.New(t) assert := assert.New(t) p := tt.buildPlugin(t) @@ -345,13 +360,13 @@ func TestPluginLoad(t *testing.T) { require.NoError(p.Error) require.NotNil(p.Interface) - manifest, err := p.Interface.Manifest() + manifest, err := p.Interface.Manifest(ctx) require.NoError(err) assert.Equal(p.name, manifest.Name) - assert.NoError(p.Interface.Execute(ExecutedCommand{})) - assert.NoError(p.Interface.ExecuteHookPre(ExecutedHook{})) - assert.NoError(p.Interface.ExecuteHookPost(ExecutedHook{})) - assert.NoError(p.Interface.ExecuteHookCleanUp(ExecutedHook{})) + assert.NoError(p.Interface.Execute(ctx, &ExecutedCommand{}, clientAPI)) + assert.NoError(p.Interface.ExecuteHookPre(ctx, &ExecutedHook{}, clientAPI)) + assert.NoError(p.Interface.ExecuteHookPost(ctx, &ExecutedHook{}, clientAPI)) + assert.NoError(p.Interface.ExecuteHookCleanUp(ctx, &ExecutedHook{}, clientAPI)) }) } } @@ -491,14 +506,18 @@ func TestPluginClean(t *testing.T) { // scaffoldPlugin runs Scaffold and updates the go.mod so it uses the // current ignite/cli sources. func scaffoldPlugin(t *testing.T, dir, name string, sharedHost bool) string { + t.Helper() + require := require.New(t) - path, err := Scaffold(dir, name, sharedHost) + path, err := Scaffold(context.Background(), dir, name, sharedHost) require.NoError(err) + // We want the scaffolded plugin to use the current version of ignite/cli, // for that we need to update the plugin go.mod and add a replace to target // current ignite/cli gomod, err := gomodule.ParseAt(path) require.NoError(err) + // use GOMOD env to get current directory module path modpath, err := gocmd.Env(gocmd.EnvGOMOD) require.NoError(err) @@ -515,12 +534,14 @@ func scaffoldPlugin(t *testing.T, dir, name string, sharedHost bool) string { func assertPlugin(t *testing.T, want, have Plugin) { t.Helper() + if want.Error != nil { require.Error(t, have.Error) assert.Regexp(t, want.Error.Error(), have.Error.Error()) } else { require.NoError(t, have.Error) } + // Errors aren't comparable with assert.Equal, because of the different stacks want.Error = nil have.Error = nil diff --git a/ignite/services/plugin/protocol.go b/ignite/services/plugin/protocol.go new file mode 100644 index 0000000000..0423e2e9b6 --- /dev/null +++ b/ignite/services/plugin/protocol.go @@ -0,0 +1,233 @@ +package plugin + +import ( + "context" + + hplugin "github.com/hashicorp/go-plugin" + "google.golang.org/grpc" + + v1 "github.com/ignite/cli/ignite/services/plugin/grpc/v1" +) + +var handshakeConfig = hplugin.HandshakeConfig{ + ProtocolVersion: 1, + MagicCookieKey: "IGNITE_APP", + MagicCookieValue: "ignite", +} + +// HandshakeConfig are used to just do a basic handshake between a plugin and host. +// If the handshake fails, a user friendly error is shown. This prevents users from +// executing bad plugins or executing a plugin directory. It is a UX feature, not a +// security feature. +func HandshakeConfig() hplugin.HandshakeConfig { + return handshakeConfig +} + +// NewGRPC returns a new gRPC plugin that implements the interface over gRPC. +func NewGRPC(impl Interface) hplugin.Plugin { + return grpcPlugin{impl: impl} +} + +type grpcPlugin struct { + hplugin.NetRPCUnsupportedPlugin + + impl Interface +} + +// GRPCServer returns a new server that implements the plugin interface over gRPC. +func (p grpcPlugin) GRPCServer(broker *hplugin.GRPCBroker, s *grpc.Server) error { + v1.RegisterInterfaceServiceServer(s, &server{ + impl: p.impl, + broker: broker, + }) + return nil +} + +// GRPCClient returns a new plugin client that allows calling the plugin interface over gRPC. +func (p grpcPlugin) GRPCClient(_ context.Context, broker *hplugin.GRPCBroker, c *grpc.ClientConn) (interface{}, error) { + return &client{ + grpc: v1.NewInterfaceServiceClient(c), + broker: broker, + }, nil +} + +type client struct { + grpc v1.InterfaceServiceClient + broker *hplugin.GRPCBroker +} + +func (c client) Manifest(ctx context.Context) (*Manifest, error) { + r, err := c.grpc.Manifest(ctx, &v1.ManifestRequest{}) + if err != nil { + return nil, err + } + + return r.Manifest, nil +} + +func (c client) Execute(ctx context.Context, cmd *ExecutedCommand, api ClientAPI) error { + brokerID, stopServer := c.startClientAPIServer(api) + _, err := c.grpc.Execute(ctx, &v1.ExecuteRequest{ + Cmd: cmd, + ClientApi: brokerID, + }) + stopServer() + return err +} + +func (c client) ExecuteHookPre(ctx context.Context, h *ExecutedHook, api ClientAPI) error { + brokerID, stopServer := c.startClientAPIServer(api) + _, err := c.grpc.ExecuteHookPre(ctx, &v1.ExecuteHookPreRequest{ + Hook: h, + ClientApi: brokerID, + }) + stopServer() + return err +} + +func (c client) ExecuteHookPost(ctx context.Context, h *ExecutedHook, api ClientAPI) error { + brokerID, stopServer := c.startClientAPIServer(api) + _, err := c.grpc.ExecuteHookPost(ctx, &v1.ExecuteHookPostRequest{ + Hook: h, + ClientApi: brokerID, + }) + stopServer() + return err +} + +func (c client) ExecuteHookCleanUp(ctx context.Context, h *ExecutedHook, api ClientAPI) error { + brokerID, stopServer := c.startClientAPIServer(api) + _, err := c.grpc.ExecuteHookCleanUp(ctx, &v1.ExecuteHookCleanUpRequest{ + Hook: h, + ClientApi: brokerID, + }) + stopServer() + return err +} + +func (c client) startClientAPIServer(api ClientAPI) (uint32, func()) { + var ( + srv *grpc.Server + brokerID = c.broker.NextId() + ) + + go c.broker.AcceptAndServe(brokerID, func(opts []grpc.ServerOption) *grpc.Server { + srv = grpc.NewServer(opts...) + v1.RegisterClientAPIServiceServer(srv, &clientAPIServer{impl: api}) + return srv + }) + + return brokerID, func() { srv.Stop() } +} + +type server struct { + v1.UnimplementedInterfaceServiceServer + + impl Interface + broker *hplugin.GRPCBroker +} + +func (s server) Manifest(ctx context.Context, _ *v1.ManifestRequest) (*v1.ManifestResponse, error) { + m, err := s.impl.Manifest(ctx) + if err != nil { + return nil, err + } + + return &v1.ManifestResponse{Manifest: m}, nil +} + +func (s server) Execute(ctx context.Context, r *v1.ExecuteRequest) (*v1.ExecuteResponse, error) { + conn, err := s.broker.Dial(r.ClientApi) + if err != nil { + return nil, err + } + + defer conn.Close() + + err = s.impl.Execute(ctx, r.GetCmd(), newClientAPIClient(conn)) + if err != nil { + return nil, err + } + + return &v1.ExecuteResponse{}, nil +} + +func (s server) ExecuteHookPre(ctx context.Context, r *v1.ExecuteHookPreRequest) (*v1.ExecuteHookPreResponse, error) { + conn, err := s.broker.Dial(r.ClientApi) + if err != nil { + return nil, err + } + + defer conn.Close() + + err = s.impl.ExecuteHookPre(ctx, r.GetHook(), newClientAPIClient(conn)) + if err != nil { + return nil, err + } + + return &v1.ExecuteHookPreResponse{}, nil +} + +func (s server) ExecuteHookPost(ctx context.Context, r *v1.ExecuteHookPostRequest) (*v1.ExecuteHookPostResponse, error) { + conn, err := s.broker.Dial(r.ClientApi) + if err != nil { + return nil, err + } + + defer conn.Close() + + err = s.impl.ExecuteHookPost(ctx, r.GetHook(), newClientAPIClient(conn)) + if err != nil { + return nil, err + } + + return &v1.ExecuteHookPostResponse{}, nil +} + +func (s server) ExecuteHookCleanUp(ctx context.Context, r *v1.ExecuteHookCleanUpRequest) (*v1.ExecuteHookCleanUpResponse, error) { + conn, err := s.broker.Dial(r.ClientApi) + if err != nil { + return nil, err + } + + defer conn.Close() + + err = s.impl.ExecuteHookCleanUp(ctx, r.GetHook(), newClientAPIClient(conn)) + if err != nil { + return nil, err + } + + return &v1.ExecuteHookCleanUpResponse{}, nil +} + +func newClientAPIClient(c *grpc.ClientConn) *clientAPIClient { + return &clientAPIClient{v1.NewClientAPIServiceClient(c)} +} + +type clientAPIClient struct { + grpc v1.ClientAPIServiceClient +} + +func (c clientAPIClient) GetChainInfo(ctx context.Context) (*ChainInfo, error) { + r, err := c.grpc.GetChainInfo(ctx, &v1.GetChainInfoRequest{}) + if err != nil { + return nil, err + } + + return r.ChainInfo, nil +} + +type clientAPIServer struct { + v1.UnimplementedClientAPIServiceServer + + impl ClientAPI +} + +func (s clientAPIServer) GetChainInfo(ctx context.Context, _ *v1.GetChainInfoRequest) (*v1.GetChainInfoResponse, error) { + chainInfo, err := s.impl.GetChainInfo(ctx) + if err != nil { + return nil, err + } + + return &v1.GetChainInfoResponse{ChainInfo: chainInfo}, nil +} diff --git a/ignite/services/plugin/scaffold.go b/ignite/services/plugin/scaffold.go index ff2a7fe093..500e1f6645 100644 --- a/ignite/services/plugin/scaffold.go +++ b/ignite/services/plugin/scaffold.go @@ -19,7 +19,7 @@ import ( var fsPluginSource embed.FS // Scaffold generates a plugin structure under dir/path.Base(moduleName). -func Scaffold(dir, moduleName string, sharedHost bool) (string, error) { +func Scaffold(ctx context.Context, dir, moduleName string, sharedHost bool) (string, error) { var ( name = filepath.Base(moduleName) finalDir = path.Join(dir, name) @@ -30,29 +30,35 @@ func Scaffold(dir, moduleName string, sharedHost bool) (string, error) { finalDir, ) ) + if _, err := os.Stat(finalDir); err == nil { // finalDir already exists, don't overwrite stuff return "", errors.Errorf("directory %q already exists, abort scaffolding", finalDir) } + if err := g.Box(template); err != nil { return "", errors.WithStack(err) } - ctx := plush.NewContext() - ctx.Set("ModuleName", moduleName) - ctx.Set("Name", name) - ctx.Set("SharedHost", sharedHost) - g.Transformer(xgenny.Transformer(ctx)) + pctx := plush.NewContextWithContext(ctx) + pctx.Set("ModuleName", moduleName) + pctx.Set("Name", name) + 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) } - if err := gocmd.ModTidy(context.TODO(), finalDir); err != nil { + + if err := gocmd.ModTidy(ctx, finalDir); err != nil { return "", errors.WithStack(err) } + return finalDir, nil } diff --git a/ignite/services/plugin/scaffold_test.go b/ignite/services/plugin/scaffold_test.go index 8d7f122df3..a6b66a9db1 100644 --- a/ignite/services/plugin/scaffold_test.go +++ b/ignite/services/plugin/scaffold_test.go @@ -1,16 +1,24 @@ package plugin import ( + "context" + "path/filepath" "testing" "github.com/stretchr/testify/require" ) func TestScaffold(t *testing.T) { + // Arrange tmp := t.TempDir() + ctx := context.Background() - path, err := Scaffold(tmp, "github.com/foo/bar", false) + // Act + path, err := Scaffold(ctx, tmp, "github.com/foo/bar", false) + // Assert require.NoError(t, err) require.DirExists(t, path) + require.FileExists(t, filepath.Join(path, "go.mod")) + require.FileExists(t, filepath.Join(path, "main.go")) } diff --git a/ignite/services/plugin/template/go.mod.plush b/ignite/services/plugin/template/go.mod.plush index fe8fffd05b..97ea5b9955 100644 --- a/ignite/services/plugin/template/go.mod.plush +++ b/ignite/services/plugin/template/go.mod.plush @@ -4,5 +4,5 @@ go 1.21 require ( github.com/hashicorp/go-plugin v1.4.9 - github.com/ignite/cli v0.26.2-0.20230504112712-4324e2ff958f -) \ No newline at end of file + github.com/ignite/cli v0.27.2-0.20230905140057-d3918a77b607 +) diff --git a/ignite/services/plugin/template/main.go.plush b/ignite/services/plugin/template/main.go.plush index 077f10f250..83181ccd76 100644 --- a/ignite/services/plugin/template/main.go.plush +++ b/ignite/services/plugin/template/main.go.plush @@ -1,7 +1,7 @@ package main import ( - "encoding/gob" + "context" "fmt" "path/filepath" @@ -11,55 +11,56 @@ import ( "github.com/ignite/cli/ignite/services/plugin" ) -func init() { - gob.Register(plugin.Manifest{}) - gob.Register(plugin.ExecutedCommand{}) - gob.Register(plugin.ExecutedHook{}) -} - type app struct{} -func (app) Manifest() (plugin.Manifest, error) { - return plugin.Manifest{ +func (app) Manifest(ctx context.Context) (*plugin.Manifest, error) { + return &plugin.Manifest{ Name: "<%= Name %>", - // Add commands here - Commands: []plugin.Command{ + // TODO: Add commands here + Commands: []*plugin.Command{ // Example of a command { Use: "<%= Name %>", Short: "Explain what the command is doing...", Long: "Long description goes here...", - Flags: []plugin.Flag{ + Flags: []*plugin.Flag{ {Name: "my-flag", Type: plugin.FlagTypeString, Usage: "my flag description"}, }, PlaceCommandUnder: "ignite", // Examples of adding subcommands: - /* - Commands: []plugin.Command{ - {Use: "add"}, - {Use: "list"}, - {Use: "delete"}, - }, - */ + // Commands: []*plugin.Command{ + // {Use: "add"}, + // {Use: "list"}, + // {Use: "delete"}, + // }, }, }, - // Add hooks here - Hooks: []plugin.Hook{}, + // TODO: Add hooks here + Hooks: []*plugin.Hook{}, SharedHost: <%= SharedHost %>, }, nil } -func (app) Execute(cmd plugin.ExecutedCommand) error { +func (app) Execute(ctx context.Context, cmd *plugin.ExecutedCommand, api plugin.ClientAPI) error { // TODO: write command execution here - fmt.Printf("Hello I'm the <%= Name %> plugin\n") + fmt.Printf("Hello I'm the example-plugin plugin\n") fmt.Printf("My executed command: %q\n", cmd.Path) fmt.Printf("My args: %v\n", cmd.Args) - myFlag, _ := cmd.Flags().GetString("my-flag") + + flags, err := cmd.NewFlags() + if err != nil { + return err + } + + myFlag, _ := flags.GetString("my-flag") fmt.Printf("My flags: my-flag=%q\n", myFlag) fmt.Printf("My config parameters: %v\n", cmd.With) // This is how the plugin can access the chain: // c, err := getChain(cmd) + // if err != nil { + // return err + // } // According to the number of declared commands, you may need a switch: /* @@ -72,28 +73,37 @@ func (app) Execute(cmd plugin.ExecutedCommand) error { fmt.Println("Deleting stuff...") } */ + + // ClientAPI call example + fmt.Println(api.GetChainInfo(ctx)) + return nil } -func (app) ExecuteHookPre(hook plugin.ExecutedHook) error { - fmt.Printf("Executing hook pre %q\n", hook.Name) +func (app) ExecuteHookPre(ctx context.Context, h *plugin.ExecutedHook, api plugin.ClientAPI) error { + fmt.Printf("Executing hook pre %q\n", h.Hook.GetName()) return nil } -func (app) ExecuteHookPost(hook plugin.ExecutedHook) error { - fmt.Printf("Executing hook post %q\n", hook.Name) +func (app) ExecuteHookPost(ctx context.Context, h *plugin.ExecutedHook, api plugin.ClientAPI) error { + fmt.Printf("Executing hook post %q\n", h.Hook.GetName()) return nil } -func (app) ExecuteHookCleanUp(hook plugin.ExecutedHook) error { - fmt.Printf("Executing hook cleanup %q\n", hook.Name) +func (app) ExecuteHookCleanUp(ctx context.Context, h *plugin.ExecutedHook, api plugin.ClientAPI) error { + fmt.Printf("Executing hook cleanup %q\n", h.Hook.GetName()) return nil } -func getChain(cmd plugin.ExecutedCommand, chainOption ...chain.Option) (*chain.Chain, error) { +func getChain(cmd *plugin.ExecutedCommand, chainOption ...chain.Option) (*chain.Chain, error) { + flags, err := cmd.NewFlags() + if err != nil { + return nil, err + } + var ( - home, _ = cmd.Flags().GetString("home") - path, _ = cmd.Flags().GetString("path") + home, _ = flags.GetString("home") + path, _ = flags.GetString("path") ) if home != "" { chainOption = append(chainOption, chain.HomePath(home)) @@ -106,12 +116,11 @@ func getChain(cmd plugin.ExecutedCommand, chainOption ...chain.Option) (*chain.C } func main() { - pluginMap := map[string]hplugin.Plugin{ - "<%= Name %>": &plugin.InterfacePlugin{Impl: &app{}}, - } - hplugin.Serve(&hplugin.ServeConfig{ HandshakeConfig: plugin.HandshakeConfig(), - Plugins: pluginMap, + Plugins: map[string]hplugin.Plugin{ + "<%= Name %>": plugin.NewGRPC(&app{}), + }, + GRPCServer: hplugin.DefaultGRPCServer, }) } diff --git a/integration/plugin/plugin_test.go b/integration/plugin/plugin_test.go index 813af11180..9f0fe6268e 100644 --- a/integration/plugin/plugin_test.go +++ b/integration/plugin/plugin_test.go @@ -1,6 +1,7 @@ package plugin_test import ( + "path/filepath" "testing" "github.com/stretchr/testify/assert" @@ -14,11 +15,10 @@ import ( func TestAddRemovePlugin(t *testing.T) { var ( - require = require.New(t) - assert = assert.New(t) - env = envtest.New(t) - app = env.Scaffold("github.com/test/blog") - pluginRepo = "github.com/ignite/example-plugin" + require = require.New(t) + assert = assert.New(t) + env = envtest.New(t) + app = env.Scaffold("github.com/test/blog") assertPlugins = func(expectedLocalPlugins, expectedGlobalPlugins []pluginsconfig.Plugin) { localCfg, err := pluginsconfig.ParseDir(app.SourcePath()) @@ -36,7 +36,11 @@ func TestAddRemovePlugin(t *testing.T) { // no plugins expected assertPlugins(nil, nil) - env.Must(env.Exec("install plugin locally", + // Note: Originally plugin repo was "github.com/ignite/example-plugin" instead of a local one + pluginRepo, err := filepath.Abs("testdata/example-plugin") + require.NoError(err) + + env.Must(env.Exec("add plugin locally", step.NewSteps(step.New( step.Exec(envtest.IgniteApp, "app", "install", pluginRepo, "k1=v1", "k2=v2"), step.Workdir(app.SourcePath()), diff --git a/integration/plugin/testdata/example-plugin/go.mod b/integration/plugin/testdata/example-plugin/go.mod new file mode 100644 index 0000000000..70704d2477 --- /dev/null +++ b/integration/plugin/testdata/example-plugin/go.mod @@ -0,0 +1,82 @@ +module example-plugin + +go 1.20 + +require ( + github.com/hashicorp/go-plugin v1.4.9 + github.com/ignite/cli v0.27.1 +) + +require ( + github.com/Microsoft/go-winio v0.6.1 // indirect + github.com/ProtonMail/go-crypto v0.0.0-20230518184743-7afd39499903 // indirect + github.com/acomagu/bufpipe v1.0.4 // indirect + github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect + github.com/aymerick/douceur v0.2.0 // indirect + github.com/charmbracelet/lipgloss v0.6.0 // indirect + github.com/cloudflare/circl v1.3.3 // 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/go-git/gcfg v1.5.0 // indirect + github.com/go-git/go-billy/v5 v5.4.1 // indirect + github.com/go-git/go-git/v5 v5.6.1 // 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.3 // 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.16 // indirect + github.com/gobuffalo/tags/v3 v3.1.4 // indirect + github.com/gobuffalo/validate/v3 v3.3.3 // indirect + github.com/gofrs/uuid v4.3.0+incompatible // indirect + github.com/golang/protobuf v1.5.3 // indirect + github.com/gorilla/css v1.0.0 // indirect + github.com/hashicorp/go-hclog v1.2.0 // indirect + github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb // indirect + github.com/imdario/mergo v0.3.15 // 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/lucasb-eyer/go-colorful v1.2.0 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.19 // indirect + github.com/mattn/go-runewidth v0.0.14 // indirect + github.com/microcosm-cc/bluemonday v1.0.20 // indirect + github.com/mitchellh/go-testing-interface v1.14.1 // indirect + github.com/muesli/reflow v0.3.0 // indirect + github.com/muesli/termenv v0.15.1 // indirect + github.com/oklog/run v1.0.0 // indirect + github.com/pjbgf/sha1cd v0.3.0 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/rivo/uniseg v0.4.4 // indirect + github.com/sergi/go-diff v1.3.1 // indirect + github.com/sirupsen/logrus v1.9.2 // indirect + github.com/skeema/knownhosts v1.1.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.7.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.7 // indirect + golang.org/x/crypto v0.9.0 // indirect + golang.org/x/exp v0.0.0-20230519143937-03e91628a987 // indirect + golang.org/x/mod v0.10.0 // indirect + golang.org/x/net v0.10.0 // indirect + golang.org/x/sync v0.2.0 // indirect + golang.org/x/sys v0.8.0 // indirect + golang.org/x/term v0.8.0 // indirect + golang.org/x/text v0.9.0 // indirect + golang.org/x/tools v0.9.1 // indirect + google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect + google.golang.org/grpc v1.55.0 // indirect + google.golang.org/protobuf v1.30.0 // indirect + gopkg.in/warnings.v0 v0.1.2 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect +) + +replace ( + github.com/ignite/cli => ../../../../ +) diff --git a/integration/plugin/testdata/example-plugin/go.sum b/integration/plugin/testdata/example-plugin/go.sum new file mode 100644 index 0000000000..56b88f4cac --- /dev/null +++ b/integration/plugin/testdata/example-plugin/go.sum @@ -0,0 +1,288 @@ +github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= +github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= +github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= +github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8/go.mod h1:I0gYDMZ6Z5GRU7l58bNFSkPTFN6Yl12dsUlAZ8xy98g= +github.com/ProtonMail/go-crypto v0.0.0-20230518184743-7afd39499903 h1:ZK3C5DtzV2nVAQTx5S5jQvMeDqWtD1By5mOoyY/xJek= +github.com/ProtonMail/go-crypto v0.0.0-20230518184743-7afd39499903/go.mod h1:8TI4H3IbrackdNgv+92dI+rhpCaLqM0IfpgCgenFvRE= +github.com/acomagu/bufpipe v1.0.4 h1:e3H4WUzM3npvo5uv95QuJM3cQspFNtFBzvJ2oNjKIDQ= +github.com/acomagu/bufpipe v1.0.4/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4= +github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= +github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= +github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= +github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= +github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= +github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= +github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA= +github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= +github.com/charmbracelet/lipgloss v0.6.0 h1:1StyZB9vBSOyuZxQUcUwGr17JmojPNm87inij9N3wJY= +github.com/charmbracelet/lipgloss v0.6.0/go.mod h1:tHh2wr34xcHjC2HCXIlGSG1jaDF0S0atAUvBMP6Ppuk= +github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtMxxK7fi4I= +github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs= +github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= +github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= +github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= +github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= +github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= +github.com/gliderlabs/ssh v0.3.5 h1:OcaySEmAQJgyYcArR+gGGTHCyE7nvhEMTlYY+Dp8CpY= +github.com/gliderlabs/ssh v0.3.5/go.mod h1:8XB4KraRrX39qHhT6yxPsHedjA08I/uBVwj4xC+/+z4= +github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4= +github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= +github.com/go-git/go-billy/v5 v5.3.1/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= +github.com/go-git/go-billy/v5 v5.4.1 h1:Uwp5tDRkPr+l/TnbHOQzp+tmJfLceOlbVucgpTz8ix4= +github.com/go-git/go-billy/v5 v5.4.1/go.mod h1:vjbugF6Fz7JIflbVpl1hJsGjSHNltrSw45YK/ukIvQg= +github.com/go-git/go-git-fixtures/v4 v4.3.1 h1:y5z6dd3qi8Hl+stezc8p3JxDkoTRqMAlKnXHuzrfjTQ= +github.com/go-git/go-git-fixtures/v4 v4.3.1/go.mod h1:8LHG1a3SRW71ettAD/jW13h8c6AqjVSeL11RAdgaqpo= +github.com/go-git/go-git/v5 v5.6.1 h1:q4ZRqQl4pR/ZJHc1L5CFjGA1a10u76aV1iC+nh+bHsk= +github.com/go-git/go-git/v5 v5.6.1/go.mod h1:mvyoL6Unz0PiTQrGQfSfiLFhBH1c1e84ylC2MDs4ee8= +github.com/gobuffalo/flect v0.3.0 h1:erfPWM+K1rFNIQeRPdeEXxo8yFr/PO17lhRnS8FUrtk= +github.com/gobuffalo/flect v0.3.0/go.mod h1:5pf3aGnsvqvCj50AVni7mJJF8ICxGZ8HomberC3pXLE= +github.com/gobuffalo/genny/v2 v2.1.0 h1:cCRBbqzo3GfNvj3UetD16zRgUvWFEyyl0qTqquuIqOM= +github.com/gobuffalo/genny/v2 v2.1.0/go.mod h1:4yoTNk4bYuP3BMM6uQKYPvtP6WsXFGm2w2EFYZdRls8= +github.com/gobuffalo/github_flavored_markdown v1.1.3 h1:rSMPtx9ePkFB22vJ+dH+m/EUBS8doQ3S8LeEXcdwZHk= +github.com/gobuffalo/github_flavored_markdown v1.1.3/go.mod h1:IzgO5xS6hqkDmUh91BW/+Qxo/qYnvfzoz3A7uLkg77I= +github.com/gobuffalo/helpers v0.6.7 h1:C9CedoRSfgWg2ZoIkVXgjI5kgmSpL34Z3qdnzpfNVd8= +github.com/gobuffalo/helpers v0.6.7/go.mod h1:j0u1iC1VqlCaJEEVkZN8Ia3TEzfj/zoXANqyJExTMTA= +github.com/gobuffalo/logger v1.0.7 h1:LTLwWelETXDYyqF/ASf0nxaIcdEOIJNxRokPcfI/xbU= +github.com/gobuffalo/logger v1.0.7/go.mod h1:u40u6Bq3VVvaMcy5sRBclD8SXhBYPS0Qk95ubt+1xJM= +github.com/gobuffalo/packd v1.0.2 h1:Yg523YqnOxGIWCp69W12yYBKsoChwI7mtu6ceM9Bwfw= +github.com/gobuffalo/packd v1.0.2/go.mod h1:sUc61tDqGMXON80zpKGp92lDb86Km28jfvX7IAyxFT8= +github.com/gobuffalo/plush/v4 v4.1.16 h1:Y6jVVTLdg1BxRXDIbTJz+J8QRzEAtv5ZwYpGdIFR7VU= +github.com/gobuffalo/plush/v4 v4.1.16/go.mod h1:6t7swVsarJ8qSLw1qyAH/KbrcSTwdun2ASEQkOznakg= +github.com/gobuffalo/tags/v3 v3.1.4 h1:X/ydLLPhgXV4h04Hp2xlbI2oc5MDaa7eub6zw8oHjsM= +github.com/gobuffalo/tags/v3 v3.1.4/go.mod h1:ArRNo3ErlHO8BtdA0REaZxijuWnWzF6PUXngmMXd2I0= +github.com/gobuffalo/validate/v3 v3.3.3 h1:o7wkIGSvZBYBd6ChQoLxkz2y1pfmhbI4jNJYh6PuNJ4= +github.com/gobuffalo/validate/v3 v3.3.3/go.mod h1:YC7FsbJ/9hW/VjQdmXPvFqvRis4vrRYFxr69WiNZw6g= +github.com/gofrs/uuid v4.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gofrs/uuid v4.3.0+incompatible h1:CaSVZxm5B+7o45rtab4jC2G37WGYX1zQfuU2i6DSvnc= +github.com/gofrs/uuid v4.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY= +github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c= +github.com/hashicorp/go-hclog v1.2.0 h1:La19f8d7WIlm4ogzNHB0JGqs5AUDAZ2UfCY4sJXcJdM= +github.com/hashicorp/go-hclog v1.2.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= +github.com/hashicorp/go-plugin v1.4.9 h1:ESiK220/qE0aGxWdzKIvRH69iLiuN/PjoLTm69RoWtU= +github.com/hashicorp/go-plugin v1.4.9/go.mod h1:viDMjcLJuDui6pXb8U4HVfb8AamCWhHGUjr2IrTF67s= +github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb h1:b5rjCoWHc7eqmAS4/qyk21ZsHyb6Mxv/jykxvNTkU4M= +github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= +github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= +github.com/imdario/mergo v0.3.15 h1:M8XP7IuFNsqUx6VPK2P9OSmsYsI/YFaGil0uD21V3dM= +github.com/imdario/mergo v0.3.15/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= +github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= +github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c= +github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= +github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= +github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= +github.com/matryer/is v1.2.0 h1:92UTHpy8CDwaJ08GqLDzhhuixiBUUD1p3AU6PHddz4A= +github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA= +github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= +github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= +github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= +github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/microcosm-cc/bluemonday v1.0.20 h1:flpzsq4KU3QIYAYGV/szUat7H+GPOXR0B2JU5A1Wp8Y= +github.com/microcosm-cc/bluemonday v1.0.20/go.mod h1:yfBmMi8mxvaZut3Yytv+jTXRY8mxyjJ0/kQBTElld50= +github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU= +github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= +github.com/mmcloughlin/avo v0.5.0/go.mod h1:ChHFdoV7ql95Wi7vuq2YT1bwCJqiWdZrQ1im3VujLYM= +github.com/muesli/reflow v0.2.1-0.20210115123740-9e1d0d53df68/go.mod h1:Xk+z4oIWdQqJzsxyjgl3P22oYZnHdZ8FFTHAQQt5BMQ= +github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s= +github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8= +github.com/muesli/termenv v0.11.1-0.20220204035834-5ac8409525e0/go.mod h1:Bd5NYQ7pd+SrtBSrSNoBBmXlcY8+Xj4BMJgh8qcZrvs= +github.com/muesli/termenv v0.15.1 h1:UzuTb/+hhlBugQz28rpzey4ZuKcZ03MeKsoG7IJZIxs= +github.com/muesli/termenv v0.15.1/go.mod h1:HeAQPTzpfs016yGtA4g00CsdYnVLJvxsS4ANqrZs2sQ= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= +github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= +github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= +github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= +github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= +github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/sirupsen/logrus v1.9.2 h1:oxx1eChJGI6Uks2ZC4W1zpLlVgqB8ner4EuQwV4Ik1Y= +github.com/sirupsen/logrus v1.9.2/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/skeema/knownhosts v1.1.0/go.mod h1:sKFq3RD6/TKZkSWn8boUbDC7Qkgcv+8XXijpFO6roag= +github.com/skeema/knownhosts v1.1.1 h1:MTk78x9FPgDFVFkDLTrsnnfCJl7g1C/nnKvePgrIngE= +github.com/skeema/knownhosts v1.1.1/go.mod h1:g4fPeYpque7P0xefxtGzV81ihjC8sX2IqpAoNkjxbMo= +github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d h1:yKm7XZV6j9Ev6lojP2XaIshpT4ymkqhMeSghO5Ps00E= +github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE= +github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e h1:qpG93cPwA5f7s/ZPBJnGOYQNK/vKsaDaseuKT5Asee8= +github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA= +github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= +github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= +github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ= +go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= +golang.org/x/arch v0.1.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= +golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= +golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= +golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= +golang.org/x/exp v0.0.0-20230519143937-03e91628a987 h1:3xJIFvzUFbu4ls0BTBYcgbCGhA63eAOEMxIHugyXJqA= +golang.org/x/exp v0.0.0-20230519143937-03e91628a987/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= +golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.0.0-20221002022538-bcab6841153b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI= +golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.0.0-20220722155259-a9ba230a4035/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.9.1 h1:8WMNJAz3zrtPmnYC7ISf5dEn3MT0gY7jBJfw27yrrLo= +golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A= +google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= +google.golang.org/grpc v1.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag= +google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= diff --git a/integration/plugin/testdata/example-plugin/main.go b/integration/plugin/testdata/example-plugin/main.go new file mode 100644 index 0000000000..4a8b177bf4 --- /dev/null +++ b/integration/plugin/testdata/example-plugin/main.go @@ -0,0 +1,74 @@ +package main + +import ( + "context" + "fmt" + + hplugin "github.com/hashicorp/go-plugin" + + "github.com/ignite/cli/ignite/services/plugin" +) + +type p struct{} + +func (p) Manifest(context.Context) (*plugin.Manifest, error) { + return &plugin.Manifest{ + Name: "example-plugin", + Commands: []*plugin.Command{ + { + Use: "example-plugin", + Short: "Explain what the command is doing...", + Long: "Long description goes here...", + Flags: []*plugin.Flag{ + {Name: "my-flag", Type: plugin.FlagTypeString, Usage: "my flag description"}, + }, + PlaceCommandUnder: "ignite", + }, + }, + Hooks: []*plugin.Hook{}, + }, nil +} + +func (p) Execute(ctx context.Context, cmd *plugin.ExecutedCommand, api plugin.ClientAPI) error { + fmt.Printf("Hello I'm the example-plugin plugin\n") + fmt.Printf("My executed command: %q\n", cmd.Path) + fmt.Printf("My args: %v\n", cmd.Args) + + flags, err := cmd.NewFlags() + if err != nil { + return err + } + + myFlag, _ := flags.GetString("my-flag") + fmt.Printf("My flags: my-flag=%q\n", myFlag) + fmt.Printf("My config parameters: %v\n", cmd.With) + + fmt.Println(api.GetChainInfo(ctx)) + + return nil +} + +func (p) ExecuteHookPre(_ context.Context, h *plugin.ExecutedHook, _ plugin.ClientAPI) error { + fmt.Printf("Executing hook pre %q\n", h.Hook.GetName()) + return nil +} + +func (p) ExecuteHookPost(_ context.Context, h *plugin.ExecutedHook, _ plugin.ClientAPI) error { + fmt.Printf("Executing hook post %q\n", h.Hook.GetName()) + return nil +} + +func (p) ExecuteHookCleanUp(_ context.Context, h *plugin.ExecutedHook, _ plugin.ClientAPI) error { + fmt.Printf("Executing hook cleanup %q\n", h.Hook.GetName()) + return nil +} + +func main() { + hplugin.Serve(&hplugin.ServeConfig{ + HandshakeConfig: plugin.HandshakeConfig(), + Plugins: map[string]hplugin.Plugin{ + "example-plugin": plugin.NewGRPC(&p{}), + }, + GRPCServer: hplugin.DefaultGRPCServer, + }) +} diff --git a/proto/buf.gen.yaml b/proto/buf.gen.yaml new file mode 100644 index 0000000000..36d3d55811 --- /dev/null +++ b/proto/buf.gen.yaml @@ -0,0 +1,8 @@ +version: v1 +plugins: +- plugin: buf.build/protocolbuffers/go + out: . + opt: paths=source_relative +- plugin: buf.build/grpc/go + out: . + opt: paths=source_relative diff --git a/proto/buf.md b/proto/buf.md new file mode 100644 index 0000000000..00a7d287b3 --- /dev/null +++ b/proto/buf.md @@ -0,0 +1,3 @@ +# Protobufs + +This is the public protocol buffers API for [Ignite CLI](https://github.com/ignite/cli). diff --git a/proto/buf.yaml b/proto/buf.yaml new file mode 100644 index 0000000000..faea9af67b --- /dev/null +++ b/proto/buf.yaml @@ -0,0 +1,15 @@ +version: v1 +name: buf.build/ignitehq/cli +breaking: + use: + - FILE +lint: + use: + - DEFAULT + - FILE_LOWER_SNAKE_CASE + except: + - UNARY_RPC + - COMMENT_FIELD + - SERVICE_SUFFIX + - PACKAGE_VERSION_SUFFIX + - RPC_REQUEST_STANDARD_NAME diff --git a/proto/ignite/services/plugin/grpc/v1/client_api.proto b/proto/ignite/services/plugin/grpc/v1/client_api.proto new file mode 100644 index 0000000000..d7b76c7bc0 --- /dev/null +++ b/proto/ignite/services/plugin/grpc/v1/client_api.proto @@ -0,0 +1,12 @@ +syntax = "proto3"; + +package ignite.services.plugin.grpc.v1; + +option go_package = "github.com/ignite/cli/ignite/services/plugin/grpc/v1"; + +message ChainInfo { + string chain_id = 1; + string app_path = 2; + string config_path = 3; + string rpc_address = 4; +} diff --git a/proto/ignite/services/plugin/grpc/v1/interface.proto b/proto/ignite/services/plugin/grpc/v1/interface.proto new file mode 100644 index 0000000000..5dcaef4209 --- /dev/null +++ b/proto/ignite/services/plugin/grpc/v1/interface.proto @@ -0,0 +1,147 @@ +syntax = "proto3"; + +package ignite.services.plugin.grpc.v1; + +option go_package = "github.com/ignite/cli/ignite/services/plugin/grpc/v1"; + +// ExecutedCommand represents a plugin command under execution. +message ExecutedCommand { + // Use is the one-line usage message. + string use = 1; + + // Path contains the command path, e.g. `ignite scaffold foo`. + string path = 2; + + // Args are the command arguments. + repeated string args = 3; + + // Full list of args taken from the command line. + repeated string os_args = 4; + + // With contains the plugin config parameters. + map with = 5; + + // Flags holds the list of command flags. + repeated Flag flags = 6; +} + +// ExecutedHook represents a plugin hook under execution. +message ExecutedHook { + // Hook is a copy of the original Hook defined in the Manifest. + Hook hook = 1; + + // ExecutedCommand gives access to the command attached by the hook. + ExecutedCommand executed_command = 2; +} + +// Manifest represents the plugin behavior. +message Manifest { + // Plugin name. + string name = 1; + + // Commands contains the commands that will be added to the list of ignite commands. + // Each commands are independent, for nested commands use the inner Commands field. + bool shared_host = 2; + + // Hooks contains the hooks that will be attached to the existing ignite commands. + repeated Command commands = 3; + + // Enables sharing a single plugin server across all running instances of a plugin. + // Useful if a plugin adds or extends long running commands. + // + // Example: if a plugin defines a hook on `ignite chain serve`, a plugin server is + // instanciated when the command is run. Now if you want to interact with that instance + // from commands defined in that plugin, you need to enable shared host, or else the + // commands will just instantiate separate plugin servers. + // + // When enabled, all plugins of the same path loaded from the same configuration will + // attach it's RPC client to a an existing RPC server. + // + // If a plugin instance has no other running plugin servers, it will create one and it + // will be the host. + repeated Hook hooks = 4; +} + +// Command represents a plugin command. +message Command { + // Use is the one-line usage message. + // + // Recommended syntax is as follow: + // [ ] identifies an optional argument. Arguments that are not enclosed in brackets are required. + // ... indicates that you can specify multiple values for the previous argument. + // | indicates mutually exclusive information. You can use the argument to the left of the separator or the + // argument to the right of the separator. You cannot use both arguments in a single use of the command. + // { } delimits a set of mutually exclusive arguments when one of the arguments is required. If the arguments are + // optional, they are enclosed in brackets ([ ]). + // + // Example: add [-F file | -D dir]... [-f format] profile + string use = 1; + + // Aliases is an array of aliases that can be used instead of the first word in Use. + repeated string aliases = 2; + + // Short is the short description shown in the 'help' output. + string short = 3; + + // Long is the long message shown in the 'help ' output. + string long = 4; + + // Hidden defines, if this command is hidden and should NOT show up in the list of available commands. + bool hidden = 5; + + // Flags holds the list of command flags. + repeated Flag flags = 6; + + // Indicates where the command should be placed. + // For instance `ignite scaffold` will place the command at the `scaffold` command. + // An empty value is interpreted as `ignite` (==root). + string place_command_under = 7; + + // List of sub commands. + repeated Command commands = 8; +} + +// Flag represents of a command line flag. +message Flag { + // Type represents the flag type. + enum Type { + TYPE_FLAG_STRING_UNSPECIFIED = 0; + TYPE_FLAG_INT = 1; + TYPE_FLAG_UINT = 2; + TYPE_FLAG_INT64 = 3; + TYPE_FLAG_UINT64 = 4; + TYPE_FLAG_BOOL = 5; + TYPE_FLAG_STRING_SLICE = 6; + } + + // Name as it appears in the command line. + string name = 1; + + // One letter abbreviation of the flag. + string shorthand = 2; + + // Help message. + string usage = 3; + + // Default flag value. + string default_value = 4; + + // Flag type. + Type type = 5; + + // Flag value. + string value = 6; + + // Indicates wether or not the flag is propagated on children commands. + bool persistent = 7; +} + +// Hook represents a user defined action within a plugin. +message Hook { + // Identifies the hook for the client to invoke the correct hook. + // It must be unique. + string name = 1; + + // Indicates the command where to register the hooks. + string place_hook_on = 2; +} diff --git a/proto/ignite/services/plugin/grpc/v1/service.proto b/proto/ignite/services/plugin/grpc/v1/service.proto new file mode 100644 index 0000000000..e35d89f2f5 --- /dev/null +++ b/proto/ignite/services/plugin/grpc/v1/service.proto @@ -0,0 +1,84 @@ +syntax = "proto3"; + +package ignite.services.plugin.grpc.v1; + +import "ignite/services/plugin/grpc/v1/client_api.proto"; +import "ignite/services/plugin/grpc/v1/interface.proto"; + +option go_package = "github.com/ignite/cli/ignite/services/plugin/grpc/v1"; + +// InterfaceService defines the interface that must be implemented by all plugins. +service InterfaceService { + // Manifest declares the plugin's Command(s) and Hook(s). + rpc Manifest(ManifestRequest) returns (ManifestResponse); + + // Execute will be invoked by ignite when a plugin Command is executed. + // It is global for all commands declared in Manifest, if you have declared + // multiple commands, use cmd.Path to distinguish them. + rpc Execute(ExecuteRequest) returns (ExecuteResponse); + + // ExecuteHookPre is invoked by ignite when a command specified by the Hook + // path is invoked. + // It is global for all hooks declared in Manifest, if you have declared + // multiple hooks, use hook.Name to distinguish them. + rpc ExecuteHookPre(ExecuteHookPreRequest) returns (ExecuteHookPreResponse); + + // ExecuteHookPost is invoked by ignite when a command specified by the hook + // path is invoked. + // It is global for all hooks declared in Manifest, if you have declared + // multiple hooks, use hook.Name to distinguish them. + rpc ExecuteHookPost(ExecuteHookPostRequest) returns (ExecuteHookPostResponse); + + // ExecuteHookCleanUp is invoked by ignite when a command specified by the + // hook path is invoked. Unlike ExecuteHookPost, it is invoked regardless of + // execution status of the command and hooks. + // It is global for all hooks declared in Manifest, if you have declared + // multiple hooks, use hook.Name to distinguish them. + rpc ExecuteHookCleanUp(ExecuteHookCleanUpRequest) returns (ExecuteHookCleanUpResponse); +} + +message ManifestRequest {} + +message ManifestResponse { + Manifest manifest = 1; +} + +message ExecuteRequest { + ExecutedCommand cmd = 1; + uint32 client_api = 2; +} + +message ExecuteResponse {} + +message ExecuteHookPreRequest { + ExecutedHook hook = 1; + uint32 client_api = 2; +} + +message ExecuteHookPreResponse {} + +message ExecuteHookPostRequest { + ExecutedHook hook = 1; + uint32 client_api = 2; +} + +message ExecuteHookPostResponse {} + +message ExecuteHookCleanUpRequest { + ExecutedHook hook = 1; + uint32 client_api = 2; +} + +message ExecuteHookCleanUpResponse {} + +// ClientAPIService defines the interface that allows plugins to get chain app analysis info. +service ClientAPIService { + // GetChainInfo returns basic chain info for the configured app + rpc GetChainInfo(GetChainInfoRequest) returns (GetChainInfoResponse); +} + +message GetChainInfoRequest {} + +message GetChainInfoResponse { + ChainInfo chain_info = 1; +}