diff --git a/changelog.md b/changelog.md index f27eb40419..d339fa4057 100644 --- a/changelog.md +++ b/changelog.md @@ -7,6 +7,7 @@ - [#4108](https://github.com/ignite/cli/pull/4108) Add `xast` package (cherry-picked from [#3770](https://github.com/ignite/cli/pull/3770)) - [#4110](https://github.com/ignite/cli/pull/4110) Scaffold a consumer chain with `interchain-security` v5.0.0-rc0. - [#4117](https://github.com/ignite/cli/pull/4117) Support relative path when installing local plugins +- [#4117](https://github.com/ignite/cli/pull/4117), [#4125](https://github.com/ignite/cli/pull/4125) Support relative path when installing local plugins ### Changes diff --git a/ignite/config/plugins/config.go b/ignite/config/plugins/config.go index 4e3ec9d494..490ee29a0d 100644 --- a/ignite/config/plugins/config.go +++ b/ignite/config/plugins/config.go @@ -76,6 +76,11 @@ func RemoveDuplicates(plugins []Plugin) (unique []Plugin) { return unique } +// IsLocalPath returns true if the path is a local directory. +func IsLocalPath(path string) bool { + return strings.HasPrefix(path, "/") || strings.HasPrefix(path, ".") || strings.HasPrefix(path, "~") +} + // IsGlobal returns whether the plugin is installed globally or locally for a chain. func (p Plugin) IsGlobal() bool { return p.Global @@ -83,7 +88,7 @@ func (p Plugin) IsGlobal() bool { // IsLocalPath returns true if the plugin path is a local directory. func (p Plugin) IsLocalPath() bool { - return strings.HasPrefix(p.Path, "/") || strings.HasPrefix(p.Path, ".") + return IsLocalPath(p.Path) } // HasPath verifies if a plugin has the given path regardless of version. diff --git a/ignite/services/plugin/plugin.go b/ignite/services/plugin/plugin.go index 7db1b4ef3e..044ea85efd 100644 --- a/ignite/services/plugin/plugin.go +++ b/ignite/services/plugin/plugin.go @@ -142,8 +142,19 @@ func newPlugin(pluginsDir string, cp pluginsconfig.Plugin, options ...Option) *P apply(p) } - if strings.HasPrefix(pluginPath, "/") { - // This is a local plugin, check if the file exists + // This is a local plugin, check if the file exists + if pluginsconfig.IsLocalPath(pluginPath) { + // if directory is relative, make it absolute + if !filepath.IsAbs(pluginPath) { + pluginPathAbs, err := filepath.Abs(pluginPath) + if err != nil { + p.Error = errors.Errorf("failed to get absolute path of %s: %w", pluginPath, err) + return p + } + + pluginPath = pluginPathAbs + } + st, err := os.Stat(pluginPath) if err != nil { p.Error = errors.Wrapf(err, "local app path %q not found", pluginPath) @@ -157,6 +168,7 @@ func newPlugin(pluginsDir string, cp pluginsconfig.Plugin, options ...Option) *P p.name = path.Base(pluginPath) return p } + // This is a remote plugin, parse the URL if i := strings.LastIndex(pluginPath, "@"); i != -1 { // path contains a reference @@ -236,23 +248,6 @@ func (p *Plugin) load(ctx context.Context) { } if p.IsLocalPath() { - // if directory is relative, make it absolute - if !filepath.IsAbs(p.srcPath) { - wd, err := os.Getwd() - if err != nil { - p.Error = errors.Errorf("failed to get working directory: %w", err) - return - } - - srcPathAbs, err := filepath.Abs(p.srcPath) - if err != nil { - p.Error = errors.Errorf("failed to get absolute path of %s: %w", p.srcPath, err) - return - } - - p.srcPath = filepath.Join(wd, srcPathAbs) - } - // trigger rebuild for local plugin if binary is outdated if p.outdatedBinary() { p.build(ctx) diff --git a/ignite/services/plugin/plugin_test.go b/ignite/services/plugin/plugin_test.go index c0a4750f7d..759ef52039 100644 --- a/ignite/services/plugin/plugin_test.go +++ b/ignite/services/plugin/plugin_test.go @@ -67,6 +67,16 @@ func TestNewPlugin(t *testing.T) { stderr: os.Stderr, }, }, + { + name: "ok: relative local plugin", + pluginCfg: pluginsconfig.Plugin{Path: "./testdata"}, + expectedPlugin: Plugin{ + srcPath: path.Join(wd, "testdata"), + name: "testdata", + stdout: os.Stdout, + stderr: os.Stderr, + }, + }, { name: "fail: remote plugin with only domain", pluginCfg: pluginsconfig.Plugin{Path: "github.com"},