Compare commits
9 commits
Author | SHA1 | Date | |
---|---|---|---|
Denis Knauf | f963e41c52 | ||
5b390b2083 | |||
3542837d7f | |||
28936187de | |||
486cf53495 | |||
ae8f1e0a33 | |||
3ca2de0cd9 | |||
9fc25c3015 | |||
f27600ce16 |
37
.gitignore
vendored
37
.gitignore
vendored
|
@ -1,49 +1,18 @@
|
||||||
# rcov generated
|
|
||||||
coverage
|
coverage
|
||||||
coverage.data
|
coverage.data
|
||||||
|
|
||||||
# rdoc generated
|
|
||||||
rdoc
|
rdoc
|
||||||
|
|
||||||
# yard generated
|
|
||||||
doc
|
doc
|
||||||
.yardoc
|
.yardoc
|
||||||
|
|
||||||
# bundler
|
|
||||||
.bundle
|
.bundle
|
||||||
|
Gemfile.lock
|
||||||
# jeweler generated
|
|
||||||
pkg
|
pkg
|
||||||
|
|
||||||
# Have editor/IDE/OS specific files you need to ignore? Consider using a global gitignore:
|
|
||||||
#
|
|
||||||
# * Create a file at ~/.gitignore
|
|
||||||
# * Include files you want ignored
|
|
||||||
# * Run: git config --global core.excludesfile ~/.gitignore
|
|
||||||
#
|
|
||||||
# After doing this, these files will be ignored in all your git projects,
|
|
||||||
# saving you from having to 'pollute' every project you touch with them
|
|
||||||
#
|
|
||||||
# Not sure what to needs to be ignored for particular editors/OSes? Here's some ideas to get you started. (Remember, remove the leading # of the line)
|
|
||||||
#
|
|
||||||
# For MacOS:
|
|
||||||
#
|
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|
||||||
# For TextMate
|
|
||||||
*.tmproj
|
*.tmproj
|
||||||
tmtags
|
tmtags
|
||||||
|
|
||||||
# For emacs:
|
|
||||||
*~
|
*~
|
||||||
\#*
|
\#*
|
||||||
.\#*
|
.\#*
|
||||||
|
*.sw[p-n]
|
||||||
# For vim:
|
|
||||||
*.swp
|
|
||||||
|
|
||||||
# For redcar:
|
|
||||||
.redcar
|
.redcar
|
||||||
|
|
||||||
# For rubinius:
|
|
||||||
*.rbc
|
*.rbc
|
||||||
|
.document
|
||||||
|
|
17
Gemfile
17
Gemfile
|
@ -1,15 +1,2 @@
|
||||||
source "http://rubygems.org"
|
source "https://rubygems.org"
|
||||||
|
gemspec
|
||||||
gem 'ffi-libc'
|
|
||||||
|
|
||||||
# Add dependencies to develop your gem here.
|
|
||||||
# Include everything needed to run rake, tests, features, etc.
|
|
||||||
group :development do
|
|
||||||
gem "shoulda"
|
|
||||||
gem "yard"
|
|
||||||
gem "redcarpet"
|
|
||||||
gem "rdoc"
|
|
||||||
gem "bundler"
|
|
||||||
gem "jeweler"
|
|
||||||
gem "simplecov"
|
|
||||||
end
|
|
||||||
|
|
52
Gemfile.lock
52
Gemfile.lock
|
@ -1,52 +0,0 @@
|
||||||
GEM
|
|
||||||
remote: http://rubygems.org/
|
|
||||||
specs:
|
|
||||||
activesupport (3.2.12)
|
|
||||||
i18n (~> 0.6)
|
|
||||||
multi_json (~> 1.0)
|
|
||||||
bourne (1.1.2)
|
|
||||||
mocha (= 0.10.5)
|
|
||||||
ffi (1.1.0)
|
|
||||||
ffi-libc (0.0.5)
|
|
||||||
ffi (>= 0.6.0, <= 1.1.0)
|
|
||||||
git (1.2.5)
|
|
||||||
i18n (0.6.4)
|
|
||||||
jeweler (1.8.4)
|
|
||||||
bundler (~> 1.0)
|
|
||||||
git (>= 1.2.5)
|
|
||||||
rake
|
|
||||||
rdoc
|
|
||||||
json (1.7.7)
|
|
||||||
metaclass (0.0.1)
|
|
||||||
mocha (0.10.5)
|
|
||||||
metaclass (~> 0.0.1)
|
|
||||||
multi_json (1.6.1)
|
|
||||||
rake (10.0.3)
|
|
||||||
rdoc (4.0.0)
|
|
||||||
json (~> 1.4)
|
|
||||||
redcarpet (2.2.2)
|
|
||||||
shoulda (3.3.2)
|
|
||||||
shoulda-context (~> 1.0.1)
|
|
||||||
shoulda-matchers (~> 1.4.1)
|
|
||||||
shoulda-context (1.0.2)
|
|
||||||
shoulda-matchers (1.4.2)
|
|
||||||
activesupport (>= 3.0.0)
|
|
||||||
bourne (~> 1.1.2)
|
|
||||||
simplecov (0.7.1)
|
|
||||||
multi_json (~> 1.0)
|
|
||||||
simplecov-html (~> 0.7.1)
|
|
||||||
simplecov-html (0.7.1)
|
|
||||||
yard (0.8.5.2)
|
|
||||||
|
|
||||||
PLATFORMS
|
|
||||||
ruby
|
|
||||||
|
|
||||||
DEPENDENCIES
|
|
||||||
bundler
|
|
||||||
ffi-libc
|
|
||||||
jeweler
|
|
||||||
rdoc
|
|
||||||
redcarpet
|
|
||||||
shoulda
|
|
||||||
simplecov
|
|
||||||
yard
|
|
28
README.md
28
README.md
|
@ -1,11 +1,12 @@
|
||||||
timeout-interrupt
|
timeout-interrupt
|
||||||
=================
|
=================
|
||||||
|
|
||||||
Works like ruby's timeout, but interrupts every call, also syscalls, which blocks the hole ruby-process.
|
Works like ruby's timeout, but interrupts *every call*, also syscalls, which blocks the hole ruby-process.
|
||||||
|
|
||||||
It uses POSIX's alarm and traps ALRM-signals.
|
It uses POSIX's alarm and traps ALRM-signals.
|
||||||
|
|
||||||
Known limitations bacause of alarm and ALRM are, that you can not use alarm or trap ALRM.
|
Known limitations bacause of alarm and ALRM are, that you can not use alarm or trap ALRM in the same time.
|
||||||
|
|
||||||
|
|
||||||
Scopes
|
Scopes
|
||||||
======
|
======
|
||||||
|
@ -23,27 +24,30 @@ If you want to know, which was raised, you need custom exceptions:
|
||||||
|
|
||||||
class CustomErrorWillBeRaised <Exception
|
class CustomErrorWillBeRaised <Exception
|
||||||
end
|
end
|
||||||
class CustomErrorNotRaise <Exception
|
class CustomErrorNotRaised <Exception
|
||||||
end
|
end
|
||||||
include TimeoutInterrupt
|
include TimeoutInterrupt
|
||||||
timeout( 1, CustomErrorWillBeRaised) { # Will be raised again
|
timeout( 1, CustomErrorWillBeRaised) { # Will be raised again
|
||||||
timeout( 10, CustomErrorNotRaise) { sleep 2 } # Will not be raised
|
timeout( 10, CustomErrorNotRaised) { sleep 2 } # Will not be raised
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Problems
|
Problems
|
||||||
========
|
========
|
||||||
|
|
||||||
Memory-Leaks or no clean up
|
Memory-Leaks and missing clean up
|
||||||
---------------------------
|
---------------------------------
|
||||||
|
|
||||||
Do not forget, syscall can have allocated memory.
|
Syscalls can allocate memory.
|
||||||
If you interrupt a call, which can not free his allocations, you will have a memory leak.
|
If you interrupt a syscall, which then cannot free his allocations, it will result in a memory leak.
|
||||||
If it opens a file, reads it and closes it and while it reads, a time out occurs, the file will not be closed.
|
If it opens a file, while it reads, a time out occurs, the file will not automatically be closed.
|
||||||
|
|
||||||
So, use it only, if your process did not live any longer or if you call something, which never allocate mem or opens a file.
|
So, you should only use it, if your process will die after interrupt or if you are sure, that your call never allocate memory or opens a file.
|
||||||
|
You could also publish informations about opened files, that it could be cleaned up later.
|
||||||
|
|
||||||
Every time, a process dies, all his memory will be freed and every file will be closed, so let your process die and you should be safe.
|
Every time, a process dies, all his memory will be freed and every file will be closed, so let your process die and you should be safe.
|
||||||
|
|
||||||
|
|
||||||
Exception-handling
|
Exception-handling
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
|
@ -60,11 +64,11 @@ Timeouts can break your exception-handling! You should not handling exception wh
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
Same happens, if clean\_up will raise an exception.
|
Same happens, if clean\_up will raise an exception, so handle it in the same way.
|
||||||
|
|
||||||
And same problem you have with ruby's `Timeout.timeout`.
|
And same problem you have with ruby's `Timeout.timeout`.
|
||||||
|
|
||||||
Copyleft
|
Copyleft
|
||||||
=========
|
=========
|
||||||
|
|
||||||
Copyright (c) 2013 Denis Knauf. See LICENSE.txt for further details.
|
Copyright (c) 2021 Denis Knauf. See LICENSE.txt for further details.
|
43
Rakefile
43
Rakefile
|
@ -1,46 +1,9 @@
|
||||||
# encoding: utf-8
|
require "bundler/gem_tasks"
|
||||||
|
task :default => :spec
|
||||||
require 'rubygems'
|
|
||||||
require 'bundler'
|
|
||||||
begin
|
|
||||||
Bundler.setup(:default, :development)
|
|
||||||
rescue Bundler::BundlerError => e
|
|
||||||
$stderr.puts e.message
|
|
||||||
$stderr.puts "Run `bundle install` to install missing gems"
|
|
||||||
exit e.status_code
|
|
||||||
end
|
|
||||||
require 'rake'
|
|
||||||
|
|
||||||
require 'jeweler'
|
|
||||||
Jeweler::Tasks.new do |gem|
|
|
||||||
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
|
||||||
gem.name = "timeout-interrupt"
|
|
||||||
gem.homepage = "http://github.com/DenisKnauf/ruby-timeout-interrupt"
|
|
||||||
gem.license = "LGPLv3"
|
|
||||||
gem.summary = %Q{"Interrupts systemcalls too."}
|
|
||||||
gem.description = %Q{Timeout-lib, which interrupts everything, also systemcalls. It uses libc-alarm.}
|
|
||||||
gem.email = "Denis.Knauf@gmail.com"
|
|
||||||
gem.authors = ["Denis Knauf"]
|
|
||||||
# dependencies defined in Gemfile
|
|
||||||
end
|
|
||||||
Jeweler::RubygemsDotOrgTasks.new
|
|
||||||
|
|
||||||
require 'rake/testtask'
|
require 'rake/testtask'
|
||||||
Rake::TestTask.new(:test) do |test|
|
Rake::TestTask.new :test do |test|
|
||||||
test.libs << 'lib' << 'test'
|
test.libs << 'lib' << 'test'
|
||||||
test.pattern = 'test/**/test_*.rb'
|
test.pattern = 'test/**/test_*.rb'
|
||||||
test.verbose = true
|
test.verbose = true
|
||||||
end
|
end
|
||||||
|
|
||||||
#require 'simplecov'
|
|
||||||
#Rcov::RcovTask.new do |test|
|
|
||||||
#test.libs << 'test'
|
|
||||||
#test.pattern = 'test/**/test_*.rb'
|
|
||||||
#test.verbose = true
|
|
||||||
#test.rcov_opts << '--exclude "gems/*"'
|
|
||||||
#end
|
|
||||||
|
|
||||||
task :default => :test
|
|
||||||
|
|
||||||
require 'yard'
|
|
||||||
YARD::Rake::YardocTask.new
|
|
||||||
|
|
|
@ -1,23 +1,6 @@
|
||||||
require 'ffi/libc'
|
require 'ffi/libc'
|
||||||
require 'timeout'
|
require 'timeout'
|
||||||
|
|
||||||
# Provided by ffi-libc-lib and extended by this library, if needed.
|
|
||||||
# Older version of ffi-libc does not provide {FFI::LibC.alarm}
|
|
||||||
module FFI
|
|
||||||
module LibC
|
|
||||||
# @!method alarm(seconds)
|
|
||||||
# Sets an alarm. After `seconds` it will send an ALRM-signal to this process.
|
|
||||||
#
|
|
||||||
# Predefined alarm will be reset and will forget.
|
|
||||||
# @note Older implementations of ffi-libc does not provide {alarm}, but we need it.
|
|
||||||
# So we detect, if it is not provided and attach it.
|
|
||||||
# @param seconds [0] Clears alarm.
|
|
||||||
# @param seconds [Integer] How many seconds should be waited, before ALRM-signal should be send?
|
|
||||||
# @return (nil)
|
|
||||||
attach_function :alarm, [:uint], :uint unless FFI::LibC.respond_to? :alarm
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Helper module for `TimeoutInterrupt`
|
# Helper module for `TimeoutInterrupt`
|
||||||
# @see TimeoutInterrupt
|
# @see TimeoutInterrupt
|
||||||
module TimeoutInterruptSingleton
|
module TimeoutInterruptSingleton
|
||||||
|
@ -51,7 +34,7 @@ module TimeoutInterruptSingleton
|
||||||
# @return [nil]
|
# @return [nil]
|
||||||
def raise_if_sb_timed_out
|
def raise_if_sb_timed_out
|
||||||
return if self.timeouts.empty?
|
return if self.timeouts.empty?
|
||||||
key, (at, bt, exception) = self.timeouts.min_by {|key,(at,bt,ex)| at }
|
_key, (at, bt, exception) = self.timeouts.min_by {|_key,(at,_bt,_ex)| at }
|
||||||
return if Time.now < at
|
return if Time.now < at
|
||||||
raise exception, 'execution expired', bt
|
raise exception, 'execution expired', bt
|
||||||
end
|
end
|
||||||
|
@ -66,7 +49,7 @@ module TimeoutInterruptSingleton
|
||||||
else
|
else
|
||||||
raise_if_sb_timed_out
|
raise_if_sb_timed_out
|
||||||
Signal.trap 'ALRM', &method( :alarm_trap)
|
Signal.trap 'ALRM', &method( :alarm_trap)
|
||||||
key, (at, bt) = timeouts.min_by {|key,(at,bt)| at }
|
_key, (at, _bt) = timeouts.min_by {|_key,(at,_bt)| at }
|
||||||
FFI::LibC.alarm (at - Time.now).to_i + 1
|
FFI::LibC.alarm (at - Time.now).to_i + 1
|
||||||
end
|
end
|
||||||
nil
|
nil
|
||||||
|
@ -76,9 +59,9 @@ module TimeoutInterruptSingleton
|
||||||
#
|
#
|
||||||
# @param seconds [0] No timeout, so block can take any time.
|
# @param seconds [0] No timeout, so block can take any time.
|
||||||
# @param seconds [Integer] In `seconds` Seconds, it should raise a timeout, if not finished.
|
# @param seconds [Integer] In `seconds` Seconds, it should raise a timeout, if not finished.
|
||||||
# @param seconds [nil] If also no block given, everything will be ignored and
|
# @param seconds [nil] If this and no block given, it will call {setup} for checking and
|
||||||
# it will call {setup} for checking and preparing next known timeout.
|
# preparing _next_ known timeout.
|
||||||
# @param exception [Exception] which will be raised if timed out.
|
# @param exception [exception] which exception will be raised if timed out?
|
||||||
# @param exception [nil] `TimeoutInterrupt::Error` will be used to raise.
|
# @param exception [nil] `TimeoutInterrupt::Error` will be used to raise.
|
||||||
# @param block [Proc] Will be called and should finish its work before it timed out.
|
# @param block [Proc] Will be called and should finish its work before it timed out.
|
||||||
# @param block [nil] Nothing will happen, instead it will return a Proc,
|
# @param block [nil] Nothing will happen, instead it will return a Proc,
|
||||||
|
@ -87,7 +70,8 @@ module TimeoutInterruptSingleton
|
||||||
# Or if not, it will return a Proc, which will expect a Proc if called.
|
# Or if not, it will return a Proc, which will expect a Proc if called.
|
||||||
# This Proc has no arguments and will prepare a timeout, like if you had given a block.
|
# This Proc has no arguments and will prepare a timeout, like if you had given a block.
|
||||||
#
|
#
|
||||||
# You can rescue `Timeout::Error`, instead `TimeoutInterrupt::Error`, it will work too.
|
# You can rescue `Timeout::Error`, instead `TimeoutInterrupt::Error`,
|
||||||
|
# it is a subclass of `Timeout::Error`.
|
||||||
#
|
#
|
||||||
# It will call your given block, which has `seconds` seconds to end.
|
# It will call your given block, which has `seconds` seconds to end.
|
||||||
# If you want to prepare a timeout, which should be used many times,
|
# If you want to prepare a timeout, which should be used many times,
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
require 'rubygems'
|
require 'rubygems'
|
||||||
require 'bundler'
|
require 'bundler'
|
||||||
|
|
||||||
begin
|
begin
|
||||||
Bundler.setup(:default, :development)
|
Bundler.setup(:default, :development)
|
||||||
rescue Bundler::BundlerError => e
|
rescue Bundler::BundlerError => e
|
||||||
|
@ -7,6 +8,7 @@ rescue Bundler::BundlerError => e
|
||||||
$stderr.puts "Run `bundle install` to install missing gems"
|
$stderr.puts "Run `bundle install` to install missing gems"
|
||||||
exit e.status_code
|
exit e.status_code
|
||||||
end
|
end
|
||||||
|
|
||||||
require 'test/unit'
|
require 'test/unit'
|
||||||
require 'shoulda'
|
require 'shoulda'
|
||||||
|
|
||||||
|
@ -14,9 +16,6 @@ require 'timeout'
|
||||||
require 'benchmark'
|
require 'benchmark'
|
||||||
require 'ffi/libc'
|
require 'ffi/libc'
|
||||||
|
|
||||||
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
|
||||||
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
|
||||||
|
|
||||||
require 'timeout_interrupt'
|
require 'timeout_interrupt'
|
||||||
|
|
||||||
class Test::Unit::TestCase
|
class Test::Unit::TestCase
|
||||||
|
|
|
@ -4,7 +4,7 @@ class TestRubyTimeoutInterrupt < Test::Unit::TestCase
|
||||||
def blocking
|
def blocking
|
||||||
t = FFI::LibC.fopen '/dev/ptmx', 'r'
|
t = FFI::LibC.fopen '/dev/ptmx', 'r'
|
||||||
b = FFI::LibC.malloc 1025
|
b = FFI::LibC.malloc 1025
|
||||||
s = FFI::LibC.fread b, 1, 1024, t
|
FFI::LibC.fread b, 1, 1024, t
|
||||||
ensure
|
ensure
|
||||||
FFI::LibC.fclose t if t
|
FFI::LibC.fclose t if t
|
||||||
FFI::LibC.free b if b
|
FFI::LibC.free b if b
|
||||||
|
@ -114,7 +114,7 @@ class TestRubyTimeoutInterrupt < Test::Unit::TestCase
|
||||||
called = false
|
called = false
|
||||||
prepared.call do
|
prepared.call do
|
||||||
assert_raise TimeoutInterrupt::Error, 'It should time out after one second, but it did not.' do
|
assert_raise TimeoutInterrupt::Error, 'It should time out after one second, but it did not.' do
|
||||||
prepared.call { 2; sleep 2 }
|
prepared.call { _ = 2; sleep 2 }
|
||||||
end
|
end
|
||||||
called = true
|
called = true
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,71 +1,33 @@
|
||||||
# Generated by jeweler
|
Gem::Specification.new do |spec|
|
||||||
# DO NOT EDIT THIS FILE DIRECTLY
|
spec.name = "timeout-interrupt"
|
||||||
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
spec.version = "0.4.0"
|
||||||
# -*- encoding: utf-8 -*-
|
|
||||||
|
|
||||||
Gem::Specification.new do |s|
|
spec.authors = ["Denis Knauf"]
|
||||||
s.name = "timeout-interrupt"
|
spec.description = "Timeout-lib, which interrupts everything, also systemcalls. It uses libc-alarm."
|
||||||
s.version = "0.3.0"
|
spec.email = ["git+timeout-interrupt@denkn.at"]
|
||||||
|
|
||||||
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
spec.summary = "\"Interrupts systemcalls too.\""
|
||||||
s.authors = ["Denis Knauf"]
|
spec.licenses = ["LGPLv3"]
|
||||||
s.date = "2013-03-14"
|
|
||||||
s.description = "Timeout-lib, which interrupts everything, also systemcalls. It uses libc-alarm."
|
|
||||||
s.email = "Denis.Knauf@gmail.com"
|
|
||||||
s.extra_rdoc_files = [
|
|
||||||
"LICENSE.txt",
|
|
||||||
"README.md"
|
|
||||||
]
|
|
||||||
s.files = [
|
|
||||||
".document",
|
|
||||||
"Gemfile",
|
|
||||||
"Gemfile.lock",
|
|
||||||
"LICENSE.txt",
|
|
||||||
"README.md",
|
|
||||||
"Rakefile",
|
|
||||||
"VERSION",
|
|
||||||
"lib/timeout_interrupt.rb",
|
|
||||||
"test/helper.rb",
|
|
||||||
"test/test_ruby-timeout-interrupt.rb",
|
|
||||||
"timeout-interrupt.gemspec"
|
|
||||||
]
|
|
||||||
s.homepage = "http://github.com/DenisKnauf/ruby-timeout-interrupt"
|
|
||||||
s.licenses = ["LGPLv3"]
|
|
||||||
s.require_paths = ["lib"]
|
|
||||||
s.rubygems_version = "1.8.11"
|
|
||||||
s.summary = "\"Interrupts systemcalls too.\""
|
|
||||||
|
|
||||||
if s.respond_to? :specification_version then
|
spec.homepage = "https://git.denkn.at/deac/ruby-timeout-interrupt"
|
||||||
s.specification_version = 3
|
spec.required_ruby_version = Gem::Requirement.new(">= 2.1.0")
|
||||||
|
|
||||||
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
spec.metadata["homepage_uri"] = spec.homepage
|
||||||
s.add_runtime_dependency(%q<ffi-libc>, [">= 0"])
|
spec.metadata["source_code_uri"] = spec.homepage
|
||||||
s.add_development_dependency(%q<shoulda>, [">= 0"])
|
spec.metadata["changelog_uri"] = spec.homepage
|
||||||
s.add_development_dependency(%q<yard>, [">= 0"])
|
|
||||||
s.add_development_dependency(%q<redcarpet>, [">= 0"])
|
# Specify which files should be added to the gem when it is released.
|
||||||
s.add_development_dependency(%q<rdoc>, [">= 0"])
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
||||||
s.add_development_dependency(%q<bundler>, [">= 0"])
|
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
||||||
s.add_development_dependency(%q<jeweler>, [">= 0"])
|
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
||||||
s.add_development_dependency(%q<simplecov>, [">= 0"])
|
end
|
||||||
else
|
spec.bindir = "bin"
|
||||||
s.add_dependency(%q<ffi-libc>, [">= 0"])
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
||||||
s.add_dependency(%q<shoulda>, [">= 0"])
|
spec.require_paths = ["lib"]
|
||||||
s.add_dependency(%q<yard>, [">= 0"])
|
|
||||||
s.add_dependency(%q<redcarpet>, [">= 0"])
|
spec.add_runtime_dependency 'ffi-libc', '>= 0.1.1'
|
||||||
s.add_dependency(%q<rdoc>, [">= 0"])
|
spec.add_development_dependency 'test-unit'
|
||||||
s.add_dependency(%q<bundler>, [">= 0"])
|
spec.add_development_dependency 'shoulda'
|
||||||
s.add_dependency(%q<jeweler>, [">= 0"])
|
spec.add_development_dependency 'rake'
|
||||||
s.add_dependency(%q<simplecov>, [">= 0"])
|
spec.add_development_dependency 'bundler'
|
||||||
end
|
|
||||||
else
|
|
||||||
s.add_dependency(%q<ffi-libc>, [">= 0"])
|
|
||||||
s.add_dependency(%q<shoulda>, [">= 0"])
|
|
||||||
s.add_dependency(%q<yard>, [">= 0"])
|
|
||||||
s.add_dependency(%q<redcarpet>, [">= 0"])
|
|
||||||
s.add_dependency(%q<rdoc>, [">= 0"])
|
|
||||||
s.add_dependency(%q<bundler>, [">= 0"])
|
|
||||||
s.add_dependency(%q<jeweler>, [">= 0"])
|
|
||||||
s.add_dependency(%q<simplecov>, [">= 0"])
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue