bundler 1.5.1 → 1.5.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.
Potentially problematic release.
This version of bundler might be problematic. Click here for more details.
- data/CHANGELOG.md +26 -2
- data/bin/bundle +1 -3
- data/bundler.gemspec +1 -1
- data/lib/bundler/cli.rb +2 -4
- data/lib/bundler/fetcher.rb +13 -12
- data/lib/bundler/installer.rb +9 -36
- data/lib/bundler/parallel_workers/unix_worker.rb +12 -4
- data/lib/bundler/parallel_workers/worker.rb +1 -0
- data/lib/bundler/rubygems_ext.rb +1 -1
- data/lib/bundler/rubygems_integration.rb +15 -8
- data/lib/bundler/templates/newgem/newgem.gemspec.tt +1 -1
- data/lib/bundler/vendor/thor.rb +63 -56
- data/lib/bundler/vendor/thor/actions.rb +52 -51
- data/lib/bundler/vendor/thor/actions/create_file.rb +35 -37
- data/lib/bundler/vendor/thor/actions/create_link.rb +1 -2
- data/lib/bundler/vendor/thor/actions/directory.rb +36 -37
- data/lib/bundler/vendor/thor/actions/empty_directory.rb +67 -69
- data/lib/bundler/vendor/thor/actions/file_manipulation.rb +11 -12
- data/lib/bundler/vendor/thor/actions/inject_into_file.rb +41 -43
- data/lib/bundler/vendor/thor/base.rb +180 -178
- data/lib/bundler/vendor/thor/command.rb +22 -25
- data/lib/bundler/vendor/thor/core_ext/hash_with_indifferent_access.rb +21 -24
- data/lib/bundler/vendor/thor/core_ext/io_binary_read.rb +1 -3
- data/lib/bundler/vendor/thor/core_ext/ordered_hash.rb +8 -10
- data/lib/bundler/vendor/thor/error.rb +2 -2
- data/lib/bundler/vendor/thor/group.rb +59 -60
- data/lib/bundler/vendor/thor/invocation.rb +39 -38
- data/lib/bundler/vendor/thor/line_editor.rb +17 -0
- data/lib/bundler/vendor/thor/line_editor/basic.rb +35 -0
- data/lib/bundler/vendor/thor/line_editor/readline.rb +88 -0
- data/lib/bundler/vendor/thor/parser/argument.rb +29 -30
- data/lib/bundler/vendor/thor/parser/arguments.rb +102 -98
- data/lib/bundler/vendor/thor/parser/option.rb +25 -25
- data/lib/bundler/vendor/thor/parser/options.rb +85 -85
- data/lib/bundler/vendor/thor/rake_compat.rb +6 -7
- data/lib/bundler/vendor/thor/runner.rb +154 -154
- data/lib/bundler/vendor/thor/shell.rb +23 -30
- data/lib/bundler/vendor/thor/shell/basic.rb +66 -57
- data/lib/bundler/vendor/thor/shell/color.rb +44 -43
- data/lib/bundler/vendor/thor/shell/html.rb +43 -44
- data/lib/bundler/vendor/thor/util.rb +37 -40
- data/lib/bundler/vendor/thor/version.rb +1 -1
- data/lib/bundler/version.rb +1 -1
- data/man/bundle-install.ronn +1 -1
- data/man/gemfile.5.ronn +1 -2
- data/spec/commands/binstubs_spec.rb +13 -0
- data/spec/install/gemfile/git_spec.rb +2 -2
- data/spec/install/gems/dependency_api_spec.rb +34 -0
- data/spec/install/gems/packed_spec.rb +2 -4
- data/spec/quality_spec.rb +2 -2
- data/spec/realworld/parallel_spec.rb +69 -0
- data/spec/runtime/setup_spec.rb +3 -2
- data/spec/spec_helper.rb +1 -0
- data/spec/support/artifice/endpoint_host_redirect.rb +15 -0
- data/spec/support/permissions.rb +11 -0
- metadata +11 -6
- data/spec/realworld/parallel_install_spec.rb +0 -23
- data/spec/realworld/parallel_update_spec.rb +0 -31
@@ -26,9 +26,9 @@ class Thor
|
|
26
26
|
end
|
27
27
|
|
28
28
|
# Stores and return the source root for this class
|
29
|
-
def source_root(path=nil)
|
29
|
+
def source_root(path = nil)
|
30
30
|
@_source_root = path if path
|
31
|
-
@_source_root
|
31
|
+
@_source_root ||= nil
|
32
32
|
end
|
33
33
|
|
34
34
|
# Returns the source paths in the following order:
|
@@ -39,8 +39,8 @@ class Thor
|
|
39
39
|
#
|
40
40
|
def source_paths_for_search
|
41
41
|
paths = []
|
42
|
-
paths +=
|
43
|
-
paths <<
|
42
|
+
paths += source_paths
|
43
|
+
paths << source_root if source_root
|
44
44
|
paths += from_superclass(:source_paths, [])
|
45
45
|
paths
|
46
46
|
end
|
@@ -48,17 +48,17 @@ class Thor
|
|
48
48
|
# Add runtime options that help actions execution.
|
49
49
|
#
|
50
50
|
def add_runtime_options!
|
51
|
-
class_option :force, :type => :boolean, :aliases =>
|
52
|
-
:desc =>
|
51
|
+
class_option :force, :type => :boolean, :aliases => '-f', :group => :runtime,
|
52
|
+
:desc => 'Overwrite files that already exist'
|
53
53
|
|
54
|
-
class_option :pretend, :type => :boolean, :aliases =>
|
55
|
-
:desc =>
|
54
|
+
class_option :pretend, :type => :boolean, :aliases => '-p', :group => :runtime,
|
55
|
+
:desc => 'Run but do not make any changes'
|
56
56
|
|
57
|
-
class_option :quiet, :type => :boolean, :aliases =>
|
58
|
-
:desc =>
|
57
|
+
class_option :quiet, :type => :boolean, :aliases => '-q', :group => :runtime,
|
58
|
+
:desc => 'Suppress status output'
|
59
59
|
|
60
|
-
class_option :skip, :type => :boolean, :aliases =>
|
61
|
-
:desc =>
|
60
|
+
class_option :skip, :type => :boolean, :aliases => '-s', :group => :runtime,
|
61
|
+
:desc => 'Skip files that already exist'
|
62
62
|
end
|
63
63
|
end
|
64
64
|
|
@@ -71,17 +71,16 @@ class Thor
|
|
71
71
|
#
|
72
72
|
# destination_root<String>:: The root directory needed for some actions.
|
73
73
|
#
|
74
|
-
def initialize(args=[], options={}, config={})
|
74
|
+
def initialize(args = [], options = {}, config = {})
|
75
75
|
self.behavior = case config[:behavior].to_s
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
76
|
+
when 'force', 'skip'
|
77
|
+
_cleanup_options_and_set(options, config[:behavior])
|
78
|
+
:invoke
|
79
|
+
when 'revoke'
|
80
|
+
:revoke
|
81
|
+
else
|
82
|
+
:invoke
|
83
|
+
end
|
85
84
|
super
|
86
85
|
self.destination_root = config[:destination_root]
|
87
86
|
end
|
@@ -113,7 +112,7 @@ class Thor
|
|
113
112
|
# Returns the given path relative to the absolute root (ie, root where
|
114
113
|
# the script started).
|
115
114
|
#
|
116
|
-
def relative_to_original_destination_root(path, remove_dot=true)
|
115
|
+
def relative_to_original_destination_root(path, remove_dot = true)
|
117
116
|
path = path.dup
|
118
117
|
if path.gsub!(@destination_stack[0], '.')
|
119
118
|
remove_dot ? (path[2..-1] || '') : path
|
@@ -130,12 +129,15 @@ class Thor
|
|
130
129
|
|
131
130
|
# Receives a file or directory and search for it in the source paths.
|
132
131
|
#
|
133
|
-
def find_in_source_paths(file)
|
132
|
+
def find_in_source_paths(file) # rubocop:disable MethodLength
|
133
|
+
possible_files = [file, file + TEMPLATE_EXTNAME]
|
134
134
|
relative_root = relative_to_original_destination_root(destination_root, false)
|
135
135
|
|
136
136
|
source_paths.each do |source|
|
137
|
-
|
138
|
-
|
137
|
+
possible_files.each do |f|
|
138
|
+
source_file = File.expand_path(f, File.join(source, relative_root))
|
139
|
+
return source_file if File.exist?(source_file)
|
140
|
+
end
|
139
141
|
end
|
140
142
|
|
141
143
|
message = "Could not find #{file.inspect} in any of your source paths. "
|
@@ -145,12 +147,12 @@ class Thor
|
|
145
147
|
end
|
146
148
|
|
147
149
|
if source_paths.empty?
|
148
|
-
message <<
|
150
|
+
message << 'Currently you have no source paths.'
|
149
151
|
else
|
150
152
|
message << "Your current source paths are: \n#{source_paths.join("\n")}"
|
151
153
|
end
|
152
154
|
|
153
|
-
|
155
|
+
fail Error, message
|
154
156
|
end
|
155
157
|
|
156
158
|
# Do something in the root or on a provided subfolder. If a relative path
|
@@ -162,7 +164,7 @@ class Thor
|
|
162
164
|
# dir<String>:: the directory to move to.
|
163
165
|
# config<Hash>:: give :verbose => true to log and use padding.
|
164
166
|
#
|
165
|
-
def inside(dir='', config={}, &block)
|
167
|
+
def inside(dir = '', config = {}, &block)
|
166
168
|
verbose = config.fetch(:verbose, false)
|
167
169
|
pretend = options[:pretend]
|
168
170
|
|
@@ -204,18 +206,18 @@ class Thor
|
|
204
206
|
#
|
205
207
|
# apply "recipes/jquery.rb"
|
206
208
|
#
|
207
|
-
def apply(path, config={})
|
209
|
+
def apply(path, config = {})
|
208
210
|
verbose = config.fetch(:verbose, true)
|
209
|
-
is_uri = path =~
|
211
|
+
is_uri = path =~ %r{^https?\://}
|
210
212
|
path = find_in_source_paths(path) unless is_uri
|
211
213
|
|
212
214
|
say_status :apply, path, verbose
|
213
215
|
shell.padding += 1 if verbose
|
214
216
|
|
215
217
|
if is_uri
|
216
|
-
contents = open(path,
|
218
|
+
contents = open(path, 'Accept' => 'application/x-thor-template') { |io| io.read }
|
217
219
|
else
|
218
|
-
contents = open(path) {|io| io.read }
|
220
|
+
contents = open(path) { |io| io.read }
|
219
221
|
end
|
220
222
|
|
221
223
|
instance_eval(contents, path)
|
@@ -235,7 +237,7 @@ class Thor
|
|
235
237
|
# run('ln -s ~/edge rails')
|
236
238
|
# end
|
237
239
|
#
|
238
|
-
def run(command, config={})
|
240
|
+
def run(command, config = {})
|
239
241
|
return unless behavior == :invoke
|
240
242
|
|
241
243
|
destination = relative_to_original_destination_root(destination_root, false)
|
@@ -259,7 +261,7 @@ class Thor
|
|
259
261
|
# command<String>:: the command to be executed.
|
260
262
|
# config<Hash>:: give :verbose => false to not log the status.
|
261
263
|
#
|
262
|
-
def run_ruby_script(command, config={})
|
264
|
+
def run_ruby_script(command, config = {})
|
263
265
|
return unless behavior == :invoke
|
264
266
|
run command, config.merge(:with => Thor::Util.ruby_command)
|
265
267
|
end
|
@@ -295,24 +297,23 @@ class Thor
|
|
295
297
|
run command, :with => :thor, :verbose => verbose, :pretend => pretend, :capture => capture
|
296
298
|
end
|
297
299
|
|
298
|
-
|
300
|
+
protected
|
299
301
|
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
302
|
+
# Allow current root to be shared between invocations.
|
303
|
+
#
|
304
|
+
def _shared_configuration #:nodoc:
|
305
|
+
super.merge!(:destination_root => destination_root)
|
306
|
+
end
|
305
307
|
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
end
|
308
|
+
def _cleanup_options_and_set(options, key) #:nodoc:
|
309
|
+
case options
|
310
|
+
when Array
|
311
|
+
%w(--force -f --skip -s).each { |i| options.delete(i) }
|
312
|
+
options << "--#{key}"
|
313
|
+
when Hash
|
314
|
+
[:force, :skip, 'force', 'skip'].each { |i| options.delete(i) }
|
315
|
+
options.merge!(key => true)
|
315
316
|
end
|
316
|
-
|
317
|
+
end
|
317
318
|
end
|
318
319
|
end
|
@@ -2,7 +2,6 @@ require 'thor/actions/empty_directory'
|
|
2
2
|
|
3
3
|
class Thor
|
4
4
|
module Actions
|
5
|
-
|
6
5
|
# Create a new file relative to the destination root with the given data,
|
7
6
|
# which is the return value of a block or a data string.
|
8
7
|
#
|
@@ -25,7 +24,7 @@ class Thor
|
|
25
24
|
data = args.first
|
26
25
|
action CreateFile.new(self, destination, block || data.to_s, config)
|
27
26
|
end
|
28
|
-
|
27
|
+
alias_method :add_file, :create_file
|
29
28
|
|
30
29
|
# CreateFile is a subset of Template, which instead of rendering a file with
|
31
30
|
# ERB, it gets the content from the user.
|
@@ -33,7 +32,7 @@ class Thor
|
|
33
32
|
class CreateFile < EmptyDirectory #:nodoc:
|
34
33
|
attr_reader :data
|
35
34
|
|
36
|
-
def initialize(base, destination, data, config={})
|
35
|
+
def initialize(base, destination, data, config = {})
|
37
36
|
@data = data
|
38
37
|
super(base, destination, config)
|
39
38
|
end
|
@@ -51,10 +50,10 @@ class Thor
|
|
51
50
|
#
|
52
51
|
def render
|
53
52
|
@render ||= if data.is_a?(Proc)
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
53
|
+
data.call
|
54
|
+
else
|
55
|
+
data
|
56
|
+
end
|
58
57
|
end
|
59
58
|
|
60
59
|
def invoke!
|
@@ -65,41 +64,40 @@ class Thor
|
|
65
64
|
given_destination
|
66
65
|
end
|
67
66
|
|
68
|
-
|
67
|
+
protected
|
69
68
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
# If force is true, run the action, otherwise check if it's not being
|
82
|
-
# skipped. If both are false, show the file_collision menu, if the menu
|
83
|
-
# returns true, force it, otherwise skip.
|
84
|
-
#
|
85
|
-
def force_or_skip_or_conflict(force, skip, &block)
|
86
|
-
if force
|
87
|
-
say_status :force, :yellow
|
88
|
-
block.call unless pretend?
|
89
|
-
elsif skip
|
90
|
-
say_status :skip, :yellow
|
91
|
-
else
|
92
|
-
say_status :conflict, :red
|
93
|
-
force_or_skip_or_conflict(force_on_collision?, true, &block)
|
94
|
-
end
|
69
|
+
# Now on conflict we check if the file is identical or not.
|
70
|
+
#
|
71
|
+
def on_conflict_behavior(&block)
|
72
|
+
if identical?
|
73
|
+
say_status :identical, :blue
|
74
|
+
else
|
75
|
+
options = base.options.merge(config)
|
76
|
+
force_or_skip_or_conflict(options[:force], options[:skip], &block)
|
95
77
|
end
|
78
|
+
end
|
96
79
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
80
|
+
# If force is true, run the action, otherwise check if it's not being
|
81
|
+
# skipped. If both are false, show the file_collision menu, if the menu
|
82
|
+
# returns true, force it, otherwise skip.
|
83
|
+
#
|
84
|
+
def force_or_skip_or_conflict(force, skip, &block)
|
85
|
+
if force
|
86
|
+
say_status :force, :yellow
|
87
|
+
block.call unless pretend?
|
88
|
+
elsif skip
|
89
|
+
say_status :skip, :yellow
|
90
|
+
else
|
91
|
+
say_status :conflict, :red
|
92
|
+
force_or_skip_or_conflict(force_on_collision?, true, &block)
|
101
93
|
end
|
94
|
+
end
|
102
95
|
|
96
|
+
# Shows the file collision menu to the user and gets the result.
|
97
|
+
#
|
98
|
+
def force_on_collision?
|
99
|
+
base.shell.file_collision(destination) { render }
|
100
|
+
end
|
103
101
|
end
|
104
102
|
end
|
105
103
|
end
|
@@ -2,7 +2,6 @@ require 'thor/actions/create_file'
|
|
2
2
|
|
3
3
|
class Thor
|
4
4
|
module Actions
|
5
|
-
|
6
5
|
# Create a new file relative to the destination root from the given source.
|
7
6
|
#
|
8
7
|
# ==== Parameters
|
@@ -20,7 +19,7 @@ class Thor
|
|
20
19
|
source = args.first
|
21
20
|
action CreateLink.new(self, destination, source, config)
|
22
21
|
end
|
23
|
-
|
22
|
+
alias_method :add_link, :create_link
|
24
23
|
|
25
24
|
# CreateLink is a subset of CreateFile, which instead of taking a block of
|
26
25
|
# data, just takes a source string from the user.
|
@@ -55,10 +55,10 @@ class Thor
|
|
55
55
|
class Directory < EmptyDirectory #:nodoc:
|
56
56
|
attr_reader :source
|
57
57
|
|
58
|
-
def initialize(base, source, destination=nil, config={}, &block)
|
58
|
+
def initialize(base, source, destination = nil, config = {}, &block)
|
59
59
|
@source = File.expand_path(base.find_in_source_paths(source.to_s))
|
60
60
|
@block = block
|
61
|
-
super(base, destination, {
|
61
|
+
super(base, destination, {:recursive => true}.merge(config))
|
62
62
|
end
|
63
63
|
|
64
64
|
def invoke!
|
@@ -70,50 +70,49 @@ class Thor
|
|
70
70
|
execute!
|
71
71
|
end
|
72
72
|
|
73
|
-
|
73
|
+
protected
|
74
74
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
75
|
+
def execute! # rubocop:disable MethodLength
|
76
|
+
lookup = Util.escape_globs(source)
|
77
|
+
lookup = config[:recursive] ? File.join(lookup, '**') : lookup
|
78
|
+
lookup = file_level_lookup(lookup)
|
79
79
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
80
|
+
files(lookup).sort.each do |file_source|
|
81
|
+
next if File.directory?(file_source)
|
82
|
+
next if config[:exclude_pattern] && file_source.match(config[:exclude_pattern])
|
83
|
+
file_destination = File.join(given_destination, file_source.gsub(source, '.'))
|
84
|
+
file_destination.gsub!('/./', '/')
|
85
85
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
end
|
86
|
+
case file_source
|
87
|
+
when /\.empty_directory$/
|
88
|
+
dirname = File.dirname(file_destination).gsub(/\/\.$/, '')
|
89
|
+
next if dirname == given_destination
|
90
|
+
base.empty_directory(dirname, config)
|
91
|
+
when /#{TEMPLATE_EXTNAME}$/
|
92
|
+
base.template(file_source, file_destination[0..-4], config, &@block)
|
93
|
+
else
|
94
|
+
base.copy_file(file_source, file_destination, config, &@block)
|
96
95
|
end
|
97
96
|
end
|
97
|
+
end
|
98
98
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
def files(lookup)
|
105
|
-
Dir[lookup]
|
106
|
-
end
|
107
|
-
else
|
108
|
-
def file_level_lookup(previous_lookup)
|
109
|
-
File.join(previous_lookup, '*')
|
110
|
-
end
|
99
|
+
if RUBY_VERSION < '2.0'
|
100
|
+
def file_level_lookup(previous_lookup)
|
101
|
+
File.join(previous_lookup, '{*,.[a-z]*}')
|
102
|
+
end
|
111
103
|
|
112
|
-
|
113
|
-
|
114
|
-
|
104
|
+
def files(lookup)
|
105
|
+
Dir[lookup]
|
106
|
+
end
|
107
|
+
else
|
108
|
+
def file_level_lookup(previous_lookup)
|
109
|
+
File.join(previous_lookup, '*')
|
115
110
|
end
|
116
111
|
|
112
|
+
def files(lookup)
|
113
|
+
Dir.glob(lookup, File::FNM_DOTMATCH)
|
114
|
+
end
|
115
|
+
end
|
117
116
|
end
|
118
117
|
end
|
119
118
|
end
|
@@ -1,6 +1,5 @@
|
|
1
1
|
class Thor
|
2
2
|
module Actions
|
3
|
-
|
4
3
|
# Creates an empty directory.
|
5
4
|
#
|
6
5
|
# ==== Parameters
|
@@ -11,7 +10,7 @@ class Thor
|
|
11
10
|
#
|
12
11
|
# empty_directory "doc"
|
13
12
|
#
|
14
|
-
def empty_directory(destination, config={})
|
13
|
+
def empty_directory(destination, config = {})
|
15
14
|
action EmptyDirectory.new(self, destination, config)
|
16
15
|
end
|
17
16
|
|
@@ -32,8 +31,8 @@ class Thor
|
|
32
31
|
# destination<String>:: Relative path to the destination of this file
|
33
32
|
# config<Hash>:: give :verbose => false to not log the status.
|
34
33
|
#
|
35
|
-
def initialize(base, destination, config={})
|
36
|
-
@base, @config = base, {
|
34
|
+
def initialize(base, destination, config = {})
|
35
|
+
@base, @config = base, {:verbose => true}.merge(config)
|
37
36
|
self.destination = destination
|
38
37
|
end
|
39
38
|
|
@@ -43,7 +42,7 @@ class Thor
|
|
43
42
|
# Boolean:: true if the file exists, false otherwise.
|
44
43
|
#
|
45
44
|
def exists?
|
46
|
-
::File.
|
45
|
+
::File.exist?(destination)
|
47
46
|
end
|
48
47
|
|
49
48
|
def invoke!
|
@@ -58,80 +57,79 @@ class Thor
|
|
58
57
|
given_destination
|
59
58
|
end
|
60
59
|
|
61
|
-
|
60
|
+
protected
|
62
61
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
62
|
+
# Shortcut for pretend.
|
63
|
+
#
|
64
|
+
def pretend?
|
65
|
+
base.options[:pretend]
|
66
|
+
end
|
68
67
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
end
|
68
|
+
# Sets the absolute destination value from a relative destination value.
|
69
|
+
# It also stores the given and relative destination. Let's suppose our
|
70
|
+
# script is being executed on "dest", it sets the destination root to
|
71
|
+
# "dest". The destination, given_destination and relative_destination
|
72
|
+
# are related in the following way:
|
73
|
+
#
|
74
|
+
# inside "bar" do
|
75
|
+
# empty_directory "baz"
|
76
|
+
# end
|
77
|
+
#
|
78
|
+
# destination #=> dest/bar/baz
|
79
|
+
# relative_destination #=> bar/baz
|
80
|
+
# given_destination #=> baz
|
81
|
+
#
|
82
|
+
def destination=(destination)
|
83
|
+
if destination
|
84
|
+
@given_destination = convert_encoded_instructions(destination.to_s)
|
85
|
+
@destination = ::File.expand_path(@given_destination, base.destination_root)
|
86
|
+
@relative_destination = base.relative_to_original_destination_root(@destination)
|
89
87
|
end
|
88
|
+
end
|
90
89
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
end
|
90
|
+
# Filenames in the encoded form are converted. If you have a file:
|
91
|
+
#
|
92
|
+
# %file_name%.rb
|
93
|
+
#
|
94
|
+
# It calls #file_name from the base and replaces %-string with the
|
95
|
+
# return value (should be String) of #file_name:
|
96
|
+
#
|
97
|
+
# user.rb
|
98
|
+
#
|
99
|
+
# The method referenced can be either public or private.
|
100
|
+
#
|
101
|
+
def convert_encoded_instructions(filename)
|
102
|
+
filename.gsub(/%(.*?)%/) do |initial_string|
|
103
|
+
method = $1.strip
|
104
|
+
base.respond_to?(method, true) ? base.send(method) : initial_string
|
107
105
|
end
|
106
|
+
end
|
108
107
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
end
|
119
|
-
|
120
|
-
destination
|
108
|
+
# Receives a hash of options and just execute the block if some
|
109
|
+
# conditions are met.
|
110
|
+
#
|
111
|
+
def invoke_with_conflict_check(&block)
|
112
|
+
if exists?
|
113
|
+
on_conflict_behavior(&block)
|
114
|
+
else
|
115
|
+
say_status :create, :green
|
116
|
+
block.call unless pretend?
|
121
117
|
end
|
122
118
|
|
123
|
-
|
124
|
-
|
125
|
-
def on_conflict_behavior(&block)
|
126
|
-
say_status :exist, :blue
|
127
|
-
end
|
119
|
+
destination
|
120
|
+
end
|
128
121
|
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
122
|
+
# What to do when the destination file already exists.
|
123
|
+
#
|
124
|
+
def on_conflict_behavior(&block)
|
125
|
+
say_status :exist, :blue
|
126
|
+
end
|
134
127
|
|
128
|
+
# Shortcut to say_status shell method.
|
129
|
+
#
|
130
|
+
def say_status(status, color)
|
131
|
+
base.shell.say_status status, relative_destination, color if config[:verbose]
|
132
|
+
end
|
135
133
|
end
|
136
134
|
end
|
137
135
|
end
|