summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2025-06-25 22:32:56 +0300
committerPaul Buetow <paul@buetow.org>2025-06-25 22:32:56 +0300
commit7c30b68f29049704c7fafed8015169e9c8047e46 (patch)
tree2c3af6da0e87cec553d0fde02aaf04cb8c2a4e01
parentaf8ab19f5def6f00081b0a6d1e5b20b76683f720 (diff)
feat: add configurable work directory with default ~/git/gitsyncer-workdir
- Add work_dir field to configuration file - Set default work directory to ~/git/gitsyncer-workdir (avoiding conflict with source repo) - Support home directory expansion (~/) in work_dir config - Command-line --work-dir flag takes precedence over config file - Automatically create work directory if it doesn't exist 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
-rw-r--r--cmd/gitsyncer/main.go10
-rw-r--r--gitsyncer.json3
-rw-r--r--internal/cli/flags.go19
-rw-r--r--internal/cli/handlers.go5
-rw-r--r--internal/config/config.go19
5 files changed, 51 insertions, 5 deletions
diff --git a/cmd/gitsyncer/main.go b/cmd/gitsyncer/main.go
index 5175a1f..021d4be 100644
--- a/cmd/gitsyncer/main.go
+++ b/cmd/gitsyncer/main.go
@@ -2,6 +2,7 @@ package main
import (
"os"
+ "path/filepath"
"codeberg.org/snonux/gitsyncer/internal/cli"
)
@@ -32,6 +33,15 @@ func main() {
os.Exit(1)
}
+ // Use config WorkDir only if no flag was explicitly provided
+ // We check if WorkDir matches the default we set in ParseFlags
+ home, _ := os.UserHomeDir()
+ defaultWorkDir := filepath.Join(home, "git", "gitsyncer-workdir")
+ if flags.WorkDir == defaultWorkDir && cfg.WorkDir != "" {
+ // User didn't specify --work-dir, so use config value
+ flags.WorkDir = cfg.WorkDir
+ }
+
// Handle list organizations flag
if flags.ListOrgs {
os.Exit(cli.HandleListOrgs(cfg))
diff --git a/gitsyncer.json b/gitsyncer.json
index 7103d92..caf1c5b 100644
--- a/gitsyncer.json
+++ b/gitsyncer.json
@@ -5,6 +5,7 @@
"name": "snonux"
},
{
+ :
"host": "git@github.com",
"name": "snonux"
}
@@ -13,4 +14,4 @@
"exclude_branches": [
"^codex/"
]
-} \ No newline at end of file
+}
diff --git a/internal/cli/flags.go b/internal/cli/flags.go
index c0320c5..9b8afdc 100644
--- a/internal/cli/flags.go
+++ b/internal/cli/flags.go
@@ -1,6 +1,10 @@
package cli
-import "flag"
+import (
+ "flag"
+ "os"
+ "path/filepath"
+)
// Flags holds all command-line flag values
type Flags struct {
@@ -38,11 +42,22 @@ func ParseFlags() *Flags {
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", ".gitsyncer-work", "working directory for cloning repositories")
+ 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.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
diff --git a/internal/cli/handlers.go b/internal/cli/handlers.go
index e2cad92..a2a9c94 100644
--- a/internal/cli/handlers.go
+++ b/internal/cli/handlers.go
@@ -103,7 +103,8 @@ func ShowConfigHelp() {
"^codex/",
"^temp-",
"-wip$"
- ]
+ ],
+ "work_dir": "~/git/gitsyncer-workdir"
}`)
}
@@ -146,7 +147,7 @@ func ShowUsage(cfg *config.Config) {
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: .gitsyncer-work)")
+ 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")
diff --git a/internal/config/config.go b/internal/config/config.go
index 84f66b1..92d2c86 100644
--- a/internal/config/config.go
+++ b/internal/config/config.go
@@ -20,6 +20,7 @@ type Config struct {
Organizations []Organization `json:"organizations"`
Repositories []string `json:"repositories,omitempty"`
ExcludeBranches []string `json:"exclude_branches,omitempty"` // Regex patterns for branches to exclude
+ WorkDir string `json:"work_dir,omitempty"` // Working directory for cloning repositories
}
// Load reads and parses the configuration file
@@ -50,6 +51,24 @@ func Load(path string) (*Config, error) {
return nil, fmt.Errorf("invalid configuration: %w", err)
}
+ // Set default WorkDir if not specified
+ if cfg.WorkDir == "" {
+ home, err := os.UserHomeDir()
+ if err != nil {
+ return nil, fmt.Errorf("failed to get home directory: %w", err)
+ }
+ cfg.WorkDir = filepath.Join(home, "git", "gitsyncer-workdir")
+ }
+
+ // Expand home directory in WorkDir if needed
+ if strings.HasPrefix(cfg.WorkDir, "~/") {
+ home, err := os.UserHomeDir()
+ if err != nil {
+ return nil, fmt.Errorf("failed to get home directory: %w", err)
+ }
+ cfg.WorkDir = filepath.Join(home, cfg.WorkDir[2:])
+ }
+
return &cfg, nil
}