Class: Carson::Waybill
- Inherits:
-
Object
- Object
- Carson::Waybill
- Defined in:
- lib/carson/waybill.rb
Overview
The shipping document filed with the bureau (GitHub PR). Has a tracking number, knows the bureaucrats’ response (cleared/held/ accepted/rejected), and can ask the bureau to accept the parcel into the registry. Uses gh CLI internally — that’s a tool, not the domain.
Instance Attribute Summary collapse
-
#label ⇒ Object
readonly
Returns the value of attribute label.
-
#tracking_number ⇒ Object
readonly
Returns the value of attribute tracking_number.
-
#url ⇒ Object
readonly
Returns the value of attribute url.
Instance Method Summary collapse
-
#accept!(method:) ⇒ Object
Ask the bureau to accept the parcel into the registry.
-
#accepted? ⇒ Boolean
Has the bureau accepted the parcel into the registry?.
-
#cleared? ⇒ Boolean
Has the bureau cleared the parcel for delivery? All bureaucrats pass, no merge blocks, merge state is clean.
-
#default_title ⇒ Object
Generate a human-readable title from the label.
-
#draft? ⇒ Boolean
Is the waybill still a draft?.
-
#file!(title: nil, body_file: nil) ⇒ Object
File the waybill with the bureau.
-
#filed? ⇒ Boolean
Has the waybill been filed with the bureau?.
-
#held? ⇒ Boolean
Is something blocking this waybill?.
-
#hold_reason ⇒ Object
Why is the waybill being held?.
-
#hold_summary ⇒ Object
Human-readable explanation of why the waybill is held.
-
#initialize(label:, warehouse_path:, tracking_number: nil, url: nil, review_gate: nil) ⇒ Waybill
constructor
A new instance of Waybill.
-
#mergeability_pending? ⇒ Boolean
Is the hold specifically because mergeability is still pending?.
-
#refresh! ⇒ Object
Check with the bureau for the latest on this waybill.
-
#rejected? ⇒ Boolean
Has the bureau rejected the waybill (closed without merge)?.
-
#stub_bureau_response(state: nil, ci: nil) ⇒ Object
Stub the bureau’s response for testing without gh CLI.
-
#to_observation ⇒ Object
Returns a hash of the bureau’s current state for tracking records.
Constructor Details
#initialize(label:, warehouse_path:, tracking_number: nil, url: nil, review_gate: nil) ⇒ Waybill
Returns a new instance of Waybill.
25 26 27 28 29 30 31 32 33 |
# File 'lib/carson/waybill.rb', line 25 def initialize( label:, warehouse_path:, tracking_number: nil, url: nil, review_gate: nil ) @label = label @warehouse_path = warehouse_path @tracking_number = tracking_number @url = url @review_gate = review_gate @state = nil @ci = nil end |
Instance Attribute Details
#label ⇒ Object (readonly)
Returns the value of attribute label.
23 24 25 |
# File 'lib/carson/waybill.rb', line 23 def label @label end |
#tracking_number ⇒ Object (readonly)
Returns the value of attribute tracking_number.
23 24 25 |
# File 'lib/carson/waybill.rb', line 23 def tracking_number @tracking_number end |
#url ⇒ Object (readonly)
Returns the value of attribute url.
23 24 25 |
# File 'lib/carson/waybill.rb', line 23 def url @url end |
Instance Method Details
#accept!(method:) ⇒ Object
Ask the bureau to accept the parcel into the registry. Updates own state after the attempt.
149 150 151 152 153 |
# File 'lib/carson/waybill.rb', line 149 def accept!( method: ) gh( "pr", "merge", tracking_number.to_s, "--#{method}" ) refresh! self end |
#accepted? ⇒ Boolean
Has the bureau accepted the parcel into the registry?
82 83 84 |
# File 'lib/carson/waybill.rb', line 82 def accepted? @state&.dig( "state" ) == "MERGED" end |
#cleared? ⇒ Boolean
Has the bureau cleared the parcel for delivery? All bureaucrats pass, no merge blocks, merge state is clean.
98 99 100 101 102 103 104 105 106 |
# File 'lib/carson/waybill.rb', line 98 def cleared? return false unless filed? return false if draft? return false unless @ci == :pass return false if merge_conflicting? || merge_behind? || merge_policy_blocked? merge_status = @state&.dig( "mergeStateStatus" ).to_s.upcase mergeable = @state&.dig( "mergeable" ).to_s.upcase merge_status == "CLEAN" || mergeable == "MERGEABLE" end |
#default_title ⇒ Object
Generate a human-readable title from the label.
66 67 68 69 70 |
# File 'lib/carson/waybill.rb', line 66 def default_title label.tr( "-", " " ).gsub( "/", ": " ).sub( /\A\w/ ) do |character| character.upcase end end |
#draft? ⇒ Boolean
Is the waybill still a draft?
92 93 94 |
# File 'lib/carson/waybill.rb', line 92 def draft? @state&.dig( "isDraft" ) || false end |
#file!(title: nil, body_file: nil) ⇒ Object
File the waybill with the bureau. Creates a PR on GitHub.
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/carson/waybill.rb', line 43 def file!( title: nil, body_file: nil ) filing_title = title || default_title arguments = [ "pr", "create", "--title", filing_title, "--head", label ] if body_file && File.exist?( body_file ) arguments.push( "--body-file", body_file ) else arguments.push( "--body", "" ) end stdout, stderr, success, = gh( *arguments ) if success @url = stdout.to_s.strip @tracking_number = @url.split( "/" ).last.to_i @tracking_number = nil if @tracking_number == 0 end # If create failed or returned no number, try to find existing. find_existing! unless filed? self end |
#filed? ⇒ Boolean
Has the waybill been filed with the bureau?
38 39 40 |
# File 'lib/carson/waybill.rb', line 38 def filed? !tracking_number.nil? end |
#held? ⇒ Boolean
Is something blocking this waybill?
109 110 111 112 |
# File 'lib/carson/waybill.rb', line 109 def held? return false if cleared? || accepted? || rejected? filed? end |
#hold_reason ⇒ Object
Why is the waybill being held?
115 116 117 118 119 120 121 122 123 124 |
# File 'lib/carson/waybill.rb', line 115 def hold_reason return "draft" if draft? return "pending_at_registry" if @ci == :pending return "failed_at_registry" if @ci == :fail return "error_at_registry" if @ci == :error return "merge_conflict" if merge_conflicting? return "behind_registry" if merge_behind? return "policy_block" if merge_policy_blocked? "mergeability_pending" end |
#hold_summary ⇒ Object
Human-readable explanation of why the waybill is held.
127 128 129 130 131 132 133 134 135 136 137 138 |
# File 'lib/carson/waybill.rb', line 127 def hold_summary case hold_reason when "draft" then "waybill is still a draft" when "pending_at_registry" then "waiting for bureaucrats to check" when "failed_at_registry" then "bureaucrats rejected the parcel" when "error_at_registry" then "unable to reach the bureaucrats" when "merge_conflict" then "parcel has conflicts with registry" when "behind_registry" then "parcel is behind the registry" when "policy_block" then "blocked by bureau policy" else "waiting for bureau assessment" end end |
#mergeability_pending? ⇒ Boolean
Is the hold specifically because mergeability is still pending?
141 142 143 |
# File 'lib/carson/waybill.rb', line 141 def mergeability_pending? hold_reason == "mergeability_pending" end |
#refresh! ⇒ Object
Check with the bureau for the latest on this waybill.
75 76 77 78 79 |
# File 'lib/carson/waybill.rb', line 75 def refresh! @state = fetch_state @ci = fetch_ci self end |
#rejected? ⇒ Boolean
Has the bureau rejected the waybill (closed without merge)?
87 88 89 |
# File 'lib/carson/waybill.rb', line 87 def rejected? @state&.dig( "state" ) == "CLOSED" end |
#stub_bureau_response(state: nil, ci: nil) ⇒ Object
Stub the bureau’s response for testing without gh CLI.
171 172 173 174 |
# File 'lib/carson/waybill.rb', line 171 def stub_bureau_response( state: nil, ci: nil ) @state = state if state @ci = ci if ci end |
#to_observation ⇒ Object
Returns a hash of the bureau’s current state for tracking records.
158 159 160 161 162 163 164 165 166 |
# File 'lib/carson/waybill.rb', line 158 def to_observation return {} unless @state.is_a?( Hash ) { pull_request_state: @state[ "state" ], pull_request_draft: @state[ "isDraft" ], pull_request_merged_at: @state[ "mergedAt" ] } end |