package cmd import ( "bytes" "encoding/json" "fmt" "os" "os/exec" "path/filepath" "strings" "github.com/spf13/cobra" ) // Config holds Gitea connection details stored in ~/.gtea.json type Config struct { URL string `json:"url"` Token string `json:"token"` Username string `json:"username"` } var rootCmd = &cobra.Command{ Use: "gtea", Short: "Gitea project and repo manager", Long: "gtea — create Gitea repos, commit, push, and pull without leaving the terminal.", } func Execute() { if err := rootCmd.Execute(); err != nil { os.Exit(1) } } func init() { rootCmd.AddCommand(configCmd) rootCmd.AddCommand(initCmd) rootCmd.AddCommand(commitCmd) rootCmd.AddCommand(pushCmd) rootCmd.AddCommand(pullCmd) rootCmd.AddCommand(statusCmd) } func configPath() string { home, _ := os.UserHomeDir() return filepath.Join(home, ".gtea.json") } func loadConfig() (*Config, error) { data, err := os.ReadFile(configPath()) if err != nil { return nil, fmt.Errorf("no config found — run 'gtea config' first") } var cfg Config if err := json.Unmarshal(data, &cfg); err != nil { return nil, fmt.Errorf("invalid config: %w", err) } if cfg.URL == "" || cfg.Token == "" || cfg.Username == "" { return nil, fmt.Errorf("incomplete config — run 'gtea config' to fill in missing fields") } return &cfg, nil } func saveConfig(cfg *Config) error { data, err := json.MarshalIndent(cfg, "", " ") if err != nil { return err } return os.WriteFile(configPath(), data, 0600) } // runGit runs a git command in dir (use "." for current directory). func runGit(dir string, args ...string) error { c := exec.Command("git", args...) c.Dir = dir c.Stdout = os.Stdout c.Stderr = os.Stderr if err := c.Run(); err != nil { return fmt.Errorf("git %s: %w", strings.Join(args, " "), err) } return nil } // currentBranch returns the name of the currently checked-out branch. func currentBranch() (string, error) { out, err := exec.Command("git", "rev-parse", "--abbrev-ref", "HEAD").Output() if err != nil { return "", err } return string(bytes.TrimSpace(out)), nil } // authCloneURL injects token credentials into an HTTPS clone URL. func authCloneURL(cfg *Config, cloneURL string) string { if strings.HasPrefix(cloneURL, "https://") { return strings.Replace( cloneURL, "https://", fmt.Sprintf("https://%s:%s@", cfg.Username, cfg.Token), 1, ) } return cloneURL }