Class: Appydave::Tools::Dam::SyncFromSsd

Inherits:
Object
  • Object
show all
Defined in:
lib/appydave/tools/dam/sync_from_ssd.rb

Overview

Sync light files from SSD to local for a brand Only copies non-video files (subtitles, images, docs)

Constant Summary collapse

LIGHT_FILE_PATTERNS =

Light file patterns to include (everything except heavy video files)

%w[
  **/*.srt
  **/*.vtt
  **/*.txt
  **/*.md
  **/*.jpg
  **/*.jpeg
  **/*.png
  **/*.webp
  **/*.json
  **/*.yml
  **/*.yaml
].freeze
HEAVY_FILE_PATTERNS =

Heavy file patterns to exclude (video files)

%w[
  *.mp4
  *.mov
  *.avi
  *.mkv
  *.webm
].freeze
EXCLUDE_PATTERNS =

Directory patterns to exclude (generated/installable content)

%w[
  **/node_modules/**
  **/.git/**
  **/.next/**
  **/dist/**
  **/build/**
  **/out/**
  **/.cache/**
  **/coverage/**
  **/.turbo/**
  **/.vercel/**
  **/tmp/**
  **/.DS_Store
].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(brand, brand_info: nil, brand_path: nil) ⇒ SyncFromSsd

Returns a new instance of SyncFromSsd.



54
55
56
57
58
# File 'lib/appydave/tools/dam/sync_from_ssd.rb', line 54

def initialize(brand, brand_info: nil, brand_path: nil)
  @brand_info = brand_info || load_brand_info(brand)
  @brand = @brand_info.key # Use resolved brand key, not original input
  @brand_path = brand_path || Config.brand_path(@brand)
end

Instance Attribute Details

#brandObject (readonly)

Returns the value of attribute brand.



12
13
14
# File 'lib/appydave/tools/dam/sync_from_ssd.rb', line 12

def brand
  @brand
end

#brand_infoObject (readonly)

Returns the value of attribute brand_info.



12
13
14
# File 'lib/appydave/tools/dam/sync_from_ssd.rb', line 12

def brand_info
  @brand_info
end

#brand_pathObject (readonly)

Returns the value of attribute brand_path.



12
13
14
# File 'lib/appydave/tools/dam/sync_from_ssd.rb', line 12

def brand_path
  @brand_path
end

Instance Method Details

#sync(dry_run: false) ⇒ Object

Sync light files from SSD for all projects in manifest



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/appydave/tools/dam/sync_from_ssd.rb', line 61

def sync(dry_run: false)
  puts dry_run ? '🔍 DRY-RUN MODE - No files will be copied' : '📦 Syncing from SSD...'
  puts ''

  # Validate SSD is mounted
  ssd_backup = brand_info.locations.ssd_backup
  unless ssd_backup && !ssd_backup.empty?
    puts "❌ SSD backup location not configured for brand '#{brand}'"
    return
  end

  unless Dir.exist?(ssd_backup)
    puts "❌ SSD not mounted at #{ssd_backup}"
    return
  end

  # Load manifest
  manifest_file = File.join(brand_path, 'projects.json')
  unless File.exist?(manifest_file)
    puts '❌ projects.json not found!'
    puts "   Run: vat manifest #{brand}"
    return
  end

  manifest = load_manifest(manifest_file)
  puts "📋 Loaded manifest: #{manifest[:projects].size} projects"
  puts "   Last updated: #{manifest[:config][:last_updated]}"
  puts ''

  # Filter projects to sync
  projects_to_sync = manifest[:projects].select { |p| should_sync_project?(p) }

  puts '🔍 Analysis:'
  puts "   Total projects in manifest: #{manifest[:projects].size}"
  puts "   Projects to sync: #{projects_to_sync.size}"
  puts "   Skipped (already local): #{manifest[:projects].size - projects_to_sync.size}"
  puts ''

  if projects_to_sync.empty?
    puts '✅ Nothing to sync - all projects either already local or not on SSD'
    return
  end

  # Sync each project
  total_stats = { files: 0, bytes: 0, skipped: 0 }

  projects_to_sync.each do |project|
    stats = sync_project(project, ssd_backup, dry_run: dry_run)

    # Only show project if there are files to sync or a warning
    if stats[:reason] || stats[:files]&.positive?
      puts "📁 #{project[:id]}"

      puts "  ⚠️  Skipped: #{stats[:reason]}" if stats[:reason]

      puts "  #{stats[:files]} file(s), #{format_bytes(stats[:bytes])}" if stats[:files]&.positive?
      puts ''
    end

    total_stats[:files] += stats[:files] || 0
    total_stats[:bytes] += stats[:bytes] || 0
    total_stats[:skipped] += stats[:skipped] || 0
  end

  puts ''
  puts '=' * 60
  puts 'Summary:'
  puts "  Projects scanned: #{projects_to_sync.size}"
  puts "  Files #{dry_run ? 'to copy' : 'copied'}: #{total_stats[:files]}"
  puts "  Total size: #{format_bytes(total_stats[:bytes])}"
  puts ''
  puts '✅ Sync complete!'
  puts '   Run without --dry-run to perform the sync' if dry_run
end