appydave-tools 0.38.0 → 0.39.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ca0b626390693cf429dec2da61dca877811720aed92dd110849a826bbe53f3fe
4
- data.tar.gz: fba4176a5c363b7578409d63a6119f495138d637c9e03f309830317fb351ba2a
3
+ metadata.gz: d5c03f22b90ef02e4609a1d50bf1c1d06cf03b782a24cd9196463a746d91f33d
4
+ data.tar.gz: 61bc3604ae50ad6d9cc037c1df8be8c9d677a11aab23387c5fe74974e0bb3da4
5
5
  SHA512:
6
- metadata.gz: 7fac67c172b7153c59aee5d9a0d845c9bac1cc77040068472e125a850295435f625626addd49becded1b52e81db53d6d206269610c807e5a318a71e3647a0b08
7
- data.tar.gz: 936903137cf045758a3d131a3254e6ff44eca468455b546e5c98b55eb516242a7d861139e20cc75331e41cee256a3ff34a233c9ba2d6d67833ac8f1a245d570a
6
+ metadata.gz: 8c6ebbbce5cea68d4168d606521a57162e2dcee80d91dfd11b3785ca2e8fa722d1199553a64b51c9734c89869e725626e0cbcef6089e73e694c9b16b12079abb
7
+ data.tar.gz: b95e4edcd87705d08b2ebdf0c5b93884cf59386da8d169e21aea881119b5f8eb14d555c8f5c6b8c83ba236904b8f99d102fc3a192f9db4d06fc814d7405731c0
data/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ # [0.38.0](https://github.com/appydave/appydave-tools/compare/v0.37.0...v0.38.0) (2025-11-21)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * rename FileUtils to FileHelper to avoid Ruby stdlib conflict ([e441b43](https://github.com/appydave/appydave-tools/commit/e441b4356ec40a66f5562e9cf0ec74f562b449b2))
7
+
8
+
9
+ ### Features
10
+
11
+ * add DAM exception hierarchy for consistent error handling ([c885590](https://github.com/appydave/appydave-tools/commit/c885590be721d2b2803fd6aaa7001afc8cdbd285))
12
+ * extract FileUtils module to eliminate 40 lines of duplication ([643748e](https://github.com/appydave/appydave-tools/commit/643748ea583eba3605e1a6ce17e117db18f66c4c))
13
+ * extract GitHelper module to eliminate ~90 lines of git operations duplication across status.rb, repo_status.rb, and repo_push.rb ([f32dc1d](https://github.com/appydave/appydave-tools/commit/f32dc1d54877a9a981878a6e7c203922e50004fe))
14
+
1
15
  # [0.37.0](https://github.com/appydave/appydave-tools/compare/v0.36.0...v0.37.0) (2025-11-21)
2
16
 
3
17
 
@@ -0,0 +1,118 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Appydave
4
+ module Tools
5
+ module Dam
6
+ # Centralized brand name resolution and transformation
7
+ #
8
+ # Handles conversion between:
9
+ # - Shortcuts: 'appydave', 'ad', 'joy', 'ss'
10
+ # - Config keys: 'appydave', 'beauty-and-joy', 'supportsignal'
11
+ # - Display names: 'v-appydave', 'v-beauty-and-joy', 'v-supportsignal'
12
+ #
13
+ # @example
14
+ # BrandResolver.expand('ad') # => 'v-appydave'
15
+ # BrandResolver.normalize('v-voz') # => 'voz'
16
+ # BrandResolver.to_config_key('ad') # => 'appydave'
17
+ # BrandResolver.to_display('voz') # => 'v-voz'
18
+ class BrandResolver
19
+ class << self
20
+ # Expand shortcut or key to full display name
21
+ # @param shortcut [String] Brand shortcut or key
22
+ # @return [String] Full brand name with v- prefix
23
+ def expand(shortcut)
24
+ return shortcut.to_s if shortcut.to_s.start_with?('v-')
25
+
26
+ key = to_config_key(shortcut)
27
+ "v-#{key}"
28
+ end
29
+
30
+ # Normalize brand name to config key (strip v- prefix)
31
+ # @param brand [String] Brand name (with or without v-)
32
+ # @return [String] Config key without v- prefix
33
+ def normalize(brand)
34
+ brand.to_s.sub(/^v-/, '')
35
+ end
36
+
37
+ # Convert to config key (handles shortcuts)
38
+ # @param input [String] Shortcut, key, or display name
39
+ # @return [String] Config key
40
+ def to_config_key(input)
41
+ # Strip v- prefix first
42
+ normalized = normalize(input)
43
+
44
+ # Look up from brands.json
45
+ Appydave::Tools::Configuration::Config.configure
46
+ brands_config = Appydave::Tools::Configuration::Config.brands
47
+
48
+ # Check if matches brand key (case-insensitive)
49
+ brand = brands_config.brands.find { |b| b.key.downcase == normalized.downcase }
50
+ return brand.key if brand
51
+
52
+ # Check if matches shortcut (case-insensitive)
53
+ brand = brands_config.brands.find { |b| b.shortcut.downcase == normalized.downcase }
54
+ return brand.key if brand
55
+
56
+ # Fall back to hardcoded shortcuts (backward compatibility)
57
+ case normalized.downcase
58
+ when 'ad' then 'appydave'
59
+ when 'joy' then 'beauty-and-joy'
60
+ when 'ss' then 'supportsignal'
61
+ else
62
+ normalized.downcase
63
+ end
64
+ end
65
+
66
+ # Convert to display name (always v- prefix)
67
+ # @param input [String] Shortcut, key, or display name
68
+ # @return [String] Display name with v- prefix
69
+ def to_display(input)
70
+ expand(input)
71
+ end
72
+
73
+ # Validate brand exists in filesystem
74
+ # @param brand [String] Brand to validate
75
+ # @raise [BrandNotFoundError] if brand invalid
76
+ # @return [String] Config key if valid
77
+ def validate(brand)
78
+ key = to_config_key(brand)
79
+
80
+ # Build brand path (avoiding circular dependency with Config.brand_path)
81
+ Appydave::Tools::Configuration::Config.configure
82
+ brand_info = Appydave::Tools::Configuration::Config.brands.get_brand(key)
83
+
84
+ # If brand has configured video_projects path, use it
85
+ if brand_info.locations.video_projects && !brand_info.locations.video_projects.empty?
86
+ brand_path = brand_info.locations.video_projects
87
+ else
88
+ # Fall back to projects_root + expanded brand name
89
+ root = Config.projects_root
90
+ brand_path = File.join(root, expand(key))
91
+ end
92
+
93
+ unless Dir.exist?(brand_path)
94
+ available = Config.available_brands_display
95
+ raise BrandNotFoundError.new(brand, available)
96
+ end
97
+
98
+ key
99
+ rescue StandardError => e
100
+ raise BrandNotFoundError, e.message unless e.is_a?(BrandNotFoundError)
101
+
102
+ raise
103
+ end
104
+
105
+ # Check if brand exists (returns boolean instead of raising)
106
+ # @param brand [String] Brand to check
107
+ # @return [Boolean] true if brand exists
108
+ def exists?(brand)
109
+ validate(brand)
110
+ true
111
+ rescue BrandNotFoundError
112
+ false
113
+ end
114
+ end
115
+ end
116
+ end
117
+ end
118
+ end
@@ -85,34 +85,11 @@ module Appydave
85
85
  end
86
86
 
87
87
  # Expand brand shortcut to full brand name
88
- # Reads from brands.json if available, falls back to hardcoded shortcuts
88
+ # Delegates to BrandResolver for centralized brand resolution
89
89
  # @param shortcut [String] Brand shortcut (e.g., 'appydave', 'ad', 'APPYDAVE')
90
90
  # @return [String] Full brand name (e.g., 'v-appydave')
91
91
  def expand_brand(shortcut)
92
- shortcut_str = shortcut.to_s
93
-
94
- return shortcut_str if shortcut_str.start_with?('v-')
95
-
96
- # Try to read from brands.json
97
- Appydave::Tools::Configuration::Config.configure
98
- brands_config = Appydave::Tools::Configuration::Config.brands
99
-
100
- # Check if input matches a brand key (case-insensitive)
101
- brand = brands_config.brands.find { |b| b.key.downcase == shortcut_str.downcase }
102
- return "v-#{brand.key}" if brand
103
-
104
- # Check if input matches a brand shortcut (case-insensitive)
105
- brand = brands_config.brands.find { |b| b.shortcut.downcase == shortcut_str.downcase }
106
- return "v-#{brand.key}" if brand
107
-
108
- # Fall back to hardcoded shortcuts for backwards compatibility
109
- normalized = shortcut_str.downcase
110
- case normalized
111
- when 'joy' then 'v-beauty-and-joy'
112
- when 'ss' then 'v-supportsignal'
113
- else
114
- "v-#{normalized}"
115
- end
92
+ BrandResolver.expand(shortcut)
116
93
  end
117
94
 
118
95
  # Get list of available brands
@@ -116,9 +116,9 @@ module Appydave
116
116
  # Check if we're inside a v-* directory
117
117
  if current =~ %r{/(v-[^/]+)/([^/]+)/?}
118
118
  brand_with_prefix = ::Regexp.last_match(1)
119
- project = ::Regexp.last_match(2) # Capture BEFORE .sub() which resets Regexp.last_match
119
+ project = ::Regexp.last_match(2) # Capture BEFORE normalize() which resets Regexp.last_match
120
120
  # Strip 'v-' prefix to get brand key (e.g., 'v-supportsignal' → 'supportsignal')
121
- brand_key = brand_with_prefix.sub(/^v-/, '')
121
+ brand_key = BrandResolver.normalize(brand_with_prefix)
122
122
  return [brand_key, project] if project_exists?(brand_key, project)
123
123
  end
124
124
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Appydave
4
4
  module Tools
5
- VERSION = '0.38.0'
5
+ VERSION = '0.39.0'
6
6
  end
7
7
  end
@@ -55,6 +55,7 @@ require 'appydave/tools/subtitle_processor/join'
55
55
  require 'appydave/tools/dam/errors'
56
56
  require 'appydave/tools/dam/file_helper'
57
57
  require 'appydave/tools/dam/git_helper'
58
+ require 'appydave/tools/dam/brand_resolver'
58
59
  require 'appydave/tools/dam/config'
59
60
  require 'appydave/tools/dam/project_resolver'
60
61
  require 'appydave/tools/dam/config_loader'
data/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "appydave-tools",
3
- "version": "0.38.0",
3
+ "version": "0.39.0",
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.38.0
4
+ version: 0.39.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Cruwys
@@ -297,6 +297,7 @@ files:
297
297
  - lib/appydave/tools/configuration/models/settings_config.rb
298
298
  - lib/appydave/tools/configuration/models/youtube_automation_config.rb
299
299
  - lib/appydave/tools/configuration/openai.rb
300
+ - lib/appydave/tools/dam/brand_resolver.rb
300
301
  - lib/appydave/tools/dam/config.rb
301
302
  - lib/appydave/tools/dam/config_loader.rb
302
303
  - lib/appydave/tools/dam/errors.rb