nakajima-dash-ci 0.0.3

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.
@@ -0,0 +1,47 @@
1
+ # CI.register(:my_awesome_app) do
2
+ # build :rspec, 'rake spec'
3
+ # build :cucumber, 'cucumber features/'
4
+ # build :selenium, 'rake selenium:test'
5
+ # end
6
+
7
+ # CI.run(:my_awesome_app)
8
+
9
+ require 'rubygems'
10
+ require 'fiveruns/dash'
11
+ require 'base'
12
+ require 'target'
13
+ require 'session'
14
+
15
+ module CI
16
+ #
17
+ class BrokenBuild < StandardError ; end
18
+
19
+ class << self
20
+ # Register a new recipe, declaring the suite it measures in the block.
21
+ # The actual Dash recipe generation doesn't happen until run() though.
22
+ def register(sym, &block)
23
+ Base.register(sym, &block)
24
+ end
25
+
26
+ # Find the instrument target class for the given recipe, generate Dash
27
+ # recipe for suite, start Dash.
28
+ def run(sym, options={})
29
+ Base.run(sym, options)
30
+ end
31
+
32
+ # Sanitize name to be passed around to indicate a suite.
33
+ def clean(sym)
34
+ sym.to_s.gsub(/\W/, '_')
35
+ end
36
+
37
+ # Get an instrument target class.
38
+ def get(sym)
39
+ CI.const_get(clean(sym).capitalize)
40
+ end
41
+
42
+ # Set an instrument target class.
43
+ def set(sym, klass)
44
+ CI.const_set(clean(sym).capitalize, klass)
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,76 @@
1
+ module CI
2
+ class Base
3
+ class << self
4
+ # Generate a new class that will have methods generated for it which
5
+ # Dash will then instrument.
6
+ def register(sym, &block)
7
+ klass = Class.new(InstrumentTarget)
8
+ klass.suites = []
9
+ CI.set(sym, klass)
10
+ new(klass).instance_eval(&block)
11
+ end
12
+
13
+ # Run a set of suites that correspond with a given generated recipe.
14
+ # This method is called after .register().
15
+ def run(sym, options={})
16
+ klass = CI.get(sym)
17
+ make_recipe(klass, CI.clean(sym), options)
18
+ klass.new.build!
19
+ end
20
+
21
+ # Generate Dash recipe from suite commands passed to the .register()
22
+ # block, then start Dash.
23
+ def make_recipe(klass, recipe, options)
24
+ puts "Generating recipe..."
25
+
26
+ Fiveruns::Dash.register_recipe recipe, :url => 'http://dash.ci' do |recipe|
27
+ klass.suites.each do |suite|
28
+ puts ' - adding %s' % suite
29
+ method_id = instrument(klass, CI.clean(suite))
30
+ recipe.time CI.clean(suite), :method => method_id
31
+ end
32
+
33
+ recipe.time :total_time, :method => 'CI.run'
34
+ recipe.counter :total_builds, :incremented_by => instrument(klass, 'finish!')
35
+ recipe.counter :green_builds, :incremented_by => instrument(klass, 'green!')
36
+ recipe.counter :broken_builds, :incremented_by => instrument(klass, 'fail!')
37
+ end
38
+
39
+ Fiveruns::Dash.logger = Logger.new \
40
+ options[:verbose] ? STDERR : StringIO.new("")
41
+
42
+ Fiveruns::Dash.start :app => options[:token] do |config|
43
+ config.add_recipe recipe
44
+ end
45
+ end
46
+
47
+ private
48
+
49
+ def instrument(klass, sym)
50
+ '%s#%s' % [klass.to_s, sym]
51
+ end
52
+ end
53
+
54
+ def initialize(klass)
55
+ @klass = klass
56
+ end
57
+
58
+ # Define a method on the instrument class for Dash to monkey-patch. The
59
+ # method corresponds to a system command that will run that suite, for
60
+ # example:
61
+ #
62
+ # CI.register(:fixjour) do
63
+ # build :specs, 'spec spec/'
64
+ # end
65
+ #
66
+ # When the command is run and exits without error, the suite passes.
67
+ def build(suite, command)
68
+ @klass.suites << suite
69
+ @klass.class_eval do
70
+ define_method(CI.clean(suite)) do
71
+ system(command) or raise(BrokenBuild.new('%s suite failed.' % suite))
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,28 @@
1
+ module CI
2
+ # Provide wrapper around dash-ruby session in order to be able to send
3
+ # data to FiveRuns when suites complete instead of relying on periodic
4
+ # update to finish.
5
+ class Session
6
+ def initialize
7
+ @session = Fiveruns::Dash.send(:session)
8
+ end
9
+
10
+ def report!
11
+ reporter.send :send_data_update
12
+ reporter.send :send_exceptions_update
13
+ end
14
+
15
+ def error(e)
16
+ @session.exception_recorder.record(e)
17
+ end
18
+
19
+ private
20
+
21
+ def reporter
22
+ @reporter ||= begin
23
+ @session.reporter.secure!
24
+ @session.reporter
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,56 @@
1
+ module CI
2
+ # Acts as target for Dash instrumentation
3
+ class InstrumentTarget
4
+ class << self
5
+ attr_accessor :suites
6
+ end
7
+
8
+ # Run each of the build's suites, calling the appropriate instrumented
9
+ # method for each respective outcome.
10
+ def build!
11
+ suites.each do |suite|
12
+ begin; send(CI.clean(suite)); green!(suite)
13
+ rescue BrokenBuild => e
14
+ error(e)
15
+ fail!(suite)
16
+ end
17
+ end ; finish! ; report!
18
+ end
19
+
20
+ # Instrumented methods
21
+ def fail!(suite)
22
+ puts "Suite failed: #{suite}"
23
+ end
24
+
25
+ def green!(suite)
26
+ puts "Suite passed: #{suite}"
27
+ end
28
+
29
+ # Ensure data gets reported back to FiveRuns before process exits.
30
+ def finish!
31
+ puts "Finished all suites."
32
+ end
33
+
34
+ def report!
35
+ session.report!
36
+ end
37
+
38
+ private
39
+
40
+ def suites
41
+ self.class.suites
42
+ end
43
+
44
+ def error(e)
45
+ session.error(e)
46
+ end
47
+
48
+ def reporter
49
+ session.reporter
50
+ end
51
+
52
+ def session
53
+ @session ||= Session.new
54
+ end
55
+ end
56
+ end
metadata ADDED
@@ -0,0 +1,67 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: nakajima-dash-ci
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
+ platform: ruby
6
+ authors:
7
+ - Pat Nakajima
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-03-06 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: fiveruns-dash-ruby
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ description:
26
+ email:
27
+ executables: []
28
+
29
+ extensions: []
30
+
31
+ extra_rdoc_files: []
32
+
33
+ files:
34
+ - lib/dash-ci.rb
35
+ - lib/dash-ci
36
+ - lib/dash-ci/base.rb
37
+ - lib/dash-ci/target.rb
38
+ - lib/dash-ci/session.rb
39
+ has_rdoc: false
40
+ homepage:
41
+ post_install_message:
42
+ rdoc_options: []
43
+
44
+ require_paths:
45
+ - lib
46
+ - lib/dash-ci
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: "0"
52
+ version:
53
+ required_rubygems_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: "0"
58
+ version:
59
+ requirements: []
60
+
61
+ rubyforge_project:
62
+ rubygems_version: 1.2.0
63
+ signing_key:
64
+ specification_version: 2
65
+ summary: CI metrics for Dash.
66
+ test_files: []
67
+