summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/gitsyncer/main.go46
-rw-r--r--internal/cli/flags.go19
-rw-r--r--internal/state/state.go79
-rw-r--r--internal/version/version.go2
4 files changed, 145 insertions, 1 deletions
diff --git a/cmd/gitsyncer/main.go b/cmd/gitsyncer/main.go
index 9828776..f27cff6 100644
--- a/cmd/gitsyncer/main.go
+++ b/cmd/gitsyncer/main.go
@@ -6,8 +6,23 @@ import (
"path/filepath"
"codeberg.org/snonux/gitsyncer/internal/cli"
+ "codeberg.org/snonux/gitsyncer/internal/state"
)
+// saveBatchRunState saves the batch run timestamp if this is a batch run
+func saveBatchRunState(flags *cli.Flags) {
+ if flags.BatchRun && flags.BatchRunStateManager != nil && flags.BatchRunState != nil {
+ flags.BatchRunState.UpdateBatchRunTime()
+ if err := flags.BatchRunStateManager.Save(flags.BatchRunState); err != nil {
+ fmt.Fprintf(os.Stderr, "Warning: Failed to save batch run state: %v\n", err)
+ } else {
+ stateFile := filepath.Join(flags.WorkDir, ".gitsyncer-state.json")
+ fmt.Printf("Batch run completed successfully. State saved to: %s\n", stateFile)
+ fmt.Println("Next batch run allowed after one week.")
+ }
+ }
+}
+
func main() {
// Parse command-line flags
flags := cli.ParseFlags()
@@ -43,6 +58,32 @@ func main() {
flags.WorkDir = cfg.WorkDir
}
+ // Handle --batch-run flag: check if it has run within the past week
+ if flags.BatchRun {
+ stateManager := state.NewManager(flags.WorkDir)
+ s, err := stateManager.Load()
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "Warning: Failed to load state: %v\n", err)
+ // Continue anyway on first run
+ }
+
+ if s.HasRunWithinWeek() {
+ fmt.Printf("Batch run was already executed within the past week (last run: %s).\n", s.LastBatchRun.Format("2006-01-02 15:04:05"))
+ stateFile := filepath.Join(flags.WorkDir, ".gitsyncer-state.json")
+ fmt.Printf("State file location: %s\n", stateFile)
+ fmt.Println("Skipping batch run. Use --full and --showcase directly to force execution.")
+ os.Exit(0)
+ }
+
+ // If we get here, we can proceed with the batch run
+ fmt.Println("Starting weekly batch run (--full --showcase)...")
+
+ // Update the state to record this batch run (we'll save it after successful completion)
+ // Store the state manager for later use
+ flags.BatchRunStateManager = stateManager
+ flags.BatchRunState = s
+ }
+
// Handle delete repository flag
if flags.DeleteRepo != "" {
os.Exit(cli.HandleDeleteRepo(cfg, flags.DeleteRepo))
@@ -108,6 +149,11 @@ func main() {
}
}
+ // Save batch run state if this was a successful batch run
+ if exitCode == 0 {
+ saveBatchRunState(flags)
+ }
+
os.Exit(exitCode)
}
diff --git a/internal/cli/flags.go b/internal/cli/flags.go
index 7640398..3a9990f 100644
--- a/internal/cli/flags.go
+++ b/internal/cli/flags.go
@@ -4,6 +4,8 @@ import (
"flag"
"os"
"path/filepath"
+
+ "codeberg.org/snonux/gitsyncer/internal/state"
)
// Flags holds all command-line flag values
@@ -27,6 +29,11 @@ type Flags struct {
Backup bool
Showcase bool
Force bool
+ BatchRun bool
+
+ // Internal fields for batch run state management (not set by flags)
+ BatchRunStateManager *state.Manager
+ BatchRunState *state.State
}
// ParseFlags parses command-line flags and returns the flags struct
@@ -54,6 +61,7 @@ func ParseFlags() *Flags {
flag.BoolVar(&f.Backup, "backup", false, "enable syncing to backup locations")
flag.BoolVar(&f.Showcase, "showcase", false, "generate project showcase using Claude after syncing")
flag.BoolVar(&f.Force, "force", false, "force regeneration of cached data")
+ flag.BoolVar(&f.BatchRun, "batch-run", false, "enable --full and --showcase (runs only once per week)")
flag.Parse()
@@ -76,5 +84,16 @@ func ParseFlags() *Flags {
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
} \ No newline at end of file
diff --git a/internal/state/state.go b/internal/state/state.go
new file mode 100644
index 0000000..af90879
--- /dev/null
+++ b/internal/state/state.go
@@ -0,0 +1,79 @@
+package state
+
+import (
+ "encoding/json"
+ "fmt"
+ "os"
+ "path/filepath"
+ "time"
+)
+
+// State represents the persistent state of gitsyncer
+type State struct {
+ LastBatchRun time.Time `json:"lastBatchRun"`
+}
+
+// Manager handles state persistence
+type Manager struct {
+ filePath string
+}
+
+// NewManager creates a new state manager
+func NewManager(workDir string) *Manager {
+ return &Manager{
+ filePath: filepath.Join(workDir, ".gitsyncer-state.json"),
+ }
+}
+
+// Load reads the state from disk
+func (m *Manager) Load() (*State, error) {
+ data, err := os.ReadFile(m.filePath)
+ if err != nil {
+ if os.IsNotExist(err) {
+ // Return empty state if file doesn't exist
+ return &State{}, nil
+ }
+ return nil, fmt.Errorf("failed to read state file: %w", err)
+ }
+
+ var state State
+ if err := json.Unmarshal(data, &state); err != nil {
+ return nil, fmt.Errorf("failed to parse state file: %w", err)
+ }
+
+ return &state, nil
+}
+
+// Save writes the state to disk
+func (m *Manager) Save(state *State) error {
+ data, err := json.MarshalIndent(state, "", " ")
+ if err != nil {
+ return fmt.Errorf("failed to marshal state: %w", err)
+ }
+
+ // Ensure directory exists
+ dir := filepath.Dir(m.filePath)
+ if err := os.MkdirAll(dir, 0755); err != nil {
+ return fmt.Errorf("failed to create state directory: %w", err)
+ }
+
+ // Write state file
+ if err := os.WriteFile(m.filePath, data, 0644); err != nil {
+ return fmt.Errorf("failed to write state file: %w", err)
+ }
+
+ return nil
+}
+
+// HasRunWithinWeek checks if the last batch run was within the past week
+func (s *State) HasRunWithinWeek() bool {
+ if s.LastBatchRun.IsZero() {
+ return false
+ }
+ return time.Since(s.LastBatchRun) < 7*24*time.Hour
+}
+
+// UpdateBatchRunTime updates the last batch run timestamp to now
+func (s *State) UpdateBatchRunTime() {
+ s.LastBatchRun = time.Now()
+} \ No newline at end of file
diff --git a/internal/version/version.go b/internal/version/version.go
index e817f13..03181e4 100644
--- a/internal/version/version.go
+++ b/internal/version/version.go
@@ -7,7 +7,7 @@ import (
var (
// Version is the current version of gitsyncer
- Version = "0.4.0"
+ Version = "0.5.0"
// GitCommit is the git commit hash at build time
GitCommit = "unknown"