verstak-desktop/internal/core/plugin/dirs.go

72 lines
1.7 KiB
Go

package plugin
import (
"os"
"path/filepath"
"strings"
)
// DirResolveOptions makes plugin directory resolution testable.
type DirResolveOptions struct {
EnvPluginDir string
CWD string
ExecutablePath string
UserConfigDir string
HomeDir string
}
// ResolveDiscoveryDirs returns plugin discovery directories in priority order:
// explicit env override, dev ./plugins, packaged binary-adjacent plugins, user plugins.
func ResolveDiscoveryDirs(opts DirResolveOptions) []string {
var dirs []string
add := func(path string) {
if path == "" {
return
}
cleaned := filepath.Clean(path)
for _, existing := range dirs {
if existing == cleaned {
return
}
}
dirs = append(dirs, cleaned)
}
if opts.EnvPluginDir != "" {
for _, path := range filepath.SplitList(opts.EnvPluginDir) {
add(path)
}
}
if opts.CWD != "" {
add(filepath.Join(opts.CWD, "plugins"))
}
if opts.ExecutablePath != "" {
add(filepath.Join(filepath.Dir(opts.ExecutablePath), "plugins"))
}
if opts.UserConfigDir != "" {
add(filepath.Join(opts.UserConfigDir, "verstak", "plugins"))
} else if opts.HomeDir != "" {
add(filepath.Join(opts.HomeDir, ".config", "verstak", "plugins"))
}
return dirs
}
// DefaultDiscoveryDirs resolves discovery directories from the current process.
func DefaultDiscoveryDirs() []string {
cwd, _ := os.Getwd()
exe, _ := os.Executable()
userConfig, _ := os.UserConfigDir()
home, _ := os.UserHomeDir()
return ResolveDiscoveryDirs(DirResolveOptions{
EnvPluginDir: strings.TrimSpace(os.Getenv("VERSTAK_PLUGIN_DIR")),
CWD: cwd,
ExecutablePath: exe,
UserConfigDir: userConfig,
HomeDir: home,
})
}