Class: Hubkit::Issue

Inherits:
Object
  • Object
show all
Defined in:
lib/hubkit/issue.rb

Overview

Represents one issue in github

Constant Summary collapse

ISSUE_PATTERN =

A regex which matches a textual name of an issue i.e. dingus/123 or foobar/dingus/123

%r{
  (
    (?<org>[^/]+)/(?<repo>[^/]+)
    |
    (?<repo>[^/]+)
  )
  /
  (?<number>[0-9]+)
}x

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(org:, repo:, number:) ⇒ Issue

Create a new issue model


58
59
60
61
62
# File 'lib/hubkit/issue.rb', line 58

def initialize(org:, repo:, number:)
  @org = org
  @repo = repo
  @number = number
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args, &block) ⇒ Object

Allow access to elements of the github payload by calling the names as methods


180
181
182
183
# File 'lib/hubkit/issue.rb', line 180

def method_missing(name, *args, &block)
  return to_gh[name] if args.length == 0 && !block_given? && to_gh.key?(name)
  super
end

Instance Attribute Details

#numberFixnum

the issue's number


6
7
8
# File 'lib/hubkit/issue.rb', line 6

def number
  @number
end

#orgString

the github organization name of the issue


6
7
8
# File 'lib/hubkit/issue.rb', line 6

def org
  @org
end

#repoString

the github repo name


6
7
8
# File 'lib/hubkit/issue.rb', line 6

def repo
  @repo
end

Class Method Details

.from_gh(org:, repo:, gh:) ⇒ Object

Create an Issue model from a github api payload. Preseeds the github payload of the model to avoid refetching from the API later.


46
47
48
49
50
# File 'lib/hubkit/issue.rb', line 46

def self.from_gh(org:, repo:, gh:)
  new(org: org, repo: repo, number: gh['number']).tap do |issue|
    issue.instance_variable_set(:@_to_gh, gh)
  end
end

.from_name(name) ⇒ Hubkit::Issue

Create an Issue model from the textual name of the issue

Examples:

Hubkit::Issue.from_name('foobar/dingus/123')

25
26
27
# File 'lib/hubkit/issue.rb', line 25

def self.from_name(name)
  new(**parameters_from_name(name))
end

.parameters_from_name(name) ⇒ Hash

Parse an issue name into org, repo, and number


32
33
34
35
36
37
38
39
# File 'lib/hubkit/issue.rb', line 32

def self.parameters_from_name(name)
  match_data = Issue::ISSUE_PATTERN.match(name)
  {
    org: match_data[:org] || Hubkit::Configuration.default_org,
    repo: match_data[:repo],
    number: match_data[:number],
  }
end

Instance Method Details

#event_paginatorEventPaginator

Returns a paginator for fetching all events for this issue


149
150
151
152
153
154
155
# File 'lib/hubkit/issue.rb', line 149

def event_paginator
  EventPaginator.new(
    org: @org,
    repo: @repo,
    issue_number: @number,
  )
end

#eventsEventCollection

The EventCollection of events related to this Issue


139
140
141
142
143
144
145
# File 'lib/hubkit/issue.rb', line 139

def events
  @_events ||=
    EventCollection.new(
      event_paginator,
    )
    .reverse_chronological
end

#label!(label) ⇒ Enumerable

Add a label to an issue


79
80
81
82
# File 'lib/hubkit/issue.rb', line 79

def label!(label)
  Hubkit.client.issues.labels.add @org, @repo, @number, label
  labels.append(label).uniq!
end

#labelsEnumerable

A list of all of the current labels of the issue


72
73
74
# File 'lib/hubkit/issue.rb', line 72

def labels
  @_labels ||= to_gh['labels'].map { |label| label.name.downcase }
end

#pull?Boolean

Returns true if the issue is a pull request


105
106
107
# File 'lib/hubkit/issue.rb', line 105

def pull?
  to_gh['pull_request'].present?
end

#to_ghGithub::Mash

The issue payload from the github API


66
67
68
# File 'lib/hubkit/issue.rb', line 66

def to_gh
  @_to_gh ||= Github.issues.get(@org, @repo, @number).body
end

#to_textString

A plaintext version of the issue, with the name, title, and body


170
171
172
# File 'lib/hubkit/issue.rb', line 170

def to_text
  "#{number}: #{title}\n---\n#{body}\n"
end

#true_issue?Boolean

Returns true if the issue is not a pull request


111
112
113
# File 'lib/hubkit/issue.rb', line 111

def true_issue?
  !pull?
end

#unlabel! {|label_name| ... } ⇒ Enumerable

Remove a label from an issue

Yield Parameters:

  • label_name (String)

    a current label. if the block returns true, this label will be removed from the list


88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/hubkit/issue.rb', line 88

def unlabel!(&block)
  fail('Block is required for unlabel') unless block_given?
  to_gh.labels.map(&:name)
  .select do |label_name|
    yield label_name
  end
  .each do |label_name|
    Hubkit.client.issues.labels.remove @org, @repo, @number, label_name: label_name
    labels.delete(label_name)
  end
  labels
end

#users_ever_assignedEnumerable

Return the list of usernames of every user ever assigned to an issue


160
161
162
163
164
165
# File 'lib/hubkit/issue.rb', line 160

def users_ever_assigned
  events
    .select { |event| event.event == 'assigned' }
    .map { |event| event.assignee. }
    .uniq
end

#when_closedDateTime

Returns when the issue was closed


132
133
134
135
# File 'lib/hubkit/issue.rb', line 132

def when_closed
  return unless events.closed.any?
  Time.parse(events.closed.first['created_at'])
end

#when_labeled(label) ⇒ Date

Returns the time at which the issue was labeled `label`. It will return the time of the latest such event.


119
120
121
122
# File 'lib/hubkit/issue.rb', line 119

def when_labeled(label)
  return unless events.labeled(label).any?
  Time.parse(events.labeled(label).first['created_at'])
end

#when_openedDateTime

Returns when the issue was opened


126
127
128
# File 'lib/hubkit/issue.rb', line 126

def when_opened
  Time.parse(created_at)
end