corundum 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. data/doc/README +2 -0
  2. data/doc/Specifications +6 -0
  3. data/doc/coverage/assets/0.5.3/app.js +88 -0
  4. data/doc/coverage/assets/0.5.3/fancybox/blank.gif +0 -0
  5. data/doc/coverage/assets/0.5.3/fancybox/fancy_close.png +0 -0
  6. data/doc/coverage/assets/0.5.3/fancybox/fancy_loading.png +0 -0
  7. data/doc/coverage/assets/0.5.3/fancybox/fancy_nav_left.png +0 -0
  8. data/doc/coverage/assets/0.5.3/fancybox/fancy_nav_right.png +0 -0
  9. data/doc/coverage/assets/0.5.3/fancybox/fancy_shadow_e.png +0 -0
  10. data/doc/coverage/assets/0.5.3/fancybox/fancy_shadow_n.png +0 -0
  11. data/doc/coverage/assets/0.5.3/fancybox/fancy_shadow_ne.png +0 -0
  12. data/doc/coverage/assets/0.5.3/fancybox/fancy_shadow_nw.png +0 -0
  13. data/doc/coverage/assets/0.5.3/fancybox/fancy_shadow_s.png +0 -0
  14. data/doc/coverage/assets/0.5.3/fancybox/fancy_shadow_se.png +0 -0
  15. data/doc/coverage/assets/0.5.3/fancybox/fancy_shadow_sw.png +0 -0
  16. data/doc/coverage/assets/0.5.3/fancybox/fancy_shadow_w.png +0 -0
  17. data/doc/coverage/assets/0.5.3/fancybox/fancy_title_left.png +0 -0
  18. data/doc/coverage/assets/0.5.3/fancybox/fancy_title_main.png +0 -0
  19. data/doc/coverage/assets/0.5.3/fancybox/fancy_title_over.png +0 -0
  20. data/doc/coverage/assets/0.5.3/fancybox/fancy_title_right.png +0 -0
  21. data/doc/coverage/assets/0.5.3/fancybox/fancybox-x.png +0 -0
  22. data/doc/coverage/assets/0.5.3/fancybox/fancybox-y.png +0 -0
  23. data/doc/coverage/assets/0.5.3/fancybox/fancybox.png +0 -0
  24. data/doc/coverage/assets/0.5.3/fancybox/jquery.fancybox-1.3.1.css +363 -0
  25. data/doc/coverage/assets/0.5.3/fancybox/jquery.fancybox-1.3.1.pack.js +44 -0
  26. data/doc/coverage/assets/0.5.3/favicon_green.png +0 -0
  27. data/doc/coverage/assets/0.5.3/favicon_red.png +0 -0
  28. data/doc/coverage/assets/0.5.3/favicon_yellow.png +0 -0
  29. data/doc/coverage/assets/0.5.3/highlight.css +129 -0
  30. data/doc/coverage/assets/0.5.3/highlight.pack.js +1 -0
  31. data/doc/coverage/assets/0.5.3/jquery-1.6.2.min.js +18 -0
  32. data/doc/coverage/assets/0.5.3/jquery.dataTables.min.js +152 -0
  33. data/doc/coverage/assets/0.5.3/jquery.timeago.js +141 -0
  34. data/doc/coverage/assets/0.5.3/jquery.url.js +174 -0
  35. data/doc/coverage/assets/0.5.3/loading.gif +0 -0
  36. data/doc/coverage/assets/0.5.3/magnify.png +0 -0
  37. data/doc/coverage/assets/0.5.3/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  38. data/doc/coverage/assets/0.5.3/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  39. data/doc/coverage/assets/0.5.3/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  40. data/doc/coverage/assets/0.5.3/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  41. data/doc/coverage/assets/0.5.3/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  42. data/doc/coverage/assets/0.5.3/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  43. data/doc/coverage/assets/0.5.3/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  44. data/doc/coverage/assets/0.5.3/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  45. data/doc/coverage/assets/0.5.3/smoothness/images/ui-icons_222222_256x240.png +0 -0
  46. data/doc/coverage/assets/0.5.3/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
  47. data/doc/coverage/assets/0.5.3/smoothness/images/ui-icons_454545_256x240.png +0 -0
  48. data/doc/coverage/assets/0.5.3/smoothness/images/ui-icons_888888_256x240.png +0 -0
  49. data/doc/coverage/assets/0.5.3/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
  50. data/doc/coverage/assets/0.5.3/smoothness/jquery-ui-1.8.4.custom.css +295 -0
  51. data/doc/coverage/assets/0.5.3/stylesheet.css +383 -0
  52. data/doc/coverage/index.html +6511 -0
  53. data/lib/corundum.rb +130 -0
  54. data/lib/corundum/email.rb +92 -0
  55. data/lib/corundum/gem_building.rb +34 -0
  56. data/lib/corundum/gemcutter.rb +110 -0
  57. data/lib/corundum/gemspec_sanity.rb +32 -0
  58. data/lib/corundum/rspec.rb +135 -0
  59. data/lib/corundum/rubyforge.rb +95 -0
  60. data/lib/corundum/simplecov.rb +123 -0
  61. data/lib/corundum/tasklib.rb +57 -0
  62. data/lib/corundum/tasklibs.rb +8 -0
  63. data/lib/corundum/version_control.rb +36 -0
  64. data/lib/corundum/version_control/monotone.rb +126 -0
  65. data/lib/corundum/yardoc.rb +33 -0
  66. data/spec/bogus_spec.rb +3 -0
  67. data/spec/smoking_spec.rb +29 -0
  68. data/spec_help/file-sandbox.rb +164 -0
  69. data/spec_help/gem_test_suite.rb +17 -0
  70. data/spec_help/spec_helper.rb +4 -0
  71. data/spec_help/ungemmer.rb +36 -0
  72. metadata +292 -0
data/lib/corundum.rb ADDED
@@ -0,0 +1,130 @@
1
+ require 'corundum/tasklib'
2
+
3
+ #require 'rubygems'
4
+ #require 'rubygems/installer'
5
+
6
+ module Corundum
7
+ extend Rake::DSL
8
+
9
+ class Toolkit < TaskLib
10
+ def default_configuration(namespace)
11
+ @configuration.marshal_load(
12
+ :namespace => namespace,
13
+ :finished_dir => "corundum",
14
+ :finished_files => OpenStruct.new,
15
+
16
+ :browser => "chromium",
17
+ :gemspec => nil,
18
+ :gemspec_path => nil,
19
+ :email => OpenStruct.new(
20
+ :servers => [ OpenStruct.new({ :server => "ruby-lang.org", :helo => "gmail.com" }) ],
21
+ :announce_to_email => "ruby-talk@ruby-lang.org"
22
+ ),
23
+ :package_dir => "pkg",
24
+ :files => OpenStruct.new(:code => nil, :test => nil, :docs => nil),
25
+ :file_lists => OpenStruct.new(:code => nil, :test => nil, :docs => nil, :all => nil),
26
+ :rubyforge => OpenStruct.new(),
27
+ :doc_dir => "rubydoc"
28
+ )
29
+ end
30
+
31
+ def load_gemspec
32
+ @configuration.gemspec_path ||= guess_gemspec
33
+ @configuration.gemspec ||= Gem::Specification::load(@configuration.gemspec_path)
34
+ return @configuration.gemspec
35
+ end
36
+
37
+ def resolve_configuration
38
+ load_gemspec
39
+
40
+ @configuration.finished_files.build ||= File::join(
41
+ @configuration.finished_dir, "build_#{@configuration.gemspec.version}")
42
+ @configuration.finished_files.qa ||= File::join(
43
+ @configuration.finished_dir, "qa_#{@configuration.gemspec.version}")
44
+ @configuration.finished_files.package ||= File::join(
45
+ @configuration.finished_dir, "package_#{@configuration.gemspec.version}")
46
+ @configuration.finished_files.release ||= File::join(
47
+ @configuration.finished_dir, "release_#{@configuration.gemspec.version}")
48
+ @configuration.finished_files.press ||= File::join(
49
+ @configuration.finished_dir, "press_#{@configuration.gemspec.version}")
50
+
51
+ @configuration.files.code ||= @configuration.gemspec.files.grep(%r{^lib/})
52
+ @configuration.files.test ||= @configuration.gemspec.files.grep(%r{^spec/})
53
+ @configuration.files.docs ||= @configuration.gemspec.files.grep(%r{^doc/})
54
+
55
+ @configuration.file_lists.code ||= FileList['lib/**/*.rb']
56
+ @configuration.file_lists.test ||= FileList['test/**/*.rb','spec/**/*.rb','features/**/*.rb']
57
+ @configuration.file_lists.docs ||= FileList['doc/**/*.rb']
58
+ @configuration.file_lists.all ||=
59
+ @configuration.file_lists.code +
60
+ @configuration.file_lists.test +
61
+ @configuration.file_lists.docs
62
+
63
+ @configuration.rubyforge.group_id ||= @configuration.gemspec.rubyforge_project
64
+ @configuration.rubyforge.package_id ||= @configuration.gemspec.name.downcase
65
+ @configuration.rubyforge.release_name ||= @configuration.gemspec.full_name
66
+ @configuration.rubyforge.home_page ||= @configuration.gemspec.homepage
67
+ @configuration.rubyforge.project_page ||= "http://rubyforge.org/project/#{@configuration.gemspec.rubyforge_project}/"
68
+ end
69
+
70
+ def guess_gemspec
71
+ speclist = Dir[File.expand_path("*.gemspec", Rake::original_dir)]
72
+ if speclist.length == 0
73
+ puts "Found no *.gemspec files"
74
+ exit 1
75
+ elsif speclist.length > 1
76
+ puts "Found too many *.gemspec files: #{speclist.inspect}"
77
+ exit 1
78
+ end
79
+ speclist[0]
80
+ end
81
+
82
+ def define
83
+ in_namespace do
84
+ directory @configuration.finished_dir
85
+
86
+ desc "Run preflight checks"
87
+ task :preflight
88
+
89
+ desc "Run quality assurance tasks"
90
+ task :qa => :preflight
91
+ file @configuration.finished_files.qa => [:qa, @configuration.finished_dir] do |task|
92
+ touch task.name
93
+ end
94
+
95
+ desc "Build the package"
96
+ task :build => @configuration.finished_files.qa
97
+ file @configuration.finished_files.build => [:build, @configuration.finished_dir] do |task|
98
+ touch task.name
99
+ end
100
+
101
+ desc "Push package out to the world"
102
+ task :release => @configuration.finished_files.build
103
+ file @configuration.finished_files.release => [:release, @configuration.finished_dir] do |task|
104
+ touch task.name
105
+ end
106
+
107
+ desc "Announce publication"
108
+ task :press => @configuration.finished_files.release
109
+ file @configuration.finished_files.press => [:press, @configuration.finished_dir] do |task|
110
+ touch task.name
111
+ end
112
+ end
113
+ end
114
+
115
+ def old_define
116
+
117
+ task @publishing.namespace => "#{@gem_building.namespace}:push"
118
+ task "#{@publishing.namespace}:docs" => "#{@documentation.namespace}:docs"
119
+ task "#{@publishing.namespace}:rubyforge" => ["#{@quality_assurance.namespace}:sign_off", "#{@gem_building.namespace}:package"]
120
+
121
+ require 'corundum/press'
122
+ Press.new(@press.namespace) do |press|
123
+ press.rubyforge = @rubyforge
124
+ press.gemspec = @configuration.gemspec
125
+ press.announce_to_email = @email.announce_to_email
126
+ press.email_servers = @email.servers
127
+ end
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,92 @@
1
+ require 'corundum/tasklib'
2
+
3
+ module Corundum
4
+ class Email < TaskLib
5
+ def default_namespace
6
+ :email
7
+ end
8
+
9
+ def receive_tasklibs(toolkit)
10
+ @toolkit = toolkit
11
+ end
12
+
13
+ def default_configuration(namespace, toolkit_config)
14
+ @configuration.namespace = namespace
15
+ @configuration.rubyforge = toolkit_config.rubyforge
16
+ @configuration.email_servers = []
17
+ @configuration.gemspec = toolkit_config.gemspec
18
+ @configuration.announce_to_email = nil
19
+ @configuration.urls = OpenStruct.new
20
+ end
21
+
22
+ def resolve_configuration
23
+ @configuration.urls.home_page ||=
24
+ @configuration.gemspec.homepage
25
+
26
+ @configuration.urls.project_page ||=
27
+ @configuration.rubyforge.project_page
28
+
29
+ end
30
+
31
+ def announcement
32
+ changes = ""
33
+ begin
34
+ File::open("./Changelog", "r") do |changelog|
35
+ changes = "Changes:\n\n"
36
+ changes += changelog.read
37
+ end
38
+ rescue Exception
39
+ end
40
+
41
+ urls = "Project: #{@configuration.urls.project_page}\n" +
42
+ "Homepage: #{@configuration.urls.home_page}"
43
+
44
+ subject = "#{@configuration.gemspec.name} #{@configuration.gemspec.version} Released"
45
+ title = "#{@configuration.gemspec.name} version #{@configuration.gemspec.version} has been released!"
46
+ body = "#{@configuration.gemspec.description}\n\n#{changes}\n\n#{urls}"
47
+
48
+ return subject, title, body
49
+ end
50
+
51
+ def define
52
+ desc 'Announce release on email'
53
+ task @configuration.namespace => ["#{@configuration.namespace.to_s}:rubyforge", "#{@configuration.namespace.to_s}:email"]
54
+ namespace @configuration.namespace do
55
+ file "email.txt" do |t|
56
+ require 'mailfactory'
57
+
58
+ subject, title, body= announcement
59
+
60
+ mail = MailFactory.new
61
+ mail.To = @configuration.announce_to_email
62
+ mail.From = @configuration.gemspec.email
63
+ mail.Subject = "[ANN] " + subject
64
+ mail.text = [title, body].join("\n\n")
65
+
66
+ File.open(t.name, "w") do |mailfile|
67
+ mailfile.write mail.to_s
68
+ end
69
+ end
70
+
71
+ task :email => "email.txt" do
72
+ require 'net/smtp'
73
+
74
+ @configuration.email_servers.each do |server_config|
75
+ begin
76
+ File::open("email.txt", "r") do |email|
77
+ Net::SMTP.start(server_config[:server], 25, server_config[:helo], server_config[:username], server_config[:password]) do |smtp|
78
+ smtp.data do |mta|
79
+ mta.write(email.read)
80
+ end
81
+ end
82
+ end
83
+ break
84
+ rescue Object => ex
85
+ puts ex.message
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,34 @@
1
+ require 'corundum/tasklib'
2
+
3
+ module Corundum
4
+ class GemBuilding < TaskLib
5
+ def receive_tasklibs(toolkit)
6
+ @toolkit = toolkit
7
+ end
8
+
9
+ def default_configuration(namespace, toolkit_config)
10
+ @configuration.namespace = namespace || :package
11
+ @configuration.gemspec = toolkit_config.gemspec
12
+ @configuration.qa_finished_file = toolkit_config.finished_files.qa
13
+ @configuration.package_dir = "pkg"
14
+ end
15
+
16
+ def define
17
+ require 'rubygems/package_task'
18
+
19
+ in_namespace do
20
+ package = Gem::PackageTask.new(@configuration.gemspec) do |t|
21
+ t.need_tar_gz = true
22
+ t.need_tar_bz2 = true
23
+ t.package_dir = @configuration.package_dir
24
+ end
25
+
26
+ task(:package).prerequisites.each do |package_type|
27
+ file package_type => @configuration.qa_finished_file
28
+ end
29
+ end
30
+
31
+ task :build => in_namespace("gem")
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,110 @@
1
+ require 'corundum/tasklib'
2
+
3
+ module Corundum
4
+ class GemCutter < TaskLib
5
+ def receive_tasklibs(toolkit, build)
6
+ @toolkit = toolkit
7
+ @build = build
8
+ end
9
+
10
+ def default_configuration(namespace, toolkit_config, build_config)
11
+ @configuration.namespace = namespace || :gemcutter
12
+ @configuration.gemspec = toolkit_config.gemspec
13
+ @configuration.build_finished_path = toolkit_config.finished_files.build
14
+ @configuration.gem_path = nil
15
+ @configuration.gem_name = nil
16
+ @configuration.package_dir = build_config.package_dir
17
+ end
18
+
19
+ def resolve_configuration
20
+ @configuration.gem_path ||=
21
+ File::join(@configuration.package_dir, @configuration.gemspec.file_name)
22
+
23
+ @configuration.gem_name ||= @configuration.gemspec.full_name
24
+ end
25
+
26
+ module CommandTweaks
27
+ def setup_args(args = nil)
28
+ args ||= []
29
+ handle_options(args)
30
+ end
31
+
32
+ def gem_list=(list)
33
+ @configuration.gems = list
34
+ end
35
+
36
+ def get_all_gem_names
37
+ return @configuration.gems if defined?(@configuration.gems)
38
+ super
39
+ end
40
+
41
+ def get_one_gem_name
42
+ return @configuration.gems.first if defined?(@configuration.gems)
43
+ super
44
+ end
45
+ end
46
+
47
+ def get_command(klass, args=nil)
48
+ cmd = klass.new
49
+ cmd.extend(CommandTweaks)
50
+ cmd.setup_args(args)
51
+ cmd
52
+ end
53
+
54
+ def define
55
+ in_namespace do
56
+ task :uninstall do |t|
57
+ when_writing("Uninstalling #{@configuration.gem_name}") do
58
+ require "rubygems/commands/uninstall_command"
59
+ uninstall = get_command Gem::Commands::UninstallCommand
60
+ uninstall.options[:args] = [@configuration.gem_path]
61
+ uninstall.execute
62
+ end
63
+ end
64
+
65
+ task :install => [@configuration.gem_path] do |t|
66
+ when_writing("Installing #{@configuration.gem_path}") do
67
+ require "rubygems/commands/install_command"
68
+ install = get_command Gem::Commands::InstallCommand
69
+ install.options[:args] = [@configuration.gem_path]
70
+ install.execute
71
+ end
72
+ end
73
+
74
+ task :reinstall => [:uninstall, :install]
75
+
76
+ task :dependencies_available do
77
+ checker = Gem::SpecFetcher.new
78
+ @configuration.gemspec.runtime_dependencies.each do |dep|
79
+ fulfilling = checker.find_matching(dep,false,false,false)
80
+ if fulfilling.empty?
81
+ fail "Dependency #{dep} is unfulfilled remotely"
82
+ else
83
+ puts "Remotely fulfilled: #{dep}" if verbose
84
+ end
85
+ end
86
+ end
87
+
88
+ task :is_unpushed do
89
+ checker = Gem::SpecFetcher.new
90
+ dep = Gem::Dependency.new(@configuration.gemspec.name, "= #{@configuration.gemspec.version}")
91
+ fulfilling = checker.find_matching(dep,false,false,true)
92
+ unless fulfilling.empty?
93
+ fail "Gem #{@configuration.gemspec.full_name} is already pushed"
94
+ end
95
+ end
96
+
97
+ desc 'Push a gem up to Gemcutter'
98
+ task :push => [:dependencies_available, :is_unpushed] do
99
+ require "rubygems/commands/push_command"
100
+ push = get_command(Gem::Commands::PushCommand)
101
+ push.options[:args] = [@configuration.gem_path]
102
+ push.execute
103
+ end
104
+ task :push => @configuration.build_finished_path
105
+ end
106
+ task :release => in_namespace(:push)
107
+ task :preflight => in_namespace(:dependencies_available, :is_unpushed)
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,32 @@
1
+ require 'corundum/tasklib'
2
+
3
+ module Corundum
4
+ class GemspecSanity < TaskLib
5
+ def default_namespace
6
+ :gemspec_sanity
7
+ end
8
+
9
+ def receive_tasklibs(toolkit)
10
+ @toolkit = toolkit
11
+ end
12
+
13
+ def default_configuration(namespace, toolkit_config)
14
+ @configuration.namespace = namespace
15
+ @configuration.gemspec = toolkit_config.gemspec
16
+ end
17
+
18
+ def define
19
+ in_namespace do
20
+ task :files_exist do
21
+ missing = @configuration.gemspec.files.find_all do |path|
22
+ not File::exists?(path)
23
+ end
24
+
25
+ fail "Files mentioned in gemspec are missing: #{missing.join(", ")}" unless missing.empty?
26
+ end
27
+ end
28
+
29
+ task :preflight => in_namespace(:files_exist)
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,135 @@
1
+ require 'corundum/tasklib'
2
+ require 'rspec/core'
3
+
4
+ module Corundum
5
+ #TODO: this should take two command generators as arguments: the test runner,
6
+ #and the coverage tool - then the various tasks are the result of the
7
+ #collaboration of those two.
8
+ #
9
+ class RSpec < TaskLib
10
+ def receive_tasklibs(toolkit)
11
+ @toolkit = toolkit
12
+ end
13
+
14
+ def default_configuration(namespace, toolkit_config)
15
+ @configuration.task_options = OpenStruct.new(
16
+ :pattern => nil,
17
+ :ruby_opts => nil,
18
+ :rspec_opts => nil,
19
+ :warning => false,
20
+ :verbose => true,
21
+ :fail_on_error => true,
22
+ :ruby_opts => [],
23
+ :rspec_opts => %w{--format documentation --out last_run --color --format documentation},
24
+ :failure_message => "Spec examples failed.",
25
+ :files_to_run => nil
26
+ )
27
+
28
+ @configuration.namespace = namespace || :rspec
29
+ @configuration.gemspec_path = toolkit_config.gemspec_path
30
+ @configuration.qa_finished_path = toolkit_config.qa_finished_path
31
+ end
32
+
33
+ def resolve_configuration
34
+ @configuration.task_options.rspec_configs = @configuration.task_options.rspec_opts
35
+ @configuration.task_options.rspec_opts = []
36
+ @configuration.task_options.rspec_path ||= 'rspec'
37
+ @configuration.task_options.rspec_path = %x"which #{@configuration.task_options.rspec_path}".chomp
38
+ @configuration.task_options.pattern ||= './spec{,/*/**}/*_spec.rb'
39
+ @configuration.task_options.files_to_run ||= "spec"
40
+ end
41
+
42
+ #XXX some point in the future, there needs to be a composible command
43
+ #object
44
+ def ruby_command(options)
45
+ cmd_parts = []
46
+ cmd_parts << RUBY
47
+ cmd_parts << options.ruby_opts
48
+ cmd_parts << "-w" if options.warning?
49
+ if /^1\.8/ =~ RUBY_VERSION
50
+ cmd_parts << "-S"
51
+ end
52
+ return cmd_parts
53
+ end
54
+
55
+ def runner_command(options)
56
+ cmd_parts = []
57
+ cmd_parts << options.rspec_path
58
+ cmd_parts << options.rspec_opts
59
+ cmd_parts << options.files_to_run
60
+ return cmd_parts
61
+ end
62
+
63
+ def full_command(options)
64
+ cmd_parts = ruby_command(options) + runner_command(options)
65
+ return cmd_parts.flatten.compact.reject{|part| part.nil? or part.empty?}.join(" ")
66
+ end
67
+
68
+ def custom_options
69
+ options = @configuration.task_options.dup
70
+ yield(options)
71
+ return options
72
+ end
73
+
74
+ def define_spec_task(name)
75
+ options = if block_given?
76
+ custom_options{|options| yield(options) if block_given?}
77
+ else
78
+ @configuration.task_options
79
+ end
80
+ task name do
81
+ RakeFileUtils.send(:verbose, verbose) do
82
+ if options.files_to_run.empty?
83
+ puts "No examples matching #{options.pattern} could be found"
84
+ else
85
+ begin
86
+ cmd = full_command(options)
87
+ puts cmd if options.verbose
88
+ success = system(cmd)
89
+ rescue
90
+ puts options.failure_message if options.failure_message
91
+ end
92
+ raise("ruby #{cmd} failed") if options.fail_on_error unless success
93
+ end
94
+ end
95
+ end
96
+ end
97
+
98
+ def define
99
+ desc "Run failing examples if any exist, otherwise, run the whole suite"
100
+ task @configuration.namespace => "#{@configuration.namespace}:quick"
101
+
102
+ in_namespace do
103
+ desc "Always run every spec"
104
+ define_spec_task(:all)
105
+
106
+ desc "Generate specifications documentation"
107
+ define_spec_task(:doc) do |t|
108
+ t.rspec_opts = %w{-o /dev/null -f d -o doc/Specifications}
109
+ t.failure_message = "Failed generating specification docs"
110
+ t.verbose = false
111
+ end
112
+
113
+ desc "Run only failing examples listed in last_run"
114
+ define_spec_task(:quick) do |t|
115
+ examples = []
116
+ begin
117
+ File.open("last_run", "r") do |fail_list|
118
+ fail_list.lines.grep(%r{^\s*\d+\)\s*(.*)}) do |line|
119
+ examples << $1.gsub(/'/){"[']"}
120
+ end
121
+ end
122
+ rescue
123
+ end
124
+ unless examples.empty?
125
+ t.rspec_opts << "--example"
126
+ t.rspec_opts << "\"#{examples.join("|")}\""
127
+ end
128
+ t.failure_message = "Spec examples failed."
129
+ end
130
+ end
131
+
132
+ task :qa => in_namespace(:doc)
133
+ end
134
+ end
135
+ end