Render import:status as an aligned table
Assisted-by: GLM-5.3 via pi
diff --git a/tasks/import.rake b/tasks/import.rake
index 0888845..fc48ad5 100644
--- a/tasks/import.rake
+++ b/tasks/import.rake
@@ -87,22 +87,24 @@ namespace :import do
next
end
- # The statuses in their order through an import, so the line reads
- # as where the plan has got to rather than an alphabetical jumble.
- plans.each do
- host = it.host ? "on #{it.host}" : "not yet on a host"
- puts "#{it.dir.basename} #{it.source} #{host}"
- counts = it.contacts.group_by(&:status).transform_values(&:length)
- summary = [
- ["to land", counts.fetch(nil, 0)],
- ["landed", counts.fetch("landed", 0)],
- ["imported", counts.fetch("imported", 0)],
- ["removed", counts.fetch("removed", 0)],
- ].reject { |_, count| count.zero? }.map { |label, count| "#{count} #{label}" }.join(", ")
- word = it.contacts.size == 1 ? "contact" : "contacts"
- puts summary.empty? ? " #{it.contacts.size} #{word}" : " #{it.contacts.size} #{word}: #{summary}"
- end
-
+ # One aligned row per plan, the statuses as columns in their order
+ # through an import, so where a plan has got to is read off the
+ # row rather than parsed out of a sentence. The plan names are the
+ # directories', copy-pasteable into PLAN=.
+ headers = ["plan", "host", "contacts", "planned", "landed", "imported", "removed"]
+ rows = plans.map { |plan|
+ counts = plan.contacts.group_by(&:status).transform_values(&:length)
+ [plan.dir.basename.to_s, plan.host || "—", plan.contacts.size.to_s,
+ counts.fetch(nil, 0).to_s, counts.fetch("landed", 0).to_s,
+ counts.fetch("imported", 0).to_s, counts.fetch("removed", 0).to_s]
+ }
+ widths = headers.each_index.map { |i| [headers[i].length, *rows.map { it[i].length }].max }
+ table = rows.unshift(headers).map { |row|
+ row.each_with_index.map { |cell, i| cell.public_send(i < 2 ? :ljust : :rjust, widths[i]) }.join(" ")
+ }
+ puts table
+
+ puts ""
landing = plans.find(&ImportTasks::TO_LAND)
leaving = plans.find(&ImportTasks::TO_LEAVE)
puts "next: import:execute would land #{landing.dir.basename}" if landing
diff --git a/test/tasks/test_import.rb b/test/tasks/test_import.rb
index 2f29d52..4c714ac 100644
--- a/test/tasks/test_import.rb
+++ b/test/tasks/test_import.rb
@@ -28,12 +28,11 @@ class ImportStatusTaskTest < Minitest::Test
out, = run_task(root)
- assert_includes out, "macos-20260901T000000Z macos on https://contacts.example"
- assert_includes out, " 2 contacts: 1 imported, 1 removed"
- assert_includes out, "macos-20260916T180412Z macos not yet on a host"
- assert_includes out, " 1 contact: 1 to land"
- assert_includes out, "next: import:execute would land macos-20260916T180412Z"
- assert_includes out, "next: import:macos:remove would clear macos-20260901T000000Z"
+ assert_match(%r{plan\s+host\s+contacts\s+planned\s+landed\s+imported\s+removed}, out)
+ assert_match(/macos-20260901T000000Z\s+https:\/\/contacts\.example\s+2\s+0\s+0\s+1\s+1/, out)
+ assert_match(/macos-20260916T180412Z\s+—\s+1\s+1\s+0\s+0\s+0/, out)
+ assert_includes out, "next: import:execute would land macos-20260916T180412Z\n"
+ assert_includes out, "next: import:macos:remove would clear macos-20260901T000000Z\n"
end
end