Class: RosettAi::Project::SyncManager

Inherits:
Object
  • Object
show all
Defined in:
lib/rosett_ai/project/sync_manager.rb

Overview

Handles upstream synchronization for rosett-ai-managed projects.

Detects breaking changes when upstream templates are updated and applies updates with user confirmation or --force flag.

Author:

  • hugo

  • claude

Instance Method Summary collapse

Constructor Details

#initialize(project_root:, force: false) ⇒ SyncManager

Returns a new instance of SyncManager.

Parameters:

  • project_root (Pathname)

    root directory of the project

  • force (Boolean) (defaults to: false)

    apply breaking changes without prompting



20
21
22
23
24
# File 'lib/rosett_ai/project/sync_manager.rb', line 20

def initialize(project_root:, force: false)
  @project_root = project_root
  @project_dir = project_root.join('.rosett-ai')
  @force = force
end

Instance Method Details

#simulateHash

Preview what sync would change without applying.

Returns:

  • (Hash)

    same structure as sync but without writing files



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/rosett_ai/project/sync_manager.rb', line 59

def simulate
  validate!
  origin = load_origin
  template_name = origin['template']
  template_dir = RosettAi.root.join(TemplateApplier::TEMPLATES_DIR, template_name)

  return { updated: [], conflicts: [], skipped: [] } unless template_dir.directory?

  results = { updated: [], conflicts: [], skipped: [] }

  Dir.glob(template_dir.join('**', '*').to_s).each do |tmpl_path|
    tmpl = Pathname.new(tmpl_path)
    next if tmpl.directory?

    relative = tmpl.relative_path_from(template_dir)
    dest = @project_dir.join(relative)

    classify_change(tmpl, dest, relative, results)
  end

  results
end

#syncHash

Synchronizes the project with upstream template updates.

Returns:

  • (Hash)

    result with :updated, :conflicts, :skipped arrays



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/rosett_ai/project/sync_manager.rb', line 29

def sync
  validate!
  origin = load_origin
  template_name = origin['template']
  template_dir = RosettAi.root.join(TemplateApplier::TEMPLATES_DIR, template_name)

  unless template_dir.directory?
    return { updated: [], conflicts: [], skipped: [],
             error: 'Template no longer available' }
  end

  results = { updated: [], conflicts: [], skipped: [] }

  Dir.glob(template_dir.join('**', '*').to_s).each do |tmpl_path|
    tmpl = Pathname.new(tmpl_path)
    next if tmpl.directory?

    relative = tmpl.relative_path_from(template_dir)
    dest = @project_dir.join(relative)

    sync_file(tmpl, dest, relative, results)
  end

  update_origin_timestamp(origin) unless results[:updated].empty?
  results
end