lita-github_pr_list 0.0.1

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.
Files changed (38) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +24 -0
  3. data/.hound.yml +8 -0
  4. data/.rspec +4 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE +21 -0
  7. data/README.md +51 -0
  8. data/Rakefile +6 -0
  9. data/bin/rake +16 -0
  10. data/bin/rspec +16 -0
  11. data/lib/lita/github_pr_list/alias_user.rb +19 -0
  12. data/lib/lita/github_pr_list/comment_hook.rb +42 -0
  13. data/lib/lita/github_pr_list/pull_request.rb +62 -0
  14. data/lib/lita/github_pr_list/status.rb +44 -0
  15. data/lib/lita/github_pr_list/version.rb +5 -0
  16. data/lib/lita/github_pr_list/web_hook.rb +39 -0
  17. data/lib/lita/github_pr_list.rb +7 -0
  18. data/lib/lita/handlers/github_pr_list.rb +91 -0
  19. data/lita-github_pr_list.gemspec +30 -0
  20. data/spec/fixtures/issue_comment_event_failed.json +180 -0
  21. data/spec/fixtures/issue_comment_event_fixed.json +180 -0
  22. data/spec/fixtures/issue_comment_event_in_review.json +180 -0
  23. data/spec/fixtures/issue_comment_event_passed.json +180 -0
  24. data/spec/fixtures/issue_comments_failed.json +83 -0
  25. data/spec/fixtures/issue_comments_fixed.json +111 -0
  26. data/spec/fixtures/issue_comments_in_review.json +83 -0
  27. data/spec/fixtures/issue_comments_new.json +56 -0
  28. data/spec/fixtures/issue_comments_passed.json +83 -0
  29. data/spec/fixtures/one_org_issue_list.json +182 -0
  30. data/spec/fixtures/repository_hooks.json +34 -0
  31. data/spec/fixtures/repository_list.json +108 -0
  32. data/spec/fixtures/two_org_issue_list.json +362 -0
  33. data/spec/lita/handlers/alias_spec.rb +13 -0
  34. data/spec/lita/handlers/comment_hook_spec.rb +57 -0
  35. data/spec/lita/handlers/pull_request_spec.rb +72 -0
  36. data/spec/lita/handlers/web_hook_spec.rb +50 -0
  37. data/spec/spec_helper.rb +8 -0
  38. metadata +222 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: beeb7009c49b1c0b9d0e0b4a545e026d44977136
4
+ data.tar.gz: f80eb0cd2ed89ead579fad36e4f8ed711d4f5651
5
+ SHA512:
6
+ metadata.gz: e6c011f75f9aedc132bf069e3a9ef837c9191951274209033cce5db6e105e5af3d9e099906c22dc8053cccbf175a18f2c92d6387002125460f008d968ccf6748
7
+ data.tar.gz: c6164d0556c112064ed90ca655c164df6526b7769c3fd3bb2cd3dffe2c99ed517c3d9d1ce3aba789e5f14a4e800e15ae6bf1fdd44c0992b3bfeecdcf797cedec
data/.gitignore ADDED
@@ -0,0 +1,24 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
23
+ vendor
24
+ .env
data/.hound.yml ADDED
@@ -0,0 +1,8 @@
1
+ LineLength:
2
+ Max: 130
3
+
4
+ StringLiterals:
5
+ Enabled: false
6
+
7
+ EmptyLinesAroundBody:
8
+ Enabled: false
data/.rspec ADDED
@@ -0,0 +1,4 @@
1
+ --color
2
+ --require spec_helper
3
+ --require rspec/instafail
4
+ --format documentation
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in lita-github_pr_list.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2014 Alberta Motor Assocation
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,51 @@
1
+ # lita-github_pr_list
2
+
3
+ lita-google-images is a handler for Lita that connects up with Github and lists an organizations pull requests
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'lita-github_pr_list'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install lita-github_pr_list
18
+
19
+ ## Configuration
20
+
21
+ ```
22
+ Lita.configure do |config|
23
+ ...
24
+ config.handlers.github_pr_list.github_organization = ENV['GITHUB_ORG']
25
+ config.handlers.github_pr_list.github_access_token = ENV['GITHUB_TOKEN']
26
+ ...
27
+ end
28
+ ```
29
+
30
+ ## Usage
31
+
32
+ ```Lita: pr list```
33
+
34
+ All of the open pull requests for an organization will get listed out from lita. If it has one of the emoji statuses below it
35
+ will display it, otherwise it will display :new:.
36
+
37
+ ## Emoji status
38
+
39
+ New - :new: - This is the default state, shown (new) if none of the other states are set.
40
+ Pass - :elephant: :elephant: :elephant: = (elephant)(elephant)(elephant)
41
+ In Review - :book: = (book)
42
+ Fail - :poop: = (poop)
43
+ Fixed - :wave: = (wave)
44
+
45
+ ## Contributing
46
+
47
+ 1. Fork it ( https://github.com/amaabca/lita-github_pr_list/fork )
48
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
49
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
50
+ 4. Push to the branch (`git push origin my-new-feature`)
51
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/rake ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'rake' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('rake', 'rake')
data/bin/rspec ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'rspec' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('rspec-core', 'rspec')
@@ -0,0 +1,19 @@
1
+ module Lita
2
+ module GithubPrList
3
+ class AliasUser
4
+ attr_accessor :response, :redis
5
+
6
+ def initialize(params = {})
7
+ self.response = params.fetch(:response, nil)
8
+ self.redis = params.fetch(:redis, nil)
9
+ raise "invalid params in #{self.class.name}" if response.nil? || redis.nil?
10
+ end
11
+
12
+ def create_alias
13
+ github_username, hipchat_username = response.matches.first[0], response.matches.first[1]
14
+ redis.set("alias:#{github_username}", hipchat_username)
15
+ response.reply "Mapped #{github_username} to #{hipchat_username}"
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,42 @@
1
+ module Lita
2
+ module GithubPrList
3
+ class CommentHook
4
+ attr_accessor :request, :response, :payload, :commenter, :issue_owner, :issue_title, :issue_body, :status,
5
+ :issue_html_url, :redis
6
+
7
+ def initialize(params = {})
8
+ self.response = params.fetch(:response, nil)
9
+ self.request = params.fetch(:request, nil)
10
+ self.redis = params.fetch(:redis, nil)
11
+
12
+ raise "invalid params in #{self.class.name}" if response.nil? || request.nil? || redis.nil?
13
+
14
+ # https://developer.github.com/v3/activity/events/types/#issuecommentevent
15
+ self.payload = JSON.parse(request.body.read)
16
+ self.commenter = redis.get("alias:#{payload["sender"]["login"]}") || payload["sender"]["login"]
17
+ self.issue_owner = redis.get("alias:#{payload["issue"]["user"]["login"]}") || payload["issue"]["user"]["login"]
18
+ self.issue_title = payload["issue"]["title"]
19
+ self.issue_html_url = payload["issue"]["html_url"]
20
+ self.issue_body = payload["comment"]["body"]
21
+ end
22
+
23
+ def message
24
+ status = Status.new({comment: issue_body}).comment_status
25
+
26
+ if !status.empty?
27
+ if status[:emoji] == Lita::GithubPrList::Status::PASS_EMOJI
28
+ "@#{issue_owner} your pull request: #{issue_title} has passed. #{issue_html_url}"
29
+ elsif status[:emoji] == Lita::GithubPrList::Status::REVIEW_EMOJI
30
+ "@#{commenter} is currently reviewing: #{issue_title}. #{issue_html_url}"
31
+ elsif status[:emoji] == Lita::GithubPrList::Status::FAIL_EMOJI
32
+ "@#{issue_owner} your pull request: #{issue_title} has failed. #{issue_html_url}"
33
+ elsif status[:emoji] == Lita::GithubPrList::Status::FIXED_EMOJI
34
+ "#{issue_title} has been fixed: #{issue_html_url}"
35
+ end
36
+ else
37
+ nil
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,62 @@
1
+ require "octokit"
2
+
3
+ module Lita
4
+ module GithubPrList
5
+ class PullRequest
6
+ attr_accessor :github_client, :github_organization, :github_pull_requests,
7
+ :summary, :response
8
+
9
+ def initialize(params = {})
10
+ self.response = params.fetch(:response, nil)
11
+ github_token = params.fetch(:github_token, nil)
12
+ self.github_organization = params.fetch(:github_organization, nil)
13
+ self.github_pull_requests = []
14
+
15
+ raise "invalid params in #{self.class.name}" if response.nil? || github_token.nil? || github_organization.nil?
16
+
17
+ self.github_client = Octokit::Client.new(access_token: github_token, auto_paginate: true)
18
+ end
19
+
20
+ def list
21
+ get_pull_requests
22
+ build_summary
23
+
24
+ response.reply summary
25
+ end
26
+
27
+ private
28
+ def get_pull_requests
29
+ # Grab the issues and sort out the pull request issues
30
+ issues = github_client.org_issues(github_organization, { filter: 'all', sort: 'created' })
31
+
32
+ issues.each do |i|
33
+ github_pull_requests << i if i.pull_request
34
+ end
35
+ end
36
+
37
+ def build_summary
38
+ self.summary = "I found #{github_pull_requests.count} open pull requests for #{github_organization}"
39
+
40
+ github_pull_requests.each do |pr_issue|
41
+ status = repo_status("#{pr_issue.repository.full_name}", pr_issue.number)
42
+ self.summary += "\n#{pr_issue.repository.name} #{status} #{pr_issue.title} #{pr_issue.pull_request.html_url}"
43
+ end
44
+ end
45
+
46
+ def repo_status(repo_full_name, issue_number)
47
+ status = { emoji: "(new)", status: "New" }
48
+
49
+ comments(repo_full_name, issue_number).each do |c|
50
+ status = Lita::GithubPrList::Status.new(comment: c.body, status: status).comment_status
51
+ end
52
+
53
+ status[:emoji]
54
+ end
55
+
56
+ def comments(repo_full_name, issue_number, options = nil)
57
+ github_options = options || { direction: 'asc', sort: 'created' }
58
+ github_client.issue_comments(repo_full_name, issue_number, github_options)
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,44 @@
1
+ module Lita
2
+ module GithubPrList
3
+ class Status
4
+ attr_accessor :comment, :status,
5
+ :pass_regex, :review_regex, :fail_regex, :fixed_regex
6
+
7
+ PASS_REGEX = /:elephant: :elephant: :elephant:/
8
+ REVIEW_REGEX = /:book:/
9
+ FAIL_REGEX = /:poop:/
10
+ FIXED_REGEX = /:wave:/
11
+
12
+ PASS_EMOJI = "(elephant)(elephant)(elephant)"
13
+ REVIEW_EMOJI = "(book)"
14
+ FAIL_EMOJI = "(poop)"
15
+ FIXED_EMOJI = "(wave)"
16
+
17
+ def initialize(params = {})
18
+ self.comment = params.fetch(:comment, nil)
19
+ self.status = params.fetch(:status, {})
20
+
21
+ raise "invalid params in #{self.class.name}" if comment.nil?
22
+ end
23
+
24
+ def comment_status
25
+ case self.comment
26
+ when PASS_REGEX
27
+ status[:emoji] = PASS_EMOJI
28
+ status[:status] = "Passed"
29
+ when REVIEW_REGEX
30
+ status[:emoji] = REVIEW_EMOJI
31
+ status[:status] = "In Review"
32
+ when FAIL_REGEX
33
+ status[:emoji] = FAIL_EMOJI
34
+ status[:status] = "Failed"
35
+ when FIXED_REGEX
36
+ status[:emoji] = FIXED_EMOJI
37
+ status[:status] = "Fixed"
38
+ end
39
+
40
+ status
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,5 @@
1
+ module Lita
2
+ module GithubPrList
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,39 @@
1
+ require "octokit"
2
+
3
+ module Lita
4
+ module GithubPrList
5
+ class WebHook
6
+ attr_accessor :web_hook, :github_client, :github_organization, :github_pull_requests
7
+
8
+ def initialize(params = {})
9
+ github_token = params.fetch(:github_token, nil)
10
+ self.github_organization = params.fetch(:github_organization, nil)
11
+ self.web_hook = params.fetch(:web_hook, nil)
12
+
13
+ raise "invalid params in #{self.class.name}" if github_token.nil? || github_organization.nil? || web_hook.nil?
14
+
15
+ self.github_client = Octokit::Client.new(access_token: github_token, auto_paginate: true)
16
+ end
17
+
18
+ def add_hooks
19
+ github_client.repositories(github_organization).each do |repo|
20
+ config = { url: "#{web_hook}", content_type: "json" }
21
+ events = { events: ["issue_comment"] }
22
+
23
+ github_client.create_hook(repo.full_name, "web", config, events)
24
+ end
25
+ end
26
+
27
+ def remove_hooks
28
+ github_client.repositories(github_organization).each do |repo|
29
+ github_client.hooks(repo.full_name).each do |hook|
30
+ if hook.config.url == web_hook
31
+ github_client.remove_hook(repo.full_name, hook.id)
32
+ end
33
+ end
34
+ end
35
+ end
36
+
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,7 @@
1
+ require "lita/github_pr_list/version"
2
+ require "lita/github_pr_list/status"
3
+ require "lita/github_pr_list/comment_hook"
4
+ require "lita/github_pr_list/pull_request"
5
+ require "lita/github_pr_list/alias_user"
6
+ require "lita/github_pr_list/web_hook"
7
+ require "lita/handlers/github_pr_list"
@@ -0,0 +1,91 @@
1
+ require "lita"
2
+ require "json"
3
+
4
+ module Lita
5
+ module Handlers
6
+ class GithubPrList < Handler
7
+ def initialize(robot)
8
+ super
9
+ end
10
+
11
+ def self.default_config(config)
12
+ config.github_organization = nil
13
+ config.github_access_token = nil
14
+ config.web_hook = nil
15
+ end
16
+
17
+ route(/pr list/i, :list_org_pr, command: true,
18
+ help: { "pr list" => "List open pull requests for an organization." }
19
+ )
20
+
21
+ route(/pr add hooks/i, :add_pr_hooks, command: true,
22
+ help: { "pr add hooks" => "Add a pr web hook to every repo in your organization." }
23
+ )
24
+
25
+ route(/pr remove hooks/i, :remove_pr_hooks, command: true,
26
+ help: { "pr remove hooks" => "Remove the pr web hook from every repo in your organization." }
27
+ )
28
+
29
+ route(/pr alias user (\w*) (\w*)/i, :alias_user, command: true,
30
+ help: { "pr alias user <GithubUsername> <HipchatUsername>" => "Create an alias to match a Github "\
31
+ "username to a Hipchat Username." }
32
+ )
33
+
34
+ http.post "/comment_hook", :comment_hook
35
+
36
+ def list_org_pr(response)
37
+ Lita::GithubPrList::PullRequest.new({ github_organization: github_organization,
38
+ github_token: github_access_token,
39
+ response: response, redis: redis }).list
40
+ end
41
+
42
+ def alias_user(response)
43
+ Lita::GithubPrList::AliasUser.new({ response:response, redis: redis }).create_alias
44
+ end
45
+
46
+ def comment_hook(request, response)
47
+ message = Lita::GithubPrList::CommentHook.new({ request: request, response: response, redis: redis }).message
48
+
49
+ rooms = Lita.config.adapter.rooms
50
+ rooms ||= [:all]
51
+ rooms.each do |room|
52
+ target = Source.new(room: room)
53
+ robot.send_message(target, message) unless message.nil?
54
+ end
55
+
56
+ response.body << "Nothing to see here..."
57
+ end
58
+
59
+ def add_pr_hooks(response)
60
+ response.reply "Adding webhooks to #{github_organization}, this may take "\
61
+ "awhile..."
62
+
63
+ Lita::GithubPrList::WebHook.new(github_organization: github_organization,
64
+ github_token: github_access_token,
65
+ web_hook: web_hook).add_hooks
66
+ end
67
+
68
+ def remove_pr_hooks(response)
69
+ response.reply "Removing github_pr_list webhooks from #{github_organization},"\
70
+ " this may take awhile..."
71
+
72
+ Lita::GithubPrList::WebHook.new(github_organization: github_organization,
73
+ github_token: github_access_token,
74
+ web_hook: web_hook).remove_hooks
75
+ end
76
+
77
+ private
78
+ def github_organization
79
+ Lita.config.handlers.github_pr_list.github_organization
80
+ end
81
+ def github_access_token
82
+ Lita.config.handlers.github_pr_list.github_access_token
83
+ end
84
+ def web_hook
85
+ Lita.config.handlers.github_pr_list.web_hook
86
+ end
87
+ end
88
+
89
+ Lita.register_handler(GithubPrList)
90
+ end
91
+ end
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'lita/github_pr_list/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "lita-github_pr_list"
8
+ spec.version = Lita::GithubPrList::VERSION
9
+ spec.authors = ["Michael van den Beuken", "Ruben Estevez", "Jordan Babe", "Mathieu Gilbert", "Ryan Jones", "Darko Dosenovic"]
10
+ spec.email = ["michael.beuken@gmail.com", "ruben.a.estevez@gmail.com", "jorbabe@gmail.com", "mathieu.gilbert@ama.ab.ca", "ryan.michael.jones@gmail.com", "darko.dosenovic@ama.ab.ca"]
11
+ spec.summary = %q{List open pull requests for an organization.}
12
+ spec.description = %q{List open pull requests for an organization.}
13
+ spec.homepage = "https://github.com/amaabca/lita-github_pr_list"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_runtime_dependency "lita"
22
+ spec.add_runtime_dependency "octokit", "~> 3.0"
23
+
24
+ spec.add_development_dependency "bundler", "~> 1.6"
25
+ spec.add_development_dependency "rake"
26
+ spec.add_development_dependency "pry"
27
+ spec.add_development_dependency "rspec"
28
+ spec.add_development_dependency "rspec-instafail"
29
+ spec.add_development_dependency "simplecov"
30
+ end