Module: Harnex::TerminalStatus
- Defined in:
- lib/harnex/terminal_status.rb
Class Method Summary collapse
- .blank_to_nil(value) ⇒ Object
- .build_from_history(record, fallback_repo_root) ⇒ Object
- .build_from_summary(record, summary_path, fallback_repo_root) ⇒ Object
- .classify_summary_state(actual) ⇒ Object
- .history_exit(status) ⇒ Object
- .history_paths(repo_root) ⇒ Object
- .history_record?(record) ⇒ Boolean
- .history_time(record) ⇒ Object
- .newer_history?(candidate, current) ⇒ Boolean
- .newer_summary?(candidate, current) ⇒ Boolean
- .parse_time(value) ⇒ Object
- .resolve(id:, repo_root: Dir.pwd) ⇒ Object
- .scan_dispatch_path(path, id) ⇒ Object
- .summary_record?(record) ⇒ Boolean
- .summary_time(record) ⇒ Object
- .unknown(id:, repo_root: Dir.pwd) ⇒ Object
Class Method Details
.blank_to_nil(value) ⇒ Object
197 198 199 200 |
# File 'lib/harnex/terminal_status.rb', line 197 def blank_to_nil(value) text = value.to_s text.empty? ? nil : text end |
.build_from_history(record, fallback_repo_root) ⇒ Object
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 |
# File 'lib/harnex/terminal_status.rb', line 156 def build_from_history(record, fallback_repo_root) status = record["status"].to_s state = case status when "completed" "completed" when "failed", "timeout", "killed" "failed" else "unknown" end { "id" => record["id"].to_s, "repo_root" => fallback_repo_root, "state" => state, "terminal" => state != "unknown", "task_complete" => record["terminal_event"].to_s == "task_complete", "exit" => history_exit(status), "exit_code" => nil, "summary_out" => blank_to_nil(record["summary_out_path"]), "started_at" => record["started_at"], "ended_at" => record["ended_at"], "source" => "dispatch_history" } end |
.build_from_summary(record, summary_path, fallback_repo_root) ⇒ Object
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
# File 'lib/harnex/terminal_status.rb', line 126 def build_from_summary(record, summary_path, fallback_repo_root) = record["meta"] || {} actual = record["actual"] || {} state = classify_summary_state(actual) { "id" => ["id"].to_s, "repo_root" => ["repo"] || fallback_repo_root, "state" => state, "terminal" => state != "unknown", "task_complete" => !!actual["task_complete"], "exit" => blank_to_nil(actual["exit"]), "exit_code" => actual["exit_code"], "summary_out" => summary_path, "started_at" => ["started_at"], "ended_at" => ["ended_at"], "source" => "summary_out" } end |
.classify_summary_state(actual) ⇒ Object
145 146 147 148 149 150 151 152 153 154 |
# File 'lib/harnex/terminal_status.rb', line 145 def classify_summary_state(actual) exit = actual["exit"].to_s exit_code = actual["exit_code"] return "completed" if exit == "success" return "completed" if exit.empty? && exit_code == 0 return "failed" unless exit.empty? && exit_code.nil? "unknown" end |
.history_exit(status) ⇒ Object
182 183 184 185 186 187 188 189 190 191 192 193 194 195 |
# File 'lib/harnex/terminal_status.rb', line 182 def history_exit(status) case status when "completed" "success" when "timeout" "timeout" when "killed" "killed" when "failed" "failure" else nil end end |
.history_paths(repo_root) ⇒ Object
56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/harnex/terminal_status.rb', line 56 def history_paths(repo_root) local_path = DispatchHistory.path_for(repo_root) return [local_path] if File.file?(local_path) global_path = DispatchHistory.global_path return [global_path] if File.file?(global_path) [] rescue StandardError [] end |
.history_record?(record) ⇒ Boolean
94 95 96 |
# File 'lib/harnex/terminal_status.rb', line 94 def history_record?(record) record["schema_version"] == 1 && record.key?("status") end |
.history_time(record) ⇒ Object
116 117 118 |
# File 'lib/harnex/terminal_status.rb', line 116 def history_time(record) parse_time(record["ended_at"]) || parse_time(record["started_at"]) || Time.at(0) end |
.newer_history?(candidate, current) ⇒ Boolean
105 106 107 108 109 110 |
# File 'lib/harnex/terminal_status.rb', line 105 def newer_history?(candidate, current) return false unless candidate return true unless current history_time(candidate) >= history_time(current) end |
.newer_summary?(candidate, current) ⇒ Boolean
98 99 100 101 102 103 |
# File 'lib/harnex/terminal_status.rb', line 98 def newer_summary?(candidate, current) return false unless candidate return true unless current summary_time(candidate) >= summary_time(current) end |
.parse_time(value) ⇒ Object
120 121 122 123 124 |
# File 'lib/harnex/terminal_status.rb', line 120 def parse_time(value) Time.iso8601(value.to_s) rescue ArgumentError nil end |
.resolve(id:, repo_root: Dir.pwd) ⇒ Object
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'lib/harnex/terminal_status.rb', line 8 def resolve(id:, repo_root: Dir.pwd) normalized_id = Harnex.normalize_id(id) root = File.(repo_root.to_s.empty? ? Dir.pwd : repo_root) latest_summary = nil latest_summary_path = nil latest_history = nil history_paths(root).each do |path| summary, history = scan_dispatch_path(path, normalized_id) if newer_summary?(summary, latest_summary) latest_summary = summary latest_summary_path = path end latest_history = history if newer_history?(history, latest_history) end summary_path = latest_history && latest_history["summary_out_path"].to_s.strip if summary_path && !summary_path.empty? && File.file?(summary_path) summary, = scan_dispatch_path(summary_path, normalized_id) if newer_summary?(summary, latest_summary) latest_summary = summary latest_summary_path = summary_path end end return build_from_summary(latest_summary, latest_summary_path, root) if latest_summary return build_from_history(latest_history, root) if latest_history nil end |
.scan_dispatch_path(path, id) ⇒ Object
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/harnex/terminal_status.rb', line 68 def scan_dispatch_path(path, id) summary_record = nil history_record = nil File.foreach(path) do |line| record = JSON.parse(line) next unless record.is_a?(Hash) if summary_record?(record) && record.dig("meta", "id").to_s == id summary_record = record elsif history_record?(record) && record["id"].to_s == id history_record = record end rescue JSON::ParserError next end [summary_record, history_record] rescue Errno::ENOENT [nil, nil] end |
.summary_record?(record) ⇒ Boolean
90 91 92 |
# File 'lib/harnex/terminal_status.rb', line 90 def summary_record?(record) record["meta"].is_a?(Hash) && record["actual"].is_a?(Hash) end |
.summary_time(record) ⇒ Object
112 113 114 |
# File 'lib/harnex/terminal_status.rb', line 112 def summary_time(record) parse_time(record.dig("meta", "ended_at")) || parse_time(record.dig("meta", "started_at")) || Time.at(0) end |
.unknown(id:, repo_root: Dir.pwd) ⇒ Object
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/harnex/terminal_status.rb', line 40 def unknown(id:, repo_root: Dir.pwd) { "id" => Harnex.normalize_id(id), "repo_root" => File.(repo_root.to_s.empty? ? Dir.pwd : repo_root), "state" => "unknown", "terminal" => false, "task_complete" => false, "exit" => nil, "exit_code" => nil, "summary_out" => nil, "started_at" => nil, "ended_at" => nil, "source" => "none" } end |