rest-core 1.0.1 → 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/CHANGES.md +10 -0
- data/Rakefile +7 -2
- data/lib/rest-core/app/coolio-fiber.rb +1 -1
- data/lib/rest-core/app/em-http-request-async.rb +1 -1
- data/lib/rest-core/app/em-http-request-fiber.rb +4 -1
- data/lib/rest-core/builder.rb +0 -3
- data/lib/rest-core/client.rb +1 -1
- data/lib/rest-core/middleware/cache.rb +1 -0
- data/lib/rest-core/middleware/timeout.rb +7 -1
- data/lib/rest-core/middleware/timeout/coolio_timer.rb +6 -0
- data/lib/rest-core/middleware/timeout/eventmachine_timer.rb +10 -0
- data/lib/rest-core/version.rb +1 -1
- data/lib/rest-core/wrapper.rb +12 -6
- data/rest-core.gemspec +4 -4
- data/test/test_cache.rb +69 -0
- data/test/test_timeout.rb +15 -0
- metadata +4 -4
- data/task/.gitignore +0 -1
- data/task/gemgem.rb +0 -257
data/.gitignore
CHANGED
data/CHANGES.md
CHANGED
@@ -1,5 +1,15 @@
|
|
1
1
|
# CHANGES
|
2
2
|
|
3
|
+
## rest-core 1.0.2 -- 2012-06-05
|
4
|
+
|
5
|
+
### Enhancement
|
6
|
+
|
7
|
+
* Some internal refactoring.
|
8
|
+
|
9
|
+
### Bugs fixes
|
10
|
+
|
11
|
+
* Properly handle asynchronous timers for eventmachine and cool.io.
|
12
|
+
|
3
13
|
## rest-core 1.0.1 -- 2012-05-14
|
4
14
|
|
5
15
|
* [`Auto`] Check for eventmachine first instead of cool.io
|
data/Rakefile
CHANGED
@@ -1,8 +1,13 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
begin
|
4
|
+
require "#{dir = File.dirname(__FILE__)}/task/gemgem"
|
5
|
+
rescue LoadError
|
6
|
+
sh "git submodule update --init"
|
7
|
+
exec Gem.ruby, "-S", "rake", *ARGV
|
8
|
+
end
|
5
9
|
|
10
|
+
Gemgem.dir = dir
|
6
11
|
($LOAD_PATH << File.expand_path("#{Gemgem.dir}/lib" )).uniq!
|
7
12
|
|
8
13
|
desc 'Generate gemspec'
|
@@ -11,10 +11,10 @@ class RestCore::CoolioFiber
|
|
11
11
|
:url => request_uri(env) ,
|
12
12
|
:payload => env[REQUEST_PAYLOAD],
|
13
13
|
:headers => env[REQUEST_HEADERS]))
|
14
|
+
rescue FiberError
|
14
15
|
end
|
15
16
|
|
16
17
|
def process env, response
|
17
|
-
env[TIMER].detach if env[TIMER]
|
18
18
|
Thread.current[:coolio_http_client].detach if
|
19
19
|
Thread.current[:coolio_http_client].kind_of?(::Coolio::HttpFiber)
|
20
20
|
|
@@ -28,7 +28,7 @@ class RestCore::EmHttpRequestAsync
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def respond env, client
|
31
|
-
env[TIMER].cancel if env[TIMER]
|
31
|
+
env[TIMER].cancel if env[TIMER] && !env[TIMER].canceled?
|
32
32
|
env[ASYNC].call(env.merge(
|
33
33
|
RESPONSE_BODY => client.response,
|
34
34
|
RESPONSE_STATUS => client.response_header.status,
|
@@ -28,8 +28,11 @@ class RestCore::EmHttpRequestFiber
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def respond f, env, client
|
31
|
-
env[TIMER].cancel if env[TIMER]
|
32
31
|
f.resume(process(env, client)) if f.alive?
|
32
|
+
rescue FiberError
|
33
|
+
# whenever timeout, client.close would be called,
|
34
|
+
# and then errback would be called. in this case,
|
35
|
+
# the fiber is already resumed by the timer
|
33
36
|
end
|
34
37
|
|
35
38
|
def process env, client
|
data/lib/rest-core/builder.rb
CHANGED
data/lib/rest-core/client.rb
CHANGED
@@ -25,7 +25,10 @@ class RestCore::Timeout
|
|
25
25
|
if root_fiber? && env[ASYNC]
|
26
26
|
yield(env.merge(TIMER => timeout_with_callback(env, class_name)))
|
27
27
|
else
|
28
|
-
|
28
|
+
timer = timeout_with_resume(env, class_name)
|
29
|
+
response = yield(env.merge(TIMER => timer))
|
30
|
+
timer.cancel unless timer.canceled?
|
31
|
+
response
|
29
32
|
end
|
30
33
|
else
|
31
34
|
::Timeout.timeout(timeout(env)){ yield(env) }
|
@@ -60,6 +63,9 @@ class RestCore::Timeout
|
|
60
63
|
f = Fiber.current
|
61
64
|
EventMachineTimer.new(timeout(env), error = timeout_error){
|
62
65
|
f.resume(error) if f.alive?
|
66
|
+
# no need to check if the fiber is already resumed or not,
|
67
|
+
# because monitor should have already handled this in the
|
68
|
+
# case of fibers
|
63
69
|
}
|
64
70
|
|
65
71
|
when /Coolio/
|
@@ -6,9 +6,19 @@ class RestCore::Timeout::EventMachineTimer < ::EventMachine::Timer
|
|
6
6
|
super(timeout, &block) if block_given?
|
7
7
|
self.timeout = timeout
|
8
8
|
self.error = error
|
9
|
+
@canceled = false
|
9
10
|
end
|
10
11
|
|
11
12
|
def on_timeout &block
|
12
13
|
send(:initialize, timeout, error, &block)
|
13
14
|
end
|
15
|
+
|
16
|
+
def cancel
|
17
|
+
super
|
18
|
+
@canceled = true
|
19
|
+
end
|
20
|
+
|
21
|
+
def canceled?
|
22
|
+
@canceled
|
23
|
+
end
|
14
24
|
end
|
data/lib/rest-core/version.rb
CHANGED
data/lib/rest-core/wrapper.rb
CHANGED
@@ -3,16 +3,21 @@ require 'rest-core'
|
|
3
3
|
|
4
4
|
module RestCore::Wrapper
|
5
5
|
include RestCore
|
6
|
+
|
7
|
+
module DefaultApp
|
8
|
+
def default_app
|
9
|
+
@default_app ||= RestCore::Dry
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
6
13
|
def self.included mod
|
7
|
-
mod.send(:
|
14
|
+
mod.send(:extend, DefaultApp)
|
8
15
|
class << mod
|
9
16
|
attr_writer :default_app
|
10
|
-
def default_app
|
11
|
-
@default_app ||= RestCore::Dry
|
12
|
-
end
|
13
17
|
end
|
14
18
|
end
|
15
19
|
|
20
|
+
attr_reader :init, :middles, :wrapped
|
16
21
|
attr_writer :default_app
|
17
22
|
def default_app
|
18
23
|
@default_app ||= self.class.default_app
|
@@ -22,6 +27,7 @@ module RestCore::Wrapper
|
|
22
27
|
@middles ||= []
|
23
28
|
instance_eval(&block) if block_given?
|
24
29
|
@wrapped ||= to_app
|
30
|
+
@init = nil
|
25
31
|
end
|
26
32
|
|
27
33
|
def use middle, *args, &block
|
@@ -43,9 +49,9 @@ module RestCore::Wrapper
|
|
43
49
|
}.flatten
|
44
50
|
end
|
45
51
|
|
46
|
-
def to_app init
|
52
|
+
def to_app app=init || default_app
|
47
53
|
# === foldr m.new app middles
|
48
|
-
middles.reverse.inject(
|
54
|
+
middles.reverse.inject(app.new){ |app_, (middle, args, block)|
|
49
55
|
begin
|
50
56
|
middle.new(app_, *partial_deep_copy(args), &block)
|
51
57
|
rescue ArgumentError => e
|
data/rest-core.gemspec
CHANGED
@@ -2,13 +2,13 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = "rest-core"
|
5
|
-
s.version = "1.0.
|
5
|
+
s.version = "1.0.2"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = [
|
9
9
|
"Cardinal Blue",
|
10
10
|
"Lin Jen-Shin (godfat)"]
|
11
|
-
s.date = "2012-05
|
11
|
+
s.date = "2012-06-05"
|
12
12
|
s.description = "Modular Ruby clients interface for REST APIs\n\nThere has been an explosion in the number of REST APIs available today.\nTo address the need for a way to access these APIs easily and elegantly,\nwe have developed [rest-core][], which consists of composable middleware\nthat allows you to build a REST client for any REST API. Or in the case of\ncommon APIs such as Facebook, Github, and Twitter, you can simply use the\ndedicated clients provided by [rest-more][].\n\n[rest-core]: https://github.com/cardinalblue/rest-core\n[rest-more]: https://github.com/cardinalblue/rest-more"
|
13
13
|
s.email = ["dev (XD) cardinalblue.com"]
|
14
14
|
s.files = [
|
@@ -78,10 +78,9 @@ Gem::Specification.new do |s|
|
|
78
78
|
"pending/test_multi.rb",
|
79
79
|
"pending/test_test_util.rb",
|
80
80
|
"rest-core.gemspec",
|
81
|
-
"task/.gitignore",
|
82
|
-
"task/gemgem.rb",
|
83
81
|
"test/test_auth_basic.rb",
|
84
82
|
"test/test_builder.rb",
|
83
|
+
"test/test_cache.rb",
|
85
84
|
"test/test_client.rb",
|
86
85
|
"test/test_client_oauth1.rb",
|
87
86
|
"test/test_default_query.rb",
|
@@ -101,6 +100,7 @@ Gem::Specification.new do |s|
|
|
101
100
|
s.test_files = [
|
102
101
|
"test/test_auth_basic.rb",
|
103
102
|
"test/test_builder.rb",
|
103
|
+
"test/test_cache.rb",
|
104
104
|
"test/test_client.rb",
|
105
105
|
"test/test_client_oauth1.rb",
|
106
106
|
"test/test_default_query.rb",
|
data/test/test_cache.rb
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
|
2
|
+
require 'rest-core/test'
|
3
|
+
|
4
|
+
describe RC::Cache do
|
5
|
+
after do
|
6
|
+
WebMock.reset!
|
7
|
+
RR.verify
|
8
|
+
end
|
9
|
+
|
10
|
+
should 'basic' do
|
11
|
+
c = RC::Builder.client do
|
12
|
+
use RC::Cache, {}, 3600
|
13
|
+
run Class.new{
|
14
|
+
attr_accessor :tick
|
15
|
+
def initialize
|
16
|
+
self.tick = 0
|
17
|
+
end
|
18
|
+
def call env
|
19
|
+
self.tick +=1
|
20
|
+
env.merge(RC::RESPONSE_BODY => 'response')
|
21
|
+
end
|
22
|
+
}
|
23
|
+
end.new
|
24
|
+
c.get('/')
|
25
|
+
c.cache.should.eq({Digest::MD5.hexdigest('/') => 'response'})
|
26
|
+
c.app.app.tick.should.eq 1
|
27
|
+
c.get('/')
|
28
|
+
c.app.app.tick.should.eq 1
|
29
|
+
c.cache.clear
|
30
|
+
c.get('/')
|
31
|
+
c.app.app.tick.should.eq 2
|
32
|
+
end
|
33
|
+
|
34
|
+
should 'cancel timeout for fiber' do
|
35
|
+
any_instance_of(RC::Timeout::EventMachineTimer) do |timer|
|
36
|
+
proxy.mock(timer).cancel.times(2)
|
37
|
+
end
|
38
|
+
path = 'http://example.com/'
|
39
|
+
stub_request(:get, path).to_return(:body => 'response')
|
40
|
+
c = RC::Builder.client do
|
41
|
+
use RC::Timeout, 10
|
42
|
+
use RC::Cache, {}, 3600
|
43
|
+
run RC::EmHttpRequestFiber
|
44
|
+
end.new
|
45
|
+
EM.run{ Fiber.new{
|
46
|
+
c.request_full(RC::REQUEST_PATH => path)
|
47
|
+
c.request_full(RC::REQUEST_PATH => path)
|
48
|
+
EM.stop }.resume }
|
49
|
+
c.cache.size.should.eq 1
|
50
|
+
end if defined?(Fiber)
|
51
|
+
|
52
|
+
should 'cancel timeout for async' do
|
53
|
+
path = 'http://example.com/'
|
54
|
+
any_instance_of(RC::Timeout::EventMachineTimer) do |timer|
|
55
|
+
mock(timer).cancel.times(2)
|
56
|
+
end
|
57
|
+
stub_request(:get, path).to_return(:body => 'response')
|
58
|
+
c = RC::Builder.client do
|
59
|
+
use RC::Timeout, 10
|
60
|
+
use RC::Cache, {}, 3600
|
61
|
+
run RC::EmHttpRequestAsync
|
62
|
+
end.new
|
63
|
+
EM.run{
|
64
|
+
c.request_full(RC::REQUEST_PATH => path){
|
65
|
+
c.request_full(RC::REQUEST_PATH => path){
|
66
|
+
EM.stop }}}
|
67
|
+
c.cache.size.should.eq 1
|
68
|
+
end
|
69
|
+
end
|
data/test/test_timeout.rb
CHANGED
@@ -6,6 +6,10 @@ describe RC::Timeout do
|
|
6
6
|
@app = RC::Timeout.new(RC::Dry.new, 0)
|
7
7
|
end
|
8
8
|
|
9
|
+
after do
|
10
|
+
WebMock.reset!
|
11
|
+
end
|
12
|
+
|
9
13
|
should 'bypass timeout if timeout is 0' do
|
10
14
|
mock(@app).monitor.times(0)
|
11
15
|
@app.call({}).should.eq({})
|
@@ -16,4 +20,15 @@ describe RC::Timeout do
|
|
16
20
|
mock.proxy(@app).monitor(env).times(1)
|
17
21
|
@app.call(env).should.eq(env)
|
18
22
|
end
|
23
|
+
|
24
|
+
should 'return correct result under fibers' do
|
25
|
+
path = 'http://example.com/'
|
26
|
+
stub_request(:get, path).to_return(:body => 'response')
|
27
|
+
|
28
|
+
c = RC::Builder.client do
|
29
|
+
use RC::Timeout, 10
|
30
|
+
run RC::EmHttpRequestFiber
|
31
|
+
end.new
|
32
|
+
EM.run{Fiber.new{c.get(path).should.eq('response');EM.stop}.resume}
|
33
|
+
end if defined?(Fiber)
|
19
34
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rest-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2012-05
|
13
|
+
date: 2012-06-05 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rest-client
|
@@ -119,10 +119,9 @@ files:
|
|
119
119
|
- pending/test_multi.rb
|
120
120
|
- pending/test_test_util.rb
|
121
121
|
- rest-core.gemspec
|
122
|
-
- task/.gitignore
|
123
|
-
- task/gemgem.rb
|
124
122
|
- test/test_auth_basic.rb
|
125
123
|
- test/test_builder.rb
|
124
|
+
- test/test_cache.rb
|
126
125
|
- test/test_client.rb
|
127
126
|
- test/test_client_oauth1.rb
|
128
127
|
- test/test_default_query.rb
|
@@ -162,6 +161,7 @@ summary: Modular Ruby clients interface for REST APIs
|
|
162
161
|
test_files:
|
163
162
|
- test/test_auth_basic.rb
|
164
163
|
- test/test_builder.rb
|
164
|
+
- test/test_cache.rb
|
165
165
|
- test/test_client.rb
|
166
166
|
- test/test_client_oauth1.rb
|
167
167
|
- test/test_default_query.rb
|
data/task/.gitignore
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
*.rbc
|
data/task/gemgem.rb
DELETED
@@ -1,257 +0,0 @@
|
|
1
|
-
|
2
|
-
require 'pathname'
|
3
|
-
|
4
|
-
module Gemgem
|
5
|
-
class << self
|
6
|
-
attr_accessor :dir, :spec
|
7
|
-
end
|
8
|
-
|
9
|
-
module_function
|
10
|
-
def create
|
11
|
-
yield(spec = Gem::Specification.new{ |s|
|
12
|
-
s.authors = ['Lin Jen-Shin (godfat)']
|
13
|
-
s.email = ['godfat (XD) godfat.org']
|
14
|
-
|
15
|
-
s.description = description.join
|
16
|
-
s.summary = description.first
|
17
|
-
|
18
|
-
s.rubygems_version = Gem::VERSION
|
19
|
-
s.date = Time.now.strftime('%Y-%m-%d')
|
20
|
-
s.files = gem_files
|
21
|
-
s.test_files = gem_files.grep(%r{^test/(.+?/)*test_.+?\.rb$})
|
22
|
-
s.executables = Dir['bin/*'].map{ |f| File.basename(f) }
|
23
|
-
s.require_paths = %w[lib]
|
24
|
-
})
|
25
|
-
spec.homepage ||= "https://github.com/godfat/#{spec.name}"
|
26
|
-
spec
|
27
|
-
end
|
28
|
-
|
29
|
-
def readme
|
30
|
-
path = %w[README.md README].find{ |name|
|
31
|
-
File.exist?("#{Gemgem.dir}/#{name}")
|
32
|
-
}
|
33
|
-
@readme ||=
|
34
|
-
if path
|
35
|
-
ps = File.read(path).scan(/#+[^\n]+\n\n.+?(?=\n\n#+[^\n]+\n)/m)
|
36
|
-
ps.inject({'HEADER' => ps.first}){ |r, s, i|
|
37
|
-
r[s[/\w+/]] = s
|
38
|
-
r
|
39
|
-
}
|
40
|
-
else
|
41
|
-
{}
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
def description
|
46
|
-
@description ||= (readme['DESCRIPTION']||'').sub(/.+\n\n/, '').lines.to_a
|
47
|
-
end
|
48
|
-
|
49
|
-
def changes
|
50
|
-
path = %w[CHANGES.md CHANGES].find{ |name|
|
51
|
-
File.exist?("#{Gemgem.dir}/#{name}")
|
52
|
-
}
|
53
|
-
@changes ||=
|
54
|
-
if path
|
55
|
-
date = '\d+{4}\-\d+{2}\-\d{2}'
|
56
|
-
File.read(path).match(
|
57
|
-
/([^\n]+#{date}\n\n(.+?))(?=\n\n[^\n]+#{date}\n)/m)[1]
|
58
|
-
else
|
59
|
-
''
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
def ann_md
|
64
|
-
"##{readme['HEADER'].sub(/([\w\-]+)/, "[\\1](#{spec.homepage})")}\n\n" \
|
65
|
-
"##{readme['DESCRIPTION'][/[^\n]+\n\n[^\n]+/]}\n\n" \
|
66
|
-
"### CHANGES:\n\n" \
|
67
|
-
"###{changes}\n\n" \
|
68
|
-
"##{readme['INSTALLATION']}\n\n" +
|
69
|
-
if readme['SYNOPSIS'] then "##{readme['SYNOPSIS']}" else '' end
|
70
|
-
end
|
71
|
-
|
72
|
-
def ann_html
|
73
|
-
gem 'nokogiri'
|
74
|
-
gem 'kramdown'
|
75
|
-
|
76
|
-
IO.popen('kramdown', 'r+') do |md|
|
77
|
-
md.puts Gemgem.ann_md
|
78
|
-
md.close_write
|
79
|
-
require 'nokogiri'
|
80
|
-
html = Nokogiri::XML.parse("<gemgem>#{md.read}</gemgem>")
|
81
|
-
html.css('*').each{ |n| n.delete('id') }
|
82
|
-
html.root.children.to_html
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
def ann_email
|
87
|
-
"#{readme['HEADER'].sub(/([\w\-]+)/, "\\1 <#{spec.homepage}>")}\n\n" \
|
88
|
-
"#{readme['DESCRIPTION']}\n\n" \
|
89
|
-
"#{readme['INSTALLATION']}\n\n" +
|
90
|
-
if readme['SYNOPSIS'] then "##{readme['SYNOPSIS']}\n\n" else '' end +
|
91
|
-
"## CHANGES:\n\n" \
|
92
|
-
"##{changes}\n\n"
|
93
|
-
end
|
94
|
-
|
95
|
-
def gem_tag
|
96
|
-
"#{spec.name}-#{spec.version}"
|
97
|
-
end
|
98
|
-
|
99
|
-
def write
|
100
|
-
File.open("#{dir}/#{spec.name}.gemspec", 'w'){ |f|
|
101
|
-
f << split_lines(spec.to_ruby) }
|
102
|
-
end
|
103
|
-
|
104
|
-
def split_lines ruby
|
105
|
-
ruby.gsub(/(.+?)\[(.+?)\]/){ |s|
|
106
|
-
if $2.index(',')
|
107
|
-
"#{$1}[\n #{$2.split(',').map(&:strip).join(",\n ")}]"
|
108
|
-
else
|
109
|
-
s
|
110
|
-
end
|
111
|
-
}
|
112
|
-
end
|
113
|
-
|
114
|
-
def all_files
|
115
|
-
@all_files ||= find_files(Pathname.new(dir)).map{ |file|
|
116
|
-
if file.to_s =~ %r{\.git/}
|
117
|
-
nil
|
118
|
-
else
|
119
|
-
file.to_s
|
120
|
-
end
|
121
|
-
}.compact.sort
|
122
|
-
end
|
123
|
-
|
124
|
-
def gem_files
|
125
|
-
@gem_files ||= all_files - ignored_files
|
126
|
-
end
|
127
|
-
|
128
|
-
def ignored_files
|
129
|
-
@ignored_file ||= all_files.select{ |path| ignore_patterns.find{ |ignore|
|
130
|
-
path =~ ignore && !git_files.include?(path)}}
|
131
|
-
end
|
132
|
-
|
133
|
-
def git_files
|
134
|
-
@git_files ||= if File.exist?("#{dir}/.git")
|
135
|
-
`git ls-files`.split("\n")
|
136
|
-
else
|
137
|
-
[]
|
138
|
-
end
|
139
|
-
end
|
140
|
-
|
141
|
-
# protected
|
142
|
-
def find_files path
|
143
|
-
path.children.select(&:file?).map{|file| file.to_s[(dir.size+1)..-1]} +
|
144
|
-
path.children.select(&:directory?).map{|dir| find_files(dir)}.flatten
|
145
|
-
end
|
146
|
-
|
147
|
-
def ignore_patterns
|
148
|
-
@ignore_files ||= expand_patterns(
|
149
|
-
File.read("#{dir}/.gitignore").split("\n").reject{ |pattern|
|
150
|
-
pattern.strip == ''
|
151
|
-
}).map{ |pattern| %r{^([^/]+/)*?#{Regexp.escape(pattern)}(/[^/]+)*?$} }
|
152
|
-
end
|
153
|
-
|
154
|
-
def expand_patterns pathes
|
155
|
-
pathes.map{ |path|
|
156
|
-
if path !~ /\*/
|
157
|
-
path
|
158
|
-
else
|
159
|
-
expand_patterns(
|
160
|
-
Dir[path] +
|
161
|
-
Pathname.new(File.dirname(path)).children.select(&:directory?).
|
162
|
-
map{ |prefix| "#{prefix}/#{File.basename(path)}" })
|
163
|
-
end
|
164
|
-
}.flatten
|
165
|
-
end
|
166
|
-
end
|
167
|
-
|
168
|
-
namespace :gem do
|
169
|
-
|
170
|
-
desc 'Install gem'
|
171
|
-
task :install => [:build] do
|
172
|
-
sh("#{Gem.ruby} -S gem install pkg/#{Gemgem.gem_tag}")
|
173
|
-
end
|
174
|
-
|
175
|
-
desc 'Build gem'
|
176
|
-
task :build => [:spec] do
|
177
|
-
sh("#{Gem.ruby} -S gem build #{Gemgem.spec.name}.gemspec")
|
178
|
-
sh("mkdir -p pkg")
|
179
|
-
sh("mv #{Gemgem.gem_tag}.gem pkg/")
|
180
|
-
end
|
181
|
-
|
182
|
-
desc 'Release gem'
|
183
|
-
task :release => [:spec, :check, :build] do
|
184
|
-
sh("git tag #{Gemgem.gem_tag}")
|
185
|
-
sh("git push")
|
186
|
-
sh("git push --tags")
|
187
|
-
sh("#{Gem.ruby} -S gem push pkg/#{Gemgem.gem_tag}.gem")
|
188
|
-
end
|
189
|
-
|
190
|
-
task :check do
|
191
|
-
ver = Gemgem.spec.version.to_s
|
192
|
-
|
193
|
-
if ENV['VERSION'].nil?
|
194
|
-
puts("\x1b[35mExpected " \
|
195
|
-
"\x1b[33mVERSION\x1b[35m=\x1b[33m#{ver}\x1b[m")
|
196
|
-
exit(1)
|
197
|
-
|
198
|
-
elsif ENV['VERSION'] != ver
|
199
|
-
puts("\x1b[35mExpected \x1b[33mVERSION\x1b[35m=\x1b[33m#{ver} " \
|
200
|
-
"\x1b[35mbut got\n " \
|
201
|
-
"\x1b[33mVERSION\x1b[35m=\x1b[33m#{ENV['VERSION']}\x1b[m")
|
202
|
-
exit(2)
|
203
|
-
end
|
204
|
-
end
|
205
|
-
|
206
|
-
end # of gem namespace
|
207
|
-
|
208
|
-
desc 'Run tests in memory'
|
209
|
-
task :test do
|
210
|
-
require 'bacon'
|
211
|
-
Bacon.extend(Bacon::TestUnitOutput)
|
212
|
-
Bacon.summary_on_exit
|
213
|
-
$LOAD_PATH.unshift('lib')
|
214
|
-
Dir['./test/**/test_*.rb'].each{ |file| require file[0..-4] }
|
215
|
-
end
|
216
|
-
|
217
|
-
desc 'Run tests with shell'
|
218
|
-
task 'test:shell', :RUBY_OPTS do |t, args|
|
219
|
-
files = Dir['test/**/test_*.rb'].join(' ')
|
220
|
-
|
221
|
-
cmd = [Gem.ruby, args[:RUBY_OPTS],
|
222
|
-
'-I', 'lib', '-S', 'bacon', '--quiet', files]
|
223
|
-
|
224
|
-
sh(cmd.compact.join(' '))
|
225
|
-
end
|
226
|
-
|
227
|
-
desc 'Generate ann markdown'
|
228
|
-
task 'ann:md' => ['gem:spec'] do
|
229
|
-
puts Gemgem.ann_md
|
230
|
-
end
|
231
|
-
|
232
|
-
desc 'Generate ann html'
|
233
|
-
task 'ann:html' => ['gem:spec'] do
|
234
|
-
puts Gemgem.ann_html
|
235
|
-
end
|
236
|
-
|
237
|
-
desc 'Generate ann email'
|
238
|
-
task 'ann:email' => ['gem:spec'] do
|
239
|
-
puts Gemgem.ann_email
|
240
|
-
end
|
241
|
-
|
242
|
-
desc 'Generate rdoc'
|
243
|
-
task :doc => ['gem:spec'] do
|
244
|
-
sh("yardoc -o rdoc --main README.md" \
|
245
|
-
" --files #{Gemgem.spec.extra_rdoc_files.join(',')}")
|
246
|
-
end
|
247
|
-
|
248
|
-
desc 'Remove ignored files'
|
249
|
-
task :clean => ['gem:spec'] do
|
250
|
-
trash = "~/.Trash/#{Gemgem.spec.name}/"
|
251
|
-
sh "mkdir -p #{trash}" unless File.exist?(File.expand_path(trash))
|
252
|
-
Gemgem.ignored_files.each{ |file| sh "mv #{file} #{trash}" }
|
253
|
-
end
|
254
|
-
|
255
|
-
task :default do
|
256
|
-
puts `#{Gem.ruby} -S #{$PROGRAM_NAME} -T`
|
257
|
-
end
|