codebot 1.2.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 +7 -0
- data/.github/ISSUE_TEMPLATE.md +32 -0
- data/.github/ISSUE_TEMPLATE/formatter_issue.md +20 -0
- data/.github/PULL_REQUEST_TEMPLATE.md +13 -0
- data/.gitignore +10 -0
- data/.rspec +1 -0
- data/.rubocop.yml +11 -0
- data/.travis.yml +26 -0
- data/CODE_OF_CONDUCT.md +46 -0
- data/CONTRIBUTING.md +15 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +75 -0
- data/LICENSE +21 -0
- data/README.md +230 -0
- data/Rakefile +29 -0
- data/bin/console +8 -0
- data/codebot.gemspec +49 -0
- data/exe/codebot +7 -0
- data/lib/codebot.rb +8 -0
- data/lib/codebot/channel.rb +134 -0
- data/lib/codebot/command_error.rb +17 -0
- data/lib/codebot/config.rb +125 -0
- data/lib/codebot/configuration_error.rb +17 -0
- data/lib/codebot/core.rb +76 -0
- data/lib/codebot/cryptography.rb +38 -0
- data/lib/codebot/event.rb +62 -0
- data/lib/codebot/ext/cinch/ssl_extensions.rb +37 -0
- data/lib/codebot/formatter.rb +242 -0
- data/lib/codebot/formatters.rb +109 -0
- data/lib/codebot/formatters/.rubocop.yml +2 -0
- data/lib/codebot/formatters/commit_comment.rb +43 -0
- data/lib/codebot/formatters/fork.rb +40 -0
- data/lib/codebot/formatters/gitlab_issue_hook.rb +56 -0
- data/lib/codebot/formatters/gitlab_job_hook.rb +77 -0
- data/lib/codebot/formatters/gitlab_merge_request_hook.rb +57 -0
- data/lib/codebot/formatters/gitlab_note_hook.rb +119 -0
- data/lib/codebot/formatters/gitlab_pipeline_hook.rb +51 -0
- data/lib/codebot/formatters/gitlab_push_hook.rb +83 -0
- data/lib/codebot/formatters/gitlab_wiki_page_hook.rb +56 -0
- data/lib/codebot/formatters/gollum.rb +67 -0
- data/lib/codebot/formatters/issue_comment.rb +41 -0
- data/lib/codebot/formatters/issues.rb +41 -0
- data/lib/codebot/formatters/ping.rb +79 -0
- data/lib/codebot/formatters/public.rb +30 -0
- data/lib/codebot/formatters/pull_request.rb +71 -0
- data/lib/codebot/formatters/pull_request_review_comment.rb +49 -0
- data/lib/codebot/formatters/push.rb +172 -0
- data/lib/codebot/formatters/watch.rb +38 -0
- data/lib/codebot/integration.rb +195 -0
- data/lib/codebot/integration_manager.rb +225 -0
- data/lib/codebot/ipc_client.rb +83 -0
- data/lib/codebot/ipc_server.rb +79 -0
- data/lib/codebot/irc_client.rb +102 -0
- data/lib/codebot/irc_connection.rb +156 -0
- data/lib/codebot/message.rb +37 -0
- data/lib/codebot/metadata.rb +15 -0
- data/lib/codebot/network.rb +240 -0
- data/lib/codebot/network_manager.rb +181 -0
- data/lib/codebot/options.rb +49 -0
- data/lib/codebot/options/base.rb +55 -0
- data/lib/codebot/options/core.rb +126 -0
- data/lib/codebot/options/integration.rb +101 -0
- data/lib/codebot/options/network.rb +109 -0
- data/lib/codebot/payload.rb +32 -0
- data/lib/codebot/request.rb +51 -0
- data/lib/codebot/sanitizers.rb +130 -0
- data/lib/codebot/serializable.rb +101 -0
- data/lib/codebot/shortener.rb +43 -0
- data/lib/codebot/thread_controller.rb +70 -0
- data/lib/codebot/user_error.rb +13 -0
- data/lib/codebot/validation_error.rb +17 -0
- data/lib/codebot/web_listener.rb +107 -0
- data/lib/codebot/web_server.rb +58 -0
- data/webhook.png +0 -0
- metadata +249 -0
@@ -0,0 +1,83 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
|
3
|
+
module Codebot
|
4
|
+
module Formatters
|
5
|
+
module Gitlab
|
6
|
+
# This class formats Push events from Gitlab
|
7
|
+
class PushHook < Formatter
|
8
|
+
def before_commit
|
9
|
+
extract(:before)
|
10
|
+
end
|
11
|
+
|
12
|
+
def after_commit
|
13
|
+
extract(:after)
|
14
|
+
end
|
15
|
+
|
16
|
+
def repository_name
|
17
|
+
extract(:repository, :name)
|
18
|
+
end
|
19
|
+
|
20
|
+
def repository_url
|
21
|
+
extract(:repository, :homepage)
|
22
|
+
end
|
23
|
+
|
24
|
+
def compare_url
|
25
|
+
commits = "#{before_commit}...#{before_commit}"
|
26
|
+
shorten_url "#{repository_url}/compare/#{commits}"
|
27
|
+
end
|
28
|
+
|
29
|
+
def commit_default_format
|
30
|
+
'%<repository>s/%<branch>s %<hash>s %<author>s: %<title>s'
|
31
|
+
end
|
32
|
+
|
33
|
+
def commit_author(commit)
|
34
|
+
return nil unless commit['author'].is_a? Hash
|
35
|
+
|
36
|
+
commit['author']['name']
|
37
|
+
end
|
38
|
+
|
39
|
+
def commit_summary(commit)
|
40
|
+
commit_default_format % {
|
41
|
+
repository: format_repository(repository_name),
|
42
|
+
branch: format_branch(branch),
|
43
|
+
hash: format_hash(commit['id']),
|
44
|
+
author: format_user(commit_author(commit)),
|
45
|
+
title: prettify(commit['message'])
|
46
|
+
}
|
47
|
+
end
|
48
|
+
|
49
|
+
def branch
|
50
|
+
extract(:ref).split('/')[2..-1].join('/')
|
51
|
+
end
|
52
|
+
|
53
|
+
def num_commits
|
54
|
+
format_number(extract(:total_commits_count).to_i,
|
55
|
+
'new commit', 'new commits')
|
56
|
+
end
|
57
|
+
|
58
|
+
def summary_format
|
59
|
+
'[%<repository>s] %<user>s pushed %<num_commits>s ' \
|
60
|
+
'to %<branch>s: %<url>s'
|
61
|
+
end
|
62
|
+
|
63
|
+
def default_summary
|
64
|
+
user_name = extract(:user_name)
|
65
|
+
|
66
|
+
summary_format % {
|
67
|
+
repository: format_repository(repository_name),
|
68
|
+
user: format_user(user_name),
|
69
|
+
num_commits: num_commits,
|
70
|
+
branch: format_branch(branch),
|
71
|
+
url: compare_url
|
72
|
+
}
|
73
|
+
end
|
74
|
+
|
75
|
+
def format
|
76
|
+
[default_summary] + extract(:commits).map do |commit|
|
77
|
+
commit_summary(commit)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Codebot
|
4
|
+
module Formatters
|
5
|
+
module Gitlab
|
6
|
+
# Triggers on a Wiki Page Hook event
|
7
|
+
class WikiPageHook < Formatter
|
8
|
+
def format
|
9
|
+
["#{summary}: #{format_url url}"]
|
10
|
+
end
|
11
|
+
|
12
|
+
def summary
|
13
|
+
default_format % {
|
14
|
+
repository: format_repository(repository_name),
|
15
|
+
sender: format_user(sender_name),
|
16
|
+
action: action,
|
17
|
+
title: wiki_title
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
def default_format
|
22
|
+
'[%<repository>s] %<sender>s %<action>s page \'%<title>s\''
|
23
|
+
end
|
24
|
+
|
25
|
+
def repository_name
|
26
|
+
extract(:project, :path_with_namespace)
|
27
|
+
end
|
28
|
+
|
29
|
+
def sender_name
|
30
|
+
extract(:user, :name)
|
31
|
+
end
|
32
|
+
|
33
|
+
def summary_url
|
34
|
+
extract(:object_attributes, :url)
|
35
|
+
end
|
36
|
+
|
37
|
+
def action
|
38
|
+
case wiki_action
|
39
|
+
when 'create' then 'created'
|
40
|
+
when 'delete' then 'deleted'
|
41
|
+
when 'update', nil then 'updated'
|
42
|
+
else wiki_action
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def wiki_action
|
47
|
+
extract(:object_attributes, :action)
|
48
|
+
end
|
49
|
+
|
50
|
+
def wiki_title
|
51
|
+
extract(:object_attributes, :title)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Portions (c) 2008 Logical Awesome, LLC (released under the MIT license).
|
4
|
+
# See the LICENSE file for the full MIT license text.
|
5
|
+
|
6
|
+
module Codebot
|
7
|
+
module Formatters
|
8
|
+
# This class formats gollum events.
|
9
|
+
class Gollum < Formatter
|
10
|
+
# Formats IRC messages for a gollum event.
|
11
|
+
#
|
12
|
+
# @return [Array<String>] the formatted messages
|
13
|
+
def format
|
14
|
+
["#{summary}: #{format_url url}"]
|
15
|
+
end
|
16
|
+
|
17
|
+
def summary
|
18
|
+
default_format % {
|
19
|
+
repository: format_repository(repository_name),
|
20
|
+
sender: format_user(sender_name),
|
21
|
+
summary: (pages.one? ? single_page_summary : multi_page_summary)
|
22
|
+
}
|
23
|
+
end
|
24
|
+
|
25
|
+
def default_format
|
26
|
+
'[%<repository>s] %<sender>s %<summary>s'
|
27
|
+
end
|
28
|
+
|
29
|
+
def single_page_summary
|
30
|
+
page = pages.first.to_h
|
31
|
+
short = prettify page['summary']
|
32
|
+
suffix = ": #{short}" unless short.empty?
|
33
|
+
"#{page['action']} wiki page #{page['title']}#{suffix}"
|
34
|
+
end
|
35
|
+
|
36
|
+
def multi_page_summary
|
37
|
+
actions = []
|
38
|
+
counts = action_counts
|
39
|
+
counts.each { |verb, num| actions << "#{verb} #{format_number num}" }
|
40
|
+
changes = ary_to_sentence(
|
41
|
+
actions,
|
42
|
+
'pushed an empty commit that did not affect any'
|
43
|
+
)
|
44
|
+
singular_noun = counts.last.to_a.last.to_i.eql?(1)
|
45
|
+
"#{changes} wiki #{singular_noun ? 'page' : 'pages'}"
|
46
|
+
end
|
47
|
+
|
48
|
+
def action_counts
|
49
|
+
Hash.new(0).tap do |hash|
|
50
|
+
pages.each { |page| hash[page['action']] += 1 }
|
51
|
+
end.sort
|
52
|
+
end
|
53
|
+
|
54
|
+
def summary_url
|
55
|
+
if pages.one?
|
56
|
+
pages.first['html_url'].to_s
|
57
|
+
else
|
58
|
+
"#{repository_url}/wiki"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def pages
|
63
|
+
extract(:pages).to_a
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Codebot
|
4
|
+
module Formatters
|
5
|
+
# This class formats issue_comment events.
|
6
|
+
class IssueComment < Formatter
|
7
|
+
# Formats IRC messages for an issue_comment event.
|
8
|
+
#
|
9
|
+
# @return [Array<String>] the formatted messages
|
10
|
+
def format
|
11
|
+
["#{summary}: #{format_url url}"]
|
12
|
+
end
|
13
|
+
|
14
|
+
def summary
|
15
|
+
default_format % {
|
16
|
+
repository: format_repository(repository_name),
|
17
|
+
sender: format_user(sender_name),
|
18
|
+
number: issue_number,
|
19
|
+
summary: prettify(comment_body)
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
23
|
+
def default_format
|
24
|
+
'[%<repository>s] %<sender>s commented on issue' \
|
25
|
+
' #%<number>s: %<summary>s'
|
26
|
+
end
|
27
|
+
|
28
|
+
def summary_url
|
29
|
+
extract(:comment, :html_url).to_s
|
30
|
+
end
|
31
|
+
|
32
|
+
def comment_body
|
33
|
+
extract(:comment, :body).to_s
|
34
|
+
end
|
35
|
+
|
36
|
+
def issue_number
|
37
|
+
extract(:issue, :number)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Codebot
|
4
|
+
module Formatters
|
5
|
+
# This class formats issues events.
|
6
|
+
class Issues < Formatter
|
7
|
+
# Formats IRC messages for an issue event.
|
8
|
+
#
|
9
|
+
# @return [Array<String>] the formatted messages
|
10
|
+
def format
|
11
|
+
["#{summary}: #{format_url url}"] if opened? || closed?
|
12
|
+
end
|
13
|
+
|
14
|
+
def summary
|
15
|
+
default_format % {
|
16
|
+
repository: format_repository(repository_name),
|
17
|
+
sender: format_user(sender_name),
|
18
|
+
action: action,
|
19
|
+
number: issue_number,
|
20
|
+
title: issue_title
|
21
|
+
}
|
22
|
+
end
|
23
|
+
|
24
|
+
def default_format
|
25
|
+
'[%<repository>s] %<sender>s %<action>s issue #%<number>s: %<title>s'
|
26
|
+
end
|
27
|
+
|
28
|
+
def summary_url
|
29
|
+
extract(:issue, :html_url).to_s
|
30
|
+
end
|
31
|
+
|
32
|
+
def issue_number
|
33
|
+
extract(:issue, :number)
|
34
|
+
end
|
35
|
+
|
36
|
+
def issue_title
|
37
|
+
extract(:issue, :title)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Codebot
|
4
|
+
module Formatters
|
5
|
+
# This class formats ping events.
|
6
|
+
class Ping < Formatter
|
7
|
+
# Formats IRC messages for a ping event.
|
8
|
+
#
|
9
|
+
# @return [Array<String>] the formatted messages
|
10
|
+
def format
|
11
|
+
["#{summary}: #{format_url url}"]
|
12
|
+
end
|
13
|
+
|
14
|
+
def summary
|
15
|
+
default_format % {
|
16
|
+
scope: format_scope,
|
17
|
+
sender: format_user(sender_name),
|
18
|
+
events: format_events
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
22
|
+
def default_format
|
23
|
+
'[%<scope>s] %<sender>s added a webhook for %<events>s'
|
24
|
+
end
|
25
|
+
|
26
|
+
def summary_url
|
27
|
+
case extract(:hook, :type)
|
28
|
+
when /\Aorganization\z/i
|
29
|
+
login = extract(:organization, :login).to_s
|
30
|
+
"https://github.com/#{login}"
|
31
|
+
when /\Arepository\z/i
|
32
|
+
extract(:repository, :html_url).to_s
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def format_events
|
37
|
+
if hook_events.empty?
|
38
|
+
'no events'
|
39
|
+
elsif hook_events.include? '*'
|
40
|
+
format_event 'all events'
|
41
|
+
else
|
42
|
+
format_events_some
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def format_events_some
|
47
|
+
if hook_events.length > 5
|
48
|
+
"#{format_number(hook_events.length)} events"
|
49
|
+
elsif hook_events.one?
|
50
|
+
"the #{format_event hook_events.first} event"
|
51
|
+
else
|
52
|
+
"the #{formatted_hook_events} events"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def hook_events
|
57
|
+
extract(:hook, :events).to_a.uniq
|
58
|
+
end
|
59
|
+
|
60
|
+
def formatted_hook_events
|
61
|
+
ary_to_sentence(hook_events.sort.map { |event| format_event event })
|
62
|
+
end
|
63
|
+
|
64
|
+
# Formats the name of the repository or organization the webhook belongs
|
65
|
+
# to.
|
66
|
+
#
|
67
|
+
# @return [String] the formatted scope
|
68
|
+
def format_scope
|
69
|
+
case extract(:hook, :type)
|
70
|
+
when /\Aorganization\z/i
|
71
|
+
format_user extract(:organization, :login)
|
72
|
+
when /\Arepository\z/i
|
73
|
+
login = extract(:repository, :owner, :login)
|
74
|
+
"#{format_user login}/#{format_repository repository_name}"
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Codebot
|
4
|
+
module Formatters
|
5
|
+
# This class formats public events.
|
6
|
+
class Public < Formatter
|
7
|
+
# Formats IRC messages for a public event.
|
8
|
+
#
|
9
|
+
# @return [Array<String>] the formatted messages
|
10
|
+
def format
|
11
|
+
["#{summary}: #{format_url url}"]
|
12
|
+
end
|
13
|
+
|
14
|
+
def summary
|
15
|
+
default_format % {
|
16
|
+
repository: format_repository(repository_name),
|
17
|
+
sender: format_user(sender_name)
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
def default_format
|
22
|
+
'[%<repository>s] %<sender>s open-sourced the repository'
|
23
|
+
end
|
24
|
+
|
25
|
+
def summary_url
|
26
|
+
repository_url
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Portions (c) 2008 Logical Awesome, LLC (released under the MIT license).
|
4
|
+
# See the LICENSE file for the full MIT license text.
|
5
|
+
|
6
|
+
module Codebot
|
7
|
+
module Formatters
|
8
|
+
# This class formats pull_request events.
|
9
|
+
class PullRequest < Formatter
|
10
|
+
# Formats IRC messages for a pull_request event.
|
11
|
+
#
|
12
|
+
# @return [Array<String>] the formatted messages
|
13
|
+
def format
|
14
|
+
["#{summary}: #{format_url url}"] if opened? || closed?
|
15
|
+
end
|
16
|
+
|
17
|
+
def summary
|
18
|
+
default_format % {
|
19
|
+
repository: format_repository(repository_name),
|
20
|
+
sender: format_user(sender_name),
|
21
|
+
action: action,
|
22
|
+
number: pull_number,
|
23
|
+
title: pull_title,
|
24
|
+
base_ref: pull_base_ref,
|
25
|
+
head_title: pull_head_title
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
def default_format
|
30
|
+
'[%<repository>s] %<sender>s %<action>s pull request #%<number>s: ' \
|
31
|
+
'%<title>s (%<base_ref>s...%<head_title>s)'
|
32
|
+
end
|
33
|
+
|
34
|
+
def pull_number
|
35
|
+
extract(:pull_request, :number)
|
36
|
+
end
|
37
|
+
|
38
|
+
def pull_title
|
39
|
+
extract(:pull_request, :title)
|
40
|
+
end
|
41
|
+
|
42
|
+
def pull_base_label
|
43
|
+
extract(:pull_request, :base, :label)
|
44
|
+
end
|
45
|
+
|
46
|
+
def pull_base_ref
|
47
|
+
pull_base_label.to_s.split(':').last
|
48
|
+
end
|
49
|
+
|
50
|
+
def pull_head_label
|
51
|
+
extract(:pull_request, :head, :label)
|
52
|
+
end
|
53
|
+
|
54
|
+
def pull_head_ref
|
55
|
+
pull_head_label.to_s.split(':').last
|
56
|
+
end
|
57
|
+
|
58
|
+
def pull_head_title
|
59
|
+
if pull_head_ref == pull_base_ref
|
60
|
+
pull_head_ref
|
61
|
+
else
|
62
|
+
pull_head_label
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def summary_url
|
67
|
+
extract(:pull_request, :html_url).to_s
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|