rest-core 1.0.1 → 1.0.2
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.
- 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
|