bundler 0.8.1 → 0.9.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of bundler might be problematic. Click here for more details.
- data/README +7 -0
- data/bin/bundle +3 -0
- data/lib/bundler.rb +72 -37
- data/lib/bundler/cli.rb +64 -68
- data/lib/bundler/definition.rb +78 -0
- data/lib/bundler/dependency.rb +7 -57
- data/lib/bundler/dsl.rb +42 -142
- data/lib/bundler/environment.rb +94 -54
- data/lib/bundler/index.rb +98 -0
- data/lib/bundler/installer.rb +137 -0
- data/lib/bundler/remote_specification.rb +1 -1
- data/lib/bundler/resolver.rb +20 -50
- data/lib/bundler/rubygems.rb +22 -0
- data/lib/bundler/source.rb +185 -295
- data/lib/bundler/specification.rb +22 -0
- data/lib/bundler/templates/Gemfile +4 -0
- data/lib/bundler/templates/environment.erb +3 -153
- data/lib/bundler/ui.rb +51 -0
- data/lib/bundler/vendor/thor.rb +241 -0
- data/lib/bundler/vendor/thor/actions.rb +274 -0
- data/lib/bundler/vendor/thor/actions/create_file.rb +103 -0
- data/lib/bundler/vendor/thor/actions/directory.rb +91 -0
- data/lib/bundler/vendor/thor/actions/empty_directory.rb +134 -0
- data/lib/bundler/vendor/thor/actions/file_manipulation.rb +223 -0
- data/lib/bundler/vendor/thor/actions/inject_into_file.rb +101 -0
- data/lib/bundler/vendor/thor/base.rb +515 -0
- data/lib/bundler/vendor/thor/core_ext/file_binary_read.rb +9 -0
- data/lib/bundler/vendor/thor/core_ext/hash_with_indifferent_access.rb +75 -0
- data/lib/bundler/vendor/thor/core_ext/ordered_hash.rb +100 -0
- data/lib/bundler/vendor/thor/error.rb +27 -0
- data/lib/bundler/vendor/thor/group.rb +267 -0
- data/lib/bundler/vendor/thor/invocation.rb +178 -0
- data/lib/bundler/vendor/thor/parser.rb +4 -0
- data/lib/bundler/vendor/thor/parser/argument.rb +67 -0
- data/lib/bundler/vendor/thor/parser/arguments.rb +145 -0
- data/lib/bundler/vendor/thor/parser/option.rb +132 -0
- data/lib/bundler/vendor/thor/parser/options.rb +142 -0
- data/lib/bundler/vendor/thor/rake_compat.rb +66 -0
- data/lib/bundler/vendor/thor/runner.rb +303 -0
- data/lib/bundler/vendor/thor/shell.rb +78 -0
- data/lib/bundler/vendor/thor/shell/basic.rb +239 -0
- data/lib/bundler/vendor/thor/shell/color.rb +108 -0
- data/lib/bundler/vendor/thor/task.rb +111 -0
- data/lib/bundler/vendor/thor/util.rb +233 -0
- data/lib/bundler/vendor/thor/version.rb +3 -0
- metadata +48 -26
- data/README.markdown +0 -284
- data/Rakefile +0 -81
- data/lib/bundler/bundle.rb +0 -314
- data/lib/bundler/commands/bundle_command.rb +0 -72
- data/lib/bundler/commands/exec_command.rb +0 -36
- data/lib/bundler/finder.rb +0 -51
- data/lib/bundler/gem_bundle.rb +0 -11
- data/lib/bundler/gem_ext.rb +0 -34
- data/lib/bundler/runtime.rb +0 -2
- data/lib/bundler/templates/app_script.erb +0 -3
- data/lib/bundler/templates/environment_picker.erb +0 -4
- data/lib/rubygems_plugin.rb +0 -6
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rubygems/specification'
|
3
|
+
|
4
|
+
module Gem
|
5
|
+
@loaded_stacks = Hash.new { |h,k| h[k] = [] }
|
6
|
+
|
7
|
+
class Specification
|
8
|
+
attr_accessor :source, :location
|
9
|
+
|
10
|
+
def load_paths
|
11
|
+
require_paths.map {|p| File.join(full_gem_path, p) }
|
12
|
+
end
|
13
|
+
|
14
|
+
def groups
|
15
|
+
@groups ||= []
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class Dependency
|
20
|
+
attr_accessor :source, :group
|
21
|
+
end
|
22
|
+
end
|
data/lib/bundler/source.rb
CHANGED
@@ -1,357 +1,247 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
# Represents a source of rubygems. Initially, this is only gem repositories, but
|
5
|
-
# eventually, this will be git, svn, HTTP
|
6
|
-
class Source
|
7
|
-
attr_reader :bundle
|
8
|
-
|
9
|
-
def initialize(bundle, options)
|
10
|
-
@bundle = bundle
|
11
|
-
end
|
1
|
+
require "rubygems/remote_fetcher"
|
2
|
+
require "rubygems/format"
|
3
|
+
require "digest/sha1"
|
12
4
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
5
|
+
module Bundler
|
6
|
+
module Source
|
7
|
+
class Rubygems
|
8
|
+
attr_reader :uri, :options
|
9
|
+
|
10
|
+
def initialize(options = {})
|
11
|
+
@options = options
|
12
|
+
@uri = options[:uri]
|
13
|
+
@uri = URI.parse(@uri) unless @uri.is_a?(URI)
|
14
|
+
raise ArgumentError, "The source must be an absolute URI" unless @uri.absolute?
|
20
15
|
end
|
21
|
-
new_gems
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
class GemSource < Source
|
26
|
-
attr_reader :uri
|
27
|
-
|
28
|
-
def initialize(bundle, options)
|
29
|
-
super
|
30
|
-
@uri = options[:uri]
|
31
|
-
@uri = URI.parse(@uri) unless @uri.is_a?(URI)
|
32
|
-
raise ArgumentError, "The source must be an absolute URI" unless @uri.absolute?
|
33
|
-
end
|
34
|
-
|
35
|
-
def local?
|
36
|
-
false
|
37
|
-
end
|
38
|
-
|
39
|
-
def gems
|
40
|
-
@specs ||= fetch_specs
|
41
|
-
end
|
42
16
|
|
43
|
-
|
44
|
-
|
45
|
-
end
|
46
|
-
|
47
|
-
def to_s
|
48
|
-
@uri.to_s
|
49
|
-
end
|
50
|
-
|
51
|
-
class RubygemsRetardation < StandardError; end
|
52
|
-
|
53
|
-
def download(spec)
|
54
|
-
Bundler.logger.info "Downloading #{spec.full_name}.gem"
|
55
|
-
|
56
|
-
destination = bundle.gem_path
|
57
|
-
|
58
|
-
unless destination.writable?
|
59
|
-
raise RubygemsRetardation, "destination: #{destination} is not writable"
|
17
|
+
def specs
|
18
|
+
@specs ||= fetch_specs
|
60
19
|
end
|
61
20
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
spec.__swap__(new_spec)
|
69
|
-
end
|
21
|
+
def install(spec)
|
22
|
+
Bundler.ui.info "* #{spec.name} (#{spec.version})"
|
23
|
+
if Index.from_installed_gems[spec].any?
|
24
|
+
Bundler.ui.info " * already installed... skipping"
|
25
|
+
return
|
26
|
+
end
|
70
27
|
|
71
|
-
|
28
|
+
destination = Gem.dir
|
72
29
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
30
|
+
Bundler.ui.info " * Downloading..."
|
31
|
+
gem_path = Gem::RemoteFetcher.fetcher.download(spec, uri, destination)
|
32
|
+
Bundler.ui.info " * Installing..."
|
33
|
+
installer = Gem::Installer.new gem_path,
|
34
|
+
:install_dir => Gem.dir,
|
35
|
+
:ignore_dependencies => true
|
77
36
|
|
78
|
-
|
79
|
-
gems = Hash.new { |h,k| h[k] = [] }
|
80
|
-
index.each do |name, version, platform|
|
81
|
-
spec = RemoteSpecification.new(name, version, platform, @uri)
|
82
|
-
spec.source = self
|
83
|
-
gems[spec.name] << spec if Gem::Platform.match(spec.platform)
|
37
|
+
installer.install
|
84
38
|
end
|
85
|
-
gems
|
86
|
-
end
|
87
39
|
|
88
|
-
|
89
|
-
Marshal.load(Gem::RemoteFetcher.fetcher.fetch_path("#{uri}/specs.4.8.gz"))
|
90
|
-
rescue Gem::RemoteFetcher::FetchError => e
|
91
|
-
raise ArgumentError, "#{to_s} is not a valid source: #{e.message}"
|
92
|
-
end
|
40
|
+
private
|
93
41
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
42
|
+
def fetch_specs
|
43
|
+
index = Index.new
|
44
|
+
Bundler.ui.info "Source: Fetching remote index for `#{uri}`... "
|
45
|
+
(main_specs + prerelease_specs).each do |name, version, platform|
|
46
|
+
spec = RemoteSpecification.new(name, version, platform, @uri)
|
47
|
+
spec.source = self
|
48
|
+
index << spec
|
49
|
+
end
|
50
|
+
Bundler.ui.info "done."
|
51
|
+
index.freeze
|
52
|
+
end
|
101
53
|
|
102
|
-
|
54
|
+
def main_specs
|
55
|
+
Marshal.load(Gem::RemoteFetcher.fetcher.fetch_path("#{uri}/specs.4.8.gz"))
|
56
|
+
rescue Gem::RemoteFetcher::FetchError => e
|
57
|
+
raise ArgumentError, "#{to_s} is not a valid source: #{e.message}"
|
58
|
+
end
|
103
59
|
|
104
|
-
|
105
|
-
|
60
|
+
def prerelease_specs
|
61
|
+
Marshal.load(Gem::RemoteFetcher.fetcher.fetch_path("#{uri}/prerelease_specs.4.8.gz"))
|
62
|
+
rescue Gem::RemoteFetcher::FetchError
|
63
|
+
Bundler.logger.warn "Source '#{uri}' does not support prerelease gems"
|
64
|
+
[]
|
65
|
+
end
|
106
66
|
end
|
107
67
|
|
108
|
-
|
109
|
-
|
110
|
-
|
68
|
+
class GemCache
|
69
|
+
def initialize(options)
|
70
|
+
@path = options[:path]
|
71
|
+
end
|
111
72
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
end
|
73
|
+
def specs
|
74
|
+
@specs ||= begin
|
75
|
+
index = Index.new
|
116
76
|
|
117
|
-
|
118
|
-
|
119
|
-
|
77
|
+
Dir["#{@path}/*.gem"].each do |gemfile|
|
78
|
+
spec = Gem::Format.from_file_by_path(gemfile).spec
|
79
|
+
spec.source = self
|
80
|
+
index << spec
|
81
|
+
end
|
120
82
|
|
121
|
-
|
122
|
-
|
123
|
-
|
83
|
+
index.freeze
|
84
|
+
end
|
85
|
+
end
|
124
86
|
|
125
|
-
|
126
|
-
|
127
|
-
end
|
87
|
+
def install(spec)
|
88
|
+
destination = Gem.dir
|
128
89
|
|
129
|
-
|
130
|
-
|
131
|
-
|
90
|
+
installer = Gem::Installer.new "#{@path}/#{spec.full_name}.gem",
|
91
|
+
:install_dir => Gem.dir,
|
92
|
+
:ignore_dependencies => true
|
132
93
|
|
133
|
-
|
134
|
-
|
135
|
-
gemfile = gemfile.dirname.join('..', 'cache', "#{spec.full_name}.gem")
|
136
|
-
bundle.cache(gemfile)
|
94
|
+
installer.install
|
95
|
+
end
|
137
96
|
end
|
138
97
|
|
139
|
-
|
140
|
-
|
141
|
-
end
|
98
|
+
class Path
|
99
|
+
attr_reader :path, :options
|
142
100
|
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
@location = options[:location]
|
149
|
-
end
|
101
|
+
def initialize(options)
|
102
|
+
@options = options
|
103
|
+
@glob = options[:glob] || "{,*/}*.gemspec"
|
104
|
+
@path = options[:path]
|
105
|
+
end
|
150
106
|
|
151
|
-
|
152
|
-
|
153
|
-
|
107
|
+
def default_spec(*args)
|
108
|
+
return @default_spec if args.empty?
|
109
|
+
name, version = *args
|
110
|
+
@default_spec = Specification.new do |s|
|
111
|
+
s.name = name
|
112
|
+
s.source = self
|
113
|
+
s.version = Gem::Version.new(version)
|
114
|
+
s.relative_loaded_from = "#{name}.gemspec"
|
115
|
+
end
|
116
|
+
end
|
154
117
|
|
155
|
-
|
156
|
-
|
157
|
-
|
118
|
+
def local_specs
|
119
|
+
@local_specs ||= begin
|
120
|
+
index = Index.new
|
121
|
+
|
122
|
+
if File.directory?(path)
|
123
|
+
Dir["#{path}/#{@glob}"].each do |file|
|
124
|
+
file = Pathname.new(file)
|
125
|
+
if spec = eval(File.read(file))
|
126
|
+
spec = Specification.from_gemspec(spec)
|
127
|
+
spec.loaded_from = file
|
128
|
+
spec.source = self
|
129
|
+
index << spec
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
index << default_spec if default_spec && index.empty?
|
134
|
+
end
|
158
135
|
|
159
|
-
|
160
|
-
|
161
|
-
|
136
|
+
index.freeze
|
137
|
+
end
|
138
|
+
end
|
162
139
|
|
163
|
-
|
164
|
-
location.to_s
|
165
|
-
end
|
140
|
+
alias specs local_specs
|
166
141
|
|
167
|
-
def download(spec)
|
168
|
-
# raise NotImplementedError
|
169
142
|
end
|
170
143
|
|
171
|
-
|
172
|
-
|
173
|
-
def fetch_specs
|
174
|
-
specs = Hash.new { |h,k| h[k] = [] }
|
144
|
+
class Git < Path
|
145
|
+
attr_reader :uri, :ref
|
175
146
|
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
147
|
+
def initialize(options)
|
148
|
+
@options = options
|
149
|
+
@glob = options[:glob] || "{,*/}*.gemspec"
|
150
|
+
@uri = options[:uri]
|
151
|
+
@ref = options[:ref] || options[:branch] || 'master'
|
180
152
|
end
|
181
153
|
|
182
|
-
|
183
|
-
|
184
|
-
end
|
185
|
-
|
186
|
-
class DirectorySource < Source
|
187
|
-
attr_reader :location, :specs, :required_specs
|
188
|
-
|
189
|
-
def initialize(bundle, options)
|
190
|
-
super
|
191
|
-
if options[:location]
|
192
|
-
@location = Pathname.new(options[:location]).expand_path
|
154
|
+
def options
|
155
|
+
@options.merge(:ref => revision)
|
193
156
|
end
|
194
|
-
@glob = options[:glob] || "**/*.gemspec"
|
195
|
-
@specs = {}
|
196
|
-
@required_specs = []
|
197
|
-
end
|
198
157
|
|
199
|
-
|
200
|
-
|
201
|
-
@specs[path.to_s] = Gem::Specification.new do |s|
|
202
|
-
s.name = name
|
203
|
-
s.version = Gem::Version.new(version)
|
158
|
+
def path
|
159
|
+
Bundler.install_path.join("#{base_name}-#{uri_hash}-#{ref}")
|
204
160
|
end
|
205
|
-
end
|
206
161
|
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
def gems
|
212
|
-
@gems ||= begin
|
213
|
-
# Locate all gemspecs from the directory
|
214
|
-
specs = locate_gemspecs
|
215
|
-
specs = merge_defined_specs(specs)
|
162
|
+
def to_s
|
163
|
+
@uri
|
164
|
+
end
|
216
165
|
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
166
|
+
def specs
|
167
|
+
@specs ||= begin
|
168
|
+
index = Index.new
|
169
|
+
# Start by making sure the git cache is up to date
|
170
|
+
cache
|
171
|
+
# Find all gemspecs in the repo
|
172
|
+
in_cache do
|
173
|
+
out = %x(git ls-tree -r #{revision}).strip
|
174
|
+
lines = out.split("\n").select { |l| l =~ /\.gemspec$/ }
|
175
|
+
# Loop over the lines and extract the relative path and the
|
176
|
+
# git hash
|
177
|
+
lines.each do |line|
|
178
|
+
next unless line =~ %r{^(\d+) (blob|tree) ([a-zf0-9]+)\t(.*)$}
|
179
|
+
hash, file = $3, $4
|
180
|
+
# Read the gemspec
|
181
|
+
if spec = eval(%x(git cat-file blob #{$3}))
|
182
|
+
spec = Specification.from_gemspec(spec)
|
183
|
+
spec.relative_loaded_from = file
|
184
|
+
spec.source = self
|
185
|
+
index << spec
|
186
|
+
end
|
187
|
+
end
|
221
188
|
end
|
222
|
-
end
|
223
189
|
|
224
|
-
|
225
|
-
end
|
226
|
-
end
|
190
|
+
index << default_spec if default_spec && index.empty?
|
227
191
|
|
228
|
-
|
229
|
-
Dir["#{location}/#{@glob}"].inject({}) do |specs, file|
|
230
|
-
file = Pathname.new(file)
|
231
|
-
if spec = eval(File.read(file)) # and validate_gemspec(file.dirname, spec)
|
232
|
-
spec.location = file.dirname.expand_path
|
233
|
-
specs[spec.full_name] = spec
|
192
|
+
index.freeze
|
234
193
|
end
|
235
|
-
specs
|
236
194
|
end
|
237
|
-
end
|
238
195
|
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
# elsif File.expand_path(existing.location) != File.expand_path(spec.location)
|
251
|
-
# raise DirectorySourceError, "The location you specified for #{spec.name}" \
|
252
|
-
# " is '#{spec.location}'. The gemspec was found at '#{existing.location}'."
|
196
|
+
def install(spec)
|
197
|
+
@installed ||= begin
|
198
|
+
FileUtils.mkdir_p(path)
|
199
|
+
Dir.chdir(path) do
|
200
|
+
unless File.exist?(".git")
|
201
|
+
%x(git clone --recursive --no-checkout #{cache_path} #{path})
|
202
|
+
end
|
203
|
+
%x(git fetch --quiet)
|
204
|
+
%x(git reset --hard #{revision})
|
205
|
+
%x(git submodule init)
|
206
|
+
%x(git submodule update)
|
253
207
|
end
|
254
|
-
|
255
|
-
# raise "Your gem definition is not valid: #{spec}"
|
256
|
-
else
|
257
|
-
specs[spec.full_name] = spec
|
208
|
+
true
|
258
209
|
end
|
259
210
|
end
|
260
|
-
specs
|
261
|
-
end
|
262
211
|
|
263
|
-
|
264
|
-
path = Pathname.new(path)
|
265
|
-
msg = "Gemspec for #{spec.name} (#{spec.version}) is invalid:"
|
266
|
-
# Check the require_paths
|
267
|
-
(spec.require_paths || []).each do |require_path|
|
268
|
-
unless path.join(require_path).directory?
|
269
|
-
Bundler.logger.warn "#{msg} Missing require path: '#{require_path}'"
|
270
|
-
return false
|
271
|
-
end
|
272
|
-
end
|
212
|
+
private
|
273
213
|
|
274
|
-
|
275
|
-
|
276
|
-
unless path.join(spec.bindir, exec).file?
|
277
|
-
Bundler.logger.warn "#{msg} Missing executable: '#{File.join(spec.bindir, exec)}'"
|
278
|
-
return false
|
279
|
-
end
|
214
|
+
def base_name
|
215
|
+
File.basename(uri, ".git")
|
280
216
|
end
|
281
217
|
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
def ==(other)
|
286
|
-
# TMP HAX
|
287
|
-
other.is_a?(DirectorySource)
|
288
|
-
end
|
289
|
-
|
290
|
-
def to_s
|
291
|
-
"directory: '#{location}'"
|
292
|
-
end
|
293
|
-
|
294
|
-
def download(spec)
|
295
|
-
# Nothing needed here
|
296
|
-
end
|
297
|
-
end
|
298
|
-
|
299
|
-
class GitSource < DirectorySource
|
300
|
-
attr_reader :ref, :uri, :branch
|
301
|
-
|
302
|
-
def initialize(bundle, options)
|
303
|
-
super
|
304
|
-
@uri = options[:uri]
|
305
|
-
@branch = options[:branch] || 'master'
|
306
|
-
@ref = options[:ref] || "origin/#{@branch}"
|
307
|
-
end
|
308
|
-
|
309
|
-
def local?
|
310
|
-
raise SourceNotCached, "Git repository '#{@uri}' has not been cloned yet" unless location.directory?
|
311
|
-
super
|
312
|
-
end
|
313
|
-
|
314
|
-
def location
|
315
|
-
# TMP HAX to get the *.gemspec reading to work
|
316
|
-
bundle.gem_path.join('dirs', File.basename(@uri, '.git'))
|
317
|
-
end
|
318
|
-
|
319
|
-
def gems
|
320
|
-
update if Bundler.remote?
|
321
|
-
checkout if Bundler.writable?
|
322
|
-
super
|
323
|
-
end
|
324
|
-
|
325
|
-
def download(spec)
|
326
|
-
# Nothing needed here
|
327
|
-
end
|
218
|
+
def uri_hash
|
219
|
+
Digest::SHA1.hexdigest(URI.parse(uri).normalize.to_s.sub(%r{/$}, ''))
|
220
|
+
end
|
328
221
|
|
329
|
-
|
330
|
-
|
331
|
-
|
222
|
+
def cache_path
|
223
|
+
@cache_path ||= Bundler.cache.join("git", "#{base_name}-#{uri_hash}")
|
224
|
+
end
|
332
225
|
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
fetch
|
226
|
+
def cache
|
227
|
+
if cache_path.exist?
|
228
|
+
Bundler.ui.info "Source: Updating `#{uri}`... "
|
229
|
+
in_cache { `git fetch --quiet #{uri} master:master` }
|
337
230
|
else
|
338
|
-
|
231
|
+
Bundler.ui.info "Source: Cloning `#{uri}`... "
|
232
|
+
FileUtils.mkdir_p(cache_path.dirname)
|
233
|
+
`git clone #{uri} #{cache_path} --bare --no-hardlinks`
|
339
234
|
end
|
235
|
+
Bundler.ui.info "Done."
|
340
236
|
end
|
341
237
|
|
342
|
-
def
|
343
|
-
|
344
|
-
Dir.chdir(location) { `git fetch origin` }
|
238
|
+
def revision
|
239
|
+
@revision ||= in_cache { `git rev-parse #{ref}`.strip }
|
345
240
|
end
|
346
241
|
|
347
|
-
def
|
348
|
-
|
349
|
-
FileUtils.mkdir_p(location.dirname)
|
350
|
-
`git clone #{@uri} #{location} --no-hardlinks`
|
351
|
-
end
|
352
|
-
|
353
|
-
def checkout
|
354
|
-
Dir.chdir(location) { `git checkout --quiet #{@ref}` }
|
242
|
+
def in_cache(&blk)
|
243
|
+
Dir.chdir(cache_path, &blk)
|
355
244
|
end
|
245
|
+
end
|
356
246
|
end
|
357
|
-
end
|
247
|
+
end
|