Class: Carson::Ledger
- Inherits:
-
Object
- Object
- Carson::Ledger
- Defined in:
- lib/carson/ledger.rb
Constant Summary collapse
- UNSET =
Object.new
- ACTIVE_DELIVERY_STATES =
Delivery::ACTIVE_STATES
- SQLITE_HEADER =
"SQLite format 3\0".b.freeze
Instance Attribute Summary collapse
-
#path ⇒ Object
readonly
Returns the value of attribute path.
Instance Method Summary collapse
-
#active_deliveries(repo_path:) ⇒ Object
Lists active deliveries for a repository in creation order.
-
#active_delivery(repo_path:, branch_name:) ⇒ Object
Looks up the active delivery for a branch, if one exists.
-
#initialize(path:) ⇒ Ledger
constructor
A new instance of Ledger.
-
#integrated_deliveries(repo_path:) ⇒ Object
Lists integrated deliveries that still retain a worktree path.
-
#latest_delivery(repo_path:, branch_name:) ⇒ Object
Looks up the newest delivery for a branch across active and terminal states.
-
#record_revision(delivery:, cause:, provider:, status:, summary:) ⇒ Object
Records one revision cycle against a delivery.
-
#revisions_for_delivery(delivery:) ⇒ Object
Returns revisions for a delivery in ascending order.
-
#update_delivery(delivery:, status: UNSET, pr_number: UNSET, pr_url: UNSET, pull_request_state: UNSET, pull_request_draft: UNSET, pull_request_merged_at: UNSET, merge_proof: UNSET, cause: UNSET, summary: UNSET, worktree_path: UNSET, integrated_at: UNSET, superseded_at: UNSET) ⇒ Object
Updates a delivery record in place.
-
#upsert_delivery(repository:, branch_name:, head:, worktree_path:, pr_number:, pr_url:, status:, summary:, cause:, pull_request_state: nil, pull_request_draft: nil, pull_request_merged_at: nil, merge_proof: nil) ⇒ Object
Creates or refreshes a delivery for the same branch head.
Constructor Details
#initialize(path:) ⇒ Ledger
Returns a new instance of Ledger.
12 13 14 15 16 |
# File 'lib/carson/ledger.rb', line 12 def initialize( path: ) @path = File.( path ) FileUtils.mkdir_p( File.dirname( @path ) ) migrate_legacy_state_if_needed! end |
Instance Attribute Details
#path ⇒ Object (readonly)
Returns the value of attribute path.
18 19 20 |
# File 'lib/carson/ledger.rb', line 18 def path @path end |
Instance Method Details
#active_deliveries(repo_path:) ⇒ Object
Lists active deliveries for a repository in creation order.
101 102 103 104 105 106 107 108 109 |
# File 'lib/carson/ledger.rb', line 101 def active_deliveries( repo_path: ) state = load_state repo_paths = repo_identity_paths( repo_path: repo_path ) state[ "deliveries" ] .select { |_key, data| repo_paths.include?( data[ "repo_path" ] ) && ACTIVE_DELIVERY_STATES.include?( data[ "status" ] ) } .sort_by { |key, data| [ delivery_sequence( data: data ), key ] } .map { |key, data| build_delivery( key: key, data: data ) } end |
#active_delivery(repo_path:, branch_name:) ⇒ Object
Looks up the active delivery for a branch, if one exists.
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/carson/ledger.rb', line 68 def active_delivery( repo_path:, branch_name: ) state = load_state repo_paths = repo_identity_paths( repo_path: repo_path ) candidates = state[ "deliveries" ].select do |_key, data| repo_paths.include?( data[ "repo_path" ] ) && data[ "branch_name" ] == branch_name && ACTIVE_DELIVERY_STATES.include?( data[ "status" ] ) end return nil if candidates.empty? key, data = candidates.max_by { |k, d| [ d[ "updated_at" ].to_s, delivery_sequence( data: d ), k ] } build_delivery( key: key, data: data ) end |
#integrated_deliveries(repo_path:) ⇒ Object
Lists integrated deliveries that still retain a worktree path.
112 113 114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/carson/ledger.rb', line 112 def integrated_deliveries( repo_path: ) state = load_state repo_paths = repo_identity_paths( repo_path: repo_path ) state[ "deliveries" ] .select do |_key, data| repo_paths.include?( data[ "repo_path" ] ) && data[ "status" ] == "integrated" && !data[ "worktree_path" ].to_s.strip.empty? end .sort_by { |key, data| [ data[ "integrated_at" ].to_s, delivery_sequence( data: data ), key ] } .map { |key, data| build_delivery( key: key, data: data ) } end |
#latest_delivery(repo_path:, branch_name:) ⇒ Object
Looks up the newest delivery for a branch across active and terminal states.
85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/carson/ledger.rb', line 85 def latest_delivery( repo_path:, branch_name: ) state = load_state repo_paths = repo_identity_paths( repo_path: repo_path ) candidates = state[ "deliveries" ].select do |_key, data| repo_paths.include?( data[ "repo_path" ] ) && data[ "branch_name" ] == branch_name end return nil if candidates.empty? key, data = candidates.max_by { |k, d| [ d[ "updated_at" ].to_s, delivery_sequence( data: d ), k ] } build_delivery( key: key, data: data ) end |
#record_revision(delivery:, cause:, provider:, status:, summary:) ⇒ Object
Records one revision cycle against a delivery.
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
# File 'lib/carson/ledger.rb', line 164 def record_revision( delivery:, cause:, provider:, status:, summary: ) = now_utc with_state do |state| _key, data = resolve_delivery_entry( state: state, delivery: delivery ) revisions = data[ "revisions" ] ||= [] next_number = ( revisions.map { |r| r[ "number" ].to_i }.max || 0 ) + 1 finished = %w[completed failed stalled].include?( status ) ? : nil revision_data = { "number" => next_number, "cause" => cause, "provider" => provider, "status" => status, "started_at" => , "finished_at" => finished, "summary" => summary } revisions << revision_data data[ "updated_at" ] = build_revision( data: revision_data ) end end |
#revisions_for_delivery(delivery:) ⇒ Object
Returns revisions for a delivery in ascending order.
191 192 193 |
# File 'lib/carson/ledger.rb', line 191 def revisions_for_delivery( delivery: ) delivery.revisions.sort_by( &:number ) end |
#update_delivery(delivery:, status: UNSET, pr_number: UNSET, pr_url: UNSET, pull_request_state: UNSET, pull_request_draft: UNSET, pull_request_merged_at: UNSET, merge_proof: UNSET, cause: UNSET, summary: UNSET, worktree_path: UNSET, integrated_at: UNSET, superseded_at: UNSET) ⇒ Object
Updates a delivery record in place.
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 |
# File 'lib/carson/ledger.rb', line 127 def update_delivery( delivery:, status: UNSET, pr_number: UNSET, pr_url: UNSET, pull_request_state: UNSET, pull_request_draft: UNSET, pull_request_merged_at: UNSET, merge_proof: UNSET, cause: UNSET, summary: UNSET, worktree_path: UNSET, integrated_at: UNSET, superseded_at: UNSET ) with_state do |state| key, data = resolve_delivery_entry( state: state, delivery: delivery ) data[ "status" ] = status unless status.equal?( UNSET ) data[ "pr_number" ] = pr_number unless pr_number.equal?( UNSET ) data[ "pr_url" ] = pr_url unless pr_url.equal?( UNSET ) data[ "pull_request_state" ] = pull_request_state unless pull_request_state.equal?( UNSET ) data[ "pull_request_draft" ] = pull_request_draft unless pull_request_draft.equal?( UNSET ) data[ "pull_request_merged_at" ] = pull_request_merged_at unless pull_request_merged_at.equal?( UNSET ) data[ "merge_proof" ] = serialise_merge_proof( merge_proof: merge_proof ) unless merge_proof.equal?( UNSET ) data[ "cause" ] = cause unless cause.equal?( UNSET ) data[ "summary" ] = summary unless summary.equal?( UNSET ) data[ "worktree_path" ] = worktree_path unless worktree_path.equal?( UNSET ) data[ "integrated_at" ] = integrated_at unless integrated_at.equal?( UNSET ) data[ "superseded_at" ] = superseded_at unless superseded_at.equal?( UNSET ) data[ "updated_at" ] = now_utc build_delivery( key: key, data: data, repository: delivery.repository ) end end |
#upsert_delivery(repository:, branch_name:, head:, worktree_path:, pr_number:, pr_url:, status:, summary:, cause:, pull_request_state: nil, pull_request_draft: nil, pull_request_merged_at: nil, merge_proof: nil) ⇒ Object
Creates or refreshes a delivery for the same branch head.
21 22 23 24 25 26 27 28 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 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/carson/ledger.rb', line 21 def upsert_delivery( repository:, branch_name:, head:, worktree_path:, pr_number:, pr_url:, status:, summary:, cause:, pull_request_state: nil, pull_request_draft: nil, pull_request_merged_at: nil, merge_proof: nil ) = now_utc with_state do |state| repo_paths = repo_identity_paths( repo_path: repository.path ) matches = matching_deliveries( state: state, repo_paths: repo_paths, branch_name: branch_name, head: head ) key = delivery_key( repo_path: repository.path, branch_name: branch_name, head: head ) sequence = matches.map { |_existing_key, data| delivery_sequence( data: data ) }.compact.min created_at = matches.map { |_existing_key, data| data.fetch( "created_at", "" ).to_s }.reject( &:empty? ).min || revisions = merged_revisions( entries: matches ) matches.each { |existing_key, _data| state[ "deliveries" ].delete( existing_key ) } supersede_branch!( state: state, repo_path: repository.path, branch_name: branch_name, timestamp: ) state[ "deliveries" ][ key ] = { "sequence" => sequence || next_delivery_sequence!( state: state ), "repo_path" => repository.path, "branch_name" => branch_name, "head" => head, "worktree_path" => worktree_path, "status" => status, "pr_number" => pr_number, "pr_url" => pr_url, "pull_request_state" => pull_request_state, "pull_request_draft" => pull_request_draft, "pull_request_merged_at" => pull_request_merged_at, "merge_proof" => serialise_merge_proof( merge_proof: merge_proof ), "cause" => cause, "summary" => summary, "created_at" => created_at, "updated_at" => , "integrated_at" => nil, "superseded_at" => nil, "revisions" => revisions } build_delivery( key: key, data: state[ "deliveries" ][ key ], repository: repository ) end end |