agile_notifier 1.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 41aec86572fd574612c90eeaff7b250a38747428
4
- data.tar.gz: ff763fd1bfaddd9ec1e846edcd8d33b1bc8f1822
3
+ metadata.gz: 381bca60d1cdcef7b0e28496244aa7213c097821
4
+ data.tar.gz: 7dc6ba3581331d1287e11ef0591d81f74d3e1a72
5
5
  SHA512:
6
- metadata.gz: a4edb8f07f0afcac32d63b945472b2706db8716a2aa4995c77d7082961a5cc4457d0832dc7fc56e7993bb8c4e80b20870071d5d1aec61e839a420546570441a4
7
- data.tar.gz: 2f63fb2a3d1a039de45045b93ba6d75b2d6294785185158d148ac8407bf39bff8006e126e56487316fc7cec031aafc6cc5164830ed62d63b3adf9e4885aed564
6
+ metadata.gz: 14097412a80312dcfadb891f78e9c24da4105a177f5e5145e84acb5b74aa101945da21f572d1396da69228b55e04783d982fdc25bb678ec35ea0b9a32e2114d8
7
+ data.tar.gz: 1b12fb78c97282349b18065f615d0924d3f67e5413987bc074d347353b176db1c2883016cef054520d5795c0acd3bb1926a86b1c841c2e426fcbacbbcc1cdded
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ .idea/
data/README.md CHANGED
@@ -31,6 +31,17 @@ AgileNotifier::Configuration.set do
31
31
  alert_on_fail
32
32
  alert_on_fix
33
33
  alert_on_unstable
34
+
35
+ its_url 'https://jira.atlassian.com'
36
+ its_auth 'jira_username', 'jira_password'
37
+ its_get 'Jira'
38
+ its_set_wip 'BAM', 'project = BAM AND status = Resolved AND resolution = Unresolved', 3
39
+ its_set_wip 'XXX', 'project = XXX AND status = Resolved AND resolution = Unresolved', 5
40
+
41
+ speak 'en'
42
+ play 'Alex'
43
+
44
+ alert_on_wip
34
45
  end
35
46
  ```
36
47
 
@@ -39,6 +50,4 @@ end
39
50
 
40
51
  * TTS service benefits from online MARY TTS Web Client: http://mary.dfki.de:59125/ While it has limited languages support, please check before use.
41
52
  * play command comes from package sox which is not pre-installed, you have to install manually beforehand by:
42
- * ```
43
- sudo apt-get install sox libsox-fmt-all
44
- ```
53
+ * ```sudo apt-get install sox libsox-fmt-all```
@@ -7,7 +7,7 @@ Gem::Specification.new do |s|
7
7
  s.name = 'agile_notifier'
8
8
  s.version = AgileNotifier::VERSION
9
9
  s.license = 'MIT'
10
- s.date = '2014-05-06'
10
+ s.date = '2014-08-25'
11
11
  s.summary = %q{agile_notifier alerts you via making wonderful noises when your Continuous Integration status changes.}
12
12
  s.description = %q{agile_notifier alerts you via making wonderful noises when your Continuous Integration status changes. It totally makes software development more agile and more fun.}
13
13
  s.authors = ['Jing Li']
@@ -2,7 +2,7 @@
2
2
 
3
3
  module AgileNotifier
4
4
  class Composer
5
- SENTENCES_BLAME = {
5
+ SENTENCES_BLAME_COMMITTER = {
6
6
  de: [
7
7
  "%{committer_name} hat den Build kaputt gemacht.",
8
8
  "Schießt %{committer_name} mit der Nerf Gun ab!",
@@ -26,7 +26,7 @@ module AgileNotifier
26
26
  ]
27
27
  }
28
28
 
29
- SENTENCES_WARN = {
29
+ SENTENCES_WARN_COMMITTER = {
30
30
  de: [
31
31
  "%{committer_name} hat den Build krank gemacht.",
32
32
  "%{committer_name} hat etwas nicht gut genug gemacht."
@@ -45,7 +45,7 @@ module AgileNotifier
45
45
  ]
46
46
  }
47
47
 
48
- SENTENCES_PRAISE = {
48
+ SENTENCES_PRAISE_COMMITTER = {
49
49
  de: [
50
50
  "%{committer_name} hat den Build gefixt!",
51
51
  "%{committer_name} ist ein Genie!",
@@ -69,7 +69,34 @@ module AgileNotifier
69
69
  ]
70
70
  }
71
71
 
72
+ SENTENCES_WARN_WIP_LIMIT = {
73
+ de: [
74
+ "Kanban WIP übersteigt das Limit.",
75
+ "Kanban hat einen Flaschenhals.",
76
+ "Kanban hat zu viele Tickets, arbeitet jemand schon daran?"
77
+ ],
78
+ en: [
79
+ "Kanban WIP exceeds limit.",
80
+ "Kanban has hit a bottleneck.",
81
+ "Kanban has stacked too many items, is anyone working on it?"
82
+ ],
83
+ es: [
84
+ "El limite de WIP ha sido excedido.",
85
+ "El Kanban se esta llenando mucho.",
86
+ "Hay demasiados elementos Kanban, alguien esta trabajando en el?"
87
+ ],
88
+ zh: [
89
+ "看板瓶颈上限超出",
90
+ "搞什么呢? 看板堆积太多工作了, 想被炒鱿鱼吗?",
91
+ "看板, 嘟嘟, 请注意. 看板, 嘟嘟, 请注意."
92
+ ]
93
+ }
94
+
72
95
  class << self
96
+ def warn_wip_limit(args)
97
+ random_picker(SENTENCES_WARN_WIP_LIMIT[args[:language]])
98
+ end
99
+
73
100
  def blame_committer_of_a_commit(args)
74
101
  committer_name = get_committer_name_of_a_commit(args)
75
102
  blame_committer(committer_name, args[:language])
@@ -92,15 +119,15 @@ module AgileNotifier
92
119
  end
93
120
 
94
121
  def blame_committer(committer_name, language)
95
- mention_committer(committer_name, SENTENCES_BLAME[language])
122
+ mention_committer(committer_name, SENTENCES_BLAME_COMMITTER[language])
96
123
  end
97
124
 
98
125
  def warn_committer(committer_name, language)
99
- mention_committer(committer_name, SENTENCES_WARN[language])
126
+ mention_committer(committer_name, SENTENCES_WARN_COMMITTER[language])
100
127
  end
101
128
 
102
129
  def praise_committer(committer_name, language)
103
- mention_committer(committer_name, SENTENCES_PRAISE[language])
130
+ mention_committer(committer_name, SENTENCES_PRAISE_COMMITTER[language])
104
131
  end
105
132
 
106
133
  def mention_committer(committer_name, sentences)
@@ -114,6 +141,6 @@ module AgileNotifier
114
141
  end
115
142
  end
116
143
 
117
- private_class_method :get_committer_name_of_a_commit, :blame_committer, :praise_committer, :mention_committer, :random_picker
144
+ private_class_method :get_committer_name_of_a_commit, :blame_committer, :warn_committer, :praise_committer, :mention_committer, :random_picker
118
145
  end
119
146
  end
@@ -4,6 +4,7 @@ module AgileNotifier
4
4
  class Configuration
5
5
  def initialize(&blk)
6
6
  @current_module = Object.const_get(self.class.to_s.split('::').first)
7
+ @its_args = Hash.new
7
8
  instance_eval(&blk)
8
9
  end
9
10
 
@@ -48,6 +49,22 @@ module AgileNotifier
48
49
  return @scm
49
50
  end
50
51
 
52
+ def its_url(url)
53
+ @its_args[:url] = url
54
+ end
55
+
56
+ def its_auth(username, password)
57
+ @its_args.merge!(:username => username, :password => password)
58
+ end
59
+
60
+ def its_get(its_type)
61
+ @its = @current_module.const_get(its_type).new(@its_args)
62
+ end
63
+
64
+ def its_set_wip(project, query, limit)
65
+ @its.set_limit(project, query, limit)
66
+ end
67
+
51
68
  def speak(language)
52
69
  @language = language.to_s.downcase.intern
53
70
  end
@@ -69,18 +86,26 @@ module AgileNotifier
69
86
  end
70
87
 
71
88
  def alert(composer_type, judger_type)
72
- args = Hash.new
73
- args[:language] = @language
74
- args[:voice] = @voice if @voice
75
89
  composer_type = composer_type.to_s.downcase
76
90
  judger_type = judger_type.to_s.downcase
77
91
  composer_method = "#{composer_type}_committer_of_a_commit".intern
78
92
  judger_method = "on_#{judger_type}".intern
79
93
  text = Composer.send(composer_method, repo: @scm.repository, revision: @ci.job.last_build.revision, language: @language)
80
- Judger.send(judger_method, @ci.job.last_build, text, args)
94
+ Judger.send(judger_method, @ci.job.last_build, text, organize_args)
95
+ end
96
+
97
+ def alert_on_wip
98
+ Judger.on_limit(@its, organize_args)
99
+ end
100
+
101
+ def organize_args
102
+ args = Hash.new
103
+ args[:language] = @language
104
+ args[:voice] = @voice if @voice
105
+ args
81
106
  end
82
107
 
83
108
  private_class_method :new
84
- private :alert
109
+ private :alert, :organize_args
85
110
  end
86
111
  end
@@ -1,19 +1,21 @@
1
1
  module AgileNotifier
2
2
  class ITS
3
- def initialize(url)
4
- @url = url
3
+ include Servable
4
+
5
+ def initialize(args)
6
+ @url = args.fetch(:url)
7
+ end
8
+
9
+ def query_amount_of_tickets(query)
10
+ raise(NotImplementedError, "Abstract method [#{__method__}] is called, please implement", caller)
5
11
  end
6
12
 
7
- class Project
8
- def initialize(name)
9
- @name = name
10
- end
13
+ def set_limit(project, query, limit)
14
+ raise(NotImplementedError, "Abstract method [#{__method__}] is called, please implement", caller)
11
15
  end
12
16
 
13
- class Issue
14
- def initialize(id)
15
- @id = id
16
- end
17
+ def exceeds_limit?
18
+ raise(NotImplementedError, "Abstract method [#{__method__}] is called, please implement", caller)
17
19
  end
18
20
  end
19
21
  end
@@ -1,7 +1,49 @@
1
1
  require_relative 'its'
2
+ require_relative 'response_helper'
2
3
 
3
4
  module AgileNotifier
4
5
  class Jira < ITS
5
-
6
+ include ResponseHelper
7
+
8
+ alias_method :original_is_available?, :is_available?
9
+
10
+ API_VERSION_URL = '/rest/api/latest/'
11
+ USERAGENT = 'AgileNotifier'
12
+
13
+ def initialize(args)
14
+ @url = args.fetch(:url).gsub(/\/$/, '') + API_VERSION_URL
15
+ @username = args.fetch(:username)
16
+ @password = args.fetch(:password)
17
+ @wip = Hash.new
18
+ end
19
+
20
+ def is_available?
21
+ original_is_available?(@url + 'serverInfo')
22
+ end
23
+
24
+ def query_amount_of_tickets(jql)
25
+ get_value('total', jql)
26
+ end
27
+
28
+ def set_limit(project, query, limit)
29
+ @wip[project] = {:query => query, :limit => limit}
30
+ end
31
+
32
+ def exceeds_limit?
33
+ @wip.inject({}) do |result, (key, value)|
34
+ result.merge({key => query_amount_of_tickets(value[:query]) > value[:limit]})
35
+ end
36
+ end
37
+
38
+ def get_value(key, jql, max = 1)
39
+ get_value_of_key(key,
40
+ @url + 'search',
41
+ :method => :post,
42
+ :headers => {'Content-Type' => 'application/json', 'User-Agent' => USERAGENT},
43
+ :basic_auth => {:username => @username, :password => @password},
44
+ :body => {'jql' => jql, 'maxResults' => max}.to_json)
45
+ end
46
+
47
+ private :get_value
6
48
  end
7
49
  end
@@ -1,4 +1,5 @@
1
1
  require_relative 'tts'
2
+ require_relative 'composer'
2
3
 
3
4
  module AgileNotifier
4
5
  class Judger
@@ -19,6 +20,13 @@ module AgileNotifier
19
20
  on_condition(trackable.fixed?, text, args)
20
21
  end
21
22
 
23
+ def on_limit(its, args)
24
+ its.exceeds_limit?.each do |key, value|
25
+ on_condition(value, "#{key} #{Composer.warn_wip_limit(args)}", args)
26
+ sleep 1.5 if value
27
+ end
28
+ end
29
+
22
30
  def on_condition(condition, text, args)
23
31
  if condition
24
32
  TTS.speak(text, args)
@@ -8,16 +8,22 @@ module AgileNotifier
8
8
  module ResponseHelper
9
9
  def get_value_of_key(key, *args)
10
10
  pm = PrivateMethods.new
11
- pm.get_value_of_key_from_json(key, pm.get_json_response(*args))
11
+ pm.get_value_of_key_from_json(key, pm.request_json_response(*args))
12
12
  end
13
13
 
14
14
  class PrivateMethods
15
- def get_json_response(*args)
16
- response = HTTParty.get(*args)
17
- if response.code == 200
18
- return JSON.parse(response.body)
15
+ def request_json_response(*args)
16
+ method = ((args[1].respond_to?(:delete) ? args[1].delete(:method) : false) || :get).to_sym
17
+ supported_methods = [:get, :post, :put, :delete, :head, :options]
18
+ unless supported_methods.include?(method)
19
+ raise(RuntimeError, "Unsupported HTTP Method: #{method.to_s}", caller)
19
20
  else
20
- raise(ResponseError, "HTTP Status Code: #{response.code} - #{response.parsed_response}", caller)
21
+ response = HTTParty.send(method, *args)
22
+ if response.code.to_s.match(/^2\d{2}$/)
23
+ return JSON.parse(response.body)
24
+ else
25
+ raise(ResponseError, "HTTP Status Code: #{response.code} - #{response.parsed_response}", caller)
26
+ end
21
27
  end
22
28
  end
23
29
 
@@ -1,5 +1,5 @@
1
1
  Dir[(File.expand_path(File.dirname(__FILE__)) + "/agile_notifier/*.rb")].each { |file| require file }
2
2
 
3
3
  module AgileNotifier
4
- VERSION = '1.1.1'
4
+ VERSION = '2.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: agile_notifier
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.1
4
+ version: '2.0'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jing Li
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-05-06 00:00:00.000000000 Z
11
+ date: 2014-08-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json
@@ -79,6 +79,7 @@ executables: []
79
79
  extensions: []
80
80
  extra_rdoc_files: []
81
81
  files:
82
+ - .gitignore
82
83
  - Gemfile
83
84
  - Gemfile.lock
84
85
  - README.md