Class: Ace::Task::Molecules::TaskScanner
- Inherits:
-
Object
- Object
- Ace::Task::Molecules::TaskScanner
- Defined in:
- lib/ace/task/molecules/task_scanner.rb
Overview
Wraps DirectoryScanner for task-format directories. Uses a custom id_extractor that matches xxx.t.yyy-slug folder names. Excludes subtask folders from primary scan results.
Constant Summary collapse
- TASK_ID_EXTRACTOR =
ID extractor for task-format folders: “8pp.t.q7w-fix-login”
->(folder_name) { match = folder_name.match(/^([0-9a-z]{3}\.[a-z]\.[0-9a-z]{3})-(.+)$/) return nil unless match id = match[1] slug = match[2] [id, slug] }
- FILE_PATTERN =
"*.s.md"
Instance Attribute Summary collapse
-
#last_folder_counts ⇒ Object
readonly
Returns the value of attribute last_folder_counts.
-
#last_scan_total ⇒ Object
readonly
Returns the value of attribute last_scan_total.
Instance Method Summary collapse
-
#initialize(root_dir) ⇒ TaskScanner
constructor
A new instance of TaskScanner.
-
#root_exists? ⇒ Boolean
Check if root directory exists.
-
#scan ⇒ Array<ScanResult>
Scan for all primary tasks (excludes subtask folders).
-
#scan_all ⇒ Array<ScanResult>
Scan for all items including subtask folders.
-
#scan_in_folder(folder) ⇒ Array<ScanResult>
Scan and filter by special folder or virtual filter.
-
#scan_subtasks(parent_dir, parent_id:) ⇒ Array<ScanResult>
Scan for subtask directories within a parent task directory.
Constructor Details
#initialize(root_dir) ⇒ TaskScanner
Returns a new instance of TaskScanner.
27 28 29 30 31 32 33 34 |
# File 'lib/ace/task/molecules/task_scanner.rb', line 27 def initialize(root_dir) @root_dir = root_dir @scanner = Ace::Support::Items::Molecules::DirectoryScanner.new( root_dir, file_pattern: FILE_PATTERN, id_extractor: TASK_ID_EXTRACTOR ) end |
Instance Attribute Details
#last_folder_counts ⇒ Object (readonly)
Returns the value of attribute last_folder_counts.
12 13 14 |
# File 'lib/ace/task/molecules/task_scanner.rb', line 12 def last_folder_counts @last_folder_counts end |
#last_scan_total ⇒ Object (readonly)
Returns the value of attribute last_scan_total.
12 13 14 |
# File 'lib/ace/task/molecules/task_scanner.rb', line 12 def last_scan_total @last_scan_total end |
Instance Method Details
#root_exists? ⇒ Boolean
Check if root directory exists
116 117 118 |
# File 'lib/ace/task/molecules/task_scanner.rb', line 116 def root_exists? Dir.exist?(@root_dir) end |
#scan ⇒ Array<ScanResult>
Scan for all primary tasks (excludes subtask folders).
38 39 40 |
# File 'lib/ace/task/molecules/task_scanner.rb', line 38 def scan @scanner.scan.reject { |sr| subtask_folder?(sr.folder_name) } end |
#scan_all ⇒ Array<ScanResult>
Scan for all items including subtask folders.
63 64 65 |
# File 'lib/ace/task/molecules/task_scanner.rb', line 63 def scan_all @scanner.scan end |
#scan_in_folder(folder) ⇒ Array<ScanResult>
Scan and filter by special folder or virtual filter
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/ace/task/molecules/task_scanner.rb', line 45 def scan_in_folder(folder) results = scan @last_scan_total = results.size @last_folder_counts = results.group_by(&:special_folder).transform_values(&:size) return results if folder.nil? virtual = Ace::Support::Items::Atoms::SpecialFolderDetector.virtual_filter?(folder) case virtual when :all then results when :next then results.select { |r| r.special_folder.nil? } else normalized = Ace::Support::Items::Atoms::SpecialFolderDetector.normalize(folder) results.select { |r| r.special_folder == normalized } end end |
#scan_subtasks(parent_dir, parent_id:) ⇒ Array<ScanResult>
Scan for subtask directories within a parent task directory. Subtask folders follow the pattern: parent_id.char-slug
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 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/ace/task/molecules/task_scanner.rb', line 73 def scan_subtasks(parent_dir, parent_id:) return [] unless Dir.exist?(parent_dir) results = [] Dir.entries(parent_dir).sort.each do |entry| next if entry.start_with?(".") full_path = File.join(parent_dir, entry) next unless File.directory?(full_path) subtask_id = nil slug = nil # Short format: "0-slug" or "a-slug" if (short_match = entry.match(/^([a-z0-9])-(.+)$/)) subtask_id = "#{parent_id}.#{short_match[1]}" slug = short_match[2] else next end spec_files = Dir.glob(File.join(full_path, FILE_PATTERN)) next if spec_files.empty? special_folder = Ace::Support::Items::Atoms::SpecialFolderDetector.detect_in_path( full_path, root: @root_dir ) results << Ace::Support::Items::Models::ScanResult.new( id: subtask_id, slug: slug, folder_name: entry, dir_path: full_path, file_path: spec_files.first, special_folder: special_folder ) end results.sort_by(&:id) end |