codebot 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. checksums.yaml +7 -0
  2. data/.github/ISSUE_TEMPLATE.md +32 -0
  3. data/.github/ISSUE_TEMPLATE/formatter_issue.md +20 -0
  4. data/.github/PULL_REQUEST_TEMPLATE.md +13 -0
  5. data/.gitignore +10 -0
  6. data/.rspec +1 -0
  7. data/.rubocop.yml +11 -0
  8. data/.travis.yml +26 -0
  9. data/CODE_OF_CONDUCT.md +46 -0
  10. data/CONTRIBUTING.md +15 -0
  11. data/Gemfile +4 -0
  12. data/Gemfile.lock +75 -0
  13. data/LICENSE +21 -0
  14. data/README.md +230 -0
  15. data/Rakefile +29 -0
  16. data/bin/console +8 -0
  17. data/codebot.gemspec +49 -0
  18. data/exe/codebot +7 -0
  19. data/lib/codebot.rb +8 -0
  20. data/lib/codebot/channel.rb +134 -0
  21. data/lib/codebot/command_error.rb +17 -0
  22. data/lib/codebot/config.rb +125 -0
  23. data/lib/codebot/configuration_error.rb +17 -0
  24. data/lib/codebot/core.rb +76 -0
  25. data/lib/codebot/cryptography.rb +38 -0
  26. data/lib/codebot/event.rb +62 -0
  27. data/lib/codebot/ext/cinch/ssl_extensions.rb +37 -0
  28. data/lib/codebot/formatter.rb +242 -0
  29. data/lib/codebot/formatters.rb +109 -0
  30. data/lib/codebot/formatters/.rubocop.yml +2 -0
  31. data/lib/codebot/formatters/commit_comment.rb +43 -0
  32. data/lib/codebot/formatters/fork.rb +40 -0
  33. data/lib/codebot/formatters/gitlab_issue_hook.rb +56 -0
  34. data/lib/codebot/formatters/gitlab_job_hook.rb +77 -0
  35. data/lib/codebot/formatters/gitlab_merge_request_hook.rb +57 -0
  36. data/lib/codebot/formatters/gitlab_note_hook.rb +119 -0
  37. data/lib/codebot/formatters/gitlab_pipeline_hook.rb +51 -0
  38. data/lib/codebot/formatters/gitlab_push_hook.rb +83 -0
  39. data/lib/codebot/formatters/gitlab_wiki_page_hook.rb +56 -0
  40. data/lib/codebot/formatters/gollum.rb +67 -0
  41. data/lib/codebot/formatters/issue_comment.rb +41 -0
  42. data/lib/codebot/formatters/issues.rb +41 -0
  43. data/lib/codebot/formatters/ping.rb +79 -0
  44. data/lib/codebot/formatters/public.rb +30 -0
  45. data/lib/codebot/formatters/pull_request.rb +71 -0
  46. data/lib/codebot/formatters/pull_request_review_comment.rb +49 -0
  47. data/lib/codebot/formatters/push.rb +172 -0
  48. data/lib/codebot/formatters/watch.rb +38 -0
  49. data/lib/codebot/integration.rb +195 -0
  50. data/lib/codebot/integration_manager.rb +225 -0
  51. data/lib/codebot/ipc_client.rb +83 -0
  52. data/lib/codebot/ipc_server.rb +79 -0
  53. data/lib/codebot/irc_client.rb +102 -0
  54. data/lib/codebot/irc_connection.rb +156 -0
  55. data/lib/codebot/message.rb +37 -0
  56. data/lib/codebot/metadata.rb +15 -0
  57. data/lib/codebot/network.rb +240 -0
  58. data/lib/codebot/network_manager.rb +181 -0
  59. data/lib/codebot/options.rb +49 -0
  60. data/lib/codebot/options/base.rb +55 -0
  61. data/lib/codebot/options/core.rb +126 -0
  62. data/lib/codebot/options/integration.rb +101 -0
  63. data/lib/codebot/options/network.rb +109 -0
  64. data/lib/codebot/payload.rb +32 -0
  65. data/lib/codebot/request.rb +51 -0
  66. data/lib/codebot/sanitizers.rb +130 -0
  67. data/lib/codebot/serializable.rb +101 -0
  68. data/lib/codebot/shortener.rb +43 -0
  69. data/lib/codebot/thread_controller.rb +70 -0
  70. data/lib/codebot/user_error.rb +13 -0
  71. data/lib/codebot/validation_error.rb +17 -0
  72. data/lib/codebot/web_listener.rb +107 -0
  73. data/lib/codebot/web_server.rb +58 -0
  74. data/webhook.png +0 -0
  75. 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