Class: Ace::Git::Worktree::Atoms::TaskIDExtractor
- Inherits:
-
Object
- Object
- Ace::Git::Worktree::Atoms::TaskIDExtractor
- Defined in:
- lib/ace/git/worktree/atoms/task_id_extractor.rb
Overview
Extracts task IDs from task data, preserving hierarchical subtask notation
This atom provides a single source of truth for task ID extraction across ace-git-worktree, ensuring consistent handling of hierarchical task IDs (e.g., “121.01” for subtasks).
Class Method Summary collapse
-
.extract(task_data) ⇒ String
Extract task ID from task data hash.
-
.normalize(task_ref) ⇒ String?
Normalize a task reference string to simple ID format.
Class Method Details
.extract(task_data) ⇒ String
Extract task ID from task data hash
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 |
# File 'lib/ace/git/worktree/atoms/task_id_extractor.rb', line 29 def self.extract(task_data) return "unknown" unless task_data # Regex with subtask support if task_data[:id] # B36TS full ID: "8pp.t.hy4" -> "hy4", or subtask "8pp.t.hy4.a" -> "hy4.a" if match = task_data[:id].match(/\A[0-9a-z]{3}\.[a-z]\.([0-9a-z]{3}(?:\.[a-z0-9])?)\z/) return match[1] end # Try subtask pattern first (e.g., "v.0.9.0+task.121.01" -> "121.01") if match = task_data[:id].match(/(?:ace-)?(?:task|t)\.(\d+)\.(\d{2})$/) return "#{match[1]}.#{match[2]}" end # Then simple pattern (e.g., "v.0.9.0+task.094" -> "094") if match = task_data[:id].match(/(?:ace-)?(?:task|t)\.(\d+)$/) return match[1] end # Fallback for partial patterns (e.g., "task.121.1" -> "121", ignoring invalid suffix) if match = task_data[:id].match(/(?:ace-)?(?:task|t)\.(\d+)/) return match[1] end end # Last resort: use task_number (doesn't include subtask suffix) task_data[:task_number]&.to_s || "unknown" end |
.normalize(task_ref) ⇒ String?
Normalize a task reference string to simple ID format
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 |
# File 'lib/ace/git/worktree/atoms/task_id_extractor.rb', line 60 def self.normalize(task_ref) ref = task_ref.to_s.strip return nil if ref.empty? # Regex patterns for recognized ACE task ID formats # B36TS full ID: "8pp.t.hy4" -> "hy4", or subtask "8pp.t.hy4.a" -> "hy4.a" if match = ref.match(/\A[0-9a-z]{3}\.[a-z]\.([0-9a-z]{3}(?:\.[a-z0-9])?)\z/) match[1] # B36TS short ref: exactly 3 lowercase alphanumeric chars (e.g., "hy4") elsif match = ref.match(/\A([0-9a-z]{3})\z/) match[1] # ACE task IDs are 3-digit zero-padded (081, 121, etc.) # Try hierarchical pattern first (e.g., "121.01", "task.121.01") elsif match = ref.match(/(\d{3})\.(\d{2})(?:\b|$)/) "#{match[1]}.#{match[2]}" # Try ace-task/ace-t or task/t directory at end of path (e.g., "ace-task.hy4", "/path/to/task.121") elsif match = ref.match(/(?:ace-)?(?:task|t)\.([0-9a-z]{3})\/?$/) match[1] # Try task./t. prefix in middle of path (e.g., ".cache/test/task.121") # Use negative lookbehind to skip ace-task.XXX / ace-t.XXX parent directories elsif match = ref.match(/(?<!ace-)(?:task|t)\.(\d{3})(?:\b|$)/) match[1] # Try bare 3-digit task ID (e.g., "121", "081") elsif match = ref.match(/\b(\d{3})\b/) match[1] end end |