appydave-tools 0.18.1 → 0.18.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -12,6 +12,22 @@ module Appydave
12
12
  class S3Operations
13
13
  attr_reader :brand_info, :brand, :project_id, :brand_path, :s3_client
14
14
 
15
+ # Directory patterns to exclude from archive/upload (generated/installable content)
16
+ EXCLUDE_PATTERNS = %w[
17
+ **/node_modules/**
18
+ **/.git/**
19
+ **/.next/**
20
+ **/dist/**
21
+ **/build/**
22
+ **/out/**
23
+ **/.cache/**
24
+ **/coverage/**
25
+ **/.turbo/**
26
+ **/.vercel/**
27
+ **/tmp/**
28
+ **/.DS_Store
29
+ ].freeze
30
+
15
31
  def initialize(brand, project_id, brand_info: nil, brand_path: nil, s3_client: nil)
16
32
  @project_id = project_id
17
33
 
@@ -37,9 +53,11 @@ module Appydave
37
53
  Aws::S3::Client.new(
38
54
  credentials: credentials,
39
55
  region: brand_info.aws.region,
40
- http_wire_trace: false,
41
- ssl_verify_peer: true,
42
- ssl_ca_bundle: '/etc/ssl/cert.pem' # macOS system certificates
56
+ http_wire_trace: false
57
+ # AWS SDK auto-detects SSL certificates on all platforms:
58
+ # - Windows: Uses Windows Certificate Store
59
+ # - macOS: Finds system certificates automatically
60
+ # - Linux: Finds OpenSSL certificates
43
61
  )
44
62
  end
45
63
 
@@ -500,20 +518,23 @@ module Appydave
500
518
  end
501
519
 
502
520
  size = calculate_directory_size(source_dir)
503
- puts '📋 Copy to SSD:'
521
+ puts '📋 Copy to SSD (excluding generated files):'
504
522
  puts " Source: #{source_dir}"
505
523
  puts " Dest: #{dest_dir}"
506
524
  puts " Size: #{file_size_human(size)}"
507
525
  puts ''
508
526
 
509
527
  if dry_run
510
- puts ' [DRY-RUN] Would copy entire project to SSD'
528
+ puts ' [DRY-RUN] Would copy project to SSD (excluding node_modules, .git, etc.)'
511
529
  return true
512
530
  end
513
531
 
514
- FileUtils.mkdir_p(File.dirname(dest_dir))
515
- FileUtils.cp_r(source_dir, dest_dir, preserve: true)
516
- puts ' ✅ Copied to SSD'
532
+ FileUtils.mkdir_p(dest_dir)
533
+
534
+ # Copy files with exclusion filtering
535
+ stats = copy_with_exclusions(source_dir, dest_dir)
536
+
537
+ puts " ✅ Copied to SSD (#{stats[:files]} files, excluded #{stats[:excluded]} generated files)"
517
538
 
518
539
  true
519
540
  rescue StandardError => e
@@ -521,6 +542,47 @@ module Appydave
521
542
  false
522
543
  end
523
544
 
545
+ # Copy directory contents with exclusion filtering
546
+ def copy_with_exclusions(source_dir, dest_dir)
547
+ stats = { files: 0, excluded: 0 }
548
+
549
+ Dir.glob(File.join(source_dir, '**', '*'), File::FNM_DOTMATCH).each do |source_path|
550
+ next if File.directory?(source_path)
551
+ next if ['.', '..'].include?(File.basename(source_path))
552
+
553
+ relative_path = source_path.sub("#{source_dir}/", '')
554
+
555
+ if excluded_path?(relative_path)
556
+ stats[:excluded] += 1
557
+ next
558
+ end
559
+
560
+ dest_path = File.join(dest_dir, relative_path)
561
+ FileUtils.mkdir_p(File.dirname(dest_path))
562
+ FileUtils.cp(source_path, dest_path, preserve: true)
563
+ stats[:files] += 1
564
+ end
565
+
566
+ stats
567
+ end
568
+
569
+ # Check if path should be excluded (generated/installable content)
570
+ def excluded_path?(relative_path)
571
+ EXCLUDE_PATTERNS.any? do |pattern|
572
+ # Extract directory/file name from pattern (remove **)
573
+ excluded_name = pattern.gsub('**/', '').chomp('/**')
574
+ path_segments = relative_path.split('/')
575
+
576
+ if excluded_name.include?('*')
577
+ # Pattern with wildcards - use fnmatch on filename
578
+ File.fnmatch(excluded_name, File.basename(relative_path))
579
+ else
580
+ # Check if any path segment matches the excluded name
581
+ path_segments.include?(excluded_name)
582
+ end
583
+ end
584
+ end
585
+
524
586
  # Delete local project directory
525
587
  def delete_local_project(project_dir, dry_run: false)
526
588
  size = calculate_directory_size(project_dir)
@@ -35,6 +35,22 @@ module Appydave
35
35
  *.webm
36
36
  ].freeze
37
37
 
38
+ # Directory patterns to exclude (generated/installable content)
39
+ EXCLUDE_PATTERNS = %w[
40
+ **/node_modules/**
41
+ **/.git/**
42
+ **/.next/**
43
+ **/dist/**
44
+ **/build/**
45
+ **/out/**
46
+ **/.cache/**
47
+ **/coverage/**
48
+ **/.turbo/**
49
+ **/.vercel/**
50
+ **/tmp/**
51
+ **/.DS_Store
52
+ ].freeze
53
+
38
54
  def initialize(brand, brand_info: nil, brand_path: nil)
39
55
  @brand_info = brand_info || load_brand_info(brand)
40
56
  @brand = @brand_info.key # Use resolved brand key, not original input
@@ -184,6 +200,7 @@ module Appydave
184
200
  LIGHT_FILE_PATTERNS.each do |pattern|
185
201
  Dir.glob(File.join(ssd_path, pattern)).each do |source_file|
186
202
  next if heavy_file?(source_file)
203
+ next if excluded_file?(source_file, ssd_path)
187
204
 
188
205
  copy_stats = copy_light_file(source_file, ssd_path, local_dir, dry_run: dry_run)
189
206
  stats[:files] += copy_stats[:files]
@@ -199,6 +216,30 @@ module Appydave
199
216
  HEAVY_FILE_PATTERNS.any? { |pattern| File.fnmatch(pattern, File.basename(source_file)) }
200
217
  end
201
218
 
219
+ # Check if file should be excluded (generated/installable content)
220
+ def excluded_file?(source_file, ssd_path)
221
+ relative_path = source_file.sub("#{ssd_path}/", '')
222
+
223
+ EXCLUDE_PATTERNS.any? do |pattern|
224
+ # Extract directory/file name from pattern (remove **)
225
+ # **/node_modules/** → node_modules
226
+ # **/.git/** → .git
227
+ # **/.DS_Store → .DS_Store
228
+ excluded_name = pattern.gsub('**/', '').chomp('/**')
229
+
230
+ # Check path segments for matches
231
+ path_segments = relative_path.split('/')
232
+
233
+ if excluded_name.include?('*')
234
+ # Pattern with wildcards - use fnmatch on filename
235
+ File.fnmatch(excluded_name, File.basename(relative_path))
236
+ else
237
+ # Check if any path segment matches the excluded name
238
+ path_segments.include?(excluded_name)
239
+ end
240
+ end
241
+ end
242
+
202
243
  # Copy a single light file
203
244
  def copy_light_file(source_file, ssd_path, local_dir, dry_run: false)
204
245
  relative_path = source_file.sub("#{ssd_path}/", '')
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Appydave
4
4
  module Tools
5
- VERSION = '0.18.1'
5
+ VERSION = '0.18.2'
6
6
  end
7
7
  end
data/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "appydave-tools",
3
- "version": "0.18.1",
3
+ "version": "0.18.2",
4
4
  "description": "AppyDave YouTube Automation Tools",
5
5
  "scripts": {
6
6
  "release": "semantic-release"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: appydave-tools
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.18.1
4
+ version: 0.18.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Cruwys
@@ -227,6 +227,10 @@ files:
227
227
  - bin/youtube_automation.rb
228
228
  - bin/youtube_manager.rb
229
229
  - docs/README.md
230
+ - docs/SESSION-SUMMARY-WINDOWS-PREP.md
231
+ - docs/WINDOWS-COMPATIBILITY-REPORT.md
232
+ - docs/WINDOWS-SETUP.md
233
+ - docs/WINDOWS-START-HERE.md
230
234
  - docs/archive/codebase-audit-2025-01.md
231
235
  - docs/archive/documentation-framework-proposal.md
232
236
  - docs/archive/purpose-and-philosophy.md
@@ -241,6 +245,7 @@ files:
241
245
  - docs/dam/session-summary-2025-11-09.md
242
246
  - docs/dam/usage.md
243
247
  - docs/dam/vat-testing-plan.md
248
+ - docs/dam/windows-testing-guide.md
244
249
  - docs/development/CODEX-recommendations.md
245
250
  - docs/development/README.md
246
251
  - docs/development/cli-architecture-patterns.md