feat: migrate to golang

This commit is contained in:
2026-07-19 20:01:38 +08:00
parent 302d4e6bb5
commit a2630df9e0
69 changed files with 4750 additions and 3369 deletions

85
internal/cli/root.go Normal file
View File

@ -0,0 +1,85 @@
// Package cli wires up the ss command-line interface, mirroring cli.py's
// argparse-based command tree with cobra.
package cli
import (
"fmt"
"os"
"github.com/spf13/cobra"
"gitea.epss.net.cn/klesh/ss/internal/core"
"gitea.epss.net.cn/klesh/ss/internal/corecfg"
"gitea.epss.net.cn/klesh/ss/internal/hook"
"gitea.epss.net.cn/klesh/ss/internal/storage"
"gitea.epss.net.cn/klesh/ss/internal/subscription"
)
// managers bundles the manager instances every command needs, mirroring the
// set built unconditionally in cli.py's main().
type managers struct {
Storage *storage.Manager
Subscription *subscription.Manager
CoreConfig *corecfg.Manager
Core *core.Manager
Hook *hook.Manager
}
// newManagers builds the full manager stack. configFile/outputFile/
// subscriptionName are only ever non-empty when the "config" command tree
// supplies its persistent flags, matching cli.py's main() which populates
// CoreConfigManager from args.config_file/output_file/subscription
// regardless of which subcommand is running (those attributes simply don't
// exist on the namespace for other subcommands).
func newManagers(configFile, outputFile, subscriptionName string) (*managers, error) {
s, err := storage.New()
if err != nil {
return nil, fmt.Errorf("failed to initialize storage: %w", err)
}
subMgr, err := subscription.New(s)
if err != nil {
return nil, fmt.Errorf("failed to initialize subscription manager: %w", err)
}
coreCfgMgr, err := corecfg.New(subMgr, configFile, outputFile, subscriptionName)
if err != nil {
return nil, fmt.Errorf("failed to initialize core config manager: %w", err)
}
coreMgr := core.New(coreCfgMgr)
hookMgr := hook.New(s)
return &managers{
Storage: s,
Subscription: subMgr,
CoreConfig: coreCfgMgr,
Core: coreMgr,
Hook: hookMgr,
}, nil
}
// Execute runs the ss CLI. It is the Go equivalent of cli.py's main().
func Execute() {
root := &cobra.Command{
Use: "ss",
Short: "Scientific Surfing - CLI for managing clash RSS subscriptions",
SilenceUsage: true,
SilenceErrors: true,
}
root.AddCommand(
newSubscriptionCmd(),
newCoreCmd(),
newConfigCmd(),
newServiceCmd(),
newHookCmd(),
)
if err := root.Execute(); err != nil {
if _, silent := err.(*silentError); !silent {
fmt.Printf("❌ Error: %v\n", err)
}
os.Exit(1)
}
}