bundler 1.0.22 → 1.1.pre
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/CHANGELOG.md +15 -181
- data/ISSUES.md +11 -26
- data/LICENSE +0 -2
- data/Rakefile +67 -116
- data/UPGRADING.md +4 -4
- data/bin/bundle +10 -10
- data/bundler.gemspec +5 -5
- data/lib/bundler.rb +15 -25
- data/lib/bundler/capistrano.rb +2 -2
- data/lib/bundler/cli.rb +41 -72
- data/lib/bundler/definition.rb +11 -37
- data/lib/bundler/dependency.rb +9 -13
- data/lib/bundler/deployment.rb +3 -8
- data/lib/bundler/dsl.rb +10 -24
- data/lib/bundler/fetcher.rb +101 -0
- data/lib/bundler/gem_helper.rb +6 -11
- data/lib/bundler/index.rb +8 -15
- data/lib/bundler/installer.rb +55 -35
- data/lib/bundler/lazy_specification.rb +7 -10
- data/lib/bundler/remote_specification.rb +6 -8
- data/lib/bundler/resolver.rb +18 -12
- data/lib/bundler/rubygems_ext.rb +3 -20
- data/lib/bundler/runtime.rb +57 -8
- data/lib/bundler/settings.rb +6 -4
- data/lib/bundler/setup.rb +5 -12
- data/lib/bundler/shared_helpers.rb +100 -4
- data/lib/bundler/source.rb +61 -106
- data/lib/bundler/spec_set.rb +8 -9
- data/lib/bundler/templates/newgem/Rakefile.tt +2 -1
- data/lib/bundler/templates/newgem/lib/newgem.rb.tt +0 -2
- data/lib/bundler/templates/newgem/newgem.gemspec.tt +3 -6
- data/lib/bundler/ui.rb +1 -4
- data/lib/bundler/vendor/net/http/faster.rb +27 -0
- data/lib/bundler/vendor/net/http/persistent.rb +464 -0
- data/lib/bundler/vendor/thor.rb +4 -43
- data/lib/bundler/vendor/thor/actions.rb +11 -28
- data/lib/bundler/vendor/thor/actions/create_file.rb +2 -2
- data/lib/bundler/vendor/thor/actions/directory.rb +2 -2
- data/lib/bundler/vendor/thor/actions/empty_directory.rb +0 -0
- data/lib/bundler/vendor/thor/actions/file_manipulation.rb +15 -56
- data/lib/bundler/vendor/thor/actions/inject_into_file.rb +10 -15
- data/lib/bundler/vendor/thor/base.rb +4 -24
- data/lib/bundler/vendor/thor/core_ext/file_binary_read.rb +0 -0
- data/lib/bundler/vendor/thor/core_ext/hash_with_indifferent_access.rb +0 -0
- data/lib/bundler/vendor/thor/core_ext/ordered_hash.rb +0 -0
- data/lib/bundler/vendor/thor/error.rb +0 -0
- data/lib/bundler/vendor/thor/invocation.rb +0 -0
- data/lib/bundler/vendor/thor/parser.rb +0 -0
- data/lib/bundler/vendor/thor/parser/argument.rb +0 -0
- data/lib/bundler/vendor/thor/parser/arguments.rb +2 -2
- data/lib/bundler/vendor/thor/parser/option.rb +1 -1
- data/lib/bundler/vendor/thor/parser/options.rb +16 -17
- data/lib/bundler/vendor/thor/shell.rb +0 -0
- data/lib/bundler/vendor/thor/shell/basic.rb +13 -40
- data/lib/bundler/vendor/thor/shell/color.rb +0 -0
- data/lib/bundler/vendor/thor/task.rb +4 -3
- data/lib/bundler/vendor/thor/util.rb +2 -2
- data/lib/bundler/vendor/thor/version.rb +1 -1
- data/lib/bundler/version.rb +1 -1
- data/lib/bundler/vlad.rb +0 -2
- data/man/bundle-install.ronn +3 -6
- data/man/gemfile.5.ronn +2 -7
- data/spec/cache/gems_spec.rb +0 -11
- data/spec/cache/git_spec.rb +2 -5
- data/spec/install/deploy_spec.rb +8 -8
- data/spec/install/gems/dependency_api_spec.rb +85 -0
- data/spec/install/gems/flex_spec.rb +4 -4
- data/spec/install/gems/groups_spec.rb +3 -17
- data/spec/install/gems/platform_spec.rb +16 -0
- data/spec/install/gems/simple_case_spec.rb +24 -88
- data/spec/install/gems/standalone_spec.rb +162 -0
- data/spec/install/gems/sudo_spec.rb +2 -3
- data/spec/install/gemspec_spec.rb +0 -38
- data/spec/install/git_spec.rb +4 -3
- data/spec/install/invalid_spec.rb +0 -18
- data/spec/install/path_spec.rb +1 -53
- data/spec/lock/git_spec.rb +1 -1
- data/spec/lock/lockfile_spec.rb +16 -72
- data/spec/other/check_spec.rb +6 -6
- data/spec/other/clean_spec.rb +202 -0
- data/spec/other/exec_spec.rb +7 -14
- data/spec/other/ext_spec.rb +0 -21
- data/spec/{bundler → other}/gem_helper_spec.rb +1 -16
- data/spec/other/help_spec.rb +1 -2
- data/spec/other/init_spec.rb +3 -3
- data/spec/other/newgem_spec.rb +1 -23
- data/spec/pack/gems_spec.rb +22 -0
- data/spec/quality_spec.rb +2 -6
- data/spec/runtime/require_spec.rb +10 -10
- data/spec/runtime/setup_spec.rb +12 -54
- data/spec/spec_helper.rb +7 -14
- data/spec/support/artifice/endpoint.rb +50 -0
- data/spec/support/artifice/endpoint_fallback.rb +22 -0
- data/spec/support/artifice/endpoint_marshal_fail.rb +11 -0
- data/spec/support/artifice/endpoint_redirect.rb +11 -0
- data/spec/support/builders.rb +2 -25
- data/spec/support/fakeweb/rack-1.0.0.marshal +2 -0
- data/spec/support/fakeweb/windows.rb +23 -0
- data/spec/support/helpers.rb +12 -5
- data/spec/support/matchers.rb +16 -4
- data/spec/support/path.rb +2 -0
- data/spec/support/rubygems_ext.rb +2 -6
- data/spec/update/gems_spec.rb +2 -3
- data/spec/update/git_spec.rb +2 -2
- metadata +41 -24
- data/.travis.yml +0 -31
- data/lib/bundler/gem_installer.rb +0 -9
- data/lib/bundler/gem_tasks.rb +0 -2
- data/lib/bundler/rubygems_integration.rb +0 -344
- data/lib/bundler/vendor/thor/actions/create_link.rb +0 -57
- data/lib/bundler/vendor/thor/group.rb +0 -273
- data/lib/bundler/vendor/thor/rake_compat.rb +0 -66
- data/lib/bundler/vendor/thor/runner.rb +0 -309
- data/lib/bundler/vendored_thor.rb +0 -7
data/.travis.yml
DELETED
@@ -1,31 +0,0 @@
|
|
1
|
-
before_script:
|
2
|
-
- sudo apt-get install groff -y
|
3
|
-
- rake spec:deps
|
4
|
-
|
5
|
-
script: rake spec:travis
|
6
|
-
|
7
|
-
rvm:
|
8
|
-
- 1.8.7
|
9
|
-
- 1.9.2
|
10
|
-
|
11
|
-
env:
|
12
|
-
- RGV=v1.3.6
|
13
|
-
- RGV=v1.3.7
|
14
|
-
- RGV=v1.4.2
|
15
|
-
- RGV=v1.5.3
|
16
|
-
- RGV=v1.6.2
|
17
|
-
- RGV=v1.7.2
|
18
|
-
- RGV=v1.8.10
|
19
|
-
|
20
|
-
matrix:
|
21
|
-
exclude:
|
22
|
-
- rvm: 1.9.2
|
23
|
-
env: RGV=v1.3.6
|
24
|
-
- rvm: 1.9.2
|
25
|
-
env: RGV=v1.3.7
|
26
|
-
- rvm: 1.9.2
|
27
|
-
env: RGV=v1.4.2
|
28
|
-
|
29
|
-
notifications:
|
30
|
-
email:
|
31
|
-
- travis-ci@andrearko.com
|
data/lib/bundler/gem_tasks.rb
DELETED
@@ -1,344 +0,0 @@
|
|
1
|
-
module Bundler
|
2
|
-
class RubygemsIntegration
|
3
|
-
def initialize
|
4
|
-
# Work around a RubyGems bug
|
5
|
-
configuration
|
6
|
-
end
|
7
|
-
|
8
|
-
def loaded_specs(name)
|
9
|
-
Gem.loaded_specs[name]
|
10
|
-
end
|
11
|
-
|
12
|
-
def mark_loaded(spec)
|
13
|
-
Gem.loaded_specs[spec.name] = spec
|
14
|
-
end
|
15
|
-
|
16
|
-
def path(obj)
|
17
|
-
obj.to_s
|
18
|
-
end
|
19
|
-
|
20
|
-
def platforms
|
21
|
-
Gem.platforms
|
22
|
-
end
|
23
|
-
|
24
|
-
def configuration
|
25
|
-
Gem.configuration
|
26
|
-
end
|
27
|
-
|
28
|
-
def ruby_engine
|
29
|
-
Gem.ruby_engine
|
30
|
-
end
|
31
|
-
|
32
|
-
def read_binary(path)
|
33
|
-
Gem.read_binary(path)
|
34
|
-
end
|
35
|
-
|
36
|
-
def inflate(obj)
|
37
|
-
Gem.inflate(obj)
|
38
|
-
end
|
39
|
-
|
40
|
-
def sources=(val)
|
41
|
-
Gem.sources = val
|
42
|
-
end
|
43
|
-
|
44
|
-
def sources
|
45
|
-
Gem.sources
|
46
|
-
end
|
47
|
-
|
48
|
-
def gem_dir
|
49
|
-
Gem.dir
|
50
|
-
end
|
51
|
-
|
52
|
-
def gem_bindir
|
53
|
-
Gem.bindir
|
54
|
-
end
|
55
|
-
|
56
|
-
def user_home
|
57
|
-
Gem.user_home
|
58
|
-
end
|
59
|
-
|
60
|
-
def gem_path
|
61
|
-
Gem.path
|
62
|
-
end
|
63
|
-
|
64
|
-
def marshal_spec_dir
|
65
|
-
Gem::MARSHAL_SPEC_DIR
|
66
|
-
end
|
67
|
-
|
68
|
-
def clear_paths
|
69
|
-
Gem.clear_paths
|
70
|
-
end
|
71
|
-
|
72
|
-
def bin_path(gem, bin, ver)
|
73
|
-
Gem.bin_path(gem, bin, ver)
|
74
|
-
end
|
75
|
-
|
76
|
-
def preserve_paths
|
77
|
-
# this is a no-op outside of Rubygems 1.8
|
78
|
-
yield
|
79
|
-
end
|
80
|
-
|
81
|
-
def ui=(obj)
|
82
|
-
Gem::DefaultUserInteraction.ui = obj
|
83
|
-
end
|
84
|
-
|
85
|
-
def fetch_specs(all, pre, &blk)
|
86
|
-
Gem::SpecFetcher.new.list(all, pre).each(&blk)
|
87
|
-
end
|
88
|
-
|
89
|
-
def with_build_args(args)
|
90
|
-
old_args = Gem::Command.build_args
|
91
|
-
begin
|
92
|
-
Gem::Command.build_args = args
|
93
|
-
yield
|
94
|
-
ensure
|
95
|
-
Gem::Command.build_args = old_args
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
def spec_from_gem(path)
|
100
|
-
Gem::Format.from_file_by_path(path).spec
|
101
|
-
end
|
102
|
-
|
103
|
-
def download_gem(spec, uri, path)
|
104
|
-
Gem::RemoteFetcher.fetcher.download(spec, uri, path)
|
105
|
-
end
|
106
|
-
|
107
|
-
def reverse_rubygems_kernel_mixin
|
108
|
-
# Disable rubygems' gem activation system
|
109
|
-
::Kernel.class_eval do
|
110
|
-
if private_method_defined?(:gem_original_require)
|
111
|
-
alias rubygems_require require
|
112
|
-
alias require gem_original_require
|
113
|
-
end
|
114
|
-
|
115
|
-
undef gem
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
|
-
def replace_gem(specs)
|
120
|
-
executables = specs.map { |s| s.executables }.flatten
|
121
|
-
|
122
|
-
::Kernel.send(:define_method, :gem) do |dep, *reqs|
|
123
|
-
if executables.include? File.basename(caller.first.split(':').first)
|
124
|
-
return
|
125
|
-
end
|
126
|
-
reqs.pop if reqs.last.is_a?(Hash)
|
127
|
-
|
128
|
-
unless dep.respond_to?(:name) && dep.respond_to?(:requirement)
|
129
|
-
dep = Gem::Dependency.new(dep, reqs)
|
130
|
-
end
|
131
|
-
|
132
|
-
spec = specs.find { |s| s.name == dep.name }
|
133
|
-
|
134
|
-
if spec.nil?
|
135
|
-
|
136
|
-
e = Gem::LoadError.new "#{dep.name} is not part of the bundle. Add it to Gemfile."
|
137
|
-
e.name = dep.name
|
138
|
-
if e.respond_to?(:requirement=)
|
139
|
-
e.requirement = dep.requirement
|
140
|
-
else
|
141
|
-
e.version_requirement = dep.requirement
|
142
|
-
end
|
143
|
-
raise e
|
144
|
-
elsif dep !~ spec
|
145
|
-
e = Gem::LoadError.new "can't activate #{dep}, already activated #{spec.full_name}. " \
|
146
|
-
"Make sure all dependencies are added to Gemfile."
|
147
|
-
e.name = dep.name
|
148
|
-
if e.respond_to?(:requirement=)
|
149
|
-
e.requirement = dep.requirement
|
150
|
-
else
|
151
|
-
e.version_requirement = dep.requirement
|
152
|
-
end
|
153
|
-
raise e
|
154
|
-
end
|
155
|
-
|
156
|
-
true
|
157
|
-
end
|
158
|
-
end
|
159
|
-
|
160
|
-
if defined? ::Deprecate
|
161
|
-
Deprecate = ::Deprecate
|
162
|
-
elsif defined? Gem::Deprecate
|
163
|
-
Deprecate = Gem::Deprecate
|
164
|
-
else
|
165
|
-
class Deprecate
|
166
|
-
def skip_during; yield; end
|
167
|
-
end
|
168
|
-
end
|
169
|
-
|
170
|
-
def stub_source_index137(specs)
|
171
|
-
# Rubygems versions lower than 1.7 use SourceIndex#from_gems_in
|
172
|
-
source_index_class = (class << Gem::SourceIndex ; self ; end)
|
173
|
-
source_index_class.send(:remove_method, :from_gems_in)
|
174
|
-
source_index_class.send(:define_method, :from_gems_in) do |*args|
|
175
|
-
source_index = Gem::SourceIndex.new
|
176
|
-
source_index.spec_dirs = *args
|
177
|
-
source_index.add_specs(*specs)
|
178
|
-
source_index
|
179
|
-
end
|
180
|
-
end
|
181
|
-
|
182
|
-
def stub_source_index170(specs)
|
183
|
-
Gem::SourceIndex.send(:alias_method, :old_initialize, :initialize)
|
184
|
-
Gem::SourceIndex.send(:define_method, :initialize) do |*args|
|
185
|
-
@gems = {}
|
186
|
-
# You're looking at this thinking: Oh! This is how I make those
|
187
|
-
# rubygems deprecations go away!
|
188
|
-
#
|
189
|
-
# You'd be correct BUT using of this method in production code
|
190
|
-
# must be approved by the rubygems team itself!
|
191
|
-
#
|
192
|
-
# This is your warning. If you use this and don't have approval
|
193
|
-
# we can't protect you.
|
194
|
-
#
|
195
|
-
Deprecate.skip_during do
|
196
|
-
self.spec_dirs = *args
|
197
|
-
add_specs(*specs)
|
198
|
-
end
|
199
|
-
end
|
200
|
-
end
|
201
|
-
|
202
|
-
# Used to make bin stubs that are not created by bundler work
|
203
|
-
# under bundler. The new Gem.bin_path only considers gems in
|
204
|
-
# +specs+
|
205
|
-
def replace_bin_path(specs)
|
206
|
-
gem_class = (class << Gem ; self ; end)
|
207
|
-
gem_class.send(:remove_method, :bin_path)
|
208
|
-
gem_class.send(:define_method, :bin_path) do |name, *args|
|
209
|
-
exec_name = args.first
|
210
|
-
|
211
|
-
if exec_name == 'bundle'
|
212
|
-
return ENV['BUNDLE_BIN_PATH']
|
213
|
-
end
|
214
|
-
|
215
|
-
spec = nil
|
216
|
-
|
217
|
-
if exec_name
|
218
|
-
spec = specs.find { |s| s.executables.include?(exec_name) }
|
219
|
-
spec or raise Gem::Exception, "can't find executable #{exec_name}"
|
220
|
-
else
|
221
|
-
spec = specs.find { |s| s.name == name }
|
222
|
-
exec_name = spec.default_executable or raise Gem::Exception, "no default executable for #{spec.full_name}"
|
223
|
-
end
|
224
|
-
|
225
|
-
gem_bin = File.join(spec.full_gem_path, spec.bindir, exec_name)
|
226
|
-
gem_from_path_bin = File.join(File.dirname(spec.loaded_from), spec.bindir, exec_name)
|
227
|
-
File.exist?(gem_bin) ? gem_bin : gem_from_path_bin
|
228
|
-
end
|
229
|
-
end
|
230
|
-
|
231
|
-
# Because Bundler has a static view of what specs are available,
|
232
|
-
# we don't #reflesh, so stub it out.
|
233
|
-
def replace_refresh
|
234
|
-
gem_class = (class << Gem ; self ; end)
|
235
|
-
gem_class.send(:remove_method, :refresh)
|
236
|
-
gem_class.send(:define_method, :refresh) { }
|
237
|
-
end
|
238
|
-
|
239
|
-
# Replace or hook into Rubygems to provide a bundlerized view
|
240
|
-
# of the world.
|
241
|
-
def replace_entrypoints(specs)
|
242
|
-
reverse_rubygems_kernel_mixin
|
243
|
-
|
244
|
-
replace_gem(specs)
|
245
|
-
|
246
|
-
stub_rubygems(specs)
|
247
|
-
|
248
|
-
replace_bin_path(specs)
|
249
|
-
replace_refresh
|
250
|
-
|
251
|
-
Gem.clear_paths
|
252
|
-
end
|
253
|
-
|
254
|
-
# This backports the correct segment generation code from Rubygems 1.4+
|
255
|
-
# by monkeypatching it into the method in Rubygems 1.3.6 and 1.3.7.
|
256
|
-
def backport_segment_generation
|
257
|
-
Gem::Version.send(:define_method, :segments) do
|
258
|
-
@segments ||= @version.scan(/[0-9]+|[a-z]+/i).map do |s|
|
259
|
-
/^\d+$/ =~ s ? s.to_i : s
|
260
|
-
end
|
261
|
-
end
|
262
|
-
end
|
263
|
-
|
264
|
-
# Rubygems 1.4 through 1.6
|
265
|
-
class Legacy < RubygemsIntegration
|
266
|
-
def stub_rubygems(specs)
|
267
|
-
stub_source_index137(specs)
|
268
|
-
end
|
269
|
-
|
270
|
-
def all_specs
|
271
|
-
Gem.source_index.gems.values
|
272
|
-
end
|
273
|
-
|
274
|
-
def find_name(name)
|
275
|
-
Gem.source_index.find_name(name)
|
276
|
-
end
|
277
|
-
end
|
278
|
-
|
279
|
-
# Rubygems versions 1.3.6 and 1.3.7
|
280
|
-
class Ancient < Legacy
|
281
|
-
def initialize
|
282
|
-
super
|
283
|
-
backport_segment_generation
|
284
|
-
end
|
285
|
-
end
|
286
|
-
|
287
|
-
# Rubygems 1.7
|
288
|
-
class Transitional < Legacy
|
289
|
-
def stub_rubygems(specs)
|
290
|
-
stub_source_index170(specs)
|
291
|
-
end
|
292
|
-
end
|
293
|
-
|
294
|
-
# Rubygems 1.8.5
|
295
|
-
class Modern < RubygemsIntegration
|
296
|
-
def stub_rubygems(specs)
|
297
|
-
Gem::Specification.all = specs
|
298
|
-
|
299
|
-
Gem.post_reset {
|
300
|
-
Gem::Specification.all = specs
|
301
|
-
}
|
302
|
-
|
303
|
-
stub_source_index170(specs)
|
304
|
-
end
|
305
|
-
|
306
|
-
def all_specs
|
307
|
-
Gem::Specification.to_a
|
308
|
-
end
|
309
|
-
|
310
|
-
def find_name(name)
|
311
|
-
Gem::Specification.find_all_by_name name
|
312
|
-
end
|
313
|
-
end
|
314
|
-
|
315
|
-
# Rubygems 1.8.0 to 1.8.4
|
316
|
-
class AlmostModern < Modern
|
317
|
-
# Rubygems [>= 1.8.0, < 1.8.5] has a bug that changes Gem.dir whenever
|
318
|
-
# you call Gem::Installer#install with an :install_dir set. We have to
|
319
|
-
# change it back for our sudo mode to work.
|
320
|
-
def preserve_paths
|
321
|
-
old_dir, old_path = gem_dir, gem_path
|
322
|
-
yield
|
323
|
-
Gem.use_paths(old_dir, old_path)
|
324
|
-
end
|
325
|
-
end
|
326
|
-
|
327
|
-
end
|
328
|
-
|
329
|
-
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.8.5')
|
330
|
-
@rubygems = RubygemsIntegration::Modern.new
|
331
|
-
elsif Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.8.0')
|
332
|
-
@rubygems = RubygemsIntegration::AlmostModern.new
|
333
|
-
elsif Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.7.0')
|
334
|
-
@rubygems = RubygemsIntegration::Transitional.new
|
335
|
-
elsif Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.4.0')
|
336
|
-
@rubygems = RubygemsIntegration::Legacy.new
|
337
|
-
else # Rubygems 1.3.6 and 1.3.7
|
338
|
-
@rubygems = RubygemsIntegration::Ancient.new
|
339
|
-
end
|
340
|
-
|
341
|
-
class << self
|
342
|
-
attr_reader :rubygems
|
343
|
-
end
|
344
|
-
end
|
@@ -1,57 +0,0 @@
|
|
1
|
-
require 'thor/actions/create_file'
|
2
|
-
|
3
|
-
class Thor
|
4
|
-
module Actions
|
5
|
-
|
6
|
-
# Create a new file relative to the destination root from the given source.
|
7
|
-
#
|
8
|
-
# ==== Parameters
|
9
|
-
# destination<String>:: the relative path to the destination root.
|
10
|
-
# source<String|NilClass>:: the relative path to the source root.
|
11
|
-
# config<Hash>:: give :verbose => false to not log the status.
|
12
|
-
# :: give :symbolic => false for hard link.
|
13
|
-
#
|
14
|
-
# ==== Examples
|
15
|
-
#
|
16
|
-
# create_link "config/apache.conf", "/etc/apache.conf"
|
17
|
-
#
|
18
|
-
def create_link(destination, *args, &block)
|
19
|
-
config = args.last.is_a?(Hash) ? args.pop : {}
|
20
|
-
source = args.first
|
21
|
-
action CreateLink.new(self, destination, source, config)
|
22
|
-
end
|
23
|
-
alias :add_link :create_link
|
24
|
-
|
25
|
-
# CreateLink is a subset of CreateFile, which instead of taking a block of
|
26
|
-
# data, just takes a source string from the user.
|
27
|
-
#
|
28
|
-
class CreateLink < CreateFile #:nodoc:
|
29
|
-
attr_reader :data
|
30
|
-
|
31
|
-
# Checks if the content of the file at the destination is identical to the rendered result.
|
32
|
-
#
|
33
|
-
# ==== Returns
|
34
|
-
# Boolean:: true if it is identical, false otherwise.
|
35
|
-
#
|
36
|
-
def identical?
|
37
|
-
exists? && File.identical?(render, destination)
|
38
|
-
end
|
39
|
-
|
40
|
-
def invoke!
|
41
|
-
invoke_with_conflict_check do
|
42
|
-
FileUtils.mkdir_p(File.dirname(destination))
|
43
|
-
# Create a symlink by default
|
44
|
-
config[:symbolic] ||= true
|
45
|
-
File.unlink(destination) if exists?
|
46
|
-
if config[:symbolic]
|
47
|
-
File.symlink(render, destination)
|
48
|
-
else
|
49
|
-
File.link(render, destination)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
given_destination
|
53
|
-
end
|
54
|
-
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
@@ -1,273 +0,0 @@
|
|
1
|
-
require 'thor/base'
|
2
|
-
|
3
|
-
# Thor has a special class called Thor::Group. The main difference to Thor class
|
4
|
-
# is that it invokes all tasks at once. It also include some methods that allows
|
5
|
-
# invocations to be done at the class method, which are not available to Thor
|
6
|
-
# tasks.
|
7
|
-
class Thor::Group
|
8
|
-
class << self
|
9
|
-
# The description for this Thor::Group. If none is provided, but a source root
|
10
|
-
# exists, tries to find the USAGE one folder above it, otherwise searches
|
11
|
-
# in the superclass.
|
12
|
-
#
|
13
|
-
# ==== Parameters
|
14
|
-
# description<String>:: The description for this Thor::Group.
|
15
|
-
#
|
16
|
-
def desc(description=nil)
|
17
|
-
case description
|
18
|
-
when nil
|
19
|
-
@desc ||= from_superclass(:desc, nil)
|
20
|
-
else
|
21
|
-
@desc = description
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
# Prints help information.
|
26
|
-
#
|
27
|
-
# ==== Options
|
28
|
-
# short:: When true, shows only usage.
|
29
|
-
#
|
30
|
-
def help(shell)
|
31
|
-
shell.say "Usage:"
|
32
|
-
shell.say " #{banner}\n"
|
33
|
-
shell.say
|
34
|
-
class_options_help(shell)
|
35
|
-
shell.say self.desc if self.desc
|
36
|
-
end
|
37
|
-
|
38
|
-
# Stores invocations for this class merging with superclass values.
|
39
|
-
#
|
40
|
-
def invocations #:nodoc:
|
41
|
-
@invocations ||= from_superclass(:invocations, {})
|
42
|
-
end
|
43
|
-
|
44
|
-
# Stores invocation blocks used on invoke_from_option.
|
45
|
-
#
|
46
|
-
def invocation_blocks #:nodoc:
|
47
|
-
@invocation_blocks ||= from_superclass(:invocation_blocks, {})
|
48
|
-
end
|
49
|
-
|
50
|
-
# Invoke the given namespace or class given. It adds an instance
|
51
|
-
# method that will invoke the klass and task. You can give a block to
|
52
|
-
# configure how it will be invoked.
|
53
|
-
#
|
54
|
-
# The namespace/class given will have its options showed on the help
|
55
|
-
# usage. Check invoke_from_option for more information.
|
56
|
-
#
|
57
|
-
def invoke(*names, &block)
|
58
|
-
options = names.last.is_a?(Hash) ? names.pop : {}
|
59
|
-
verbose = options.fetch(:verbose, true)
|
60
|
-
|
61
|
-
names.each do |name|
|
62
|
-
invocations[name] = false
|
63
|
-
invocation_blocks[name] = block if block_given?
|
64
|
-
|
65
|
-
class_eval <<-METHOD, __FILE__, __LINE__
|
66
|
-
def _invoke_#{name.to_s.gsub(/\W/, '_')}
|
67
|
-
klass, task = self.class.prepare_for_invocation(nil, #{name.inspect})
|
68
|
-
|
69
|
-
if klass
|
70
|
-
say_status :invoke, #{name.inspect}, #{verbose.inspect}
|
71
|
-
block = self.class.invocation_blocks[#{name.inspect}]
|
72
|
-
_invoke_for_class_method klass, task, &block
|
73
|
-
else
|
74
|
-
say_status :error, %(#{name.inspect} [not found]), :red
|
75
|
-
end
|
76
|
-
end
|
77
|
-
METHOD
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
# Invoke a thor class based on the value supplied by the user to the
|
82
|
-
# given option named "name". A class option must be created before this
|
83
|
-
# method is invoked for each name given.
|
84
|
-
#
|
85
|
-
# ==== Examples
|
86
|
-
#
|
87
|
-
# class GemGenerator < Thor::Group
|
88
|
-
# class_option :test_framework, :type => :string
|
89
|
-
# invoke_from_option :test_framework
|
90
|
-
# end
|
91
|
-
#
|
92
|
-
# ==== Boolean options
|
93
|
-
#
|
94
|
-
# In some cases, you want to invoke a thor class if some option is true or
|
95
|
-
# false. This is automatically handled by invoke_from_option. Then the
|
96
|
-
# option name is used to invoke the generator.
|
97
|
-
#
|
98
|
-
# ==== Preparing for invocation
|
99
|
-
#
|
100
|
-
# In some cases you want to customize how a specified hook is going to be
|
101
|
-
# invoked. You can do that by overwriting the class method
|
102
|
-
# prepare_for_invocation. The class method must necessarily return a klass
|
103
|
-
# and an optional task.
|
104
|
-
#
|
105
|
-
# ==== Custom invocations
|
106
|
-
#
|
107
|
-
# You can also supply a block to customize how the option is giong to be
|
108
|
-
# invoked. The block receives two parameters, an instance of the current
|
109
|
-
# class and the klass to be invoked.
|
110
|
-
#
|
111
|
-
def invoke_from_option(*names, &block)
|
112
|
-
options = names.last.is_a?(Hash) ? names.pop : {}
|
113
|
-
verbose = options.fetch(:verbose, :white)
|
114
|
-
|
115
|
-
names.each do |name|
|
116
|
-
unless class_options.key?(name)
|
117
|
-
raise ArgumentError, "You have to define the option #{name.inspect} " <<
|
118
|
-
"before setting invoke_from_option."
|
119
|
-
end
|
120
|
-
|
121
|
-
invocations[name] = true
|
122
|
-
invocation_blocks[name] = block if block_given?
|
123
|
-
|
124
|
-
class_eval <<-METHOD, __FILE__, __LINE__
|
125
|
-
def _invoke_from_option_#{name.to_s.gsub(/\W/, '_')}
|
126
|
-
return unless options[#{name.inspect}]
|
127
|
-
|
128
|
-
value = options[#{name.inspect}]
|
129
|
-
value = #{name.inspect} if TrueClass === value
|
130
|
-
klass, task = self.class.prepare_for_invocation(#{name.inspect}, value)
|
131
|
-
|
132
|
-
if klass
|
133
|
-
say_status :invoke, value, #{verbose.inspect}
|
134
|
-
block = self.class.invocation_blocks[#{name.inspect}]
|
135
|
-
_invoke_for_class_method klass, task, &block
|
136
|
-
else
|
137
|
-
say_status :error, %(\#{value} [not found]), :red
|
138
|
-
end
|
139
|
-
end
|
140
|
-
METHOD
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
# Remove a previously added invocation.
|
145
|
-
#
|
146
|
-
# ==== Examples
|
147
|
-
#
|
148
|
-
# remove_invocation :test_framework
|
149
|
-
#
|
150
|
-
def remove_invocation(*names)
|
151
|
-
names.each do |name|
|
152
|
-
remove_task(name)
|
153
|
-
remove_class_option(name)
|
154
|
-
invocations.delete(name)
|
155
|
-
invocation_blocks.delete(name)
|
156
|
-
end
|
157
|
-
end
|
158
|
-
|
159
|
-
# Overwrite class options help to allow invoked generators options to be
|
160
|
-
# shown recursively when invoking a generator.
|
161
|
-
#
|
162
|
-
def class_options_help(shell, groups={}) #:nodoc:
|
163
|
-
get_options_from_invocations(groups, class_options) do |klass|
|
164
|
-
klass.send(:get_options_from_invocations, groups, class_options)
|
165
|
-
end
|
166
|
-
super(shell, groups)
|
167
|
-
end
|
168
|
-
|
169
|
-
# Get invocations array and merge options from invocations. Those
|
170
|
-
# options are added to group_options hash. Options that already exists
|
171
|
-
# in base_options are not added twice.
|
172
|
-
#
|
173
|
-
def get_options_from_invocations(group_options, base_options) #:nodoc:
|
174
|
-
invocations.each do |name, from_option|
|
175
|
-
value = if from_option
|
176
|
-
option = class_options[name]
|
177
|
-
option.type == :boolean ? name : option.default
|
178
|
-
else
|
179
|
-
name
|
180
|
-
end
|
181
|
-
next unless value
|
182
|
-
|
183
|
-
klass, task = prepare_for_invocation(name, value)
|
184
|
-
next unless klass && klass.respond_to?(:class_options)
|
185
|
-
|
186
|
-
value = value.to_s
|
187
|
-
human_name = value.respond_to?(:classify) ? value.classify : value
|
188
|
-
|
189
|
-
group_options[human_name] ||= []
|
190
|
-
group_options[human_name] += klass.class_options.values.select do |option|
|
191
|
-
base_options[option.name.to_sym].nil? && option.group.nil? &&
|
192
|
-
!group_options.values.flatten.any? { |i| i.name == option.name }
|
193
|
-
end
|
194
|
-
|
195
|
-
yield klass if block_given?
|
196
|
-
end
|
197
|
-
end
|
198
|
-
|
199
|
-
# Returns tasks ready to be printed.
|
200
|
-
def printable_tasks(*)
|
201
|
-
item = []
|
202
|
-
item << banner
|
203
|
-
item << (desc ? "# #{desc.gsub(/\s+/m,' ')}" : "")
|
204
|
-
[item]
|
205
|
-
end
|
206
|
-
|
207
|
-
def handle_argument_error(task, error) #:nodoc:
|
208
|
-
raise error, "#{task.name.inspect} was called incorrectly. Are you sure it has arity equals to 0?"
|
209
|
-
end
|
210
|
-
|
211
|
-
protected
|
212
|
-
|
213
|
-
# The method responsible for dispatching given the args.
|
214
|
-
def dispatch(task, given_args, given_opts, config) #:nodoc:
|
215
|
-
if Thor::HELP_MAPPINGS.include?(given_args.first)
|
216
|
-
help(config[:shell])
|
217
|
-
return
|
218
|
-
end
|
219
|
-
|
220
|
-
args, opts = Thor::Options.split(given_args)
|
221
|
-
opts = given_opts || opts
|
222
|
-
|
223
|
-
if task
|
224
|
-
new(args, opts, config).invoke_task(all_tasks[task])
|
225
|
-
else
|
226
|
-
new(args, opts, config).invoke_all
|
227
|
-
end
|
228
|
-
end
|
229
|
-
|
230
|
-
# The banner for this class. You can customize it if you are invoking the
|
231
|
-
# thor class by another ways which is not the Thor::Runner.
|
232
|
-
def banner
|
233
|
-
"#{basename} #{self_task.formatted_usage(self, false)}"
|
234
|
-
end
|
235
|
-
|
236
|
-
# Represents the whole class as a task.
|
237
|
-
def self_task #:nodoc:
|
238
|
-
Thor::DynamicTask.new(self.namespace, class_options)
|
239
|
-
end
|
240
|
-
|
241
|
-
def baseclass #:nodoc:
|
242
|
-
Thor::Group
|
243
|
-
end
|
244
|
-
|
245
|
-
def create_task(meth) #:nodoc:
|
246
|
-
tasks[meth.to_s] = Thor::Task.new(meth, nil, nil, nil, nil)
|
247
|
-
true
|
248
|
-
end
|
249
|
-
end
|
250
|
-
|
251
|
-
include Thor::Base
|
252
|
-
|
253
|
-
protected
|
254
|
-
|
255
|
-
# Shortcut to invoke with padding and block handling. Use internally by
|
256
|
-
# invoke and invoke_from_option class methods.
|
257
|
-
def _invoke_for_class_method(klass, task=nil, *args, &block) #:nodoc:
|
258
|
-
with_padding do
|
259
|
-
if block
|
260
|
-
case block.arity
|
261
|
-
when 3
|
262
|
-
block.call(self, klass, task)
|
263
|
-
when 2
|
264
|
-
block.call(self, klass)
|
265
|
-
when 1
|
266
|
-
instance_exec(klass, &block)
|
267
|
-
end
|
268
|
-
else
|
269
|
-
invoke klass, task, *args
|
270
|
-
end
|
271
|
-
end
|
272
|
-
end
|
273
|
-
end
|