http_router 0.3.10 → 0.3.11
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/README.rdoc +1 -1
- data/Rakefile +5 -9
- data/benchmarks/rec2.rb +3 -0
- data/http_router.gemspec +2 -1
- data/lib/http_router.rb +0 -2
- data/lib/http_router/node.rb +11 -15
- data/lib/http_router/root.rb +23 -19
- data/lib/http_router/route.rb +10 -10
- data/lib/http_router/version.rb +1 -1
- data/spec/misc_spec.rb +1 -1
- metadata +27 -14
- data/Tumbler +0 -4
- data/ext/gem_rake.rb +0 -126
data/README.rdoc
CHANGED
@@ -14,7 +14,7 @@ This is very new code. Lots of stuff probably doesn't work right. I will likely
|
|
14
14
|
* Regex support for variables.
|
15
15
|
* Request condition support.
|
16
16
|
* Partial matches.
|
17
|
-
* Supports interstitial variables (e.g. /my-:variable-brings.all.the.boys/yard)
|
17
|
+
* Supports interstitial variables (e.g. /my-:variable-brings.all.the.boys/yard) and unnamed variable /one/:/two
|
18
18
|
* Very fast and small code base (~1,000 loc).
|
19
19
|
* Sinatra compatibility.
|
20
20
|
|
data/Rakefile
CHANGED
@@ -1,18 +1,15 @@
|
|
1
1
|
require 'rubygems'
|
2
|
+
require 'bundler'
|
2
3
|
require 'spec'
|
4
|
+
require 'code_stats'
|
3
5
|
require 'spec/rake/spectask'
|
6
|
+
|
4
7
|
Spec::Rake::SpecTask.new(:spec) do |t|
|
5
8
|
t.spec_opts ||= []
|
6
9
|
t.spec_opts << "--options" << "spec/spec.opts"
|
7
10
|
t.spec_files = FileList['spec/**/*_spec.rb']
|
8
11
|
end
|
9
12
|
|
10
|
-
begin
|
11
|
-
require 'code_stats'
|
12
|
-
CodeStats::Tasks.new
|
13
|
-
rescue LoadError
|
14
|
-
end
|
15
|
-
|
16
13
|
require 'rake/rdoctask'
|
17
14
|
desc "Generate documentation"
|
18
15
|
Rake::RDocTask.new do |rd|
|
@@ -21,6 +18,5 @@ Rake::RDocTask.new do |rd|
|
|
21
18
|
rd.rdoc_dir = 'rdoc'
|
22
19
|
end
|
23
20
|
|
24
|
-
|
25
|
-
|
26
|
-
Bundler::GemHelper.install_tasks
|
21
|
+
Bundler::GemHelper.install_tasks
|
22
|
+
CodeStats::Tasks.new(:reporting_depth => 3)
|
data/benchmarks/rec2.rb
CHANGED
data/http_router.gemspec
CHANGED
@@ -23,10 +23,11 @@ Gem::Specification.new do |s|
|
|
23
23
|
s.add_runtime_dependency 'rack', '>=1.0'
|
24
24
|
s.add_runtime_dependency 'url_mount', '>=0.2.1'
|
25
25
|
s.add_development_dependency 'rspec'
|
26
|
+
s.add_development_dependency 'code_stats'
|
26
27
|
s.add_development_dependency 'rake'
|
27
28
|
s.add_development_dependency 'sinatra'
|
28
29
|
s.add_development_dependency 'rbench'
|
29
|
-
s.add_development_dependency '
|
30
|
+
s.add_development_dependency 'bundler', ">= 1.0.0.rc4"
|
30
31
|
|
31
32
|
if s.respond_to? :specification_version then
|
32
33
|
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
data/lib/http_router.rb
CHANGED
data/lib/http_router/node.rb
CHANGED
@@ -133,10 +133,10 @@ class HttpRouter
|
|
133
133
|
current_nodes
|
134
134
|
end
|
135
135
|
|
136
|
-
def find_on_parts(request, parts, params
|
136
|
+
def find_on_parts(request, parts, params)
|
137
137
|
if parts and !parts.empty?
|
138
138
|
if parts.size == 1 and parts.first == ''
|
139
|
-
potential_match = find_on_parts(request, [], params
|
139
|
+
potential_match = find_on_parts(request, [], params)
|
140
140
|
if potential_match and (router.ignore_trailing_slash? or potential_match.value && potential_match.value.route.trailing_slash_ignore?)
|
141
141
|
parts.shift
|
142
142
|
return potential_match
|
@@ -149,10 +149,10 @@ class HttpRouter
|
|
149
149
|
if tester.respond_to?(:matches?) and match = tester.matches?(parts)
|
150
150
|
dupped_parts = parts.dup
|
151
151
|
params.push((val = tester.consume(match, dupped_parts) and val.is_a?(Array)) ? val.map{|v| Rack::Utils.uri_unescape(v)} : Rack::Utils.uri_unescape(val))
|
152
|
-
parts.replace(dupped_parts) if response = node.find_on_parts(request, dupped_parts, params
|
152
|
+
parts.replace(dupped_parts) if response = node.find_on_parts(request, dupped_parts, params)
|
153
153
|
elsif tester.respond_to?(:match) and match = tester.match(parts.whole_path) and match.begin(0) == 0
|
154
154
|
dupped_parts = router.split(parts.whole_path[match[0].size, parts.whole_path.size])
|
155
|
-
parts.replace(dupped_parts) if response = node.find_on_parts(request, dupped_parts, params
|
155
|
+
parts.replace(dupped_parts) if response = node.find_on_parts(request, dupped_parts, params)
|
156
156
|
else
|
157
157
|
nil
|
158
158
|
end
|
@@ -161,14 +161,14 @@ class HttpRouter
|
|
161
161
|
end
|
162
162
|
if match = @lookup && @lookup[parts.first]
|
163
163
|
parts.shift
|
164
|
-
return match.find_on_parts(request, parts, params
|
164
|
+
return match.find_on_parts(request, parts, params)
|
165
165
|
elsif @catchall
|
166
166
|
params.push((val = @catchall.variable.consume(nil, parts) and val.is_a?(Array)) ? val.map{|v| Rack::Utils.uri_unescape(v)} : Rack::Utils.uri_unescape(val))
|
167
|
-
return @catchall.find_on_parts(request, parts, params
|
167
|
+
return @catchall.find_on_parts(request, parts, params)
|
168
168
|
end
|
169
169
|
end
|
170
170
|
if request_node
|
171
|
-
request_node.find_on_request_methods(request
|
171
|
+
request_node.find_on_request_methods(request)
|
172
172
|
elsif arbitrary_node
|
173
173
|
arbitrary_node.find_on_arbitrary(request)
|
174
174
|
elsif @value
|
@@ -203,7 +203,7 @@ class HttpRouter
|
|
203
203
|
RequestMethods = [:request_method, :host, :port, :scheme, :user_agent, :ip, :fullpath, :query_string]
|
204
204
|
attr_accessor :request_method
|
205
205
|
|
206
|
-
def find_on_request_methods(request
|
206
|
+
def find_on_request_methods(request)
|
207
207
|
if @request_method
|
208
208
|
request_method_satisfied = false
|
209
209
|
request_value = request.send(request_method)
|
@@ -212,23 +212,19 @@ class HttpRouter
|
|
212
212
|
regexp === request_value
|
213
213
|
end
|
214
214
|
request_method_satisfied = true if next_node
|
215
|
-
next_node &&= next_node.last.find_on_request_methods(request
|
215
|
+
next_node &&= next_node.last.find_on_request_methods(request)
|
216
216
|
return next_node if next_node
|
217
217
|
end
|
218
218
|
if @lookup and next_node = @lookup[request_value]
|
219
219
|
request_method_satisfied = true
|
220
|
-
next_node = next_node.find_on_request_methods(request
|
220
|
+
next_node = next_node.find_on_request_methods(request)
|
221
221
|
return next_node if next_node
|
222
222
|
end
|
223
223
|
if @catchall
|
224
224
|
request_method_satisfied = true
|
225
|
-
next_node = @catchall.find_on_request_methods(request
|
225
|
+
next_node = @catchall.find_on_request_methods(request)
|
226
226
|
return next_node if next_node
|
227
227
|
end
|
228
|
-
if @request_method == :request_method
|
229
|
-
alternate_request_methods.concat(@lookup.keys)
|
230
|
-
alternate_request_methods.request_method_found ||= request_method_satisfied
|
231
|
-
end
|
232
228
|
end
|
233
229
|
|
234
230
|
if @arbitrary_node
|
data/lib/http_router/root.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
class HttpRouter
|
2
2
|
class Root < Node
|
3
|
+
HttpRequestMethods = %w(HEAD GET HEAD POST DELETE PUT)
|
4
|
+
|
3
5
|
class AlternativeRequestMethods < Array
|
4
6
|
attr_accessor :request_method_found
|
5
7
|
end
|
@@ -10,26 +12,21 @@ class HttpRouter
|
|
10
12
|
end
|
11
13
|
|
12
14
|
def find(request)
|
13
|
-
path = request.path_info.dup
|
14
|
-
parts = router.split(path)
|
15
|
-
parts << '' if path[path.size - 1] == ?/
|
16
15
|
params = []
|
17
|
-
|
18
|
-
|
19
|
-
process_response(
|
20
|
-
find_on_parts(request, parts, params, alternate_request_methods),
|
21
|
-
parts,
|
22
|
-
params,
|
23
|
-
request,
|
24
|
-
alternate_request_methods
|
25
|
-
)
|
16
|
+
parts = get_parts(request)
|
17
|
+
node = find_on_parts(request, parts, params)
|
18
|
+
process_response(node, parts, params, request)
|
26
19
|
end
|
27
|
-
|
20
|
+
|
21
|
+
def get_parts(request)
|
22
|
+
parts = router.split(request.path_info.dup)
|
23
|
+
parts << '' if request.path_info[-1] == ?/
|
24
|
+
parts
|
25
|
+
end
|
26
|
+
|
28
27
|
private
|
29
|
-
def process_response(node, parts, params, request
|
30
|
-
if node
|
31
|
-
node
|
32
|
-
elsif node && node.value
|
28
|
+
def process_response(node, parts, params, request)
|
29
|
+
if node && node.value
|
33
30
|
if parts.empty?
|
34
31
|
Response.matched(node.value, params, request.path_info)
|
35
32
|
elsif node.value.route.partially_match?
|
@@ -39,10 +36,17 @@ class HttpRouter
|
|
39
36
|
nil
|
40
37
|
end
|
41
38
|
else
|
42
|
-
|
39
|
+
alternate_methods = (HttpRequestMethods - [request.request_method]).select do |alternate_method|
|
40
|
+
test_request = request.dup
|
41
|
+
test_request.env['REQUEST_METHOD'] = alternate_method
|
42
|
+
node = find_on_parts(test_request, get_parts(request), [])
|
43
|
+
node && node.value
|
44
|
+
end
|
45
|
+
|
46
|
+
if alternate_methods.empty?
|
43
47
|
nil
|
44
48
|
else
|
45
|
-
Response.unmatched(405, {"Allow" =>
|
49
|
+
Response.unmatched(405, {"Allow" => alternate_methods.join(", ")})
|
46
50
|
end
|
47
51
|
end
|
48
52
|
end
|
data/lib/http_router/route.rb
CHANGED
@@ -301,23 +301,23 @@ class HttpRouter
|
|
301
301
|
paths = HttpRouter::OptionalCompiler.new(@path).paths
|
302
302
|
paths.map do |path|
|
303
303
|
splitting_indexes = []
|
304
|
-
|
304
|
+
variable_position = 0
|
305
305
|
counter = 0
|
306
306
|
original_path = path.dup
|
307
307
|
split_path = router.split(path)
|
308
|
-
|
308
|
+
position = 0
|
309
309
|
new_path = split_path.map do |part|
|
310
|
-
|
310
|
+
processed_parts = case part
|
311
311
|
when /^:([a-zA-Z_0-9]*)$/
|
312
312
|
v_name = ($1.empty? ? anonymous_variable(counter += 1) : $1).to_sym
|
313
313
|
router.variable(v_name, @matches_with[v_name])
|
314
314
|
when /^\*([a-zA-Z_0-9]*)$/
|
315
|
-
if
|
315
|
+
if position != split_path.size - 1
|
316
316
|
v_name = ($1.empty? ? anonymous_variable(counter += 1) : $1).to_sym
|
317
|
-
splitting_indexes <<
|
318
|
-
remaining_path_parts = split_path[
|
317
|
+
splitting_indexes << variable_position
|
318
|
+
remaining_path_parts = split_path[position + 1, split_path.size]
|
319
319
|
look_ahead_variable = remaining_path_parts.find{|p| p[0] == ?: || p[0] == ?*}
|
320
|
-
remaining_matcher = split_path[
|
320
|
+
remaining_matcher = split_path[position + 1, look_ahead_variable ? remaining_path_parts.index(look_ahead_variable) : split_path.size].join('/')
|
321
321
|
remaining_path_parts.index(look_ahead_variable) if look_ahead_variable
|
322
322
|
router.variable(v_name, /^(#{@matches_with[v_name] || '[^\/]*?'}\/)+(?=#{Regexp.quote(remaining_matcher)})/)
|
323
323
|
else
|
@@ -327,9 +327,9 @@ class HttpRouter
|
|
327
327
|
else
|
328
328
|
generate_interstitial_parts(part)
|
329
329
|
end
|
330
|
-
|
331
|
-
|
332
|
-
|
330
|
+
variable_position += Array(processed_parts).select{|part| part.is_a?(Variable)}.size
|
331
|
+
position += 1
|
332
|
+
processed_parts
|
333
333
|
end
|
334
334
|
new_path.flatten!
|
335
335
|
Path.new(self, original_path, new_path, splitting_indexes.empty? ? nil : splitting_indexes)
|
data/lib/http_router/version.rb
CHANGED
data/spec/misc_spec.rb
CHANGED
@@ -9,7 +9,7 @@ describe "HttpRouter" do
|
|
9
9
|
route = @router.add('/:test', :conditions => {:request_method => %w{HEAD GET}, :host => 'host1'}, :default_values => {:page => 1}, :matching => {:test => /\d+/}, :name => :foobar).to :test
|
10
10
|
@router.recognize(Rack::MockRequest.env_for('http://host2/variable', :method => 'POST')).should be_nil
|
11
11
|
@router.recognize(Rack::MockRequest.env_for('http://host1/variable', :method => 'POST')).should be_nil
|
12
|
-
@router.recognize(Rack::MockRequest.env_for('http://host2/123', :method => 'POST')).
|
12
|
+
@router.recognize(Rack::MockRequest.env_for('http://host2/123', :method => 'POST')).should be_nil
|
13
13
|
@router.recognize(Rack::MockRequest.env_for('http://host1/123', :method => 'POST')).matched?.should be_false
|
14
14
|
@router.recognize(Rack::MockRequest.env_for('http://host1/123', :method => 'GET' )).route.dest.should == :test
|
15
15
|
@router.url(:foobar, '123').should == '/123?page=1'
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: http_router
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 5
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 3
|
9
|
-
-
|
10
|
-
version: 0.3.
|
9
|
+
- 11
|
10
|
+
version: 0.3.11
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Joshua Hull
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-08-
|
18
|
+
date: 2010-08-08 00:00:00 -07:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -64,7 +64,7 @@ dependencies:
|
|
64
64
|
type: :development
|
65
65
|
version_requirements: *id003
|
66
66
|
- !ruby/object:Gem::Dependency
|
67
|
-
name:
|
67
|
+
name: code_stats
|
68
68
|
prerelease: false
|
69
69
|
requirement: &id004 !ruby/object:Gem::Requirement
|
70
70
|
none: false
|
@@ -78,7 +78,7 @@ dependencies:
|
|
78
78
|
type: :development
|
79
79
|
version_requirements: *id004
|
80
80
|
- !ruby/object:Gem::Dependency
|
81
|
-
name:
|
81
|
+
name: rake
|
82
82
|
prerelease: false
|
83
83
|
requirement: &id005 !ruby/object:Gem::Requirement
|
84
84
|
none: false
|
@@ -92,7 +92,7 @@ dependencies:
|
|
92
92
|
type: :development
|
93
93
|
version_requirements: *id005
|
94
94
|
- !ruby/object:Gem::Dependency
|
95
|
-
name:
|
95
|
+
name: sinatra
|
96
96
|
prerelease: false
|
97
97
|
requirement: &id006 !ruby/object:Gem::Requirement
|
98
98
|
none: false
|
@@ -106,21 +106,36 @@ dependencies:
|
|
106
106
|
type: :development
|
107
107
|
version_requirements: *id006
|
108
108
|
- !ruby/object:Gem::Dependency
|
109
|
-
name:
|
109
|
+
name: rbench
|
110
110
|
prerelease: false
|
111
111
|
requirement: &id007 !ruby/object:Gem::Requirement
|
112
112
|
none: false
|
113
113
|
requirements:
|
114
114
|
- - ">="
|
115
115
|
- !ruby/object:Gem::Version
|
116
|
-
hash:
|
116
|
+
hash: 3
|
117
117
|
segments:
|
118
118
|
- 0
|
119
|
-
|
120
|
-
- 11
|
121
|
-
version: 0.0.11
|
119
|
+
version: "0"
|
122
120
|
type: :development
|
123
121
|
version_requirements: *id007
|
122
|
+
- !ruby/object:Gem::Dependency
|
123
|
+
name: bundler
|
124
|
+
prerelease: false
|
125
|
+
requirement: &id008 !ruby/object:Gem::Requirement
|
126
|
+
none: false
|
127
|
+
requirements:
|
128
|
+
- - ">="
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
hash: 977940573
|
131
|
+
segments:
|
132
|
+
- 1
|
133
|
+
- 0
|
134
|
+
- 0
|
135
|
+
- rc4
|
136
|
+
version: 1.0.0.rc4
|
137
|
+
type: :development
|
138
|
+
version_requirements: *id008
|
124
139
|
description: This library allows you to recognize and build URLs in a Rack application. As well it contains an interface for use within Sinatra.
|
125
140
|
email: joshbuddy@gmail.com
|
126
141
|
executables: []
|
@@ -135,7 +150,6 @@ files:
|
|
135
150
|
- Gemfile
|
136
151
|
- README.rdoc
|
137
152
|
- Rakefile
|
138
|
-
- Tumbler
|
139
153
|
- benchmarks/gen2.rb
|
140
154
|
- benchmarks/generation_bm.rb
|
141
155
|
- benchmarks/rack_mount.rb
|
@@ -154,7 +168,6 @@ files:
|
|
154
168
|
- examples/unnamed_variable.ru
|
155
169
|
- examples/variable.ru
|
156
170
|
- examples/variable_with_regex.ru
|
157
|
-
- ext/gem_rake.rb
|
158
171
|
- http_router.gemspec
|
159
172
|
- lib/ext/rack/rack_mapper.rb
|
160
173
|
- lib/ext/rack/rack_urlmap.rb
|
data/Tumbler
DELETED
data/ext/gem_rake.rb
DELETED
@@ -1,126 +0,0 @@
|
|
1
|
-
module Bundler
|
2
|
-
class GemHelper
|
3
|
-
|
4
|
-
def self.install_tasks
|
5
|
-
dir = caller.find{|c| /Rakefile:/}[/^(.*?)\/Rakefile:/, 1]
|
6
|
-
GemHelper.new(dir).install
|
7
|
-
end
|
8
|
-
|
9
|
-
attr_reader :spec_path, :base, :name
|
10
|
-
|
11
|
-
def initialize(base, name = nil)
|
12
|
-
@base = base
|
13
|
-
@name = name || interpolate_name
|
14
|
-
@spec_path = File.join(@base, "#{@name}.gemspec")
|
15
|
-
end
|
16
|
-
|
17
|
-
def install
|
18
|
-
desc 'Build your gem into the pkg directory'
|
19
|
-
task 'build' do
|
20
|
-
build_gem
|
21
|
-
end
|
22
|
-
|
23
|
-
desc 'Install your gem into the pkg directory'
|
24
|
-
task 'install' do
|
25
|
-
install_gem
|
26
|
-
end
|
27
|
-
|
28
|
-
desc 'Push your gem to rubygems'
|
29
|
-
task 'push' do
|
30
|
-
push_gem
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
def build_gem
|
35
|
-
file_name = nil
|
36
|
-
sh("gem build #{spec_path}") {
|
37
|
-
file_name = File.basename(built_gem_path)
|
38
|
-
FileUtils.mkdir_p(File.join(base, 'pkg'))
|
39
|
-
FileUtils.mv(built_gem_path, 'pkg')
|
40
|
-
}
|
41
|
-
File.join(base, 'pkg', file_name)
|
42
|
-
end
|
43
|
-
|
44
|
-
def install_gem
|
45
|
-
built_gem_path = build_gem
|
46
|
-
sh("gem install #{built_gem_path}")
|
47
|
-
end
|
48
|
-
|
49
|
-
def push_gem
|
50
|
-
guard_clean
|
51
|
-
guard_already_tagged
|
52
|
-
tag_version {
|
53
|
-
git_push
|
54
|
-
rubygem_push(build_gem)
|
55
|
-
}
|
56
|
-
end
|
57
|
-
|
58
|
-
protected
|
59
|
-
def rubygem_push(path)
|
60
|
-
sh("gem push #{path}")
|
61
|
-
end
|
62
|
-
|
63
|
-
def built_gem_path
|
64
|
-
Dir[File.join(base, "#{name}-*.gem")].sort_by{|f| File.mtime(f)}.last
|
65
|
-
end
|
66
|
-
|
67
|
-
def interpolate_name
|
68
|
-
gemspecs = Dir[File.join(base, "*.gemspec")]
|
69
|
-
raise "Unable to determine name from existing gemspec." unless gemspecs.size == 1
|
70
|
-
|
71
|
-
File.basename(gemspecs.first)[/^(.*)\.gemspec$/, 1]
|
72
|
-
end
|
73
|
-
|
74
|
-
def git_push
|
75
|
-
sh "git push --all"
|
76
|
-
sh "git push --tags"
|
77
|
-
end
|
78
|
-
|
79
|
-
def guard_already_tagged
|
80
|
-
sh('git tag').split(/\n/).include?(current_version_tag) and raise("This tag has already been committed to the repo.")
|
81
|
-
end
|
82
|
-
|
83
|
-
def guard_clean
|
84
|
-
clean? or raise("There are files that need to be committed first.")
|
85
|
-
end
|
86
|
-
|
87
|
-
def clean?
|
88
|
-
sh("git ls-files -dm").split("\n").size.zero?
|
89
|
-
end
|
90
|
-
|
91
|
-
def tag_version
|
92
|
-
sh "git tag #{current_version_tag}"
|
93
|
-
yield if block_given?
|
94
|
-
rescue
|
95
|
-
sh "git tag -d #{current_version_tag}"
|
96
|
-
raise
|
97
|
-
end
|
98
|
-
|
99
|
-
def current_version
|
100
|
-
raise("Version file could not be found at #{version_file_path}") unless File.exist?(version_file_path)
|
101
|
-
File.read(version_file_path)[/V(ERSION|ersion)\s*=\s*(["'])(.*?)\2/, 3]
|
102
|
-
end
|
103
|
-
|
104
|
-
def version_file_path
|
105
|
-
File.join(base, 'lib', name, 'version.rb')
|
106
|
-
end
|
107
|
-
|
108
|
-
def current_version_tag
|
109
|
-
"v#{current_version}"
|
110
|
-
end
|
111
|
-
|
112
|
-
def sh(cmd, &block)
|
113
|
-
output, code = sh_with_code(cmd, &block)
|
114
|
-
code == 0 ? output : raise(output)
|
115
|
-
end
|
116
|
-
|
117
|
-
def sh_with_code(cmd, &block)
|
118
|
-
output = ''
|
119
|
-
Dir.chdir(base) {
|
120
|
-
output = `#{cmd}`
|
121
|
-
block.call if block and $? == 0
|
122
|
-
}
|
123
|
-
[output, $?]
|
124
|
-
end
|
125
|
-
end
|
126
|
-
end
|