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 +4 -4
- data/.gitignore +1 -0
- data/README.md +12 -3
- data/agile_notifier.gemspec +1 -1
- data/lib/agile_notifier/composer.rb +34 -7
- data/lib/agile_notifier/configuration.rb +30 -5
- data/lib/agile_notifier/its.rb +12 -10
- data/lib/agile_notifier/jira.rb +43 -1
- data/lib/agile_notifier/judger.rb +8 -0
- data/lib/agile_notifier/response_helper.rb +12 -6
- data/lib/agile_notifier.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 381bca60d1cdcef7b0e28496244aa7213c097821
|
4
|
+
data.tar.gz: 7dc6ba3581331d1287e11ef0591d81f74d3e1a72
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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```
|
data/agile_notifier.gemspec
CHANGED
@@ -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-
|
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
|
-
|
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
|
-
|
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
|
-
|
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,
|
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,
|
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,
|
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,
|
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
|
data/lib/agile_notifier/its.rb
CHANGED
@@ -1,19 +1,21 @@
|
|
1
1
|
module AgileNotifier
|
2
2
|
class ITS
|
3
|
-
|
4
|
-
|
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
|
-
|
8
|
-
|
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
|
-
|
14
|
-
|
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
|
data/lib/agile_notifier/jira.rb
CHANGED
@@ -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.
|
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
|
16
|
-
|
17
|
-
|
18
|
-
|
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
|
-
|
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
|
|
data/lib/agile_notifier.rb
CHANGED
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:
|
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-
|
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
|