Class: SmartTodo::Events

Inherits:
Object
  • Object
show all
Defined in:
lib/smart_todo/events.rb

Overview

This module contains all the methods accessible for SmartTodo comments. It is meant to be reopened by the host application in order to define its own events.

An event needs to return a String containing the message that will be sent to the TODO assignee or false in case the event hasn't been met.

Examples:

Adding a custom event

module SmartTodo
  class Events
    def trello_card_close(card)
      ...
    end
  end
end

TODO(on: trello_card_close(381), to: '[email protected]')

Instance Method Summary collapse

Constructor Details

#initialize(now: nil, spec_set: nil, current_ruby_version: nil) ⇒ Events

Returns a new instance of Events.



29
30
31
32
33
34
35
# File 'lib/smart_todo/events.rb', line 29

def initialize(now: nil, spec_set: nil, current_ruby_version: nil)
  @now = now
  @spec_set = spec_set
  @rubygems_client = nil
  @github_client = nil
  @current_ruby_version = current_ruby_version
end

Instance Method Details

#date(on_date) ⇒ false, String

Check if the date is in the past

Parameters:

  • on_date (String)

    a string parsable by Time.parse

Returns:

  • (false, String)


41
42
43
44
45
46
47
48
# File 'lib/smart_todo/events.rb', line 41

def date(on_date)
  if now >= Time.parse(on_date)
    "We are past the *#{on_date}* due date and " \
      "your TODO is now ready to be addressed."
  else
    false
  end
end

#gem_bump(gem_name, *requirements) ⇒ false, String

Check if gem_name was bumped to the requirements expected

Examples:

Expecting a specific version

gem_bump('rails', '6.0')

Expecting a version in the 5.x.x series

gem_bump('rails', '> 5.2', '< 6')

Parameters:

  • gem_name (String)
  • requirements (Array<String>)

    a list of version specifiers

Returns:

  • (false, String)


93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/smart_todo/events.rb', line 93

def gem_bump(gem_name, *requirements)
  specs = spec_set[gem_name]

  if specs.empty?
    "The gem *#{gem_name}* is not in your dependencies, I can't determine if " \
      "your TODO is ready to be addressed."
  else
    requirement = Gem::Requirement.new(requirements)
    version = specs.first.version

    if requirement.satisfied_by?(version)
      "The gem *#{gem_name}* was updated to version *#{version}* and " \
        "your TODO is now ready to be addressed."
    else
      false
    end
  end
end

#gem_release(gem_name, *requirements) ⇒ false, String

Check if a new version of gem_name was released with the requirements expected

Examples:

Expecting a specific version

gem_release('rails', '6.0')

Expecting a version in the 5.x.x series

gem_release('rails', '> 5.2', '< 6')

Parameters:

  • gem_name (String)
  • requirements (Array<String>)

    a list of version specifiers

Returns:

  • (false, String)


61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/smart_todo/events.rb', line 61

def gem_release(gem_name, *requirements)
  response = rubygems_client.get("/api/v1/versions/#{gem_name}.json")

  if response.code_type < Net::HTTPClientError
    "The gem *#{gem_name}* doesn't seem to exist, I can't determine if " \
      "your TODO is ready to be addressed."
  else
    requirement = Gem::Requirement.new(requirements)
    version = JSON.parse(response.body).find { |gem| requirement.satisfied_by?(Gem::Version.new(gem["number"])) }

    if version
      "The gem *#{gem_name}* was released to version *#{version["number"]}* and " \
        "your TODO is now ready to be addressed."
    else
      false
    end
  end
rescue Net::HTTPError, JSON::ParserError
  "Error retrieving gem information for *#{gem_name}*."
end

#issue_close(organization, repo, issue_number) ⇒ false, String

Check if the issue issue_number is closed

Parameters:

  • organization (String)

    the GitHub organization name

  • repo (String)

    the GitHub repo name

  • issue_number (String, Integer)

Returns:

  • (false, String)


118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/smart_todo/events.rb', line 118

def issue_close(organization, repo, issue_number)
  headers = github_headers(organization, repo)
  response = github_client.get("/repos/#{organization}/#{repo}/issues/#{issue_number}", headers)

  if response.code_type < Net::HTTPClientError
    <<~EOM
      I can't retrieve the information from the issue *#{issue_number}* in the *#{organization}/#{repo}* repository.

      If the repository is a private one, make sure to export the `#{GITHUB_TOKEN}`
      environment variable with a correct GitHub token.
    EOM
  elsif JSON.parse(response.body)["state"] == "closed"
    "The issue https://github.com/#{organization}/#{repo}/issues/#{issue_number} is now closed, " \
      "your TODO is ready to be addressed."
  else
    false
  end
rescue Net::HTTPError, JSON::ParserError
  "Error retrieving issue information for #{organization}/#{repo}##{issue_number}."
end

#issue_context(organization, repo, issue_number) ⇒ String?

Retrieve context information for an issue This is used when a TODO has a context: issue() attribute

Parameters:

  • organization (String)

    the GitHub organization name

  • repo (String)

    the GitHub repo name

  • issue_number (String, Integer)

Returns:

  • (String, nil)


173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
# File 'lib/smart_todo/events.rb', line 173

def issue_context(organization, repo, issue_number)
  headers = github_headers(organization, repo)
  response = github_client.get("/repos/#{organization}/#{repo}/issues/#{issue_number}", headers)

  if response.code_type < Net::HTTPClientError
    nil
  else
    issue = JSON.parse(response.body)
    state = issue["state"]
    title = issue["title"]
    assignee = issue["assignee"] ? "@#{issue["assignee"]["login"]}" : "unassigned"

    "📌 Context: Issue ##{issue_number} - \"#{title}\" [#{state}] (#{assignee}) - " \
      "https://github.com/#{organization}/#{repo}/issues/#{issue_number}"
  end
rescue Net::HTTPError, JSON::ParserError
  nil
end

#pull_request_close(organization, repo, pr_number) ⇒ false, String

Check if the pull request pr_number is closed

Parameters:

  • organization (String)

    the GitHub organization name

  • repo (String)

    the GitHub repo name

  • pr_number (String, Integer)

Returns:

  • (false, String)


145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/smart_todo/events.rb', line 145

def pull_request_close(organization, repo, pr_number)
  headers = github_headers(organization, repo)
  response = github_client.get("/repos/#{organization}/#{repo}/pulls/#{pr_number}", headers)

  if response.code_type < Net::HTTPClientError
    <<~EOM
      I can't retrieve the information from the PR *#{pr_number}* in the *#{organization}/#{repo}* repository.

      If the repository is a private one, make sure to export the `#{GITHUB_TOKEN}`
      environment variable with a correct GitHub token.
    EOM
  elsif JSON.parse(response.body)["state"] == "closed"
    "The pull request https://github.com/#{organization}/#{repo}/pull/#{pr_number} is now closed, " \
      "your TODO is ready to be addressed."
  else
    false
  end
rescue Net::HTTPError, JSON::ParserError
  "Error retrieving pull request information for #{organization}/#{repo}##{pr_number}."
end

#ruby_version(*requirements) ⇒ false, String

Check if the installed ruby version meets requirements.

Parameters:

  • requirements (Array<String>)

    a list of version specifiers

Returns:

  • (false, String)


196
197
198
199
200
201
202
203
204
# File 'lib/smart_todo/events.rb', line 196

def ruby_version(*requirements)
  requirement = Gem::Requirement.new(requirements)

  if requirement.satisfied_by?(current_ruby_version)
    "The currently installed version of Ruby #{current_ruby_version} is #{requirement}."
  else
    false
  end
end