summaryrefslogtreecommitdiff
path: root/internal/state
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2025-07-09 12:38:32 +0300
committerPaul Buetow <paul@buetow.org>2025-07-09 12:38:32 +0300
commit13a0cd1055b34a93e06b429ca75492ceb8ca1434 (patch)
tree455cec87470278aca95f3f6f6a85940c4fae2b18 /internal/state
parent60ad0b50390d455607c89801ded91f57422fcf8c (diff)
feat: add --batch-run flag for weekly automated sync
- Add --batch-run flag that enables --full and --showcase - Implement state management to track last batch run timestamp - Enforce one-week minimum interval between batch runs - Save state to .gitsyncer-state.json in work directory - Show state file location in output messages - Bump version to 0.5.0 This feature enables automated weekly full synchronization from cron or shell scripts while preventing excessive API usage. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Diffstat (limited to 'internal/state')
-rw-r--r--internal/state/state.go79
1 files changed, 79 insertions, 0 deletions
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