thor 0.16.0 → 1.2.1
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.
- checksums.yaml +7 -0
- data/CONTRIBUTING.md +15 -0
- data/README.md +23 -6
- data/bin/thor +1 -1
- data/lib/thor/actions/create_file.rb +34 -35
- data/lib/thor/actions/create_link.rb +9 -5
- data/lib/thor/actions/directory.rb +33 -23
- data/lib/thor/actions/empty_directory.rb +75 -85
- data/lib/thor/actions/file_manipulation.rb +103 -36
- data/lib/thor/actions/inject_into_file.rb +46 -36
- data/lib/thor/actions.rb +90 -68
- data/lib/thor/base.rb +302 -244
- data/lib/thor/command.rb +142 -0
- data/lib/thor/core_ext/hash_with_indifferent_access.rb +52 -24
- data/lib/thor/error.rb +90 -10
- data/lib/thor/group.rb +70 -74
- data/lib/thor/invocation.rb +63 -55
- data/lib/thor/line_editor/basic.rb +37 -0
- data/lib/thor/line_editor/readline.rb +88 -0
- data/lib/thor/line_editor.rb +17 -0
- data/lib/thor/nested_context.rb +29 -0
- data/lib/thor/parser/argument.rb +24 -28
- data/lib/thor/parser/arguments.rb +110 -102
- data/lib/thor/parser/option.rb +53 -15
- data/lib/thor/parser/options.rb +174 -97
- data/lib/thor/parser.rb +4 -4
- data/lib/thor/rake_compat.rb +12 -11
- data/lib/thor/runner.rb +159 -155
- data/lib/thor/shell/basic.rb +216 -93
- data/lib/thor/shell/color.rb +53 -40
- data/lib/thor/shell/html.rb +61 -58
- data/lib/thor/shell.rb +29 -36
- data/lib/thor/util.rb +231 -213
- data/lib/thor/version.rb +1 -1
- data/lib/thor.rb +303 -166
- data/thor.gemspec +27 -24
- metadata +36 -226
- data/.gitignore +0 -44
- data/.rspec +0 -2
- data/.travis.yml +0 -7
- data/CHANGELOG.rdoc +0 -134
- data/Gemfile +0 -15
- data/Thorfile +0 -30
- data/bin/rake2thor +0 -86
- data/lib/thor/core_ext/dir_escape.rb +0 -0
- data/lib/thor/core_ext/file_binary_read.rb +0 -9
- data/lib/thor/core_ext/ordered_hash.rb +0 -100
- data/lib/thor/task.rb +0 -132
- data/spec/actions/create_file_spec.rb +0 -170
- data/spec/actions/create_link_spec.rb +0 -81
- data/spec/actions/directory_spec.rb +0 -149
- data/spec/actions/empty_directory_spec.rb +0 -130
- data/spec/actions/file_manipulation_spec.rb +0 -370
- data/spec/actions/inject_into_file_spec.rb +0 -135
- data/spec/actions_spec.rb +0 -331
- data/spec/base_spec.rb +0 -279
- data/spec/core_ext/hash_with_indifferent_access_spec.rb +0 -43
- data/spec/core_ext/ordered_hash_spec.rb +0 -115
- data/spec/exit_condition_spec.rb +0 -19
- data/spec/fixtures/application.rb +0 -2
- data/spec/fixtures/app{1}/README +0 -3
- data/spec/fixtures/bundle/execute.rb +0 -6
- data/spec/fixtures/bundle/main.thor +0 -1
- data/spec/fixtures/doc/%file_name%.rb.tt +0 -1
- data/spec/fixtures/doc/COMMENTER +0 -10
- data/spec/fixtures/doc/README +0 -3
- data/spec/fixtures/doc/block_helper.rb +0 -3
- data/spec/fixtures/doc/components/.empty_directory +0 -0
- data/spec/fixtures/doc/config.rb +0 -1
- data/spec/fixtures/doc/config.yaml.tt +0 -1
- data/spec/fixtures/enum.thor +0 -10
- data/spec/fixtures/group.thor +0 -114
- data/spec/fixtures/invoke.thor +0 -112
- data/spec/fixtures/path with spaces +0 -0
- data/spec/fixtures/script.thor +0 -190
- data/spec/fixtures/task.thor +0 -10
- data/spec/group_spec.rb +0 -216
- data/spec/invocation_spec.rb +0 -100
- data/spec/parser/argument_spec.rb +0 -53
- data/spec/parser/arguments_spec.rb +0 -66
- data/spec/parser/option_spec.rb +0 -202
- data/spec/parser/options_spec.rb +0 -330
- data/spec/rake_compat_spec.rb +0 -72
- data/spec/register_spec.rb +0 -135
- data/spec/runner_spec.rb +0 -241
- data/spec/shell/basic_spec.rb +0 -300
- data/spec/shell/color_spec.rb +0 -81
- data/spec/shell/html_spec.rb +0 -32
- data/spec/shell_spec.rb +0 -47
- data/spec/spec_helper.rb +0 -59
- data/spec/task_spec.rb +0 -80
- data/spec/thor_spec.rb +0 -418
- data/spec/util_spec.rb +0 -196
data/lib/thor/actions.rb
CHANGED
@@ -1,18 +1,16 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
require 'thor/actions/empty_directory'
|
8
|
-
require 'thor/actions/file_manipulation'
|
9
|
-
require 'thor/actions/inject_into_file'
|
1
|
+
require_relative "actions/create_file"
|
2
|
+
require_relative "actions/create_link"
|
3
|
+
require_relative "actions/directory"
|
4
|
+
require_relative "actions/empty_directory"
|
5
|
+
require_relative "actions/file_manipulation"
|
6
|
+
require_relative "actions/inject_into_file"
|
10
7
|
|
11
8
|
class Thor
|
12
9
|
module Actions
|
13
10
|
attr_accessor :behavior
|
14
11
|
|
15
12
|
def self.included(base) #:nodoc:
|
13
|
+
super(base)
|
16
14
|
base.extend ClassMethods
|
17
15
|
end
|
18
16
|
|
@@ -26,9 +24,9 @@ class Thor
|
|
26
24
|
end
|
27
25
|
|
28
26
|
# Stores and return the source root for this class
|
29
|
-
def source_root(path=nil)
|
27
|
+
def source_root(path = nil)
|
30
28
|
@_source_root = path if path
|
31
|
-
@_source_root
|
29
|
+
@_source_root ||= nil
|
32
30
|
end
|
33
31
|
|
34
32
|
# Returns the source paths in the following order:
|
@@ -39,8 +37,8 @@ class Thor
|
|
39
37
|
#
|
40
38
|
def source_paths_for_search
|
41
39
|
paths = []
|
42
|
-
paths +=
|
43
|
-
paths <<
|
40
|
+
paths += source_paths
|
41
|
+
paths << source_root if source_root
|
44
42
|
paths += from_superclass(:source_paths, [])
|
45
43
|
paths
|
46
44
|
end
|
@@ -71,15 +69,15 @@ class Thor
|
|
71
69
|
#
|
72
70
|
# destination_root<String>:: The root directory needed for some actions.
|
73
71
|
#
|
74
|
-
def initialize(args=[], options={}, config={})
|
72
|
+
def initialize(args = [], options = {}, config = {})
|
75
73
|
self.behavior = case config[:behavior].to_s
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
74
|
+
when "force", "skip"
|
75
|
+
_cleanup_options_and_set(options, config[:behavior])
|
76
|
+
:invoke
|
77
|
+
when "revoke"
|
78
|
+
:revoke
|
79
|
+
else
|
80
|
+
:invoke
|
83
81
|
end
|
84
82
|
|
85
83
|
super
|
@@ -107,16 +105,18 @@ class Thor
|
|
107
105
|
#
|
108
106
|
def destination_root=(root)
|
109
107
|
@destination_stack ||= []
|
110
|
-
@destination_stack[0] = File.expand_path(root ||
|
108
|
+
@destination_stack[0] = File.expand_path(root || "")
|
111
109
|
end
|
112
110
|
|
113
111
|
# Returns the given path relative to the absolute root (ie, root where
|
114
112
|
# the script started).
|
115
113
|
#
|
116
|
-
def relative_to_original_destination_root(path, remove_dot=true)
|
117
|
-
|
118
|
-
if path.
|
119
|
-
|
114
|
+
def relative_to_original_destination_root(path, remove_dot = true)
|
115
|
+
root = @destination_stack[0]
|
116
|
+
if path.start_with?(root) && [File::SEPARATOR, File::ALT_SEPARATOR, nil, ''].include?(path[root.size..root.size])
|
117
|
+
path = path.dup
|
118
|
+
path[0...root.size] = '.'
|
119
|
+
remove_dot ? (path[2..-1] || "") : path
|
120
120
|
else
|
121
121
|
path
|
122
122
|
end
|
@@ -131,24 +131,27 @@ class Thor
|
|
131
131
|
# Receives a file or directory and search for it in the source paths.
|
132
132
|
#
|
133
133
|
def find_in_source_paths(file)
|
134
|
+
possible_files = [file, file + TEMPLATE_EXTNAME]
|
134
135
|
relative_root = relative_to_original_destination_root(destination_root, false)
|
135
136
|
|
136
137
|
source_paths.each do |source|
|
137
|
-
|
138
|
-
|
138
|
+
possible_files.each do |f|
|
139
|
+
source_file = File.expand_path(f, File.join(source, relative_root))
|
140
|
+
return source_file if File.exist?(source_file)
|
141
|
+
end
|
139
142
|
end
|
140
143
|
|
141
|
-
message = "Could not find #{file.inspect} in any of your source paths. "
|
144
|
+
message = "Could not find #{file.inspect} in any of your source paths. ".dup
|
142
145
|
|
143
146
|
unless self.class.source_root
|
144
147
|
message << "Please invoke #{self.class.name}.source_root(PATH) with the PATH containing your templates. "
|
145
148
|
end
|
146
149
|
|
147
|
-
if source_paths.empty?
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
150
|
+
message << if source_paths.empty?
|
151
|
+
"Currently you have no source paths."
|
152
|
+
else
|
153
|
+
"Your current source paths are: \n#{source_paths.join("\n")}"
|
154
|
+
end
|
152
155
|
|
153
156
|
raise Error, message
|
154
157
|
end
|
@@ -158,11 +161,13 @@ class Thor
|
|
158
161
|
# to the block you provide. The path is set back to the previous path when
|
159
162
|
# the method exits.
|
160
163
|
#
|
164
|
+
# Returns the value yielded by the block.
|
165
|
+
#
|
161
166
|
# ==== Parameters
|
162
167
|
# dir<String>:: the directory to move to.
|
163
168
|
# config<Hash>:: give :verbose => true to log and use padding.
|
164
169
|
#
|
165
|
-
def inside(dir=
|
170
|
+
def inside(dir = "", config = {}, &block)
|
166
171
|
verbose = config.fetch(:verbose, false)
|
167
172
|
pretend = options[:pretend]
|
168
173
|
|
@@ -172,18 +177,22 @@ class Thor
|
|
172
177
|
|
173
178
|
# If the directory doesnt exist and we're not pretending
|
174
179
|
if !File.exist?(destination_root) && !pretend
|
180
|
+
require "fileutils"
|
175
181
|
FileUtils.mkdir_p(destination_root)
|
176
182
|
end
|
177
183
|
|
184
|
+
result = nil
|
178
185
|
if pretend
|
179
186
|
# In pretend mode, just yield down to the block
|
180
|
-
block.arity == 1 ? yield(destination_root) : yield
|
187
|
+
result = block.arity == 1 ? yield(destination_root) : yield
|
181
188
|
else
|
182
|
-
|
189
|
+
require "fileutils"
|
190
|
+
FileUtils.cd(destination_root) { result = block.arity == 1 ? yield(destination_root) : yield }
|
183
191
|
end
|
184
192
|
|
185
193
|
@destination_stack.pop
|
186
194
|
shell.padding -= 1 if verbose
|
195
|
+
result
|
187
196
|
end
|
188
197
|
|
189
198
|
# Goes to the root and execute the given block.
|
@@ -204,18 +213,19 @@ class Thor
|
|
204
213
|
#
|
205
214
|
# apply "recipes/jquery.rb"
|
206
215
|
#
|
207
|
-
def apply(path, config={})
|
216
|
+
def apply(path, config = {})
|
208
217
|
verbose = config.fetch(:verbose, true)
|
209
|
-
is_uri = path =~
|
218
|
+
is_uri = path =~ %r{^https?\://}
|
210
219
|
path = find_in_source_paths(path) unless is_uri
|
211
220
|
|
212
221
|
say_status :apply, path, verbose
|
213
222
|
shell.padding += 1 if verbose
|
214
223
|
|
215
|
-
if is_uri
|
216
|
-
|
224
|
+
contents = if is_uri
|
225
|
+
require "open-uri"
|
226
|
+
URI.open(path, "Accept" => "application/x-thor-template", &:read)
|
217
227
|
else
|
218
|
-
|
228
|
+
open(path, &:read)
|
219
229
|
end
|
220
230
|
|
221
231
|
instance_eval(contents, path)
|
@@ -227,7 +237,7 @@ class Thor
|
|
227
237
|
# ==== Parameters
|
228
238
|
# command<String>:: the command to be executed.
|
229
239
|
# config<Hash>:: give :verbose => false to not log the status, :capture => true to hide to output. Specify :with
|
230
|
-
# to append an executable to command
|
240
|
+
# to append an executable to command execution.
|
231
241
|
#
|
232
242
|
# ==== Example
|
233
243
|
#
|
@@ -235,7 +245,7 @@ class Thor
|
|
235
245
|
# run('ln -s ~/edge rails')
|
236
246
|
# end
|
237
247
|
#
|
238
|
-
def run(command, config={})
|
248
|
+
def run(command, config = {})
|
239
249
|
return unless behavior == :invoke
|
240
250
|
|
241
251
|
destination = relative_to_original_destination_root(destination_root, false)
|
@@ -248,9 +258,22 @@ class Thor
|
|
248
258
|
|
249
259
|
say_status :run, desc, config.fetch(:verbose, true)
|
250
260
|
|
251
|
-
|
252
|
-
|
261
|
+
return if options[:pretend]
|
262
|
+
|
263
|
+
env_splat = [config[:env]] if config[:env]
|
264
|
+
|
265
|
+
if config[:capture]
|
266
|
+
require "open3"
|
267
|
+
result, status = Open3.capture2e(*env_splat, command.to_s)
|
268
|
+
success = status.success?
|
269
|
+
else
|
270
|
+
result = system(*env_splat, command.to_s)
|
271
|
+
success = result
|
253
272
|
end
|
273
|
+
|
274
|
+
abort if !success && config.fetch(:abort_on_failure, self.class.exit_on_failure?)
|
275
|
+
|
276
|
+
result
|
254
277
|
end
|
255
278
|
|
256
279
|
# Executes a ruby script (taking into account WIN32 platform quirks).
|
@@ -259,7 +282,7 @@ class Thor
|
|
259
282
|
# command<String>:: the command to be executed.
|
260
283
|
# config<Hash>:: give :verbose => false to not log the status.
|
261
284
|
#
|
262
|
-
def run_ruby_script(command, config={})
|
285
|
+
def run_ruby_script(command, config = {})
|
263
286
|
return unless behavior == :invoke
|
264
287
|
run command, config.merge(:with => Thor::Util.ruby_command)
|
265
288
|
end
|
@@ -268,8 +291,8 @@ class Thor
|
|
268
291
|
# switches.
|
269
292
|
#
|
270
293
|
# ==== Parameters
|
271
|
-
#
|
272
|
-
# args<Array>:: arguments to the
|
294
|
+
# command<String>:: the command to be invoked
|
295
|
+
# args<Array>:: arguments to the command
|
273
296
|
# config<Hash>:: give :verbose => false to not log the status, :capture => true to hide to output.
|
274
297
|
# Other options are given as parameter to Thor.
|
275
298
|
#
|
@@ -282,37 +305,36 @@ class Thor
|
|
282
305
|
# thor :list, :all => true, :substring => 'rails'
|
283
306
|
# #=> thor list --all --substring=rails
|
284
307
|
#
|
285
|
-
def thor(
|
308
|
+
def thor(command, *args)
|
286
309
|
config = args.last.is_a?(Hash) ? args.pop : {}
|
287
310
|
verbose = config.key?(:verbose) ? config.delete(:verbose) : true
|
288
311
|
pretend = config.key?(:pretend) ? config.delete(:pretend) : false
|
289
312
|
capture = config.key?(:capture) ? config.delete(:capture) : false
|
290
313
|
|
291
|
-
args.unshift
|
314
|
+
args.unshift(command)
|
292
315
|
args.push Thor::Options.to_switches(config)
|
293
|
-
command = args.join(
|
316
|
+
command = args.join(" ").strip
|
294
317
|
|
295
318
|
run command, :with => :thor, :verbose => verbose, :pretend => pretend, :capture => capture
|
296
319
|
end
|
297
320
|
|
298
|
-
|
321
|
+
protected
|
299
322
|
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
323
|
+
# Allow current root to be shared between invocations.
|
324
|
+
#
|
325
|
+
def _shared_configuration #:nodoc:
|
326
|
+
super.merge!(:destination_root => destination_root)
|
327
|
+
end
|
305
328
|
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
end
|
329
|
+
def _cleanup_options_and_set(options, key) #:nodoc:
|
330
|
+
case options
|
331
|
+
when Array
|
332
|
+
%w(--force -f --skip -s).each { |i| options.delete(i) }
|
333
|
+
options << "--#{key}"
|
334
|
+
when Hash
|
335
|
+
[:force, :skip, "force", "skip"].each { |i| options.delete(i) }
|
336
|
+
options.merge!(key => true)
|
315
337
|
end
|
316
|
-
|
338
|
+
end
|
317
339
|
end
|
318
340
|
end
|