tdl/cmd/extension.go

150 lines
3.8 KiB
Go

package cmd
import (
"fmt"
"io"
"os"
"os/exec"
"path/filepath"
"github.com/go-faster/errors"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/iyear/tdl/app/extension"
"github.com/iyear/tdl/core/storage"
extbase "github.com/iyear/tdl/extension"
"github.com/iyear/tdl/pkg/consts"
"github.com/iyear/tdl/pkg/extensions"
"github.com/iyear/tdl/pkg/tclient"
)
func NewExtension(em *extensions.Manager) *cobra.Command {
var dryRun bool
cmd := &cobra.Command{
Use: "extension",
Short: "Manage tdl extensions",
GroupID: groupTools.ID,
Aliases: []string{"extensions", "ext"},
PersistentPreRun: func(cmd *cobra.Command, args []string) {
em.SetDryRun(dryRun)
},
}
cmd.AddCommand(NewExtensionList(em), NewExtensionInstall(em), NewExtensionRemove(em), NewExtensionUpgrade(em))
cmd.PersistentFlags().BoolVar(&dryRun, "dry-run", false, "only print what would be done without actually doing it")
return cmd
}
func NewExtensionList(em *extensions.Manager) *cobra.Command {
cmd := &cobra.Command{
Use: "list",
Short: "List installed extension commands",
Aliases: []string{"ls"},
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
return extension.List(cmd.Context(), em)
},
}
return cmd
}
func NewExtensionInstall(em *extensions.Manager) *cobra.Command {
var force bool
cmd := &cobra.Command{
Use: "install",
Short: "Install a tdl extension",
Args: cobra.MinimumNArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
return extension.Install(cmd.Context(), em, args, force)
},
}
cmd.Flags().BoolVar(&force, "force", false, "force install even if extension already exists")
return cmd
}
func NewExtensionUpgrade(em *extensions.Manager) *cobra.Command {
cmd := &cobra.Command{
Use: "upgrade",
Short: "Upgrade a tdl extension",
RunE: func(cmd *cobra.Command, args []string) error {
return extension.Upgrade(cmd.Context(), em, args)
},
}
return cmd
}
func NewExtensionRemove(em *extensions.Manager) *cobra.Command {
cmd := &cobra.Command{
Use: "remove",
Short: "Remove an installed extension",
Args: cobra.MinimumNArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
return extension.Remove(cmd.Context(), em, args)
},
}
return cmd
}
func NewExtensionCmd(em *extensions.Manager, ext extensions.Extension, stdin io.Reader, stdout, stderr io.Writer) *cobra.Command {
return &cobra.Command{
Use: ext.Name(),
Short: fmt.Sprintf("Extension %s", ext.Name()),
RunE: func(cmd *cobra.Command, args []string) error {
ctx := cmd.Context()
opts, err := tOptions(ctx)
if err != nil {
return errors.Wrap(err, "build telegram options")
}
app, err := tclient.GetApp(opts.KV)
if err != nil {
return errors.Wrap(err, "get app")
}
session, err := storage.NewSession(opts.KV, false).LoadSession(ctx)
if err != nil {
return errors.Wrap(err, "load session")
}
dataDir := filepath.Join(consts.ExtensionsDataPath, ext.Name())
if err = os.MkdirAll(dataDir, 0o755); err != nil {
return errors.Wrap(err, "create extension data dir")
}
env := &extbase.Env{
Name: ext.Name(),
AppID: app.AppID,
AppHash: app.AppHash,
Session: session,
Namespace: viper.GetString(consts.FlagNamespace),
DataDir: dataDir,
NTP: opts.NTP,
Proxy: opts.Proxy,
Pool: viper.GetInt64(consts.FlagPoolSize),
Debug: viper.GetBool(consts.FlagDebug),
}
if err = em.Dispatch(ext, args, env, stdin, stdout, stderr); err != nil {
var execError *exec.ExitError
if errors.As(err, &execError) {
return execError
}
return fmt.Errorf("failed to run extension: %w\n", err)
}
return nil
},
GroupID: groupExtensions.ID,
DisableFlagParsing: true,
}
}