@@ -10,6 +10,8 @@ module DemoScripts
1010 # Manages swapping dependencies between production and local/GitHub versions
1111 # rubocop:disable Metrics/ClassLength
1212 class DependencySwapper < DemoManager
13+ include GitHubSpecParser
14+
1315 # Maps gem names to their npm package subdirectories
1416 NPM_PACKAGE_PATHS = {
1517 'shakapacker' => '.' ,
@@ -312,23 +314,20 @@ def validate_gem_paths(paths)
312314 paths . transform_values { |path | File . expand_path ( path ) }
313315 end
314316
315- # rubocop:disable Metrics/CyclomaticComplexity , Metrics/PerceivedComplexity , Metrics/MethodLength , Metrics/AbcSize, Metrics/BlockLength
317+ # rubocop:disable Metrics/AbcSize , Metrics/CyclomaticComplexity , Metrics/PerceivedComplexity , Metrics/MethodLength
316318 def validate_github_repos ( repos )
317319 invalid = repos . keys - SUPPORTED_GEMS
318320 raise Error , "Unsupported gems: #{ invalid . join ( ', ' ) } " if invalid . any?
319321
320322 repos . transform_values do |value |
321323 result = if value . is_a? ( String )
322- # String format: supports 'user/repo', 'user/repo#branch', or 'user/repo@tag'
323- if value . include? ( '@' )
324- repo , ref = value . split ( '@' , 2 )
325- { repo : repo , branch : ref , ref_type : :tag }
326- elsif value . include? ( '#' )
327- repo , ref = value . split ( '#' , 2 )
328- { repo : repo , branch : ref , ref_type : :branch }
329- else
330- { repo : value , branch : 'main' , ref_type : :branch }
331- end
324+ # Use shared GitHubSpecParser for consistent parsing
325+ repo , ref , ref_type = parse_github_spec ( value )
326+ {
327+ repo : repo ,
328+ branch : ref || 'main' ,
329+ ref_type : ref_type || :branch
330+ }
332331 elsif value . is_a? ( Hash )
333332 # Hash format with repo and optional branch
334333 {
@@ -340,20 +339,14 @@ def validate_github_repos(repos)
340339 raise Error , "Invalid GitHub repo format for #{ value } "
341340 end
342341
343- # Validate repo format (must be 'user/repo')
344- unless %r{\A [\w .-]+/[\w .-]+\z } . match? ( result [ :repo ] )
345- raise Error , "Invalid GitHub repo format: #{ result [ :repo ] } (must be 'user/repo')"
346- end
347-
348- # Validate branch/tag name (alphanumeric, hyphens, underscores, dots, slashes)
349- unless %r{\A [\w .\- /]+\z } . match? ( result [ :branch ] )
350- raise Error , "Invalid branch/tag name: #{ result [ :branch ] } (contains unsafe characters)"
351- end
342+ # Use shared validation methods
343+ validate_github_repo ( result [ :repo ] )
344+ validate_github_branch ( result [ :branch ] ) if result [ :branch ]
352345
353346 result
354347 end
355348 end
356- # rubocop:enable Metrics/CyclomaticComplexity , Metrics/PerceivedComplexity , Metrics/MethodLength , Metrics/AbcSize, Metrics/BlockLength
349+ # rubocop:enable Metrics/AbcSize , Metrics/CyclomaticComplexity , Metrics/PerceivedComplexity , Metrics/MethodLength
357350
358351 def validate_local_paths!
359352 gem_paths . each do |gem_name , path |
@@ -499,9 +492,17 @@ def swap_gem_to_github(content, gem_name, info)
499492 # Extract options after version (if any)
500493 options = rest . sub ( /^\s *,\s *(['"])[^'"]*\1 / , '' ) # Remove version if present
501494
502- # Build replacement: gem 'name', github: 'user/repo', branch: 'branch-name' [, options...]
495+ # Use tag: for tags, branch: for branches (default to :branch if not specified)
496+ ref_type = info [ :ref_type ] || :branch
497+ param_name = ref_type == :tag ? 'tag' : 'branch'
498+
499+ # Only omit ref when it's a branch (not tag) and the branch is 'main' or 'master'
500+ # Tags must always be explicit, even if named 'main' or 'master'
501+ should_omit_ref = ref_type == :branch && %w[ main master ] . include? ( info [ :branch ] )
502+
503+ # Build replacement: gem 'name', github: 'user/repo', branch/tag: 'ref-name' [, options...]
503504 replacement = "#{ indent } gem #{ quote } #{ gem_name } #{ quote } , github: #{ quote } #{ info [ :repo ] } #{ quote } "
504- replacement += ", branch : #{ quote } #{ info [ :branch ] } #{ quote } " if info [ :branch ] != 'main'
505+ replacement += ", #{ param_name } : #{ quote } #{ info [ :branch ] } #{ quote } " unless should_omit_ref
505506 replacement += options unless options . strip . empty?
506507 replacement
507508 end
0 commit comments