[teamai] Push 87 resource(s) from XingfenD

This commit is contained in:
2026-09-10 16:10:45 +08:00
parent 425c9c078a
commit 65c04def51
1314 changed files with 211681 additions and 0 deletions
@@ -0,0 +1,41 @@
package main
import (
"fmt"
"github.com/spf13/cobra"
)
// Cobra provides built-in validators for positional arguments.
// See the table in SKILL.md for all available validators.
var deployCmd = &cobra.Command{
Use: "deploy [environment]",
Short: "Deploy to an environment",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
env := args[0]
_ = env
// deploy...
return nil
},
}
// Custom validation example:
var deployWithValidationCmd = &cobra.Command{
Use: "deploy [environment]",
Short: "Deploy to an environment",
Args: func(cmd *cobra.Command, args []string) error {
if len(args) != 1 {
return fmt.Errorf("expected exactly 1 argument, got %d", len(args))
}
valid := map[string]bool{"dev": true, "staging": true, "prod": true}
if !valid[args[0]] {
return fmt.Errorf("invalid environment %q, must be one of: dev, staging, prod", args[0])
}
return nil
},
RunE: func(cmd *cobra.Command, args []string) error {
// deploy...
return nil
},
}
@@ -0,0 +1,58 @@
package main
import (
"bytes"
"testing"
"github.com/spf13/cobra"
)
// Test commands by executing them programmatically and capturing output.
// Use cmd.OutOrStdout() and cmd.ErrOrStderr() in commands (instead of
// os.Stdout / os.Stderr) so output can be captured in tests.
func executeCommand(root *cobra.Command, args ...string) (string, error) {
buf := new(bytes.Buffer)
root.SetOut(buf)
root.SetErr(buf)
root.SetArgs(args)
err := root.Execute()
return buf.String(), err
}
func TestServeCommand(t *testing.T) {
tests := []struct {
name string
args []string
want string
wantErr bool
}{
{
name: "default port",
args: []string{"serve"},
want: "listening on :8080\n",
},
{
name: "custom port",
args: []string{"serve", "--port", "9090"},
want: "listening on :9090\n",
},
{
name: "missing required flag",
args: []string{"serve", "--host", ""},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := executeCommand(rootCmd, tt.args...)
if (err != nil) != tt.wantErr {
t.Errorf("error = %v, wantErr %v", err, tt.wantErr)
}
if !tt.wantErr && got != tt.want {
t.Errorf("output = %q, want %q", got, tt.want)
}
})
}
}
@@ -0,0 +1,58 @@
package main
import (
"os"
"github.com/spf13/cobra"
)
// === Shell Completion Command ===
// Cobra generates completions for bash, zsh, fish, and PowerShell automatically.
func init() {
rootCmd.AddCommand(&cobra.Command{
Use: "completion [bash|zsh|fish|powershell]",
Short: "Generate shell completion script",
Args: cobra.ExactValidArgs(1),
ValidArgs: []string{"bash", "zsh", "fish", "powershell"},
RunE: func(cmd *cobra.Command, args []string) error {
switch args[0] {
case "bash":
return rootCmd.GenBashCompletionV2(os.Stdout, true)
case "zsh":
return rootCmd.GenZshCompletion(os.Stdout)
case "fish":
return rootCmd.GenFishCompletion(os.Stdout, true)
case "powershell":
return rootCmd.GenPowerShellCompletionWithDesc(os.Stdout)
}
return nil
},
})
}
// === Custom Completions ===
// Add custom completions for flags and arguments.
func customCompletionExamples() {
deployCmd.RegisterFlagCompletionFunc("env", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
return []string{
"dev\tDevelopment environment",
"staging\tStaging environment",
"prod\tProduction environment",
}, cobra.ShellCompDirectiveNoFileComp
})
// Dynamic argument completion
deployCmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if len(args) != 0 {
return nil, cobra.ShellCompDirectiveNoFileComp
}
return getAvailableServices(), cobra.ShellCompDirectiveNoFileComp
}
}
func getAvailableServices() []string {
// fetch available services dynamically
return nil
}
@@ -0,0 +1,71 @@
package main
import (
"fmt"
"log/slog"
"os"
"strings"
"github.com/fsnotify/fsnotify"
"github.com/spf13/viper"
)
// === Complete Cobra + Viper Integration ===
func initConfigComplete() error {
// 1. Config file
if cfgFile != "" {
viper.SetConfigFile(cfgFile) // explicit path
} else {
home, _ := os.UserHomeDir()
viper.AddConfigPath(home) // search $HOME
viper.AddConfigPath(".") // search current dir
viper.SetConfigName(".myapp")
viper.SetConfigType("yaml")
}
// 2. Environment variables
viper.SetEnvPrefix("MYAPP") // MYAPP_PORT, MYAPP_LOG_LEVEL
viper.SetEnvKeyReplacer(strings.NewReplacer("-", "_")) // log-level → MYAPP_LOG_LEVEL
viper.AutomaticEnv() // bind all env vars automatically
// 3. Read config file (ignore "not found")
if err := viper.ReadInConfig(); err != nil {
if _, ok := err.(viper.ConfigFileNotFoundError); !ok {
return fmt.Errorf("reading config: %w", err)
}
}
return nil
}
// === Unmarshaling into Structs ===
type Config struct {
Port int `mapstructure:"port"`
Host string `mapstructure:"host"`
LogLevel string `mapstructure:"log-level"`
Database struct {
DSN string `mapstructure:"dsn"`
MaxConn int `mapstructure:"max-conn"`
} `mapstructure:"database"`
}
func loadConfig() (Config, error) {
var cfg Config
if err := viper.Unmarshal(&cfg); err != nil {
return Config{}, fmt.Errorf("unmarshaling config: %w", err)
}
return cfg, nil
}
// === Watching Config File Changes ===
// For long-running CLIs (servers, daemons):
func watchConfig() {
viper.OnConfigChange(func(e fsnotify.Event) {
slog.Info("config file changed", "file", e.Name)
// re-read and apply config
})
viper.WatchConfig()
}
@@ -0,0 +1,28 @@
package main
import (
"errors"
"os"
"github.com/you/myapp/cmd"
)
// Pattern for mapping errors to exit codes.
func mainWithExitCodes() {
if err := cmd.Execute(); err != nil {
// Cobra already printed the error via RunE
var exitErr *ExitError
if errors.As(err, &exitErr) {
os.Exit(exitErr.Code)
}
os.Exit(1)
}
}
type ExitError struct {
Code int
Err error
}
func (e *ExitError) Error() string { return e.Err.Error() }
func (e *ExitError) Unwrap() error { return e.Err }
@@ -0,0 +1,41 @@
package main
import (
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
func flagExamples() {
// === Persistent vs Local ===
// Persistent — inherited by all subcommands
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file path")
// Local — only for this command
serveCmd.Flags().IntP("port", "p", 8080, "port to listen on")
// === Required Flags ===
serveCmd.Flags().String("host", "", "hostname to bind to")
serveCmd.MarkFlagRequired("host")
// Mutually exclusive flags
rootCmd.MarkFlagsMutuallyExclusive("json", "yaml")
// At least one required
rootCmd.MarkFlagsOneRequired("output-file", "stdout")
// === Flag Validation with RegisterFlagCompletionFunc ===
serveCmd.Flags().String("env", "dev", "environment (dev, staging, prod)")
serveCmd.RegisterFlagCompletionFunc("env", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
return []string{"dev", "staging", "prod"}, cobra.ShellCompDirectiveNoFileComp
})
// === Always Bind Flags to Viper ===
// This ensures viper.GetInt("port") returns the flag value, env var MYAPP_PORT,
// or config file value — whichever has highest precedence.
serveCmd.Flags().IntP("port", "p", 8080, "port to listen on")
viper.BindPFlag("port", serveCmd.Flags().Lookup("port"))
}
@@ -0,0 +1,12 @@
// cmd/myapp/main.go
package main
import (
"os"
)
func main() {
if err := Execute(); err != nil {
os.Exit(1)
}
}
@@ -0,0 +1,75 @@
package main
import (
"encoding/json"
"fmt"
"os"
"text/tabwriter"
"github.com/fatih/color"
"github.com/spf13/cobra"
)
// === stdout vs stderr ===
// stdout: Program output (data, results). This is what gets piped.
// stderr: Logs, progress, errors, diagnostics. Not piped by default.
func outputExample(cmd *cobra.Command, result string, err error) {
// Output data to stdout (pipeable)
fmt.Fprintln(cmd.OutOrStdout(), result)
// Logs and errors to stderr (use slog)
// slog.Error("operation failed", "error", err)
}
// === Detecting Pipe vs Terminal ===
func isTerminal() bool {
fi, err := os.Stdout.Stat()
if err != nil {
return false
}
return fi.Mode()&os.ModeCharDevice != 0
}
// === Machine-Readable Output ===
// Support --output flag for different output formats.
type User struct {
ID string
Name string
}
func printUsers(cmd *cobra.Command, users []User) error {
format, _ := cmd.Flags().GetString("output")
switch format {
case "json":
enc := json.NewEncoder(cmd.OutOrStdout())
enc.SetIndent("", " ")
return enc.Encode(users)
case "plain":
for _, u := range users {
fmt.Fprintf(cmd.OutOrStdout(), "%s\t%s\n", u.ID, u.Name)
}
default: // "table"
w := tabwriter.NewWriter(cmd.OutOrStdout(), 0, 0, 2, ' ', 0)
fmt.Fprintln(w, "ID\tNAME")
for _, u := range users {
fmt.Fprintf(w, "%s\t%s\n", u.ID, u.Name)
}
w.Flush()
}
return nil
}
// === Colors ===
// Use fatih/color — it auto-disables when output is not a terminal.
func colorExamples(cmd *cobra.Command, env string, err error) {
color.Green("Success: deployed to %s", env)
color.Red("Error: %v", err)
// Or for reusable styles
success := color.New(color.FgGreen, color.Bold).SprintFunc()
fmt.Fprintf(cmd.OutOrStdout(), "%s deployed\n", success("v1.2.3"))
}
@@ -0,0 +1,74 @@
// cmd/myapp/root.go
package main
import (
"fmt"
"log/slog"
"os"
"strings"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
var cfgFile string
var rootCmd = &cobra.Command{
Use: "myapp",
Short: "A brief description of your application",
Long: "A longer description with usage examples.",
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
return initConfig()
},
SilenceUsage: true, // don't print usage on errors from RunE
SilenceErrors: true, // handle error printing yourself
}
func Execute() error {
return rootCmd.Execute()
}
func init() {
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default $HOME/.myapp.yaml)")
rootCmd.PersistentFlags().String("log-level", "info", "log level (debug, info, warn, error)")
viper.BindPFlag("log-level", rootCmd.PersistentFlags().Lookup("log-level"))
}
func initConfig() error {
if cfgFile != "" {
viper.SetConfigFile(cfgFile)
} else {
home, err := os.UserHomeDir()
if err != nil {
return fmt.Errorf("finding home directory: %w", err)
}
viper.AddConfigPath(home)
viper.AddConfigPath(".")
viper.SetConfigName(".myapp")
viper.SetConfigType("yaml")
}
viper.SetEnvPrefix("MYAPP")
viper.SetEnvKeyReplacer(strings.NewReplacer("-", "_"))
viper.AutomaticEnv()
if err := viper.ReadInConfig(); err != nil {
if _, ok := err.(viper.ConfigFileNotFoundError); !ok {
return fmt.Errorf("reading config: %w", err)
}
}
// Set up logging based on config
level := slog.LevelInfo
switch strings.ToLower(viper.GetString("log-level")) {
case "debug":
level = slog.LevelDebug
case "warn":
level = slog.LevelWarn
case "error":
level = slog.LevelError
}
slog.SetDefault(slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{Level: level})))
return nil
}
@@ -0,0 +1,31 @@
// cmd/myapp/serve.go
package main
import (
"fmt"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
var serveCmd = &cobra.Command{
Use: "serve",
Short: "Start the HTTP server",
RunE: func(cmd *cobra.Command, args []string) error {
port := viper.GetInt("port")
fmt.Fprintf(cmd.OutOrStdout(), "listening on :%d\n", port)
// start server...
return nil
},
}
func init() {
rootCmd.AddCommand(serveCmd)
serveCmd.Flags().IntP("port", "p", 8080, "port to listen on")
viper.BindPFlag("port", serveCmd.Flags().Lookup("port"))
}
// For command groups, use AddGroup and set GroupID on commands:
//
// rootCmd.AddGroup(&cobra.Group{ID: "management", Title: "Management Commands:"})
// serveCmd.GroupID = "management"
@@ -0,0 +1,38 @@
package main
import (
"context"
"fmt"
"log/slog"
"net/http"
"os"
"os/signal"
"syscall"
"time"
"github.com/spf13/cobra"
)
// Use signal.NotifyContext to propagate cancellation through context.
var serveWithSignalCmd = &cobra.Command{
Use: "serve",
Short: "Start the server",
RunE: func(cmd *cobra.Command, args []string) error {
ctx, stop := signal.NotifyContext(cmd.Context(), os.Interrupt, syscall.SIGTERM)
defer stop()
srv := &http.Server{Addr: ":8080"}
go func() {
<-ctx.Done()
shutdownCtx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
srv.Shutdown(shutdownCtx)
}()
slog.Info("server starting", "addr", srv.Addr)
if err := srv.ListenAndServe(); err != http.ErrServerClosed {
return fmt.Errorf("server failed: %w", err)
}
return nil
},
}
@@ -0,0 +1,39 @@
// cmd/myapp/version.go
package main
import (
"fmt"
"runtime/debug"
"github.com/spf13/cobra"
)
// Set via ldflags
var (
version = "dev"
commit = "unknown"
date = "unknown"
)
var versionCmd = &cobra.Command{
Use: "version",
Short: "Print version information",
Run: func(cmd *cobra.Command, args []string) {
fmt.Fprintf(cmd.OutOrStdout(), "myapp %s (commit: %s, built: %s)\n", version, commit, date)
if info, ok := debug.ReadBuildInfo(); ok {
fmt.Fprintf(cmd.OutOrStdout(), "go: %s\n", info.GoVersion)
}
},
}
func init() {
rootCmd.AddCommand(versionCmd)
}
// Build with:
//
// go build -ldflags "-X github.com/you/myapp/cmd/myapp.version=1.2.3 \
// -X github.com/you/myapp/cmd/myapp.commit=$(git rev-parse --short HEAD) \
// -X github.com/you/myapp/cmd/myapp.date=$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
// -o bin/myapp ./cmd/myapp