Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: separate plugins.yml file #3184

Merged
merged 44 commits into from
Nov 30, 2022
Merged
Show file tree
Hide file tree
Changes from 32 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
d4ca56b
base
Nov 28, 2022
93c1ad5
base refactor
Nov 28, 2022
ee162da
refactor
Nov 28, 2022
8303068
rename
Nov 28, 2022
6565fc5
rename
Nov 28, 2022
863876f
fix comment
Nov 28, 2022
eaccb71
rename file
Nov 28, 2022
c490fa5
format
Nov 28, 2022
844c83b
refactor base
Nov 28, 2022
82e9ac0
format
Nov 28, 2022
a8592a5
refactor some imports
Nov 28, 2022
1d5bd3e
imports refactor
Nov 28, 2022
15e543a
fix
Nov 28, 2022
2cf58e4
fix import
Nov 28, 2022
4d986c3
Merge branch 'main' into feat/plugins-refacotr
Nov 28, 2022
5f8c837
refactor:
Nov 28, 2022
1459f1c
changelog
Nov 28, 2022
365df2d
Merge branch 'main' into feat/separate-plugins-config
Nov 28, 2022
ea5434a
changelog
Nov 28, 2022
1a3167e
Update ignite/services/network/networkchain/init.go
Nov 28, 2022
0ad9f3d
base -> baseconfig
Nov 28, 2022
360bc17
refactoring for clarity
Nov 28, 2022
71a75aa
v12 -> v1
Nov 28, 2022
9b89846
fix tests
Nov 28, 2022
a69a758
fix integration
Nov 28, 2022
f74180a
fix name
Nov 28, 2022
b57ac11
fix integration
Nov 28, 2022
6d081b6
Merge branch 'main' into feat/plugins-refacotr
Nov 28, 2022
7408d51
merge
Nov 28, 2022
db2ed00
format
Nov 28, 2022
1620580
merge main
Nov 28, 2022
8d24282
Merge branch 'main' into feat/separate-plugins-config
Nov 28, 2022
a40d3dc
Update ignite/cmd/cmd.go
Nov 29, 2022
e685899
imports
Nov 29, 2022
aa57e74
Merge branch 'main' into feat/separate-plugins-config
Nov 29, 2022
5c429be
LocateDefault logic
Nov 29, 2022
a6c78e9
lint fix
Nov 29, 2022
f0bde05
Merge branch 'main' into feat/separate-plugins-config
Nov 29, 2022
54e7fe3
refactor and test
Nov 29, 2022
39e92e7
finish refactor
Nov 29, 2022
9f10308
revert
Nov 29, 2022
b0e3722
Merge branch 'main' into feat/separate-plugins-config
Nov 30, 2022
631d64e
address review
Nov 30, 2022
e2d5f56
testdata
Nov 30, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

### Features

- [#3184](https://github.com/ignite/cli/pull/3184) Separate `plugins.yml` config file.
- [#3038](https://github.com/ignite/cli/pull/3038) Addition of Plugin Hooks in Plugin System
- [#3056](https://github.com/ignite/cli/pull/3056) Add `--genesis-config` flag option to `ignite network chain publish`
- [#2892](https://github.com/ignite/cli/pull/2982/) Add `ignite scaffold react` command.
Expand Down
13 changes: 13 additions & 0 deletions ignite/cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const (
flagYes = "yes"
flagClearCache = "clear-cache"
flagSkipProto = "skip-proto"
flagPlugins = "plugins"

checkVersionTimeout = time.Millisecond * 600
cacheFileName = "ignite_cache.db"
Expand Down Expand Up @@ -81,6 +82,7 @@ To get started, create a blockchain:
c.AddCommand(NewVersion())
c.AddCommand(NewPlugin())
c.AddCommand(deprecated()...)
c.PersistentFlags().AddFlagSet(flagSetPlugins())

return c
}
Expand Down Expand Up @@ -130,6 +132,17 @@ func getConfig(cmd *cobra.Command) (config string) {
return
}

func flagSetPlugins() *flag.FlagSet {
fs := flag.NewFlagSet("", flag.ContinueOnError)
fs.StringP(flagPlugins, "x", "", "Ignite plugins file (default: ./plugins.yml)")
aljo242 marked this conversation as resolved.
Show resolved Hide resolved
return fs
}

func getPlugins(cmd *cobra.Command) (config string) {
config, _ = cmd.Flags().GetString(flagPlugins)
return
}

func flagSetYes() *flag.FlagSet {
fs := flag.NewFlagSet("", flag.ContinueOnError)
fs.BoolP(flagYes, "y", false, "answers interactive yes/no questions with yes")
Expand Down
18 changes: 15 additions & 3 deletions ignite/cmd/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@ import (
"strings"
"time"

"github.com/ignite/cli/ignite/config"
aljo242 marked this conversation as resolved.
Show resolved Hide resolved

"github.com/pkg/errors"
"github.com/spf13/cobra"

pluginsconfig "github.com/ignite/cli/ignite/config/plugins"
"github.com/ignite/cli/ignite/pkg/cliui"
"github.com/ignite/cli/ignite/pkg/xgit"
"github.com/ignite/cli/ignite/services/plugin"
Expand All @@ -27,18 +30,27 @@ const (
// If no configuration found, it returns w/o error.
func LoadPlugins(ctx context.Context, rootCmd *cobra.Command) error {
// NOTE(tb) Not sure if it's the right place to load this.
aljo242 marked this conversation as resolved.
Show resolved Hide resolved
chain, err := newChainWithHomeFlags(rootCmd)
cfg, err := parseLocalPlugins(rootCmd)
tbruyelle marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
// Binary is run outside of an chain app, plugins can't be loaded
// if binary is run where there is no plugin.yml, don't load
return nil
}
plugins, err = plugin.Load(ctx, chain)

// TODO: parse global config
jeronimoalbi marked this conversation as resolved.
Show resolved Hide resolved

plugins, err = plugin.Load(ctx, cfg)
if err != nil {
return err
}
return loadPlugins(rootCmd, plugins)
}

func parseLocalPlugins(rootCmd *cobra.Command) (*pluginsconfig.Config, error) {
pluginsPath := getPlugins(rootCmd)

return config.ParsePluginsFile(pluginsPath)
}

func loadPlugins(rootCmd *cobra.Command, plugins []*plugin.Plugin) error {
// Link plugins to related commands
var loadErrors []string
Expand Down
2 changes: 1 addition & 1 deletion ignite/cmd/plugin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"

"github.com/ignite/cli/ignite/config"
config "github.com/ignite/cli/ignite/config/plugins"
aljo242 marked this conversation as resolved.
Show resolved Hide resolved
"github.com/ignite/cli/ignite/services/plugin"
"github.com/ignite/cli/ignite/services/plugin/mocks"
)
Expand Down
24 changes: 0 additions & 24 deletions ignite/config/chain/v1/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,30 +23,6 @@ type Config struct {
base.Config `yaml:",inline"`

Validators []Validator `yaml:"validators"`
Plugins []Plugin `yaml:"plugins,omitempty"`
}

// Plugin keeps plugin name and location.
type Plugin struct {
// Path holds the location of the plugin.
// A path can be local, in that case it must start with a `/`.
// A remote path on the other hand, is an URL to a public remote git
// repository. For example:
//
// path: github.com/foo/bar
//
// It can contain a path inside that repository, if for instance the repo
// contains multiple plugins, For example:
//
// path: github.com/foo/bar/plugin1
//
// It can also specify a tag or a branch, by adding a `@` and the branch/tag
// name at the end of the path. For example:
//
// path: github.com/foo/bar/plugin1@v42
Path string `yaml:"path"`
// With holds arguments passed to the plugin interface
With map[string]string `yaml:"with"`
}

func (c *Config) SetDefaults() error {
Expand Down
9 changes: 0 additions & 9 deletions ignite/config/chain/v1/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,15 +73,6 @@ func TestConfigDecode(t *testing.T) {
},
},
}},
Plugins: []v1.Plugin{
{
Path: "/path/to/plugin1",
},
{
Path: "/path/to/plugin2",
With: map[string]string{"foo": "bar", "bar": "baz"},
},
},
}
assert.Equal(expected, cfg)
}
Expand Down
36 changes: 31 additions & 5 deletions ignite/config/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,14 @@ import (
"gopkg.in/yaml.v2"

chainconfig "github.com/ignite/cli/ignite/config/chain"
"github.com/ignite/cli/ignite/config/plugins"
)

// Parse reads a config file.
// When the version of the file being read is not the latest
// it is automatically migrated to the latest version.
func Parse(configFile io.Reader) (*ChainConfig, error) {
cfg, err := parse(configFile)
cfg, err := parseChainConfig(configFile)
if err != nil {
return cfg, fmt.Errorf("error parsing config file: %w", err)
}
Expand All @@ -28,15 +29,20 @@ func Parse(configFile io.Reader) (*ChainConfig, error) {
// When the version of the file being read is not the latest
// it is automatically migrated to the latest version.
func ParseNetwork(configFile io.Reader) (*ChainConfig, error) {
cfg, err := parse(configFile)
cfg, err := parseChainConfig(configFile)
if err != nil {
return cfg, err
}

return cfg, validateNetworkConfig(cfg)
}

func parse(configFile io.Reader) (*ChainConfig, error) {
// ParsePlugins reads a config file for ignite binary plugins
func ParsePlugins(configFile io.Reader) (*plugins.Config, error) {
return parsePluginsConfig(configFile)
}

func parseChainConfig(configFile io.Reader) (*ChainConfig, error) {
var buf bytes.Buffer

// Read the config file version first to know how to decode it
Expand All @@ -47,7 +53,7 @@ func parse(configFile io.Reader) (*ChainConfig, error) {

// Decode the current config file version and assign default
// values for the fields that are empty
c, err := decodeConfig(&buf, version)
c, err := decodeChainConfig(&buf, version)
if err != nil {
return DefaultChainConfig(), err
}
Expand All @@ -67,6 +73,14 @@ func parse(configFile io.Reader) (*ChainConfig, error) {
return cfg, nil
}

func parsePluginsConfig(configFile io.Reader) (*plugins.Config, error) {
var c plugins.Config

err := yaml.NewDecoder(configFile).Decode(&c)

return &c, err
}

// ParseFile parses a config from a file path.
func ParseFile(path string) (*ChainConfig, error) {
file, err := os.Open(path)
Expand All @@ -91,6 +105,18 @@ func ParseNetworkFile(path string) (*ChainConfig, error) {
return ParseNetwork(file)
}

// ParsePluginsFile parses a plugins config.
func ParsePluginsFile(path string) (*plugins.Config, error) {
file, err := os.Open(path)
if err != nil {
return plugins.DefaultConfig(), err
}

defer file.Close()

return ParsePlugins(file)
}

// ReadConfigVersion reads the config version.
func ReadConfigVersion(configFile io.Reader) (chainconfig.Version, error) {
c := struct {
Expand All @@ -102,7 +128,7 @@ func ReadConfigVersion(configFile io.Reader) (chainconfig.Version, error) {
return c.Version, err
}

func decodeConfig(r io.Reader, version chainconfig.Version) (chainconfig.Converter, error) {
func decodeChainConfig(r io.Reader, version chainconfig.Version) (chainconfig.Converter, error) {
c, ok := Versions[version]
if !ok {
return nil, &UnsupportedVersionError{version}
Expand Down
56 changes: 56 additions & 0 deletions ignite/config/plugins/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package plugins

import (
"io"

"github.com/imdario/mergo"
"gopkg.in/yaml.v2"
)

// DefaultConfig returns a config with default values.
func DefaultConfig() *Config {
c := Config{}
return &c
}

type Config struct {
Plugins []Plugin `yaml:"plugins,omitempty"`
}

// Plugin keeps plugin name and location.
type Plugin struct {
// Path holds the location of the plugin.
// A path can be local, in that case it must start with a `/`.
// A remote path on the other hand, is an URL to a public remote git
// repository. For example:
//
// path: github.com/foo/bar
//
// It can contain a path inside that repository, if for instance the repo
// contains multiple plugins, For example:
//
// path: github.com/foo/bar/plugin1
//
// It can also specify a tag or a branch, by adding a `@` and the branch/tag
// name at the end of the path. For example:
//
// path: github.com/foo/bar/plugin1@v42
Path string `yaml:"path"`
// With holds arguments passed to the plugin interface
With map[string]string `yaml:"with"`
}

// Clone returns an identical copy of the instance
func (c *Config) Clone() (*Config, error) {
copy := Config{}
if err := mergo.Merge(&copy, c, mergo.WithAppendSlice); err != nil {
return nil, err
}

return &copy, nil
}

// Decode decodes the config file values from YAML.
func (c *Config) Decode(r io.Reader) error {
return yaml.NewDecoder(r).Decode(c)
}
36 changes: 36 additions & 0 deletions ignite/config/plugins/config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package plugins_test

import (
"os"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/ignite/cli/ignite/config/plugins"
)

func TestConfigDecode(t *testing.T) {
assert := assert.New(t)
require := require.New(t)
f, err := os.Open("testdata/plugins.yml")
require.NoError(err)
defer f.Close()
var cfg plugins.Config

err = cfg.Decode(f)

require.NoError(err)
expected := plugins.Config{
Plugins: []plugins.Plugin{
{
Path: "/path/to/plugin1",
},
{
Path: "/path/to/plugin2",
With: map[string]string{"foo": "bar", "bar": "baz"},
},
},
}
assert.Equal(expected, cfg)
}
8 changes: 8 additions & 0 deletions ignite/config/plugins/testdata/plugins.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
plugins:
- name: plugin1
path: /path/to/plugin1
- name: plugin2
path: /path/to/plugin2
with:
foo: bar
bar: baz
6 changes: 0 additions & 6 deletions ignite/config/pluginsconfig.go

This file was deleted.

Loading