Add four new infrastructure packages with CLI commands: - pkg/config: layered configuration (defaults → file → env → flags) - pkg/crypt: crypto primitives (Argon2id, AES-GCM, ChaCha20, HMAC, checksums) - pkg/plugin: plugin system with GitHub-based install/update/remove - pkg/collect: collection subsystem (GitHub, BitcoinTalk, market, papers, excavate) Fix all golangci-lint issues across the entire codebase (~100 errcheck, staticcheck SA1012/SA1019/ST1005, unused, ineffassign fixes) so that `core go qa` passes with 0 issues. Closes #167, #168, #170, #250, #251, #252, #253, #254, #255, #256 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
61 lines
1.5 KiB
Go
61 lines
1.5 KiB
Go
package plugin
|
|
|
|
import (
|
|
"context"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"github.com/host-uk/core/pkg/cli"
|
|
"github.com/host-uk/core/pkg/i18n"
|
|
"github.com/host-uk/core/pkg/io"
|
|
"github.com/host-uk/core/pkg/plugin"
|
|
)
|
|
|
|
func addInstallCommand(parent *cli.Command) {
|
|
installCmd := cli.NewCommand(
|
|
"install <source>",
|
|
i18n.T("Install a plugin from GitHub"),
|
|
i18n.T("Install a plugin from a GitHub repository.\n\nSource format: org/repo or org/repo@version"),
|
|
func(cmd *cli.Command, args []string) error {
|
|
return runInstall(args[0])
|
|
},
|
|
)
|
|
installCmd.Args = cli.ExactArgs(1)
|
|
installCmd.Example = " core plugin install host-uk/core-plugin-example\n core plugin install host-uk/core-plugin-example@v1.0.0"
|
|
|
|
parent.AddCommand(installCmd)
|
|
}
|
|
|
|
func runInstall(source string) error {
|
|
basePath, err := pluginBasePath()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
registry := plugin.NewRegistry(io.Local, basePath)
|
|
if err := registry.Load(); err != nil {
|
|
return err
|
|
}
|
|
|
|
installer := plugin.NewInstaller(io.Local, registry)
|
|
|
|
cli.Dim("Installing plugin from " + source + "...")
|
|
|
|
if err := installer.Install(context.Background(), source); err != nil {
|
|
return err
|
|
}
|
|
|
|
_, repo, _, _ := plugin.ParseSource(source)
|
|
cli.Success("Plugin " + repo + " installed successfully")
|
|
|
|
return nil
|
|
}
|
|
|
|
// pluginBasePath returns the default plugin directory (~/.core/plugins/).
|
|
func pluginBasePath() (string, error) {
|
|
home, err := os.UserHomeDir()
|
|
if err != nil {
|
|
return "", cli.Wrap(err, "failed to determine home directory")
|
|
}
|
|
return filepath.Join(home, ".core", "plugins"), nil
|
|
}
|