chicanery 0.1.0 → 0.1.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.
data/Gemfile.lock CHANGED
@@ -1,32 +1,32 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- chicanery (0.1.0)
4
+ chicanery (0.1.1)
5
5
  nokogiri (~> 1)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
- diff-lcs (1.1.3)
10
+ diff-lcs (1.2.1)
11
11
  fakeweb (1.3.0)
12
- multi_json (1.3.7)
12
+ multi_json (1.6.1)
13
13
  nokogiri (1.5.6)
14
- rake (0.9.2.2)
15
- rspec (2.11.0)
16
- rspec-core (~> 2.11.0)
17
- rspec-expectations (~> 2.11.0)
18
- rspec-mocks (~> 2.11.0)
19
- rspec-core (2.11.1)
20
- rspec-expectations (2.11.3)
21
- diff-lcs (~> 1.1.3)
22
- rspec-mocks (2.11.3)
14
+ rake (0.9.6)
15
+ rspec (2.13.0)
16
+ rspec-core (~> 2.13.0)
17
+ rspec-expectations (~> 2.13.0)
18
+ rspec-mocks (~> 2.13.0)
19
+ rspec-core (2.13.0)
20
+ rspec-expectations (2.13.0)
21
+ diff-lcs (>= 1.1.3, < 2.0)
22
+ rspec-mocks (2.13.0)
23
23
  simplecov (0.7.1)
24
24
  multi_json (~> 1.0)
25
25
  simplecov-html (~> 0.7.1)
26
26
  simplecov-gem-adapter (1.0.1)
27
27
  simplecov
28
28
  simplecov-html (0.7.1)
29
- vcr (2.3.0)
29
+ vcr (2.4.0)
30
30
 
31
31
  PLATFORMS
32
32
  ruby
data/README.md CHANGED
@@ -16,18 +16,18 @@ State is persisted between executions so that it be scheduled to run regularly w
16
16
 
17
17
  Create a configuration file. This file is just a ruby file that can make use of a few configuration and callback methods:
18
18
 
19
- require 'chicanery/cctray'
20
19
  require 'chicanery/git'
21
-
22
20
  include Chicanery::Git
23
-
24
- git_repo 'chicanery', '/tmp/chicanery', remotes: {
21
+ git 'chicanery', '.', branches: [:master], remotes: {
25
22
  github: { url: 'git://github.com/markryall/chicanery.git' }
26
23
  }
27
- server Chicanery::Cctray.new 'tddium', 'https://cihost.com/cctray.xml'
24
+
25
+ require 'chicanery/cctray'
26
+ include Chicanery::Cctray
27
+ cctray 'tddium', 'https://cihost.com/cctray.xml'
28
28
 
29
29
  when_run do |state|
30
- puts 'checked state'
30
+ puts state.has_failure? ? "something is wrong" : "all builds are fine"
31
31
  end
32
32
 
33
33
  when_commit do |repo, commit, previous|
@@ -66,6 +66,39 @@ If you want to specify an alternate location for this state file, add the follow
66
66
 
67
67
  persist_state_to '/tmp/build_state'
68
68
 
69
+ # Callbacks
70
+
71
+ ## General
72
+
73
+ The 'when_run' callback is executed on every poll.
74
+
75
+ ## Servers
76
+
77
+ The following callbacks may be received after checking a CI server:
78
+
79
+ * when_started - when a new job has started
80
+ * when_succeeded - when a job finishes successfully
81
+ * when_failed - when a job finishes unsuccessfully
82
+ * when_broken - when a previously passing job fails
83
+ * when_fixed - when a previously failing job passes
84
+
85
+ ## Repos
86
+
87
+ The following callbacks may be received after checking a source repository:
88
+
89
+ * when_commit - when a new commit is detected in the repository
90
+
91
+ Currently only git repositories are supported.
92
+
93
+ ## Site
94
+
95
+ The following callbacks may be received after checking a web site:
96
+
97
+ * when_up - the website responded with a 2xx HTTP status
98
+ * when_down - the website did not responded with a 2xx HTTP status
99
+ * when_crashed - the website was previously up and is now down
100
+ * when_recovered - the website was previously down and is now up
101
+
69
102
  ## Supported CI servers
70
103
 
71
104
  Currently only ci servers that can provide [cctray reporting format](http://confluence.public.thoughtworks.org/display/CI/Multiple+Project+Summary+Reporting+Standard) are supported.
@@ -88,7 +121,6 @@ Basic authentication is supported by passing :user => 'user', :password => 'pass
88
121
  * monitoring a subversion repository for commit notifications
89
122
  * monitoring heroku for deployment event notification
90
123
  * monitoring more ci servers (atlassian bamboo, jetbrains team city, etc.)
91
- * integration with the blinky gem to control a delcom build light
92
124
  * other interesting notifier plugins or examples
93
125
 
94
126
  ## Contributing
@@ -97,4 +129,4 @@ Basic authentication is supported by passing :user => 'user', :password => 'pass
97
129
  2. Create your feature branch (`git checkout -b my-new-feature`)
98
130
  3. Commit your changes (`git commit -am 'Add some feature'`)
99
131
  4. Push to the branch (`git push origin my-new-feature`)
100
- 5. Create new Pull Request
132
+ 5. Create new Pull Request
@@ -10,6 +10,8 @@ git 'chicanery', '.', branches: [:master], remotes: {
10
10
 
11
11
  cctray 'travis', 'https://api.travis-ci.org/repositories/markryall/chicanery/cc.xml'
12
12
 
13
+ site 'travis', 'https://api.travis-ci.org/repositories/markryall/chicanery.json'
14
+
13
15
  poll_period 10
14
16
 
15
17
  def growlnotify message
@@ -18,6 +20,7 @@ end
18
20
 
19
21
  when_run do |state|
20
22
  puts state.has_failure? ? "something is wrong" : "all builds are fine"
23
+ puts state.site_down? ? "something is wrong" : "all sites are fine"
21
24
  end
22
25
 
23
26
  when_commit do |repo, commit, previous|
@@ -45,4 +48,16 @@ end
45
48
  when_fixed do |job_name, job|
46
49
  growlnotify "job #{job_name} is fixed"
47
50
  `afplay ~/build_sounds/applause.mp3`
51
+ end
52
+
53
+ when_up do |name, site|
54
+ puts "#{name} returned #{site.code} in #{site.duration} seconds"
55
+ end
56
+
57
+ when_crashed do |name, site|
58
+ puts "#{name} has crashed with status of #{site.code}"
59
+ end
60
+
61
+ when_recovered do |name, site|
62
+ puts "#{name} has recovered with status of #{site.code}"
48
63
  end
@@ -1,4 +1,4 @@
1
- require 'net/http'
1
+ require 'chicanery/site'
2
2
  require 'nokogiri'
3
3
  require 'date'
4
4
 
@@ -12,31 +12,14 @@ module Chicanery
12
12
  server Cctray::Server.new *args
13
13
  end
14
14
 
15
- class Server
16
- attr_reader :name, :uri, :options
17
-
18
- def initialize name, url, options={}
19
- @name, @uri, @options = name, URI(url), options
20
- end
21
-
22
- def get
23
- req = Net::HTTP::Get.new(uri.path)
24
- req.basic_auth options[:user], options[:password] if options[:user] and options[:password]
25
- res = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https', verify_mode: OpenSSL::SSL::VERIFY_NONE) do |https|
26
- https.request(req)
27
- end
28
- res.value #check for success via a spectactulalry poorly named method
29
- res.body
30
- end
31
-
15
+ class Server < Chicanery::Site
32
16
  def jobs
33
17
  jobs = {}
34
- response_body = get
35
- Nokogiri::XML(response_body).css("Project").each do |project|
18
+ Nokogiri::XML(response_body = get).css("Project").each do |project|
36
19
  job = {
37
20
  activity: project[:activity] == 'Sleeping' ? :sleeping : :building,
38
21
  last_build_status: parse_build_status(project[:lastBuildStatus]),
39
- last_build_time: project[:lastBuildTime].empty? ? nil : DateTime.parse(project[:lastBuildTime]).to_time.to_i,
22
+ last_build_time: parse_build_time(project[:lastBuildTime]),
40
23
  url: project[:webUrl],
41
24
  last_label: project[:lastBuildLabel]
42
25
  }
@@ -46,6 +29,11 @@ module Chicanery
46
29
  jobs
47
30
  end
48
31
 
32
+ def parse_build_time time
33
+ return nil if time.nil? || time.empty?
34
+ DateTime.parse(time).to_time.to_i
35
+ end
36
+
49
37
  def parse_build_status status
50
38
  case status
51
39
  when /^Success/ then :success
@@ -1,6 +1,6 @@
1
1
  module Chicanery
2
2
  module Handlers
3
- %w{run started succeeded failed broken fixed commit}.each do |status|
3
+ %w{run started succeeded failed broken fixed commit up down crashed recovered}.each do |status|
4
4
  class_eval <<-EOF
5
5
  def when_#{status} &block
6
6
  #{status}_handlers << block
@@ -0,0 +1,26 @@
1
+ require 'chicanery/collections'
2
+ require 'chicanery/handlers'
3
+
4
+ module Chicanery
5
+ module Repos
6
+ include Collections
7
+ include Handlers
8
+
9
+ def check_repos current_state, previous_state
10
+ current_state[:repos] = {}
11
+ repos.each do |repo|
12
+ repo_state = repo.state
13
+ compare_repo_state repo.name, repo_state, previous_state[:repos][repo.name] if previous_state[:repos]
14
+ current_state[:repos][repo.name] = repo_state
15
+ end
16
+ end
17
+
18
+ def compare_repo_state name, current, previous
19
+ return unless previous
20
+ current.each do |branch, state|
21
+ next unless previous[branch]
22
+ notify_commit_handlers "#{name}/#{branch}", state, previous[branch] if state != previous[branch]
23
+ end
24
+ end
25
+ end
26
+ end
@@ -1,5 +1,20 @@
1
+ require 'chicanery/collections'
2
+ require 'chicanery/handlers'
3
+
1
4
  module Chicanery
2
- module StateComparison
5
+ module Servers
6
+ include Collections
7
+ include Handlers
8
+
9
+ def check_servers current_state, previous_state
10
+ current_state[:servers] = {}
11
+ servers.each do |server|
12
+ current_jobs = server.jobs
13
+ compare_jobs current_jobs, previous_state[:servers][server.name] if previous_state[:servers]
14
+ current_state[:servers][server.name] = current_jobs
15
+ end
16
+ end
17
+
3
18
  def compare_jobs current_jobs, previous_jobs
4
19
  return unless previous_jobs
5
20
  current_jobs.each do |job_name, job|
@@ -17,13 +32,5 @@ module Chicanery
17
32
  notify_broken_handlers name, current if current[:last_build_status] == :failure and previous[:last_build_status] == :success
18
33
  notify_fixed_handlers name, current if current[:last_build_status] == :success and previous[:last_build_status] == :failure
19
34
  end
20
-
21
- def compare_repo_state name, current, previous
22
- return unless previous
23
- current.each do |branch, state|
24
- next unless previous[branch]
25
- notify_commit_handlers "#{name}/#{branch}", state, previous[branch] if state != previous[branch]
26
- end
27
- end
28
35
  end
29
36
  end
@@ -0,0 +1,26 @@
1
+ require 'net/http'
2
+ require 'benchmark'
3
+
4
+ module Chicanery
5
+ class Site
6
+ attr_reader :name, :uri, :options, :body, :code, :duration
7
+
8
+ def initialize name, url, options={}
9
+ @name, @uri, @options = name, URI(url), options
10
+ end
11
+
12
+ def get
13
+ req = Net::HTTP::Get.new uri.path
14
+ req.basic_auth options[:user], options[:password] if options[:user] and options[:password]
15
+ http_opts = { use_ssl: uri.scheme == 'https' }
16
+ http_opts[:verify_mode] = OpenSSL::SSL::VERIFY_NONE unless options[:verify_ssl]
17
+ start = Time.now
18
+ res = Net::HTTP.start uri.host, uri.port, http_opts do |https|
19
+ https.request req
20
+ end
21
+ @duration, @code, @body = (Time.now - start), res.code, res.body
22
+ res.value #check for success via a spectactularly poorly named method
23
+ res.body
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,32 @@
1
+ require 'chicanery/handlers'
2
+ require 'chicanery/site'
3
+
4
+ module Chicanery
5
+ module Sites
6
+ include Handlers
7
+
8
+ def sites
9
+ @sites ||= []
10
+ end
11
+
12
+ def site *args
13
+ sites << Chicanery::Site.new(*args)
14
+ end
15
+
16
+ def check_sites current_state, previous_state
17
+ current_state[:sites] = {}
18
+ sites.each do |site|
19
+ begin
20
+ content = site.get
21
+ current_state[:sites][site.name] = :up
22
+ notify_up_handlers site.name, site
23
+ notify_recovered_handlers site.name, site if previous_state && previous_state[:sites] && previous_state[:sites][site.name] == :down
24
+ rescue Exception
25
+ current_state[:sites][site.name] = :down
26
+ notify_down_handlers site.name, site
27
+ notify_crashed_handlers site.name, site if previous_state && previous_state[:sites] && previous_state[:sites][site.name] == :up
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -7,5 +7,11 @@ module Chicanery
7
7
  end
8
8
  end.flatten.inject(false) {|v,a| v || a}
9
9
  end
10
+
11
+ def site_down?
12
+ self[:sites].map do |name, status|
13
+ status == :down
14
+ end.inject(false) {|v,a| v || a}
15
+ end
10
16
  end
11
17
  end
data/lib/chicanery.rb CHANGED
@@ -5,18 +5,18 @@ if ENV['COVERAGE']
5
5
  end
6
6
 
7
7
  require 'chicanery/persistence'
8
- require 'chicanery/collections'
9
- require 'chicanery/handlers'
10
- require 'chicanery/state_comparison'
8
+ require 'chicanery/servers'
9
+ require 'chicanery/repos'
10
+ require 'chicanery/sites'
11
11
  require 'chicanery/summary'
12
12
 
13
13
  module Chicanery
14
14
  include Persistence
15
- include Collections
16
- include Handlers
17
- include StateComparison
15
+ include Servers
16
+ include Repos
17
+ include Sites
18
18
 
19
- VERSION = "0.1.0"
19
+ VERSION = "0.1.1"
20
20
 
21
21
  def poll_period seconds=nil
22
22
  @poll_period = seconds if seconds
@@ -24,40 +24,29 @@ module Chicanery
24
24
  end
25
25
 
26
26
  def execute args
27
- load args.shift
28
- run_every poll_period
27
+ begin
28
+ load args.shift
29
+ run_every poll_period
30
+ rescue Interrupt
31
+ end
29
32
  end
30
33
 
31
34
  def run_every poll_period
32
- begin
33
- loop do
34
- run
35
- break unless poll_period
36
- sleep poll_period
37
- end
38
- rescue Interrupt
35
+ loop do
36
+ run
37
+ break unless poll_period
38
+ sleep poll_period
39
39
  end
40
40
  end
41
41
 
42
42
  def run
43
43
  previous_state = restore
44
- current_state = {
45
- servers: {},
46
- repos: {}
47
- }
48
- repos.each do |repo|
49
- repo_state = repo.state
50
- compare_repo_state repo.name, repo_state, previous_state[:repos][repo.name] if previous_state[:repos]
51
- current_state[:repos][repo.name] = repo_state
52
- end
53
- servers.each do |server|
54
- current_jobs = server.jobs
55
- compare_jobs current_jobs, previous_state[:servers][server.name] if previous_state[:servers]
56
- current_state[:servers][server.name] = current_jobs
57
- end
44
+ current_state = {}
45
+ check_servers current_state, previous_state
46
+ check_repos current_state, previous_state
47
+ check_sites current_state, previous_state
58
48
  current_state.extend Chicanery::Summary
59
49
  run_handlers.each {|handler| handler.call current_state, previous_state }
60
50
  persist current_state
61
51
  end
62
-
63
52
  end
@@ -52,17 +52,16 @@ describe Chicanery::Cctray do
52
52
  }
53
53
  end
54
54
  end
55
-
55
+
56
56
  it 'should complain if there are no jobs in response' do
57
57
  VCR.use_cassette('no_projects') do
58
58
  expect{server.jobs}.to raise_error "could not find any jobs in response: [Nothing here but us chickens]"
59
59
  end
60
60
  end
61
-
61
+
62
62
  it 'should complain if it gets a non 2xx response' do
63
63
  VCR.use_cassette('redirect') do
64
64
  expect{server.jobs}.to raise_error Net::HTTPRetriableError
65
65
  end
66
- end
67
-
66
+ end
68
67
  end
@@ -1,5 +1,5 @@
1
- describe Chicanery::StateComparison do
2
- include Chicanery::StateComparison
1
+ describe Chicanery::Servers do
2
+ include Chicanery::Servers
3
3
 
4
4
  describe '#compare_jobs' do
5
5
  let(:current_jobs) { {} }
@@ -15,10 +15,7 @@ describe Chicanery do
15
15
  end
16
16
 
17
17
  it 'should persist new state' do
18
- should_receive(:persist).with({
19
- servers: {},
20
- repos: {}
21
- })
18
+ should_receive(:persist).with servers: {}, repos: {}, sites: {}
22
19
  end
23
20
 
24
21
  it 'should sleep for specified time when poll period is provided' do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chicanery
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-01-19 00:00:00.000000000 Z
12
+ date: 2013-03-01 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: nokogiri
@@ -154,12 +154,15 @@ files:
154
154
  - lib/chicanery/git.rb
155
155
  - lib/chicanery/handlers.rb
156
156
  - lib/chicanery/persistence.rb
157
- - lib/chicanery/state_comparison.rb
157
+ - lib/chicanery/repos.rb
158
+ - lib/chicanery/servers.rb
159
+ - lib/chicanery/site.rb
160
+ - lib/chicanery/sites.rb
158
161
  - lib/chicanery/summary.rb
159
162
  - spec/chicanery/cctray_spec.rb
160
163
  - spec/chicanery/collections_spec.rb
161
164
  - spec/chicanery/persistence_spec.rb
162
- - spec/chicanery/state_comparison_spec.rb
165
+ - spec/chicanery/servers_spec.rb
163
166
  - spec/chicanery/summary_spec.rb
164
167
  - spec/chicanery_spec.rb
165
168
  - spec/embedded_chicanery_spec.rb
@@ -177,7 +180,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
177
180
  version: '0'
178
181
  segments:
179
182
  - 0
180
- hash: -1168261720268673254
183
+ hash: -3139042759217892738
181
184
  required_rubygems_version: !ruby/object:Gem::Requirement
182
185
  none: false
183
186
  requirements:
@@ -186,7 +189,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
186
189
  version: '0'
187
190
  segments:
188
191
  - 0
189
- hash: -1168261720268673254
192
+ hash: -3139042759217892738
190
193
  requirements: []
191
194
  rubyforge_project:
192
195
  rubygems_version: 1.8.23
@@ -197,7 +200,7 @@ test_files:
197
200
  - spec/chicanery/cctray_spec.rb
198
201
  - spec/chicanery/collections_spec.rb
199
202
  - spec/chicanery/persistence_spec.rb
200
- - spec/chicanery/state_comparison_spec.rb
203
+ - spec/chicanery/servers_spec.rb
201
204
  - spec/chicanery/summary_spec.rb
202
205
  - spec/chicanery_spec.rb
203
206
  - spec/embedded_chicanery_spec.rb