Class: Hiiro::PinnedPr

Inherits:
Object
  • Object
show all
Defined in:
lib/hiiro/pinned_pr.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.by_slotObject

— Class methods —



75
76
77
# File 'lib/hiiro/pinned_pr.rb', line 75

def self.by_slot
  order(:slot).where(pinned: true)
end

.create_table!(db) ⇒ Object



7
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/hiiro/pinned_pr.rb', line 7

def self.create_table!(db)
  # Drop the old TrackedPr schema (prs table without head_ref_name) so we can
  # create the merged schema. TrackedPr rows are migration artifacts only — no
  # live code reads from them.
  if db.table_exists?(:prs) && !db.schema(:prs).any? { |col, _| col == :head_ref_name }
    db.drop_table(:prs)
  end

  db.create_table?(:prs) do
    primary_key :id
    Integer :number
    String :title
    String :state
    String :url
    String :head_ref_name
    String :branch             # from old TrackedPr
    String :repo
    Integer :slot
    TrueClass :pinned          # true = pinned/monitored, false/nil = just tracked
    TrueClass :is_draft
    String :mergeable
    String :review_decision
    String :checks_json        # JSON: { total, success, pending, failed, frozen }
    String :check_runs_json    # JSON array of raw statusCheckRollup nodes
    String :reviews_json       # JSON: { approved, changes_requested, reviewers }
    String :task
    String :worktree
    String :tmux_session
    String :tmux_json          # from old TrackedPr: JSON { session, window, pane }
    String :tags_json          # JSON array of strings
    TrueClass :assigned
    TrueClass :authored
    String :depends_on_json    # JSON array of PR numbers
    String :last_checked
    String :pinned_at
    String :created_at
    String :updated_at
  end

  # Migrate data from legacy pinned_prs table if it still exists
  if db.table_exists?(:pinned_prs) && db[:pinned_prs].count > 0
    db[:pinned_prs].each do |row|
      db[:prs].insert(row.reject { |k, _| k == :id }.merge(pinned: true))
    end
  end
  db.drop_table?(:pinned_prs)
end

.find_by_number(n) ⇒ Object



79
80
81
# File 'lib/hiiro/pinned_pr.rb', line 79

def self.find_by_number(n)
  where(number: n, pinned: true).first
end

.from_git_pr(pr) ⇒ Object

Build an in-memory PinnedPr from a Hiiro::Git::Pr (does NOT save).



90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/hiiro/pinned_pr.rb', line 90

def self.from_git_pr(pr)
  new(
    number:          pr.number,
    title:           pr.title,
    state:           pr.state,
    url:             pr.url,
    head_ref_name:   pr.head_branch,
    repo:            pr.repo,
    slot:            pr.slot,
    pinned:          true,
    is_draft:        pr.is_draft,
    mergeable:       pr.mergeable,
    review_decision: pr.review_decision,
    checks_json:     Hiiro::DB::JSON.dump(pr.checks),
    check_runs_json: Hiiro::DB::JSON.dump(pr.check_runs),
    reviews_json:    Hiiro::DB::JSON.dump(pr.reviews),
    tags_json:       Hiiro::DB::JSON.dump(pr.tags),
    depends_on_json: Hiiro::DB::JSON.dump(pr.depends_on),
    task:            pr.task,
    worktree:        pr.worktree,
    tmux_session:    pr.tmux_session,
    assigned:        pr.assigned,
    authored:        pr.authored,
    last_checked:    pr.last_checked,
    pinned_at:       pr.pinned_at,
    updated_at:      pr.updated_at,
  )
end

Instance Method Details

#active?Boolean

Returns:

  • (Boolean)


191
# File 'lib/hiiro/pinned_pr.rb', line 191

def active?    = !merged? && !closed?

#check_runsObject



58
# File 'lib/hiiro/pinned_pr.rb', line 58

def check_runs  = Hiiro::DB::JSON.load(check_runs_json)

#check_runs=(v) ⇒ Object



64
# File 'lib/hiiro/pinned_pr.rb', line 64

def check_runs=(v) self.check_runs_json = Hiiro::DB::JSON.dump(v) end

#checksObject

— JSON virtual accessors —



57
# File 'lib/hiiro/pinned_pr.rb', line 57

def checks      = Hiiro::DB::JSON.load(checks_json)

#checks=(v) ⇒ Object



63
# File 'lib/hiiro/pinned_pr.rb', line 63

def checks=(v)     self.checks_json     = Hiiro::DB::JSON.dump(v) end

#closed?Boolean

Returns:

  • (Boolean)


182
# File 'lib/hiiro/pinned_pr.rb', line 182

def closed?      = state&.upcase == 'CLOSED'

#conflicting?Boolean

Returns:

  • (Boolean)


185
# File 'lib/hiiro/pinned_pr.rb', line 185

def conflicting? = mergeable == 'CONFLICTING'

#conflicts?Boolean

Returns:

  • (Boolean)


193
# File 'lib/hiiro/pinned_pr.rb', line 193

def conflicts? = conflicting?

#depends_onObject



61
# File 'lib/hiiro/pinned_pr.rb', line 61

def depends_on  = Hiiro::DB::JSON.load(depends_on_json)

#depends_on=(v) ⇒ Object



67
# File 'lib/hiiro/pinned_pr.rb', line 67

def depends_on=(v) self.depends_on_json = Hiiro::DB::JSON.dump(v) end

#draft?Boolean

Returns:

  • (Boolean)


184
# File 'lib/hiiro/pinned_pr.rb', line 184

def draft?       = is_draft == true

#drafts?Boolean

Returns:

  • (Boolean)


192
# File 'lib/hiiro/pinned_pr.rb', line 192

def drafts?    = draft?

#green?Boolean

Returns:

  • (Boolean)


188
# File 'lib/hiiro/pinned_pr.rb', line 188

def green?   = (c = checks) && c['failed'].to_i == 0 && c['pending'].to_i == 0 && c['success'].to_i > 0

#head_branchObject

Backward-compat alias — PinnedPRManager and display code use head_branch



70
# File 'lib/hiiro/pinned_pr.rb', line 70

def head_branch     = head_ref_name

#head_branch=(v) ⇒ Object



71
# File 'lib/hiiro/pinned_pr.rb', line 71

def head_branch=(v) self.head_ref_name = v end

#matches_filters?(opts, forced: []) ⇒ Boolean

Returns:

  • (Boolean)


195
196
197
198
199
200
201
202
203
# File 'lib/hiiro/pinned_pr.rb', line 195

def matches_filters?(opts, forced: [])
  state_active = Hiiro::Git::Pr::STATE_FILTER_KEYS.select { |k| forced.include?(k) || (opts.respond_to?(k) && opts.send(k)) }
  check_active = Hiiro::Git::Pr::CHECK_FILTER_KEYS.select { |k| forced.include?(k) || (opts.respond_to?(k) && opts.send(k)) }

  state_match = state_active.empty? || state_active.any? { |k| send(:"#{k}?") }
  check_match = check_active.empty? || check_active.any? { |k| send(:"#{k}?") }

  state_match && check_match
end

#merged?Boolean

Returns:

  • (Boolean)


183
# File 'lib/hiiro/pinned_pr.rb', line 183

def merged?      = state&.upcase == 'MERGED'

#open?Boolean

— Predicates (mirroring Hiiro::Git::Pr) —

Returns:

  • (Boolean)


181
# File 'lib/hiiro/pinned_pr.rb', line 181

def open?        = state&.upcase == 'OPEN'

#pending?Boolean

Returns:

  • (Boolean)


189
# File 'lib/hiiro/pinned_pr.rb', line 189

def pending? = (c = checks) && c['pending'].to_i > 0 && c['failed'].to_i == 0

#red?Boolean

Returns:

  • (Boolean)


187
# File 'lib/hiiro/pinned_pr.rb', line 187

def red?     = (c = checks) && c['failed'].to_i > 0

#reviewsObject



59
# File 'lib/hiiro/pinned_pr.rb', line 59

def reviews     = Hiiro::DB::JSON.load(reviews_json)

#reviews=(v) ⇒ Object



65
# File 'lib/hiiro/pinned_pr.rb', line 65

def reviews=(v)    self.reviews_json    = Hiiro::DB::JSON.dump(v) end

#sync_check_runsObject

Sync the check_runs table for this PR from the cached check_runs_json blob.



84
85
86
87
# File 'lib/hiiro/pinned_pr.rb', line 84

def sync_check_runs
  runs = Hiiro::DB::JSON.load(check_runs_json)
  Hiiro::CheckRun.upsert_for_pr(number, runs) if number && runs
end

#tagsObject



60
# File 'lib/hiiro/pinned_pr.rb', line 60

def tags        = Hiiro::DB::JSON.load(tags_json) || []

#tags=(v) ⇒ Object



66
# File 'lib/hiiro/pinned_pr.rb', line 66

def tags=(v)       self.tags_json       = Hiiro::DB::JSON.dump(v) end

#to_git_prObject

Convert back to a Hiiro::Git::Pr for API calls or display code that expects it.



122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/hiiro/pinned_pr.rb', line 122

def to_git_pr
  Hiiro::Git::Pr.new(
    number:          number,
    title:           title,
    state:           state,
    url:             url,
    head_branch:     head_ref_name,
    repo:            repo,
    slot:            slot,
    is_draft:        is_draft,
    mergeable:       mergeable,
    review_decision: review_decision,
    checks:          checks,
    check_runs:      check_runs,
    reviews:         reviews,
    task:            task,
    worktree:        worktree,
    tmux_session:    tmux_session,
    tags:            tags,
    assigned:        assigned,
    authored:        authored,
    depends_on:      depends_on,
    last_checked:    last_checked,
    pinned_at:       pinned_at,
    updated_at:      updated_at,
  )
end

#to_pinned_hObject

Serialize to string-keyed hash for YAML dual-write (mirrors Git::Pr#to_pinned_h).



151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/hiiro/pinned_pr.rb', line 151

def to_pinned_h
  {
    'number'            => number,
    'title'             => title,
    'state'             => state,
    'url'               => url,
    'headRefName'       => head_ref_name,
    'repo'              => repo,
    'slot'              => slot,
    'is_draft'          => is_draft,
    'mergeable'         => mergeable,
    'review_decision'   => review_decision,
    'checks'            => checks,
    'statusCheckRollup' => check_runs,
    'reviews'           => reviews,
    'last_checked'      => last_checked,
    'pinned_at'         => pinned_at,
    'updated_at'        => updated_at,
    'task'              => task,
    'worktree'          => worktree,
    'tmux_session'      => tmux_session,
    'tags'              => (Array(tags).empty? ? nil : tags),
    'assigned'          => assigned,
    'authored'          => authored,
    'depends_on'        => (Array(depends_on).empty? ? nil : depends_on),
  }.compact
end

#to_sObject



205
# File 'lib/hiiro/pinned_pr.rb', line 205

def to_s = "##{number}: #{title}"