cromwell 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,23 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
22
+ tmp
23
+ scratch_directory
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Przemyslaw Kowalczyk
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,139 @@
1
+ = Cromwell
2
+
3
+ Lord Protector of your scripts.
4
+
5
+ == Description
6
+
7
+ This is a very simple wrapper over <code>Signal#trap</code> method that allows you to easily protect your scripts from being killed while they are doing something that should not be interrupted (e.g. interacting with some non-transactional service) or is too costly to restart (e.g. long computations).
8
+
9
+ While inside the protected block, your script will ignore certain signals and continue its work, but if a signal was caught, it will terminate once the protected block is over. By default, only following signals are ignored: <code>INT</code> (keyboard interrupt <code>^C</code>), <code>TERM</code> (sent by <code>kill</code> by defautl), <code>HUP</code> (sent when shell terminates), and <code>QUIT</code> (a "dump core" signal, sent with <code>^\\</code>), but you can specify any list of them (except for <code>KILL</code> and <code>STOP</code>, of course).
10
+
11
+ For a full signal list supported on your operating system, run <code>Signal.list</code> in your <code>irb</code>. For more info on signals and their meaning, check your local <code>man signal</code>.
12
+
13
+ This gem is based on real-life production code. It is especially useful for protecting various daemon-like scripts in Rails application that are (might be) restarted with every deploy.
14
+
15
+ == Usage examples
16
+
17
+ The most important in Cromwell API is the <code>protect</code> method. It can be called in two ways: with a block and without a block.
18
+
19
+ === Block form
20
+
21
+ When used with a block, Cromwell executes the code inside the block protecting it from being interrupted with a signal:
22
+
23
+ puts 'See you in a while...'
24
+ Cromwell.protect {
25
+ sleep 10
26
+ }
27
+ puts "You're still here?"
28
+
29
+ When you run this script (which lives in <code>examples/example1.rb</code>), you won't be able to interrupt it with <code>^C</code> or simple <code>kill</code> while it's sleeping for ten seconds:
30
+
31
+ $ ruby examples/example1.rb
32
+ See you in a while...
33
+ ^C^C^C^C
34
+ [ ten seconds pass... ]
35
+ $
36
+
37
+ Because I tried to interrupt the script, it was terminated once the protected block was over. Had I not pressed <code>^C</code>, the last line would be executed:
38
+
39
+ $ ruby examples/example1.rb
40
+ See you in a while...
41
+ [ ten seconds pass... ]
42
+ You're still here?
43
+ $
44
+
45
+ The script cannot be killed, too (I run it in background to be able to run other commands in the same shell):
46
+
47
+ $ ruby examples/example1.rb &
48
+ [1] 70300
49
+ See you in a while...
50
+ $ kill 70300
51
+ [ ten seconds pass... ]
52
+ $
53
+ [1]+ Done ruby examples/example1.rb
54
+
55
+ If you really want to kill it, use <code>kill -9</code>:
56
+
57
+ $ ruby examples/example1.rb &
58
+ [1] 70328
59
+ See you in a while...
60
+ $ kill -9 70328
61
+ $
62
+ [1]+ Killed ruby examples/example1.rb
63
+
64
+ === Non-block form
65
+
66
+ If you want to have more control over what's protected in your script, you can use <code>protect</code> without the block. In that case your code will be protected until you call <code>unprotect</code> method:
67
+
68
+ puts 'See you in a while...'
69
+ Cromwell.protect
70
+ sleep 10
71
+ Cromwell.unprotect
72
+ puts "You're still here?"
73
+
74
+ The above code lives in <code>examples/example2.rb</code> and behaves in the same way as previous example.
75
+
76
+ In general it might be good idea to place the call to <code>unprotect</code> in an <code>ensure</code> block. Or, if you want your script to just run until it finishes on its own, don't call <code>unprotect</code> at all.
77
+
78
+ === Specifying other signals
79
+
80
+ If you want to protect from other signals than the default list, specify them as parameters to <code>protect</code> method:
81
+
82
+ puts "You can't stop me with ^C but you can kill me. My pid is #{$$}."
83
+ Cromwell.protect("INT") {
84
+ sleep 10
85
+ }
86
+ puts "You're still here?"
87
+
88
+ This script is still immune to <code>^C</code>:
89
+
90
+ $ ruby examples/example3.rb
91
+ You can't stop me with ^C but you can kill me. My pid is 70243.
92
+ ^C^C^C^C
93
+ [ ten seconds pass... ]
94
+ $
95
+
96
+ But can be killed:
97
+
98
+ $ ruby examples/example3.rb &
99
+ [1] 70245
100
+ You can't stop me with ^C but you can kill me. My pid is 70245.
101
+ $ kill 70245
102
+ [1]+ Terminated ruby examples/example3.rb
103
+ $
104
+
105
+ === Inspecting state
106
+
107
+ You can inspect Cromwell's state with two methods:
108
+
109
+ * <code>Cromwell.protected?</code> returns <code>true</code> when your code is protected, <code>false</code> otherwise.
110
+ * <code>Cromwell.should_exit?</code> returns <code>true</code> when a signal was caught and termination will ocur after the protected code is over.
111
+
112
+ == Compatibility
113
+
114
+ Works for me. Tested on Mac OS X 10.4--10.6 and a little bit on Debian Linux. If it works for you too, I'd be glad to know. Cromwell's reliability depends heavily on your operating system's signals implementation reliability (which may not be very stable on some systems).
115
+
116
+ == To Do list
117
+
118
+ * Remove traps when they are not needed anymore. Currently they remain in place and when you call protect again (even with different signals list), the old ones are still effective.
119
+ * Allow to customize behavior after catching a signal. Right now, the script is terminated after the protected block is done (even if the signal would not normally cause script termination).
120
+ * Play well with other trap handlers that might be installed.
121
+ * Add logger support.
122
+
123
+ == Note on Patches/Pull Requests
124
+
125
+ * Fork the project.
126
+ * Make your feature addition or bug fix.
127
+ * Add tests for it. This is important so I don't break it in a
128
+ future version unintentionally.
129
+ * Commit, do not mess with rakefile, version, or history.
130
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
131
+ * Send me a pull request. Bonus points for topic branches.
132
+
133
+ == Note on terminology
134
+
135
+ The protection from signals provided by Cromwell and the method names <code>protect</code>, <code>unprotect</code>, and <code>protected?</code> have <b>nothing</b> to do with Ruby's <code>protected</code> keyword and the general concept of a <i>protected</i> method in Ruby and other object-oriented languages.
136
+
137
+ == Copyright
138
+
139
+ Copyright (c) 2009 Przemyslaw Kowalczyk. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,94 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "cromwell"
8
+ gem.summary = %Q{Lord Protector of your scripts}
9
+ gem.description = %Q{A very simple wrapper over Signal#trap method that allows you to easily protect your scripts from being killed while they are doing something that should not be interrupted (e.g. interacting with some non-transactional service) or is too costly to restart (e.g. long computations). }
10
+ gem.email = "szeryf@negativeiq.pl"
11
+ gem.homepage = "http://github.com/szeryf/cromwell"
12
+ gem.authors = ["Przemyslaw Kowalczyk"]
13
+ gem.add_development_dependency "thoughtbot-shoulda", ">= 0"
14
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
15
+ end
16
+ Jeweler::GemcutterTasks.new
17
+ rescue LoadError
18
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
19
+ end
20
+
21
+ require 'rake/testtask'
22
+ Rake::TestTask.new(:test) do |test|
23
+ test.libs << 'lib' << 'test'
24
+ test.pattern = 'test/**/test_*.rb'
25
+ test.verbose = true
26
+ end
27
+
28
+ begin
29
+ require 'rcov/rcovtask'
30
+ Rcov::RcovTask.new do |test|
31
+ test.libs << 'test'
32
+ test.pattern = 'test/**/test_*.rb'
33
+ test.rcov_opts << "-x /gems/"
34
+ test.verbose = true
35
+ end
36
+ rescue LoadError
37
+ task :rcov do
38
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
39
+ end
40
+ end
41
+
42
+ task :test => :check_dependencies
43
+
44
+ task :default => :test
45
+
46
+ require 'rake/rdoctask'
47
+ Rake::RDocTask.new do |rdoc|
48
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
49
+
50
+ rdoc.rdoc_dir = 'rdoc'
51
+ rdoc.title = "cromwell #{version}"
52
+ rdoc.rdoc_files.include('README*')
53
+ rdoc.rdoc_files.include('lib/**/*.rb')
54
+ end
55
+
56
+ begin
57
+ require 'metric_fu'
58
+ rescue LoadError
59
+ puts "metric_fu (or a dependency) not available. If you want to run metrics, install it with: gem install metric_fu"
60
+ end
61
+
62
+ MetricFu::Configuration.run do |config|
63
+ #define which metrics you want to use
64
+ config.metrics = [:churn, :saikuro, :flog, :flay, :reek, :roodi, :rcov]
65
+ config.graphs = []
66
+ config.flay = { :dirs_to_flay => ['lib'] }
67
+ config.flog = { :dirs_to_flog => ['lib'] }
68
+ config.reek = { :dirs_to_reek => ['lib'] }
69
+ config.roodi = { :dirs_to_roodi => ['lib'] }
70
+ config.saikuro = { :output_directory => 'scratch_directory/saikuro',
71
+ :input_directory => ['lib'],
72
+ :cyclo => "",
73
+ :filter_cyclo => "0",
74
+ :warn_cyclo => "5",
75
+ :error_cyclo => "7",
76
+ :formater => "text"} #this needs to be set to "text"
77
+ config.churn = { :start_date => "1 year ago", :minimum_churn_count => 10}
78
+ config.rcov = { :test_files => ['test/**/test_*.rb'],
79
+ :rcov_opts => ["--sort coverage",
80
+ "--no-html",
81
+ "--text-coverage",
82
+ "--no-color",
83
+ "--exclude /gems/,/Library/,spec"]}
84
+ end
85
+
86
+ # fix for failing on NaN
87
+ module MetricFu
88
+ class Generator
89
+ def round_to_tenths(decimal)
90
+ decimal=0.0 if decimal.to_s.eql?('NaN')
91
+ (decimal.to_i * 10).round / 10.0
92
+ end
93
+ end
94
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
data/cromwell.gemspec ADDED
@@ -0,0 +1,60 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{cromwell}
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Przemyslaw Kowalczyk"]
12
+ s.date = %q{2010-01-03}
13
+ s.description = %q{A very simple wrapper over Signal#trap method that allows you to easily protect your scripts from being killed while they are doing something that should not be interrupted (e.g. interacting with some non-transactional service) or is too costly to restart (e.g. long computations). }
14
+ s.email = %q{szeryf@negativeiq.pl}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".gitignore",
22
+ "LICENSE",
23
+ "README.rdoc",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "cromwell.gemspec",
27
+ "examples/example1.rb",
28
+ "examples/example2.rb",
29
+ "examples/example3.rb",
30
+ "lib/cromwell.rb",
31
+ "test/helper.rb",
32
+ "test/test_cromwell.rb"
33
+ ]
34
+ s.homepage = %q{http://github.com/szeryf/cromwell}
35
+ s.rdoc_options = ["--charset=UTF-8"]
36
+ s.require_paths = ["lib"]
37
+ s.rubygems_version = %q{1.3.5}
38
+ s.summary = %q{Lord Protector of your scripts}
39
+ s.test_files = [
40
+ "test/helper.rb",
41
+ "test/test_cromwell.rb",
42
+ "examples/example1.rb",
43
+ "examples/example2.rb",
44
+ "examples/example3.rb"
45
+ ]
46
+
47
+ if s.respond_to? :specification_version then
48
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
49
+ s.specification_version = 3
50
+
51
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
52
+ s.add_development_dependency(%q<thoughtbot-shoulda>, [">= 0"])
53
+ else
54
+ s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
55
+ end
56
+ else
57
+ s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
58
+ end
59
+ end
60
+
@@ -0,0 +1,8 @@
1
+ require 'rubygems'
2
+ require 'cromwell'
3
+
4
+ puts 'See you in a while...'
5
+ Cromwell.protect {
6
+ sleep 10
7
+ }
8
+ puts "You're still here?"
@@ -0,0 +1,8 @@
1
+ require 'rubygems'
2
+ require 'cromwell'
3
+
4
+ puts 'See you in a while...'
5
+ Cromwell.protect
6
+ sleep 10
7
+ Cromwell.unprotect
8
+ puts "You're still here?"
@@ -0,0 +1,8 @@
1
+ require 'rubygems'
2
+ require 'cromwell'
3
+
4
+ puts "You can't stop me with ^C but you can kill me. My pid is #{$$}."
5
+ Cromwell.protect("INT") {
6
+ sleep 10
7
+ }
8
+ puts "You're still here?"
data/lib/cromwell.rb ADDED
@@ -0,0 +1,74 @@
1
+ class Cromwell
2
+ DEFAULT_SIGNAL_LIST = %w[INT TERM HUP QUIT].freeze
3
+
4
+ class << self
5
+ # call-seq:
6
+ # Cromwell.protect(*signals) { ... some code ... }
7
+ # Cromwell.protect(*signals)
8
+ # Cromwell.protect { ... some code ... }
9
+ # Cromwell.protect
10
+ #
11
+ # Starts protecting your code. If called with a block, only the code within a block is
12
+ # executed with signal protection. Without a block, script is protected until unprotect
13
+ # is called. Signals can be given in all the forms that <code>Signal#trap</code> recognizes.
14
+ # Without parameters, the code is protected from the signals in DEFAULT_SIGNAL_LIST.
15
+ # More info and examples in README.rdoc.
16
+ def protect *signals
17
+ set_up_traps(signals.empty? ? DEFAULT_SIGNAL_LIST : signals.flatten)
18
+ @@should_exit = false
19
+ @@protected = true
20
+ if block_given?
21
+ begin
22
+ yield
23
+ ensure
24
+ unprotect
25
+ end
26
+ end
27
+ end
28
+
29
+ # call-seq:
30
+ # Cromwell.unprotect
31
+ #
32
+ # Turns off protection from signals. Will terminate the script with <code>Kernel#exit</code>
33
+ # if signal was caught earlier (so any <code>at_exit</code> code will be executed).
34
+ # The protect method calls this automatically when executed with a block.
35
+ def unprotect
36
+ @@protected = false
37
+ exit if @@should_exit
38
+ end
39
+
40
+ # call-seq:
41
+ # Cromwell.should_exit?
42
+ #
43
+ # True when the script will be terminated after protected block, i.e. when a signal
44
+ # was caught that was protected from.
45
+ def should_exit?
46
+ @@should_exit
47
+ end
48
+
49
+ # call-seq:
50
+ # Cromwell.protected?
51
+ #
52
+ # True if the protection is currently active.
53
+ def protected?
54
+ @@protected
55
+ end
56
+
57
+ private
58
+ def set_up_traps signals
59
+ signals.each { |signal| set_up_trap signal }
60
+ end
61
+
62
+ def set_up_trap signal
63
+ trap signal do
64
+ if @@protected
65
+ #puts "Just a minute now."
66
+ @@should_exit = true
67
+ "IGNORE"
68
+ else
69
+ exit
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,31 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+ require 'mocha'
5
+
6
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
7
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
8
+ require 'cromwell'
9
+
10
+ class Test::Unit::TestCase
11
+ def assert_slept_at_least seconds, message
12
+ Process.waitpid @pid
13
+ end_time = Time.now
14
+ assert end_time - @start_time >= seconds, message
15
+ end
16
+
17
+ def assert_killed_before seconds, message
18
+ Process.waitpid @pid
19
+ end_time = Time.now
20
+ assert end_time - @start_time < seconds, message
21
+ end
22
+
23
+ def do_fork &block
24
+ @pid = fork(&block)
25
+ end
26
+
27
+ def start
28
+ @start_time = Time.now
29
+ sleep 1 # so the forked process gets to execute protected block
30
+ end
31
+ end
@@ -0,0 +1,141 @@
1
+ require 'helper'
2
+
3
+ class TestCromwell < Test::Unit::TestCase
4
+
5
+ # The tests below are hackish and slow, because I had to use sleep to find out whether
6
+ # forked process was killed or not. If you know a better (and portable!) way to do it,
7
+ # please let me know.
8
+ #
9
+ # On my OS X 10.5:
10
+ # - Process.kill always returns 1
11
+ # - Process.waitpid(@pid) always returns @pid
12
+ # - Process.waitpid(@pid, Process::WNOHANG) always returns nil
13
+ # so these methods cannot be used to determine if the forked process is still alive :(
14
+
15
+ PROCS = {
16
+ "block form" => proc {
17
+ Cromwell.protect("HUP") { sleep 3 }
18
+ },
19
+ "non block form" => proc {
20
+ Cromwell.protect "HUP"
21
+ sleep 3
22
+ Cromwell.unprotect
23
+ },
24
+ }
25
+
26
+ PROCS.each do |name, code|
27
+ context "general functionality of #{name}" do
28
+ setup do
29
+ do_fork &code
30
+ start
31
+ end
32
+
33
+ should "protect from given signal" do
34
+ Process.kill("HUP", @pid)
35
+ assert_slept_at_least 3, "child should not be killed before 3 seconds"
36
+ end
37
+
38
+ should "not protect from other signals" do
39
+ Process.kill("TERM", @pid)
40
+ assert_killed_before 3, "child should be killed before 3 seconds"
41
+ end
42
+ end
43
+ end
44
+
45
+ context "general functionality" do
46
+ PROCS2 = {
47
+ "block form" => proc {
48
+ Cromwell.protect { sleep 3 }
49
+ },
50
+ "non block form" => proc {
51
+ Cromwell.protect
52
+ sleep 3
53
+ Cromwell.unprotect
54
+ },
55
+ }
56
+
57
+ PROCS2.each do |name, code|
58
+ context name do
59
+ should "protect from default signals" do
60
+ do_fork &code
61
+ start
62
+
63
+ Cromwell::DEFAULT_SIGNAL_LIST.each do |signal|
64
+ Process.kill(signal, @pid)
65
+ end
66
+ assert_slept_at_least 3, "child should not be killed before 3 seconds"
67
+ end
68
+
69
+ should "exit right after protected block" do
70
+ do_fork {
71
+ code.call
72
+ sleep 10
73
+ }
74
+ start
75
+
76
+ Process.kill("HUP", @pid)
77
+ assert_killed_before 4, "child should be killed after 3 seconds"
78
+ end
79
+ end
80
+ end
81
+ end # general functionality
82
+
83
+ context "method protect" do
84
+ should "set up trap with given signals" do
85
+ Cromwell.expects(:set_up_traps).with(["HUP", "TERM"])
86
+ Cromwell.protect "HUP", "TERM"
87
+ end
88
+
89
+ should "set up trap with default signals" do
90
+ Cromwell.expects(:set_up_traps).with(Cromwell::DEFAULT_SIGNAL_LIST)
91
+ Cromwell.protect
92
+ end
93
+
94
+ should "assign false to should_exit" do
95
+ Cromwell.protect
96
+ assert !Cromwell.should_exit?
97
+ end
98
+
99
+ should "assign true to protected" do
100
+ Cromwell.protect
101
+ assert Cromwell.protected?
102
+ end
103
+
104
+ end # method protect
105
+
106
+ context "method protect with block" do
107
+ should "yield to block" do
108
+ im_in_ur_blok_touchin_ur_vars = false
109
+ Cromwell.protect {
110
+ im_in_ur_blok_touchin_ur_vars = true
111
+ }
112
+ assert im_in_ur_blok_touchin_ur_vars
113
+ end
114
+
115
+ should "call unprotect after block is finished" do
116
+ Cromwell.protect { i = 1 }
117
+ assert !Cromwell.protected?
118
+ end
119
+
120
+ should "assign true to protected inside block" do
121
+ Cromwell.protect {
122
+ assert Cromwell.protected?
123
+ }
124
+ end
125
+ end # method protect with block
126
+
127
+ context "method unprotect" do
128
+ should "assign false to protected" do
129
+ Cromwell.protect
130
+ Cromwell.unprotect
131
+ assert !Cromwell.protected?
132
+ end
133
+
134
+ should "terminate if should_exit is true" do
135
+ Cromwell.send(:class_variable_set, "@@should_exit", true)
136
+ Cromwell.expects(:exit)
137
+ Cromwell.unprotect
138
+ end
139
+ end # method unprotect
140
+
141
+ end
metadata ADDED
@@ -0,0 +1,81 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cromwell
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Przemyslaw Kowalczyk
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-01-03 00:00:00 +01:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: thoughtbot-shoulda
17
+ type: :development
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: "A very simple wrapper over Signal#trap method that allows you to easily protect your scripts from being killed while they are doing something that should not be interrupted (e.g. interacting with some non-transactional service) or is too costly to restart (e.g. long computations). "
26
+ email: szeryf@negativeiq.pl
27
+ executables: []
28
+
29
+ extensions: []
30
+
31
+ extra_rdoc_files:
32
+ - LICENSE
33
+ - README.rdoc
34
+ files:
35
+ - .document
36
+ - .gitignore
37
+ - LICENSE
38
+ - README.rdoc
39
+ - Rakefile
40
+ - VERSION
41
+ - cromwell.gemspec
42
+ - examples/example1.rb
43
+ - examples/example2.rb
44
+ - examples/example3.rb
45
+ - lib/cromwell.rb
46
+ - test/helper.rb
47
+ - test/test_cromwell.rb
48
+ has_rdoc: true
49
+ homepage: http://github.com/szeryf/cromwell
50
+ licenses: []
51
+
52
+ post_install_message:
53
+ rdoc_options:
54
+ - --charset=UTF-8
55
+ require_paths:
56
+ - lib
57
+ required_ruby_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: "0"
62
+ version:
63
+ required_rubygems_version: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: "0"
68
+ version:
69
+ requirements: []
70
+
71
+ rubyforge_project:
72
+ rubygems_version: 1.3.5
73
+ signing_key:
74
+ specification_version: 3
75
+ summary: Lord Protector of your scripts
76
+ test_files:
77
+ - test/helper.rb
78
+ - test/test_cromwell.rb
79
+ - examples/example1.rb
80
+ - examples/example2.rb
81
+ - examples/example3.rb