smart_todo 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/build.yml +27 -0
- data/.github/workflows/rubocop.yml +22 -0
- data/.rubocop.yml +3 -3
- data/Gemfile +2 -2
- data/Gemfile.lock +33 -26
- data/README.md +1 -1
- data/dev.yml +1 -1
- data/exe/smart_todo +3 -3
- data/lib/smart_todo/cli.rb +6 -6
- data/lib/smart_todo/dispatchers/base.rb +12 -10
- data/lib/smart_todo/dispatchers/slack.rb +25 -19
- data/lib/smart_todo/events/date.rb +1 -1
- data/lib/smart_todo/events/gem_bump.rb +2 -2
- data/lib/smart_todo/events/gem_release.rb +5 -5
- data/lib/smart_todo/events/issue_close.rb +7 -7
- data/lib/smart_todo/events.rb +2 -2
- data/lib/smart_todo/parser/comment_parser.rb +1 -1
- data/lib/smart_todo/parser/metadata_parser.rb +8 -7
- data/lib/smart_todo/parser/todo_node.rb +3 -3
- data/lib/smart_todo/slack_client.rb +10 -10
- data/lib/smart_todo/version.rb +1 -1
- data/lib/smart_todo.rb +12 -12
- data/lib/smart_todo_cop.rb +4 -4
- data/service.yml +1 -0
- data/smart_todo.gemspec +7 -6
- metadata +23 -22
- data/.rubocop-http---shopify-github-io-ruby-style-guide-rubocop-yml +0 -1027
- data/.travis.yml +0 -15
- data/CHANGELOG.md +0 -63
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8e7fe4f3876be333b1df4dcd44d965e57a0725e65900f96a518bd6a49d608165
|
|
4
|
+
data.tar.gz: 02b5370dfc45cc2337d973db79a3a6bddccb8ae295d2ec529eebbb166247873b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b1bcacca903ebeb350b7abbb8af580de31904bae313c08aac9ffd53351ea8d13897bda85d6ede9e12971dcf5fa3f5a68b2ebb1f71bcbfddd443c34e6ee6c65fc
|
|
7
|
+
data.tar.gz: 970874dccc0323c3b009ec22a083c5096172390fe7c34bb698958cd9e89deb958f5be69dc26145c945a1aac7d740875656ea8a9eb0372dfecbd7ca04745a0a2a
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ master ]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [ master ]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
build:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
name: Ruby ${{ matrix.version }}
|
|
13
|
+
strategy:
|
|
14
|
+
matrix:
|
|
15
|
+
version: [2.5, 2.6, 2.7, 3.0]
|
|
16
|
+
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v2
|
|
19
|
+
- name: Set up Ruby ${{ matrix.version }}
|
|
20
|
+
uses: ruby/setup-ruby@v1
|
|
21
|
+
with:
|
|
22
|
+
ruby-version: ${{ matrix.version }}
|
|
23
|
+
bundler-cache: true
|
|
24
|
+
- name: Run Tests
|
|
25
|
+
run: |
|
|
26
|
+
bundle exec rake test
|
|
27
|
+
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
name: RuboCop
|
|
2
|
+
|
|
3
|
+
on: [push, pull_request]
|
|
4
|
+
|
|
5
|
+
jobs:
|
|
6
|
+
build:
|
|
7
|
+
runs-on: ubuntu-latest
|
|
8
|
+
|
|
9
|
+
steps:
|
|
10
|
+
- uses: actions/checkout@v2
|
|
11
|
+
- name: Set up Ruby 3.0
|
|
12
|
+
uses: ruby/setup-ruby@v1
|
|
13
|
+
with:
|
|
14
|
+
ruby-version: 3.0
|
|
15
|
+
bundler-cache: true
|
|
16
|
+
- name: Install gems
|
|
17
|
+
run: |
|
|
18
|
+
bundle config path vendor/bundle
|
|
19
|
+
bundle config set without 'default development test'
|
|
20
|
+
bundle install --jobs 4 --retry 3
|
|
21
|
+
- name: Run RuboCop
|
|
22
|
+
run: bundle exec rubocop --parallel
|
data/.rubocop.yml
CHANGED
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -1,36 +1,43 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
smart_todo (1.
|
|
4
|
+
smart_todo (1.3.0)
|
|
5
|
+
rexml
|
|
5
6
|
|
|
6
7
|
GEM
|
|
7
8
|
remote: https://rubygems.org/
|
|
8
9
|
specs:
|
|
9
|
-
addressable (2.
|
|
10
|
-
public_suffix (>= 2.0.2, <
|
|
11
|
-
ast (2.4.
|
|
12
|
-
crack (0.4.
|
|
13
|
-
|
|
14
|
-
hashdiff (0.
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
public_suffix (3.1.1)
|
|
10
|
+
addressable (2.8.0)
|
|
11
|
+
public_suffix (>= 2.0.2, < 5.0)
|
|
12
|
+
ast (2.4.2)
|
|
13
|
+
crack (0.4.5)
|
|
14
|
+
rexml
|
|
15
|
+
hashdiff (1.0.1)
|
|
16
|
+
minitest (5.14.4)
|
|
17
|
+
parallel (1.21.0)
|
|
18
|
+
parser (3.0.2.0)
|
|
19
|
+
ast (~> 2.4.1)
|
|
20
|
+
public_suffix (4.0.6)
|
|
21
21
|
rainbow (3.0.0)
|
|
22
|
-
rake (
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
rake (13.0.6)
|
|
23
|
+
regexp_parser (2.1.1)
|
|
24
|
+
rexml (3.2.5)
|
|
25
|
+
rubocop (1.23.0)
|
|
25
26
|
parallel (~> 1.10)
|
|
26
|
-
parser (>=
|
|
27
|
+
parser (>= 3.0.0.0)
|
|
27
28
|
rainbow (>= 2.2.2, < 4.0)
|
|
29
|
+
regexp_parser (>= 1.8, < 3.0)
|
|
30
|
+
rexml
|
|
31
|
+
rubocop-ast (>= 1.12.0, < 2.0)
|
|
28
32
|
ruby-progressbar (~> 1.7)
|
|
29
|
-
unicode-display_width (>= 1.4.0, <
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
33
|
+
unicode-display_width (>= 1.4.0, < 3.0)
|
|
34
|
+
rubocop-ast (1.13.0)
|
|
35
|
+
parser (>= 3.0.1.1)
|
|
36
|
+
rubocop-shopify (2.3.0)
|
|
37
|
+
rubocop (~> 1.22)
|
|
38
|
+
ruby-progressbar (1.11.0)
|
|
39
|
+
unicode-display_width (2.1.0)
|
|
40
|
+
webmock (3.11.2)
|
|
34
41
|
addressable (>= 2.3.6)
|
|
35
42
|
crack (>= 0.3.2)
|
|
36
43
|
hashdiff (>= 0.4.0, < 2.0.0)
|
|
@@ -39,12 +46,12 @@ PLATFORMS
|
|
|
39
46
|
ruby
|
|
40
47
|
|
|
41
48
|
DEPENDENCIES
|
|
42
|
-
bundler (
|
|
49
|
+
bundler (>= 1.17)
|
|
43
50
|
minitest (~> 5.0)
|
|
44
|
-
rake (
|
|
45
|
-
rubocop
|
|
51
|
+
rake (>= 10.0)
|
|
52
|
+
rubocop-shopify
|
|
46
53
|
smart_todo!
|
|
47
54
|
webmock
|
|
48
55
|
|
|
49
56
|
BUNDLED WITH
|
|
50
|
-
|
|
57
|
+
2.2.25
|
data/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<img src="https://user-images.githubusercontent.com/8122246/61341925-b936d180-a848-11e9-95c1-0d2f398c51b1.png?raw=true" width="200">
|
|
3
3
|
</h3>
|
|
4
4
|
|
|
5
|
-
[](https://github.com/Shopify/smart_todo/actions?query=workflow%3ACI)
|
|
6
6
|
|
|
7
7
|
_SmartTodo_ is a library designed to assign users on TODO comments written in your codebase and help assignees be reminded when it's time to commit to their TODO.
|
|
8
8
|
|
data/dev.yml
CHANGED
data/exe/smart_todo
CHANGED
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
|
|
4
4
|
$LOAD_PATH.unshift("#{__dir__}/../lib")
|
|
5
5
|
|
|
6
|
-
require
|
|
6
|
+
require "smart_todo"
|
|
7
7
|
|
|
8
|
-
if ENV[
|
|
9
|
-
ARGV <<
|
|
8
|
+
if ENV["ENABLE_SMART_TODO"] && !ARGV.include?("--dispatcher")
|
|
9
|
+
ARGV << "--dispatcher" << "slack"
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
SmartTodo::CLI.new.run
|
data/lib/smart_todo/cli.rb
CHANGED
|
@@ -15,13 +15,13 @@ module SmartTodo
|
|
|
15
15
|
def run(args = ARGV)
|
|
16
16
|
paths = define_options.parse!(args)
|
|
17
17
|
validate_options!
|
|
18
|
-
paths <<
|
|
18
|
+
paths << "." if paths.empty?
|
|
19
19
|
|
|
20
20
|
paths.each do |path|
|
|
21
21
|
normalize_path(path).each do |file|
|
|
22
22
|
parse_file(file)
|
|
23
23
|
|
|
24
|
-
STDOUT.print(
|
|
24
|
+
STDOUT.print(".")
|
|
25
25
|
STDOUT.flush
|
|
26
26
|
end
|
|
27
27
|
end
|
|
@@ -38,13 +38,13 @@ module SmartTodo
|
|
|
38
38
|
def define_options
|
|
39
39
|
OptionParser.new do |opts|
|
|
40
40
|
opts.banner = "Usage: smart_todo [options] file_or_path1 file_or_path2 ..."
|
|
41
|
-
opts.on(
|
|
41
|
+
opts.on("--slack_token TOKEN") do |token|
|
|
42
42
|
@options[:slack_token] = token
|
|
43
43
|
end
|
|
44
|
-
opts.on(
|
|
44
|
+
opts.on("--fallback_channel CHANNEL") do |channel|
|
|
45
45
|
@options[:fallback_channel] = channel
|
|
46
46
|
end
|
|
47
|
-
opts.on(
|
|
47
|
+
opts.on("--dispatcher DISPATCHER") do |dispatcher|
|
|
48
48
|
@options[:dispatcher] = dispatcher
|
|
49
49
|
end
|
|
50
50
|
end
|
|
@@ -67,7 +67,7 @@ module SmartTodo
|
|
|
67
67
|
|
|
68
68
|
# @param file [String] a path to a file
|
|
69
69
|
def parse_file(file)
|
|
70
|
-
Parser::CommentParser.new(File.read(file, encoding:
|
|
70
|
+
Parser::CommentParser.new(File.read(file, encoding: "UTF-8")).parse.each do |todo_node|
|
|
71
71
|
event_message = nil
|
|
72
72
|
event_met = todo_node.metadata.events.find do |event|
|
|
73
73
|
event_message = Events.public_send(event.method_name, *event.arguments)
|
|
@@ -12,7 +12,7 @@ module SmartTodo
|
|
|
12
12
|
case dispatcher
|
|
13
13
|
when "slack"
|
|
14
14
|
Slack
|
|
15
|
-
when nil,
|
|
15
|
+
when nil, "output"
|
|
16
16
|
Output
|
|
17
17
|
end
|
|
18
18
|
end
|
|
@@ -25,7 +25,7 @@ module SmartTodo
|
|
|
25
25
|
#
|
|
26
26
|
# @return void
|
|
27
27
|
def self.validate_options!(_options)
|
|
28
|
-
raise(NotImplemetedError,
|
|
28
|
+
raise(NotImplemetedError, "subclass responsability")
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
# @param event_message [String] the success message associated
|
|
@@ -38,7 +38,7 @@ module SmartTodo
|
|
|
38
38
|
@todo_node = todo_node
|
|
39
39
|
@options = options
|
|
40
40
|
@file = file
|
|
41
|
-
@
|
|
41
|
+
@assignees = @todo_node.metadata.assignees
|
|
42
42
|
end
|
|
43
43
|
|
|
44
44
|
# This method gets called when a TODO reminder is expired and needs to be delivered.
|
|
@@ -46,7 +46,7 @@ module SmartTodo
|
|
|
46
46
|
#
|
|
47
47
|
# @return void
|
|
48
48
|
def dispatch
|
|
49
|
-
raise(NotImplemetedError,
|
|
49
|
+
raise(NotImplemetedError, "subclass responsability")
|
|
50
50
|
end
|
|
51
51
|
|
|
52
52
|
private
|
|
@@ -54,10 +54,11 @@ module SmartTodo
|
|
|
54
54
|
# Prepare the content of the message to send to the TODO assignee
|
|
55
55
|
#
|
|
56
56
|
# @param user [Hash] contain information about a user
|
|
57
|
+
# @param assignee [String] original string handle the slack message should be sent
|
|
57
58
|
# @return [String]
|
|
58
|
-
def slack_message(user)
|
|
59
|
-
header = if user.key?(
|
|
60
|
-
unexisting_user
|
|
59
|
+
def slack_message(user, assignee)
|
|
60
|
+
header = if user.key?("fallback")
|
|
61
|
+
unexisting_user(assignee)
|
|
61
62
|
else
|
|
62
63
|
existing_user
|
|
63
64
|
end
|
|
@@ -78,12 +79,13 @@ module SmartTodo
|
|
|
78
79
|
|
|
79
80
|
# Message in case a TODO's assignee doesn't exist in the Slack organization
|
|
80
81
|
#
|
|
82
|
+
# @param user [Hash]
|
|
81
83
|
# @return [String]
|
|
82
|
-
def unexisting_user
|
|
83
|
-
"Hello :wave:,\n\n`#{
|
|
84
|
+
def unexisting_user(assignee)
|
|
85
|
+
"Hello :wave:,\n\n`#{assignee}` had an assigned TODO but this user or channel doesn't exist on Slack anymore."
|
|
84
86
|
end
|
|
85
87
|
|
|
86
|
-
#
|
|
88
|
+
# Hello message for user actually existing in the organization
|
|
87
89
|
def existing_user
|
|
88
90
|
"Hello :wave:,"
|
|
89
91
|
end
|
|
@@ -6,9 +6,21 @@ module SmartTodo
|
|
|
6
6
|
# (using the associated slack email address) or a channel.
|
|
7
7
|
class Slack < Base
|
|
8
8
|
def self.validate_options!(options)
|
|
9
|
-
options[:slack_token] ||= ENV.fetch(
|
|
9
|
+
options[:slack_token] ||= ENV.fetch("SMART_TODO_SLACK_TOKEN") { raise(ArgumentError, "Missing :slack_token") }
|
|
10
10
|
|
|
11
|
-
options.fetch(:fallback_channel) { raise(ArgumentError,
|
|
11
|
+
options.fetch(:fallback_channel) { raise(ArgumentError, "Missing :fallback_channel") }
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Make a Slack API call to dispatch the message to each assignee
|
|
15
|
+
#
|
|
16
|
+
# @raise [SlackClient::Error] in case the Slack API returns an error
|
|
17
|
+
# other than `users_not_found`
|
|
18
|
+
#
|
|
19
|
+
# @return [Array] Slack response for each assignee a message was sent to
|
|
20
|
+
def dispatch
|
|
21
|
+
@assignees.each do |assignee|
|
|
22
|
+
dispatch_one(assignee)
|
|
23
|
+
end
|
|
12
24
|
end
|
|
13
25
|
|
|
14
26
|
# Make a Slack API call to dispatch the message to the user or channel
|
|
@@ -16,19 +28,20 @@ module SmartTodo
|
|
|
16
28
|
# @raise [SlackClient::Error] in case the Slack API returns an error
|
|
17
29
|
# other than `users_not_found`
|
|
18
30
|
#
|
|
31
|
+
# @param [String] the assignee handle string
|
|
19
32
|
# @return [Hash] the Slack response
|
|
20
|
-
def
|
|
21
|
-
user = slack_user_or_channel
|
|
33
|
+
def dispatch_one(assignee)
|
|
34
|
+
user = slack_user_or_channel(assignee)
|
|
22
35
|
|
|
23
|
-
client.post_message(user.dig(
|
|
36
|
+
client.post_message(user.dig("user", "id"), slack_message(user, assignee))
|
|
24
37
|
rescue SlackClient::Error => error
|
|
25
|
-
if
|
|
26
|
-
user = {
|
|
38
|
+
if ["users_not_found", "channel_not_found"].include?(error.error_code)
|
|
39
|
+
user = { "user" => { "id" => @options[:fallback_channel] }, "fallback" => true }
|
|
27
40
|
else
|
|
28
41
|
raise(error)
|
|
29
42
|
end
|
|
30
43
|
|
|
31
|
-
client.post_message(user.dig(
|
|
44
|
+
client.post_message(user.dig("user", "id"), slack_message(user, assignee))
|
|
32
45
|
end
|
|
33
46
|
|
|
34
47
|
private
|
|
@@ -37,11 +50,11 @@ module SmartTodo
|
|
|
37
50
|
# the channel the message should be sent to.
|
|
38
51
|
#
|
|
39
52
|
# @return [Hash] a suited hash containing the user ID for a given individual or a slack channel
|
|
40
|
-
def slack_user_or_channel
|
|
41
|
-
if
|
|
42
|
-
client.lookup_user_by_email(
|
|
53
|
+
def slack_user_or_channel(assignee)
|
|
54
|
+
if assignee.include?("@")
|
|
55
|
+
client.lookup_user_by_email(assignee)
|
|
43
56
|
else
|
|
44
|
-
{
|
|
57
|
+
{ "user" => { "id" => assignee } }
|
|
45
58
|
end
|
|
46
59
|
end
|
|
47
60
|
|
|
@@ -49,13 +62,6 @@ module SmartTodo
|
|
|
49
62
|
def client
|
|
50
63
|
@client ||= SlackClient.new(@options[:slack_token])
|
|
51
64
|
end
|
|
52
|
-
|
|
53
|
-
# Check if the TODO's assignee is a specific user or a channel
|
|
54
|
-
#
|
|
55
|
-
# @return [true, false]
|
|
56
|
-
def email?
|
|
57
|
-
@assignee.include?("@")
|
|
58
|
-
end
|
|
59
65
|
end
|
|
60
66
|
end
|
|
61
67
|
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
4
|
-
require
|
|
3
|
+
require "net/http"
|
|
4
|
+
require "json"
|
|
5
5
|
|
|
6
6
|
module SmartTodo
|
|
7
7
|
module Events
|
|
@@ -30,7 +30,7 @@ module SmartTodo
|
|
|
30
30
|
if response.code_type < Net::HTTPClientError
|
|
31
31
|
error_message
|
|
32
32
|
elsif (gem = version_released?(response.body))
|
|
33
|
-
message(gem[
|
|
33
|
+
message(gem["number"])
|
|
34
34
|
else
|
|
35
35
|
false
|
|
36
36
|
end
|
|
@@ -54,13 +54,13 @@ module SmartTodo
|
|
|
54
54
|
# @return [true, false]
|
|
55
55
|
def version_released?(gem_versions)
|
|
56
56
|
JSON.parse(gem_versions).find do |gem|
|
|
57
|
-
@requirements.satisfied_by?(Gem::Version.new(gem[
|
|
57
|
+
@requirements.satisfied_by?(Gem::Version.new(gem["number"]))
|
|
58
58
|
end
|
|
59
59
|
end
|
|
60
60
|
|
|
61
61
|
# @return [Net::HTTP] an instance of Net::HTTP
|
|
62
62
|
def client
|
|
63
|
-
@client ||= Net::HTTP.new(
|
|
63
|
+
@client ||= Net::HTTP.new("rubygems.org", Net::HTTP.https_default_port).tap do |client|
|
|
64
64
|
client.use_ssl = true
|
|
65
65
|
end
|
|
66
66
|
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
4
|
-
require
|
|
3
|
+
require "net/http"
|
|
4
|
+
require "json"
|
|
5
5
|
|
|
6
6
|
module SmartTodo
|
|
7
7
|
module Events
|
|
@@ -12,7 +12,7 @@ module SmartTodo
|
|
|
12
12
|
# with the `repos` scope in the +SMART_TODO_GITHUB_TOKEN+ environment variable
|
|
13
13
|
# is required.
|
|
14
14
|
class IssueClose
|
|
15
|
-
TOKEN_ENV =
|
|
15
|
+
TOKEN_ENV = "SMART_TODO_GITHUB_TOKEN"
|
|
16
16
|
|
|
17
17
|
# @param organization [String]
|
|
18
18
|
# @param repo [String]
|
|
@@ -62,7 +62,7 @@ module SmartTodo
|
|
|
62
62
|
|
|
63
63
|
# @return [Net::HTTP] an instance of Net::HTTP
|
|
64
64
|
def client
|
|
65
|
-
@client ||= Net::HTTP.new(
|
|
65
|
+
@client ||= Net::HTTP.new("api.github.com", Net::HTTP.https_default_port).tap do |client|
|
|
66
66
|
client.use_ssl = true
|
|
67
67
|
end
|
|
68
68
|
end
|
|
@@ -72,13 +72,13 @@ module SmartTodo
|
|
|
72
72
|
#
|
|
73
73
|
# @return [true, false]
|
|
74
74
|
def pull_request_closed?(pull_request)
|
|
75
|
-
JSON.parse(pull_request)[
|
|
75
|
+
JSON.parse(pull_request)["state"] == "closed"
|
|
76
76
|
end
|
|
77
77
|
|
|
78
78
|
# @return [Hash]
|
|
79
79
|
def default_headers
|
|
80
|
-
{
|
|
81
|
-
headers[
|
|
80
|
+
{ "Accept" => "application/vnd.github.v3+json" }.tap do |headers|
|
|
81
|
+
headers["Authorization"] = "token #{ENV[TOKEN_ENV]}" if ENV[TOKEN_ENV]
|
|
82
82
|
end
|
|
83
83
|
end
|
|
84
84
|
end
|
data/lib/smart_todo/events.rb
CHANGED
|
@@ -54,7 +54,7 @@ module SmartTodo
|
|
|
54
54
|
# @param issue_number [String, Integer]
|
|
55
55
|
# @return [false, String]
|
|
56
56
|
def issue_close(organization, repo, issue_number)
|
|
57
|
-
IssueClose.new(organization, repo, issue_number, type:
|
|
57
|
+
IssueClose.new(organization, repo, issue_number, type: "issues").met?
|
|
58
58
|
end
|
|
59
59
|
|
|
60
60
|
# Check if the pull request +pr_number+ is closed
|
|
@@ -64,7 +64,7 @@ module SmartTodo
|
|
|
64
64
|
# @param pr_number [String, Integer]
|
|
65
65
|
# @return [false, String]
|
|
66
66
|
def pull_request_close(organization, repo, pr_number)
|
|
67
|
-
IssueClose.new(organization, repo, pr_number, type:
|
|
67
|
+
IssueClose.new(organization, repo, pr_number, type: "pulls").met?
|
|
68
68
|
end
|
|
69
69
|
end
|
|
70
70
|
end
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
3
|
+
require "ripper"
|
|
4
4
|
|
|
5
5
|
module SmartTodo
|
|
6
6
|
module Parser
|
|
@@ -35,7 +35,7 @@ module SmartTodo
|
|
|
35
35
|
# @param args [Array]
|
|
36
36
|
# @return [Array, MethodNode]
|
|
37
37
|
def on_method_add_arg(method, args)
|
|
38
|
-
if method ==
|
|
38
|
+
if method == "TODO"
|
|
39
39
|
args
|
|
40
40
|
else
|
|
41
41
|
MethodNode.new(method, args)
|
|
@@ -58,12 +58,12 @@ module SmartTodo
|
|
|
58
58
|
# @param key [String]
|
|
59
59
|
# @param value [String, Integer, MethodNode]
|
|
60
60
|
def on_assoc_new(key, value)
|
|
61
|
-
key.tr!(
|
|
61
|
+
key.tr!(":", "")
|
|
62
62
|
|
|
63
63
|
case key
|
|
64
|
-
when
|
|
64
|
+
when "on"
|
|
65
65
|
[:on_todo_event, value]
|
|
66
|
-
when
|
|
66
|
+
when "to"
|
|
67
67
|
[:on_todo_assignee, value]
|
|
68
68
|
else
|
|
69
69
|
[:unknown, value]
|
|
@@ -78,10 +78,11 @@ module SmartTodo
|
|
|
78
78
|
end
|
|
79
79
|
|
|
80
80
|
class Visitor
|
|
81
|
-
attr_reader :events, :
|
|
81
|
+
attr_reader :events, :assignees
|
|
82
82
|
|
|
83
83
|
def initialize
|
|
84
84
|
@events = []
|
|
85
|
+
@assignees = []
|
|
85
86
|
end
|
|
86
87
|
|
|
87
88
|
# Iterate over each tokens returned from the parser and call
|
|
@@ -111,7 +112,7 @@ module SmartTodo
|
|
|
111
112
|
# @param assignee [String]
|
|
112
113
|
# @return [void]
|
|
113
114
|
def on_todo_assignee(assignee)
|
|
114
|
-
@
|
|
115
|
+
@assignees << assignee
|
|
115
116
|
end
|
|
116
117
|
end
|
|
117
118
|
end
|
|
@@ -11,7 +11,7 @@ module SmartTodo
|
|
|
11
11
|
|
|
12
12
|
# @param todo [String] the actual Ruby comment
|
|
13
13
|
def initialize(todo)
|
|
14
|
-
@metadata = MetadataParser.parse(todo.gsub(/^#/,
|
|
14
|
+
@metadata = MetadataParser.parse(todo.gsub(/^#/, ""))
|
|
15
15
|
@comments = []
|
|
16
16
|
@start = todo.match(/^#(\s+)/)[1].size
|
|
17
17
|
end
|
|
@@ -26,7 +26,7 @@ module SmartTodo
|
|
|
26
26
|
# @param comment [String]
|
|
27
27
|
# @return [void]
|
|
28
28
|
def <<(comment)
|
|
29
|
-
@comments << comment.gsub(/^#(\s+)/,
|
|
29
|
+
@comments << comment.gsub(/^#(\s+)/, "")
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
# Check if the +comment+ is indented two spaces below the
|
|
@@ -36,7 +36,7 @@ module SmartTodo
|
|
|
36
36
|
# @param comment [String]
|
|
37
37
|
# @return [true, false]
|
|
38
38
|
def indented_comment?(comment)
|
|
39
|
-
comment.match(/^#(\s
|
|
39
|
+
comment.match(/^#(\s*)/)[1].size - @start == DEFAULT_RUBY_INDENTATION
|
|
40
40
|
end
|
|
41
41
|
end
|
|
42
42
|
end
|