summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-05-29 09:55:12 +0300
committerPaul Buetow <paul@buetow.org>2026-05-29 09:55:12 +0300
commit90e3fc07894c754364809c4733e403bf4fdeb484 (patch)
treedba3e2d2297686c90b077b2734f3c5d9ea9a1e47
parent820c24ffb8bfdd2cd7cba1a5d599cbd6d092ad81 (diff)
refactor(cli): remove dead legacy flag layer (rq)
-rw-r--r--doc/api-reference.md23
-rw-r--r--doc/development.md26
-rw-r--r--internal/cli/flags.go76
-rw-r--r--internal/cli/handlers.go98
-rw-r--r--internal/cli/sync_handlers.go10
5 files changed, 12 insertions, 221 deletions
diff --git a/doc/api-reference.md b/doc/api-reference.md
index c189e99..b7ed2f8 100644
--- a/doc/api-reference.md
+++ b/doc/api-reference.md
@@ -24,7 +24,7 @@ The main package provides the application entry point.
#### func main()
Application entry point that:
-- Parses command-line flags
+- Initializes Cobra commands
- Routes to appropriate handlers
- Manages exit codes
@@ -60,36 +60,18 @@ type Flags struct {
### Functions
-#### func ParseFlags() *Flags
-Parses command-line arguments and returns a Flags struct with all options.
-
-#### func HandleVersion() int
-Displays version information and returns exit code 0.
-
#### func HandleTestGitHubToken() int
Tests GitHub token authentication:
- Loads token from config/env/file
- Validates token with API call
- Returns 0 on success, 1 on failure
-#### func LoadConfig(configPath string) (*config.Config, error)
-Loads configuration from specified path or default locations:
-- `./gitsyncer.json`
-- `~/.config/gitsyncer/config.json`
-- `~/.gitsyncer.json`
-
-#### func ShowConfigHelp()
-Displays help for creating configuration files with example.
-
#### func HandleListOrgs(cfg *config.Config) int
Lists all configured organizations from config.
#### func HandleListRepos(cfg *config.Config) int
Lists all configured repositories from config.
-#### func ShowUsage(cfg *config.Config)
-Displays comprehensive usage information.
-
#### func HandleSync(cfg *config.Config, flags *Flags) int
Synchronizes a single repository specified by `--sync` flag.
@@ -102,9 +84,6 @@ Discovers and syncs all public Codeberg repositories to other platforms.
#### func HandleSyncGitHubPublic(cfg *config.Config, flags *Flags) int
Discovers and syncs all public GitHub repositories to other platforms.
-#### func ShowFullSyncMessage()
-Displays information about full sync mode.
-
### Helper Functions (sync_handlers.go)
#### func createGitHubRepoIfNeeded(cfg *config.Config, repoName string) error
diff --git a/doc/development.md b/doc/development.md
index 75274f0..0d80958 100644
--- a/doc/development.md
+++ b/doc/development.md
@@ -300,28 +300,22 @@ test: add integration tests for branch filtering
### Adding a New Command Flag
-1. Add flag in `internal/cli/flags.go`:
+1. Add a Cobra flag on the relevant command in `internal/cmd/*.go`:
```go
- type Flags struct {
- // ... existing flags
- NewFeature bool // Add new flag
- }
-
- func ParseFlags() *Flags {
- flags := &Flags{}
- // ... existing flags
- flag.BoolVar(&flags.NewFeature, "new-feature", false, "Enable new feature")
- }
+ myCmd.Flags().BoolVar(&newFeature, "new-feature", false, "enable new feature")
```
-2. Handle flag in `cmd/gitsyncer/main.go`:
+2. Pass it through `buildFlags()` when a `cli.Flags` value is required:
```go
- if flags.NewFeature {
- os.Exit(cli.HandleNewFeature(cfg, flags))
+ func buildFlags() *cli.Flags {
+ return &cli.Flags{
+ // ... existing fields
+ NewFeature: newFeature,
+ }
}
```
-3. Implement handler in `internal/cli/handlers.go`
+3. Wire behavior in the command `Run` function and/or `internal/cli` handler.
### Adding a New Configuration Option
@@ -442,4 +436,4 @@ GITSYNCER_DEBUG=1 gitsyncer --sync test-repo
```bash
mage buildAll
```
-5. Create GitHub/Codeberg release with binaries \ No newline at end of file
+5. Create GitHub/Codeberg release with binaries
diff --git a/internal/cli/flags.go b/internal/cli/flags.go
index 4e5e617..852551c 100644
--- a/internal/cli/flags.go
+++ b/internal/cli/flags.go
@@ -1,12 +1,6 @@
package cli
-import (
- "flag"
- "os"
- "path/filepath"
-
- "codeberg.org/snonux/gitsyncer/internal/state"
-)
+import "codeberg.org/snonux/gitsyncer/internal/state"
// Flags holds all command-line flag values
type Flags struct {
@@ -42,71 +36,3 @@ type Flags struct {
BatchRunStateManager *state.Manager
BatchRunState *state.State
}
-
-// ParseFlags parses command-line flags and returns the flags struct
-func ParseFlags() *Flags {
- f := &Flags{}
-
- flag.BoolVar(&f.VersionFlag, "version", false, "print version information")
- flag.BoolVar(&f.VersionFlag, "v", false, "print version information (short)")
- flag.StringVar(&f.ConfigPath, "config", "", "path to configuration file")
- flag.StringVar(&f.ConfigPath, "c", "", "path to configuration file (short)")
- flag.BoolVar(&f.ListOrgs, "list-orgs", false, "list configured organizations")
- flag.BoolVar(&f.ListRepos, "list-repos", false, "list configured repositories")
- flag.StringVar(&f.SyncRepo, "sync", "", "repository name to sync")
- flag.BoolVar(&f.SyncAll, "sync-all", false, "sync all configured repositories")
- flag.BoolVar(&f.SyncCodebergPublic, "sync-codeberg-public", false, "sync all public Codeberg repositories to GitHub")
- flag.BoolVar(&f.SyncGitHubPublic, "sync-github-public", false, "sync all public GitHub repositories to Codeberg")
- flag.BoolVar(&f.FullSync, "full", false, "full bidirectional sync (enables --sync-codeberg-public --sync-github-public --create-github-repos --create-codeberg-repos)")
- flag.BoolVar(&f.CreateGitHubRepos, "create-github-repos", false, "automatically create missing GitHub repositories")
- flag.BoolVar(&f.CreateCodebergRepos, "create-codeberg-repos", false, "automatically create missing Codeberg repositories")
- flag.BoolVar(&f.DryRun, "dry-run", false, "show what would be synced without actually syncing")
- flag.StringVar(&f.WorkDir, "work-dir", "", "working directory for cloning repositories (default: ~/git/gitsyncer-workdir)")
- flag.BoolVar(&f.TestGitHubToken, "test-github-token", false, "test GitHub token authentication")
- flag.BoolVar(&f.Clean, "clean", false, "delete all repositories in work directory (with confirmation)")
- flag.StringVar(&f.DeleteRepo, "delete-repo", "", "delete specified repository from all configured organizations (with confirmation)")
- flag.BoolVar(&f.Backup, "backup", false, "enable syncing to backup locations")
- flag.BoolVar(&f.Showcase, "showcase", false, "generate project showcase using AI (opencode by default) after syncing")
- flag.BoolVar(&f.Force, "force", false, "force operations even when cache or sync interval checks would skip work")
- flag.BoolVar(&f.BatchRun, "batch-run", false, "enable --full and --showcase (runs only once per week)")
- flag.BoolVar(&f.CheckReleases, "check-releases", false, "manually check for version tags without releases and create them (with confirmation)")
- flag.BoolVar(&f.NoCheckReleases, "no-check-releases", false, "disable automatic release checking after sync operations")
- flag.BoolVar(&f.AutoCreateReleases, "auto-create-releases", false, "automatically create releases without confirmation prompts")
- flag.BoolVar(&f.AIReleaseNotes, "ai-release-notes", false, "generate release notes using AI (opencode by default) based on git diff")
- flag.BoolVar(&f.UpdateReleases, "update-releases", false, "update existing releases with new AI-generated notes")
- flag.BoolVar(&f.Throttle, "throttle", false, "enable throttled syncing based on local activity")
-
- flag.Parse()
-
- // Set default WorkDir if not provided
- if f.WorkDir == "" {
- home, err := os.UserHomeDir()
- if err == nil {
- f.WorkDir = filepath.Join(home, "git", "gitsyncer-workdir")
- } else {
- // Fallback if we can't get home directory
- f.WorkDir = ".gitsyncer-work"
- }
- }
-
- // Handle --full flag by enabling all sync operations
- if f.FullSync {
- f.SyncCodebergPublic = true
- f.SyncGitHubPublic = true
- f.CreateGitHubRepos = true
- f.CreateCodebergRepos = true
- }
-
- // Handle --batch-run flag by enabling --full and --showcase
- if f.BatchRun {
- f.FullSync = true
- f.Showcase = true
- // Since we set FullSync, it will trigger the above logic too
- f.SyncCodebergPublic = true
- f.SyncGitHubPublic = true
- f.CreateGitHubRepos = true
- f.CreateCodebergRepos = true
- }
-
- return f
-}
diff --git a/internal/cli/handlers.go b/internal/cli/handlers.go
index 242bc53..e337dc5 100644
--- a/internal/cli/handlers.go
+++ b/internal/cli/handlers.go
@@ -4,20 +4,12 @@ import (
"bufio"
"fmt"
"os"
- "path/filepath"
"strings"
"codeberg.org/snonux/gitsyncer/internal/config"
"codeberg.org/snonux/gitsyncer/internal/github"
- "codeberg.org/snonux/gitsyncer/internal/version"
)
-// HandleVersion prints version information
-func HandleVersion() int {
- fmt.Println(version.GetVersion())
- return 0
-}
-
// HandleTestGitHubToken tests GitHub token authentication
func HandleTestGitHubToken() int {
fmt.Println("Testing GitHub token authentication...")
@@ -45,70 +37,6 @@ func HandleTestGitHubToken() int {
return 0
}
-// LoadConfig loads configuration from the specified path or default locations
-func LoadConfig(configPath string) (*config.Config, error) {
- if configPath == "" {
- configPath = findDefaultConfigPath()
- if configPath == "" {
- return nil, fmt.Errorf("no configuration file found")
- }
- }
-
- fmt.Printf("Loaded configuration from: %s\n", configPath)
- return config.Load(configPath)
-}
-
-// findDefaultConfigPath searches for config file in default locations
-func findDefaultConfigPath() string {
- home, err := os.UserHomeDir()
- if err != nil {
- return ""
- }
-
- // Check common config locations
- configLocations := []string{
- filepath.Join(".", "gitsyncer.json"),
- filepath.Join(home, ".config", "gitsyncer", "config.json"),
- filepath.Join(home, ".gitsyncer.json"),
- }
-
- for _, loc := range configLocations {
- if _, err := os.Stat(loc); err == nil {
- return loc
- }
- }
-
- return ""
-}
-
-// ShowConfigHelp displays help for creating a configuration file
-func ShowConfigHelp() {
- home, _ := os.UserHomeDir()
-
- fmt.Println("No configuration file found. Please create one of:")
- fmt.Printf(" - ./gitsyncer.json\n")
- fmt.Printf(" - %s/.config/gitsyncer/config.json\n", home)
- fmt.Printf(" - %s/.gitsyncer.json\n", home)
- fmt.Println("\nOr specify a config file with --config flag")
- fmt.Println("\nExample configuration:")
- fmt.Println(`{
- "organizations": [
- {"host": "git@github.com", "name": "myorg"},
- {"host": "git@codeberg.org", "name": "myorg"}
- ],
- "repositories": [
- "repo1",
- "repo2"
- ],
- "exclude_branches": [
- "^codex/",
- "^temp-",
- "-wip$"
- ],
- "work_dir": "~/git/gitsyncer-workdir"
-}`)
-}
-
// HandleListOrgs lists configured organizations
func HandleListOrgs(cfg *config.Config) int {
fmt.Println("\nConfigured organizations:")
@@ -131,32 +59,6 @@ func HandleListRepos(cfg *config.Config) int {
return 0
}
-// ShowUsage displays the usage information
-func ShowUsage(cfg *config.Config) {
- fmt.Println("\ngitsyncer - Git repository synchronization tool")
- fmt.Printf("Configured with %d organization(s) and %d repository(ies)\n",
- len(cfg.Organizations), len(cfg.Repositories))
- fmt.Println("\nUsage:")
- fmt.Println(" gitsyncer --sync <repo-name> Sync a specific repository")
- fmt.Println(" gitsyncer --sync-all Sync all configured repositories")
- fmt.Println(" gitsyncer --sync-codeberg-public Sync all public Codeberg repositories to GitHub")
- fmt.Println(" gitsyncer --sync-github-public Sync all public GitHub repositories to Codeberg")
- fmt.Println(" gitsyncer --full Full bidirectional sync of all public repos")
- fmt.Println(" gitsyncer --list-orgs List configured organizations")
- fmt.Println(" gitsyncer --list-repos List configured repositories")
- fmt.Println(" gitsyncer --test-github-token Test GitHub token authentication")
- fmt.Println(" gitsyncer --delete-repo <name> Delete repository from all organizations")
- fmt.Println(" gitsyncer --version Show version information")
- fmt.Println("\nOptions:")
- fmt.Println(" --config <path> Path to configuration file")
- fmt.Println(" --work-dir <path> Working directory for operations (default: ~/git/gitsyncer-workdir)")
- fmt.Println(" --create-github-repos Create missing GitHub repositories automatically")
- fmt.Println(" --create-codeberg-repos Create missing Codeberg repositories (not yet implemented)")
- fmt.Println(" --dry-run Show what would be done without doing it")
- fmt.Println("\nGitHub Token:")
- fmt.Println(" Set via: config file, GITHUB_TOKEN env var, or ~/.gitsyncer_github_token file")
-}
-
// HandleDeleteRepo handles the --delete-repo flag
func HandleDeleteRepo(cfg *config.Config, repoName string) int {
if repoName == "" {
diff --git a/internal/cli/sync_handlers.go b/internal/cli/sync_handlers.go
index 1854b8e..e0c62de 100644
--- a/internal/cli/sync_handlers.go
+++ b/internal/cli/sync_handlers.go
@@ -637,13 +637,3 @@ func syncGitHubRepos(cfg *config.Config, flags *Flags, repos []github.Repository
return 0
}
-
-// ShowFullSyncMessage displays the full sync mode message
-func ShowFullSyncMessage() {
- fmt.Println("Full sync mode enabled:")
- fmt.Println(" - Sync all public Codeberg repos to GitHub")
- fmt.Println(" - Sync all public GitHub repos to Codeberg")
- fmt.Println(" - Create missing GitHub repositories")
- fmt.Println(" - Create missing Codeberg repositories (when implemented)")
- fmt.Println()
-}