Class: Appydave::Tools::Dam::S3ScanCommand

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

Overview

Encapsulates S3 scan logic: single-brand and all-brands scanning

Instance Method Summary collapse

Instance Method Details

#scan_allObject

Scan all brands’ S3 buckets



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
135
136
137
138
# File 'lib/appydave/tools/dam/s3_scan_command.rb', line 100

def scan_all
  Appydave::Tools::Configuration::Config.configure
  brands_config = Appydave::Tools::Configuration::Config.brands

  results = []
  brands_config.brands.each do |brand_info|
    brand_key = brand_info.key
    puts ''
    puts '=' * 60

    begin
      scan_single(brand_key)
      results << { brand: brand_key, success: true }
    rescue StandardError => e
      puts "❌ Failed to scan #{brand_key}: #{e.message}"
      results << { brand: brand_key, success: false, error: e.message }
    end
  end

  puts ''
  puts '=' * 60
  puts '📋 Summary - S3 Scans:'
  puts ''

  successful, failed = results.partition { |r| r[:success] }

  successful.each do |result|
    brand_display = result[:brand].ljust(15)
    puts "#{brand_display} Scanned successfully"
  end

  failed.each do |result|
    brand_display = result[:brand].ljust(15)
    puts "#{brand_display} #{result[:error]}"
  end

  puts ''
  puts "Total brands scanned: #{successful.size}/#{results.size}"
end

#scan_single(brand_key) ⇒ Object

Scan a single brand’s S3 bucket and update its manifest



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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
55
56
57
58
59
60
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
# File 'lib/appydave/tools/dam/s3_scan_command.rb', line 9

def scan_single(brand_key)
  puts "🔄 Scanning S3 for #{brand_key}..."
  puts ''

  scanner = Appydave::Tools::Dam::S3Scanner.new(brand_key)

  # Get brand info for S3 path
  Appydave::Tools::Configuration::Config.configure
  brand_info = Appydave::Tools::Configuration::Config.brands.get_brand(brand_key)
  bucket = brand_info.aws.s3_bucket
  prefix = brand_info.aws.s3_prefix
  region = brand_info.aws.region

  # Spinner characters for progress
  spinner_chars = ['', '', '', '', '', '', '', '', '', '']
  spinner_index = 0

  print "🔍 Scanning s3://#{bucket}/#{prefix}\n"
  print '    Scanning projects... '

  # Scan all projects with progress callback
  results = scanner.scan_all_projects(show_progress: false) do |current, total|
    print "\r    Scanning projects... #{spinner_chars[spinner_index]} (#{current}/#{total})"
    spinner_index = (spinner_index + 1) % spinner_chars.length
  end

  print "\r    Scanning projects... ✓ (#{results.size} found)\n"
  puts ''

  if results.empty?
    puts "⚠️  No projects found in S3 for #{brand_key}"
    puts '   This may indicate:'
    puts '   - No files uploaded to S3 yet'
    puts '   - S3 bucket or prefix misconfigured'
    puts '   - AWS credentials issue'
    return
  end

  # Load existing manifest
  brand_path = Appydave::Tools::Dam::Config.brand_path(brand_key)
  manifest_path = File.join(brand_path, 'projects.json')

  unless File.exist?(manifest_path)
    raise Appydave::Tools::Dam::ConfigurationError,
          "Manifest not found: #{manifest_path}. Run: dam manifest #{brand_key}"
  end

  manifest = JSON.parse(File.read(manifest_path), symbolize_names: true)

  # Identify matched and orphaned S3 projects
  local_project_ids = manifest[:projects].map { |p| p[:id] }
  matched_projects = results.slice(*local_project_ids)
  orphaned_projects = results.reject { |project_id, _| local_project_ids.include?(project_id) }

  # Merge S3 scan data into manifest for matched projects
  updated_count = 0
  manifest[:projects].each do |project|
    project_id = project[:id]
    s3_data = results[project_id]
    next unless s3_data

    project[:storage][:s3] = s3_data
    updated_count += 1
  end

  # Update timestamp and note
  manifest[:config][:last_updated] = Time.now.utc.iso8601
  manifest[:config][:note] = 'Auto-generated manifest with S3 scan data. Regenerate with: dam s3-scan'

  # Write updated manifest
  File.write(manifest_path, JSON.pretty_generate(manifest))

  # Add local sync status to matched projects
  Appydave::Tools::Dam::LocalSyncStatus.enrich!(matched_projects, brand_key)

  # Display table
  display_table(matched_projects, orphaned_projects, bucket, prefix, region)

  # Summary
  total_manifest_projects = manifest[:projects].size
  missing_count = total_manifest_projects - matched_projects.size

  puts ''
  puts 'ℹ️  Summary:'
  puts "   • Updated #{updated_count} projects in manifest"
  puts "#{missing_count} local project(s) not yet uploaded to S3" if missing_count.positive?
  puts "   • Manifest: #{manifest_path}"
  puts ''
end