thor 0.12.0 → 0.12.3
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/CHANGELOG.rdoc +3 -5
- data/Thorfile +2 -1
- data/bin/thor +1 -0
- data/lib/thor/actions/create_file.rb +2 -2
- data/lib/thor/actions/directory.rb +2 -4
- data/lib/thor/actions/file_manipulation.rb +10 -6
- data/lib/thor/actions/inject_into_file.rb +1 -1
- data/lib/thor/actions.rb +6 -5
- data/lib/thor/base.rb +30 -32
- data/lib/thor/core_ext/file_binary_read.rb +9 -0
- data/lib/thor/group.rb +44 -36
- data/lib/thor/runner.rb +44 -40
- data/lib/thor/shell/basic.rb +49 -29
- data/lib/thor/shell/color.rb +1 -1
- data/lib/thor/shell.rb +1 -1
- data/lib/thor/task.rb +32 -43
- data/lib/thor/util.rb +4 -22
- data/lib/thor/version.rb +1 -1
- data/lib/thor.rb +43 -43
- data/spec/actions/create_file_spec.rb +7 -7
- data/spec/actions/directory_spec.rb +5 -4
- data/spec/actions/file_manipulation_spec.rb +29 -16
- data/spec/actions_spec.rb +14 -13
- data/spec/base_spec.rb +1 -1
- data/spec/fixtures/bundle/main.thor +1 -0
- data/spec/fixtures/doc/%file_name%.rb.tt +1 -0
- data/spec/fixtures/doc/README +3 -0
- data/spec/fixtures/group.thor +83 -0
- data/spec/fixtures/invoke.thor +112 -0
- data/spec/fixtures/script.thor +130 -0
- data/spec/fixtures/task.thor +10 -0
- data/spec/group_spec.rb +1 -7
- data/spec/runner_spec.rb +35 -39
- data/spec/shell/basic_spec.rb +56 -62
- data/spec/shell/color_spec.rb +6 -6
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +4 -4
- data/spec/task_spec.rb +14 -32
- data/spec/thor_spec.rb +21 -22
- data/spec/util_spec.rb +7 -31
- metadata +28 -19
data/CHANGELOG.rdoc
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
==
|
|
2
|
-
|
|
3
|
-
* Improve spec coverage for Thor::Runner
|
|
4
|
-
|
|
5
|
-
== 0.12, released 2009-11-06
|
|
1
|
+
== 0.12, released 2010-01-02
|
|
6
2
|
|
|
3
|
+
* Removed rr in favor to rspec mock framework
|
|
4
|
+
* Improved output for thor -T
|
|
7
5
|
* [#7] Do not force white color on status
|
|
8
6
|
* [#8] Yield a block with the filename on directory
|
|
9
7
|
|
data/Thorfile
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# enconding: utf-8
|
|
2
2
|
|
|
3
3
|
require File.join(File.dirname(__FILE__), "lib", "thor", "version")
|
|
4
|
+
require 'rubygems'
|
|
4
5
|
require 'thor/rake_compat'
|
|
5
6
|
require 'spec/rake/spectask'
|
|
6
7
|
require 'rdoc/task'
|
|
@@ -52,7 +53,7 @@ class Default < Thor
|
|
|
52
53
|
s.bindir = "bin"
|
|
53
54
|
s.executables = %w( thor rake2thor )
|
|
54
55
|
s.files = s.extra_rdoc_files + Dir.glob("{bin,lib}/**/*")
|
|
55
|
-
s.
|
|
56
|
+
s.test_files.include 'spec/**/*'
|
|
56
57
|
s.test_files.exclude 'spec/sandbox/**/*'
|
|
57
58
|
end
|
|
58
59
|
|
data/bin/thor
CHANGED
|
@@ -42,7 +42,7 @@ class Thor
|
|
|
42
42
|
# Boolean:: true if it is identical, false otherwise.
|
|
43
43
|
#
|
|
44
44
|
def identical?
|
|
45
|
-
exists? && File.
|
|
45
|
+
exists? && File.binread(destination) == render
|
|
46
46
|
end
|
|
47
47
|
|
|
48
48
|
# Holds the content to be added to the file.
|
|
@@ -58,7 +58,7 @@ class Thor
|
|
|
58
58
|
def invoke!
|
|
59
59
|
invoke_with_conflict_check do
|
|
60
60
|
FileUtils.mkdir_p(File.dirname(destination))
|
|
61
|
-
File.open(destination, '
|
|
61
|
+
File.open(destination, 'wb') { |f| f.write render }
|
|
62
62
|
end
|
|
63
63
|
given_destination
|
|
64
64
|
end
|
|
@@ -79,11 +79,9 @@ class Thor
|
|
|
79
79
|
next if dirname == given_destination
|
|
80
80
|
base.empty_directory(dirname, config)
|
|
81
81
|
when /\.tt$/
|
|
82
|
-
destination = base.template(file_source, file_destination[0..-4], config)
|
|
83
|
-
@block.call(destination) if @block
|
|
82
|
+
destination = base.template(file_source, file_destination[0..-4], config, &@block)
|
|
84
83
|
else
|
|
85
|
-
destination = base.copy_file(file_source, file_destination, config)
|
|
86
|
-
@block.call(destination) if @block
|
|
84
|
+
destination = base.copy_file(file_source, file_destination, config, &@block)
|
|
87
85
|
end
|
|
88
86
|
end
|
|
89
87
|
end
|
|
@@ -18,12 +18,14 @@ class Thor
|
|
|
18
18
|
#
|
|
19
19
|
# copy_file "doc/README"
|
|
20
20
|
#
|
|
21
|
-
def copy_file(source, destination=nil, config={})
|
|
21
|
+
def copy_file(source, destination=nil, config={}, &block)
|
|
22
22
|
destination ||= source
|
|
23
23
|
source = File.expand_path(find_in_source_paths(source.to_s))
|
|
24
24
|
|
|
25
25
|
create_file destination, nil, config do
|
|
26
|
-
File.
|
|
26
|
+
content = File.binread(source)
|
|
27
|
+
content = block.call(content) if block
|
|
28
|
+
content
|
|
27
29
|
end
|
|
28
30
|
end
|
|
29
31
|
|
|
@@ -46,7 +48,7 @@ class Thor
|
|
|
46
48
|
#
|
|
47
49
|
def get(source, destination=nil, config={}, &block)
|
|
48
50
|
source = File.expand_path(find_in_source_paths(source.to_s)) unless source =~ /^http\:\/\//
|
|
49
|
-
render =
|
|
51
|
+
render = File.binread(source)
|
|
50
52
|
|
|
51
53
|
destination ||= if block_given?
|
|
52
54
|
block.arity == 1 ? block.call(render) : block.call
|
|
@@ -72,13 +74,15 @@ class Thor
|
|
|
72
74
|
#
|
|
73
75
|
# template "doc/README"
|
|
74
76
|
#
|
|
75
|
-
def template(source, destination=nil, config={})
|
|
77
|
+
def template(source, destination=nil, config={}, &block)
|
|
76
78
|
destination ||= source
|
|
77
79
|
source = File.expand_path(find_in_source_paths(source.to_s))
|
|
78
80
|
context = instance_eval('binding')
|
|
79
81
|
|
|
80
82
|
create_file destination, nil, config do
|
|
81
|
-
ERB.new(::File.
|
|
83
|
+
content = ERB.new(::File.binread(source), nil, '-').result(context)
|
|
84
|
+
content = block.call(content) if block
|
|
85
|
+
content
|
|
82
86
|
end
|
|
83
87
|
end
|
|
84
88
|
|
|
@@ -189,7 +193,7 @@ class Thor
|
|
|
189
193
|
say_status :gsub, relative_to_original_destination_root(path), config.fetch(:verbose, true)
|
|
190
194
|
|
|
191
195
|
unless options[:pretend]
|
|
192
|
-
content = File.
|
|
196
|
+
content = File.binread(path)
|
|
193
197
|
content.gsub!(flag, *args, &block)
|
|
194
198
|
File.open(path, 'wb') { |file| file.write(content) }
|
|
195
199
|
end
|
data/lib/thor/actions.rb
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
require 'fileutils'
|
|
2
|
+
require 'thor/core_ext/file_binary_read'
|
|
2
3
|
|
|
3
4
|
Dir[File.join(File.dirname(__FILE__), "actions", "*.rb")].each do |action|
|
|
4
5
|
require action
|
|
@@ -38,17 +39,17 @@ class Thor
|
|
|
38
39
|
# Add runtime options that help actions execution.
|
|
39
40
|
#
|
|
40
41
|
def add_runtime_options!
|
|
41
|
-
class_option :pretend, :type => :boolean, :aliases => "-p", :group => :runtime,
|
|
42
|
-
:desc => "Run but do not make any changes"
|
|
43
|
-
|
|
44
42
|
class_option :force, :type => :boolean, :aliases => "-f", :group => :runtime,
|
|
45
43
|
:desc => "Overwrite files that already exist"
|
|
46
44
|
|
|
47
|
-
class_option :
|
|
48
|
-
|
|
45
|
+
class_option :pretend, :type => :boolean, :aliases => "-p", :group => :runtime,
|
|
46
|
+
:desc => "Run but do not make any changes"
|
|
49
47
|
|
|
50
48
|
class_option :quiet, :type => :boolean, :aliases => "-q", :group => :runtime,
|
|
51
49
|
:desc => "Supress status output"
|
|
50
|
+
|
|
51
|
+
class_option :skip, :type => :boolean, :aliases => "-s", :group => :runtime,
|
|
52
|
+
:desc => "Skip files that already exist"
|
|
52
53
|
end
|
|
53
54
|
end
|
|
54
55
|
|
data/lib/thor/base.rb
CHANGED
|
@@ -92,6 +92,8 @@ class Thor
|
|
|
92
92
|
end
|
|
93
93
|
|
|
94
94
|
module ClassMethods
|
|
95
|
+
attr_accessor :debugging
|
|
96
|
+
|
|
95
97
|
# Adds an argument to the class and creates an attr_accessor for it.
|
|
96
98
|
#
|
|
97
99
|
# Arguments are different from options in several aspects. The first one
|
|
@@ -347,10 +349,11 @@ class Thor
|
|
|
347
349
|
# Default way to start generators from the command line.
|
|
348
350
|
#
|
|
349
351
|
def start(given_args=ARGV, config={})
|
|
352
|
+
self.debugging = given_args.include?("--debug")
|
|
350
353
|
config[:shell] ||= Thor::Base.shell.new
|
|
351
354
|
yield
|
|
352
355
|
rescue Thor::Error => e
|
|
353
|
-
if
|
|
356
|
+
if debugging
|
|
354
357
|
raise e
|
|
355
358
|
else
|
|
356
359
|
config[:shell].error e.message
|
|
@@ -361,48 +364,43 @@ class Thor
|
|
|
361
364
|
protected
|
|
362
365
|
|
|
363
366
|
# Prints the class options per group. If an option does not belong to
|
|
364
|
-
# any group, it
|
|
365
|
-
# hooks to add extra options, one of them if the third argument called
|
|
366
|
-
# extra_group that should be a hash in the format :group => Array[Options].
|
|
367
|
-
#
|
|
368
|
-
# The second is by returning a lambda used to print values. The lambda
|
|
369
|
-
# requires two options: the group name and the array of options.
|
|
367
|
+
# any group, it's printed as Class option.
|
|
370
368
|
#
|
|
371
|
-
def class_options_help(shell,
|
|
372
|
-
|
|
373
|
-
|
|
369
|
+
def class_options_help(shell, groups={}) #:nodoc:
|
|
370
|
+
# Group options by group
|
|
374
371
|
class_options.each do |_, value|
|
|
375
372
|
groups[value.group] ||= []
|
|
376
373
|
groups[value.group] << value
|
|
377
374
|
end
|
|
378
375
|
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
376
|
+
# Deal with default group
|
|
377
|
+
global_options = groups.delete(nil) || []
|
|
378
|
+
print_options(shell, global_options)
|
|
379
|
+
|
|
380
|
+
# Print all others
|
|
381
|
+
groups.each do |group_name, options|
|
|
382
|
+
print_options(shell, options, group_name)
|
|
383
|
+
end
|
|
384
|
+
end
|
|
385
|
+
|
|
386
|
+
# Receives a set of options and print them.
|
|
387
|
+
def print_options(shell, options, group_name=nil)
|
|
388
|
+
return if options.empty?
|
|
382
389
|
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
item.push(option.description ? "# #{option.description}" : "")
|
|
390
|
+
list = []
|
|
391
|
+
padding = options.collect{ |o| o.aliases.size }.max.to_i * 4
|
|
386
392
|
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
393
|
+
options.each do |option|
|
|
394
|
+
item = [ option.usage(padding) ]
|
|
395
|
+
item.push(option.description ? "# #{option.description}" : "")
|
|
390
396
|
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
shell.print_table(list, :ident => 2)
|
|
394
|
-
shell.say ""
|
|
395
|
-
end
|
|
397
|
+
list << item
|
|
398
|
+
list << [ "", "# Default: #{option.default}" ] if option.show_default?
|
|
396
399
|
end
|
|
397
400
|
|
|
398
|
-
#
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
# Print all others
|
|
403
|
-
groups = extra_group.merge(groups) if extra_group
|
|
404
|
-
groups.each(&printer)
|
|
405
|
-
printer
|
|
401
|
+
shell.say(group_name ? "#{group_name} options:" : "Options:")
|
|
402
|
+
shell.print_table(list, :ident => 2)
|
|
403
|
+
shell.say ""
|
|
406
404
|
end
|
|
407
405
|
|
|
408
406
|
# Raises an error if the word given is a Thor reserved word.
|
data/lib/thor/group.rb
CHANGED
|
@@ -41,16 +41,12 @@ class Thor::Group
|
|
|
41
41
|
# ==== Options
|
|
42
42
|
# short:: When true, shows only usage.
|
|
43
43
|
#
|
|
44
|
-
def help(shell
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
shell.say
|
|
51
|
-
class_options_help(shell)
|
|
52
|
-
shell.say self.desc if self.desc
|
|
53
|
-
end
|
|
44
|
+
def help(shell)
|
|
45
|
+
shell.say "Usage:"
|
|
46
|
+
shell.say " #{banner}\n"
|
|
47
|
+
shell.say
|
|
48
|
+
class_options_help(shell)
|
|
49
|
+
shell.say self.desc if self.desc
|
|
54
50
|
end
|
|
55
51
|
|
|
56
52
|
# Stores invocations for this class merging with superclass values.
|
|
@@ -177,15 +173,11 @@ class Thor::Group
|
|
|
177
173
|
# Overwrite class options help to allow invoked generators options to be
|
|
178
174
|
# shown recursively when invoking a generator.
|
|
179
175
|
#
|
|
180
|
-
def class_options_help(shell,
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
get_options_from_invocations(group_options, class_options) do |klass|
|
|
184
|
-
klass.send(:get_options_from_invocations, group_options, class_options)
|
|
176
|
+
def class_options_help(shell, groups={}) #:nodoc:
|
|
177
|
+
get_options_from_invocations(groups, class_options) do |klass|
|
|
178
|
+
klass.send(:get_options_from_invocations, groups, class_options)
|
|
185
179
|
end
|
|
186
|
-
|
|
187
|
-
group_options.merge!(extra_group) if extra_group
|
|
188
|
-
super(shell, ungrouped_name, group_options)
|
|
180
|
+
super(shell, groups)
|
|
189
181
|
end
|
|
190
182
|
|
|
191
183
|
# Get invocations array and merge options from invocations. Those
|
|
@@ -218,13 +210,27 @@ class Thor::Group
|
|
|
218
210
|
end
|
|
219
211
|
end
|
|
220
212
|
|
|
213
|
+
# Returns tasks ready to be printed.
|
|
214
|
+
def printable_tasks(*)
|
|
215
|
+
item = []
|
|
216
|
+
item << banner
|
|
217
|
+
item << (desc ? "# #{desc.gsub(/\s+/m,' ')}" : "")
|
|
218
|
+
[item]
|
|
219
|
+
end
|
|
220
|
+
|
|
221
221
|
protected
|
|
222
222
|
|
|
223
223
|
# The banner for this class. You can customize it if you are invoking the
|
|
224
224
|
# thor class by another ways which is not the Thor::Runner.
|
|
225
225
|
#
|
|
226
226
|
def banner
|
|
227
|
-
|
|
227
|
+
base = $thor_runner ? "thor" : File.basename($0.split(" ").first)
|
|
228
|
+
"#{base} #{self_task.formatted_usage(self, false)}"
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
# Represents the whole class as a task.
|
|
232
|
+
def self_task #:nodoc:
|
|
233
|
+
Thor::Task::Dynamic.new(self.namespace, class_options)
|
|
228
234
|
end
|
|
229
235
|
|
|
230
236
|
def baseclass #:nodoc:
|
|
@@ -241,23 +247,25 @@ class Thor::Group
|
|
|
241
247
|
|
|
242
248
|
protected
|
|
243
249
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
invoke klass, task, *args
|
|
250
|
+
# Shortcut to invoke with padding and block handling. Use internally by
|
|
251
|
+
# invoke and invoke_from_option class methods.
|
|
252
|
+
def _invoke_for_class_method(klass, task=nil, *args, &block) #:nodoc:
|
|
253
|
+
shell.padding += 1
|
|
254
|
+
|
|
255
|
+
result = if block_given?
|
|
256
|
+
case block.arity
|
|
257
|
+
when 3
|
|
258
|
+
block.call(self, klass, task)
|
|
259
|
+
when 2
|
|
260
|
+
block.call(self, klass)
|
|
261
|
+
when 1
|
|
262
|
+
instance_exec(klass, &block)
|
|
258
263
|
end
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
result
|
|
264
|
+
else
|
|
265
|
+
invoke klass, task, *args
|
|
262
266
|
end
|
|
267
|
+
|
|
268
|
+
shell.padding -= 1
|
|
269
|
+
result
|
|
270
|
+
end
|
|
263
271
|
end
|
data/lib/thor/runner.rb
CHANGED
|
@@ -124,11 +124,7 @@ class Thor::Runner < Thor #:nodoc:
|
|
|
124
124
|
method_options :internal => :boolean
|
|
125
125
|
def installed
|
|
126
126
|
initialize_thorfiles(nil, true)
|
|
127
|
-
|
|
128
|
-
klasses = Thor::Base.subclasses
|
|
129
|
-
klasses -= [Thor, Thor::Runner] unless options["internal"]
|
|
130
|
-
|
|
131
|
-
display_klasses(true, klasses)
|
|
127
|
+
display_klasses(true, options["internal"])
|
|
132
128
|
end
|
|
133
129
|
|
|
134
130
|
desc "list [SEARCH]", "List the available thor tasks (--substring means .*SEARCH)"
|
|
@@ -144,11 +140,15 @@ class Thor::Runner < Thor #:nodoc:
|
|
|
144
140
|
(options[:all] || k.group == group) && k.namespace =~ search
|
|
145
141
|
end
|
|
146
142
|
|
|
147
|
-
display_klasses(false, klasses)
|
|
143
|
+
display_klasses(false, false, klasses)
|
|
148
144
|
end
|
|
149
145
|
|
|
150
146
|
private
|
|
151
147
|
|
|
148
|
+
def self.banner(task)
|
|
149
|
+
"thor " + task.formatted_usage(self, false)
|
|
150
|
+
end
|
|
151
|
+
|
|
152
152
|
def thor_root
|
|
153
153
|
Thor::Util.thor_root
|
|
154
154
|
end
|
|
@@ -156,7 +156,7 @@ class Thor::Runner < Thor #:nodoc:
|
|
|
156
156
|
def thor_yaml
|
|
157
157
|
@thor_yaml ||= begin
|
|
158
158
|
yaml_file = File.join(thor_root, "thor.yml")
|
|
159
|
-
yaml
|
|
159
|
+
yaml = YAML.load_file(yaml_file) if File.exists?(yaml_file)
|
|
160
160
|
yaml || {}
|
|
161
161
|
end
|
|
162
162
|
end
|
|
@@ -215,9 +215,6 @@ class Thor::Runner < Thor #:nodoc:
|
|
|
215
215
|
# 5. c:\ <-- no Thorfiles found!
|
|
216
216
|
#
|
|
217
217
|
def thorfiles(relevant_to=nil, skip_lookup=false)
|
|
218
|
-
# TODO Remove this dealing with deprecated thor when :namespaces: is available as constants
|
|
219
|
-
save_yaml(thor_yaml) if Thor::Util.convert_constants_to_namespaces(thor_yaml)
|
|
220
|
-
|
|
221
218
|
thorfiles = []
|
|
222
219
|
|
|
223
220
|
unless skip_lookup
|
|
@@ -253,47 +250,54 @@ class Thor::Runner < Thor #:nodoc:
|
|
|
253
250
|
# Display information about the given klasses. If with_module is given,
|
|
254
251
|
# it shows a table with information extracted from the yaml file.
|
|
255
252
|
#
|
|
256
|
-
def display_klasses(with_modules=false, klasses=Thor.subclasses)
|
|
257
|
-
klasses -= [Thor, Thor::Runner] unless
|
|
253
|
+
def display_klasses(with_modules=false, show_internal=false, klasses=Thor::Base.subclasses)
|
|
254
|
+
klasses -= [Thor, Thor::Runner, Thor::Group] unless show_internal
|
|
255
|
+
|
|
258
256
|
raise Error, "No Thor tasks available" if klasses.empty?
|
|
257
|
+
show_modules if with_modules && !thor_yaml.empty?
|
|
259
258
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
259
|
+
# Remove subclasses
|
|
260
|
+
klasses.dup.each do |klass|
|
|
261
|
+
klasses -= Thor::Util.thor_classes_in(klass)
|
|
262
|
+
end
|
|
263
263
|
|
|
264
|
-
|
|
265
|
-
|
|
264
|
+
list = Hash.new { |h,k| h[k] = [] }
|
|
265
|
+
groups = klasses.select { |k| k.ancestors.include?(Thor::Group) }
|
|
266
266
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
end
|
|
267
|
+
# Get classes which inherit from Thor
|
|
268
|
+
(klasses - groups).each { |k| list[k.namespace] += k.printable_tasks(false) }
|
|
270
269
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
270
|
+
# Get classes which inherit from Thor::Base
|
|
271
|
+
groups.map! { |k| k.printable_tasks(false).first }
|
|
272
|
+
list["root"] = groups
|
|
274
273
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
274
|
+
# Order namespaces with default coming first
|
|
275
|
+
list = list.sort{ |a,b| a[0].sub(/^default/, '') <=> b[0].sub(/^default/, '') }
|
|
276
|
+
list.each { |n, tasks| display_tasks(n, tasks) unless tasks.empty? }
|
|
277
|
+
end
|
|
279
278
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
279
|
+
def display_tasks(namespace, list) #:nodoc:
|
|
280
|
+
list.sort!{ |a,b| a[0] <=> b[0] }
|
|
281
|
+
|
|
282
|
+
say shell.set_color(namespace, :blue, true)
|
|
283
|
+
say "-" * namespace.size
|
|
284
|
+
|
|
285
|
+
print_table(list, :truncate => true)
|
|
286
|
+
say
|
|
284
287
|
end
|
|
285
288
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
unless klass.tasks.empty?
|
|
290
|
-
base = klass.namespace
|
|
289
|
+
def show_modules #:nodoc:
|
|
290
|
+
info = []
|
|
291
|
+
labels = ["Modules", "Namespaces"]
|
|
291
292
|
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
say "-" * base.length
|
|
293
|
+
info << labels
|
|
294
|
+
info << [ "-" * labels[0].size, "-" * labels[1].size ]
|
|
295
295
|
|
|
296
|
-
|
|
296
|
+
thor_yaml.each do |name, hash|
|
|
297
|
+
info << [ name, hash[:namespaces].join(", ") ]
|
|
297
298
|
end
|
|
299
|
+
|
|
300
|
+
print_table info
|
|
301
|
+
say ""
|
|
298
302
|
end
|
|
299
303
|
end
|
data/lib/thor/shell/basic.rb
CHANGED
|
@@ -75,30 +75,6 @@ class Thor
|
|
|
75
75
|
!yes?(statement, color)
|
|
76
76
|
end
|
|
77
77
|
|
|
78
|
-
# Prints a list of items.
|
|
79
|
-
#
|
|
80
|
-
# ==== Parameters
|
|
81
|
-
# list<Array[String, String, ...]>
|
|
82
|
-
#
|
|
83
|
-
# ==== Options
|
|
84
|
-
# mode:: Can be :rows or :inline. Defaults to :rows.
|
|
85
|
-
# ident:: Ident each item with the value given.
|
|
86
|
-
#
|
|
87
|
-
def print_list(list, options={})
|
|
88
|
-
return if list.empty?
|
|
89
|
-
|
|
90
|
-
ident = " " * (options[:ident] || 0)
|
|
91
|
-
content = case options[:mode]
|
|
92
|
-
when :inline
|
|
93
|
-
last = list.pop
|
|
94
|
-
"#{list.join(", ")}, and #{last}"
|
|
95
|
-
else # rows
|
|
96
|
-
ident + list.join("\n#{ident}")
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
$stdout.puts content
|
|
100
|
-
end
|
|
101
|
-
|
|
102
78
|
# Prints a table.
|
|
103
79
|
#
|
|
104
80
|
# ==== Parameters
|
|
@@ -110,20 +86,26 @@ class Thor
|
|
|
110
86
|
def print_table(table, options={})
|
|
111
87
|
return if table.empty?
|
|
112
88
|
|
|
113
|
-
formats = []
|
|
89
|
+
formats, ident = [], options[:ident].to_i
|
|
90
|
+
options[:truncate] = terminal_width if options[:truncate] == true
|
|
91
|
+
|
|
114
92
|
0.upto(table.first.length - 2) do |i|
|
|
115
93
|
maxima = table.max{ |a,b| a[i].size <=> b[i].size }[i].size
|
|
116
94
|
formats << "%-#{maxima + 2}s"
|
|
117
95
|
end
|
|
118
96
|
|
|
119
|
-
formats[0] = formats[0].insert(0, " " *
|
|
97
|
+
formats[0] = formats[0].insert(0, " " * ident)
|
|
120
98
|
formats << "%s"
|
|
121
99
|
|
|
122
100
|
table.each do |row|
|
|
101
|
+
sentence = ""
|
|
102
|
+
|
|
123
103
|
row.each_with_index do |column, i|
|
|
124
|
-
|
|
104
|
+
sentence << formats[i] % column.to_s
|
|
125
105
|
end
|
|
126
|
-
|
|
106
|
+
|
|
107
|
+
sentence = truncate(sentence, options[:truncate]) if options[:truncate]
|
|
108
|
+
$stdout.puts sentence
|
|
127
109
|
end
|
|
128
110
|
end
|
|
129
111
|
|
|
@@ -143,7 +125,7 @@ class Thor
|
|
|
143
125
|
answer = ask %[Overwrite #{destination}? (enter "h" for help) #{options}]
|
|
144
126
|
|
|
145
127
|
case answer
|
|
146
|
-
when is?(:yes), is?(:force)
|
|
128
|
+
when is?(:yes), is?(:force), ""
|
|
147
129
|
return true
|
|
148
130
|
when is?(:no), is?(:skip)
|
|
149
131
|
return false
|
|
@@ -214,6 +196,44 @@ HELP
|
|
|
214
196
|
base && base.options[:quiet]
|
|
215
197
|
end
|
|
216
198
|
|
|
199
|
+
# This code was copied from Rake, available under MIT-LICENSE
|
|
200
|
+
# Copyright (c) 2003, 2004 Jim Weirich
|
|
201
|
+
def terminal_width
|
|
202
|
+
if ENV['THOR_COLUMNS']
|
|
203
|
+
result = ENV['THOR_COLUMNS'].to_i
|
|
204
|
+
else
|
|
205
|
+
result = unix? ? dynamic_width : 80
|
|
206
|
+
end
|
|
207
|
+
(result < 10) ? 80 : result
|
|
208
|
+
rescue
|
|
209
|
+
80
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
# Calculate the dynamic width of the terminal
|
|
213
|
+
def dynamic_width
|
|
214
|
+
@dynamic_width ||= (dynamic_width_stty.nonzero? || dynamic_width_tput)
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
def dynamic_width_stty
|
|
218
|
+
%x{stty size 2>/dev/null}.split[1].to_i
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
def dynamic_width_tput
|
|
222
|
+
%x{tput cols 2>/dev/null}.to_i
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
def unix?
|
|
226
|
+
RUBY_PLATFORM =~ /(aix|darwin|linux|(net|free|open)bsd|cygwin|solaris|irix|hpux)/i
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
def truncate(string, width)
|
|
230
|
+
if string.length <= width
|
|
231
|
+
string
|
|
232
|
+
else
|
|
233
|
+
( string[0, width-3] || "" ) + "..."
|
|
234
|
+
end
|
|
235
|
+
end
|
|
236
|
+
|
|
217
237
|
end
|
|
218
238
|
end
|
|
219
239
|
end
|
data/lib/thor/shell/color.rb
CHANGED
|
@@ -63,7 +63,7 @@ class Thor
|
|
|
63
63
|
#
|
|
64
64
|
def show_diff(destination, content) #:nodoc:
|
|
65
65
|
if diff_lcs_loaded? && ENV['THOR_DIFF'].nil? && ENV['RAILS_DIFF'].nil?
|
|
66
|
-
actual = File.
|
|
66
|
+
actual = File.binread(destination).to_s.split("\n")
|
|
67
67
|
content = content.to_s.split("\n")
|
|
68
68
|
|
|
69
69
|
Diff::LCS.sdiff(actual, content).each do |diff|
|
data/lib/thor/shell.rb
CHANGED
|
@@ -22,7 +22,7 @@ class Thor
|
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
module Shell
|
|
25
|
-
SHELL_DELEGATED_METHODS = [:ask, :yes?, :no?, :say, :say_status, :
|
|
25
|
+
SHELL_DELEGATED_METHODS = [:ask, :yes?, :no?, :say, :say_status, :print_table]
|
|
26
26
|
|
|
27
27
|
# Add shell to initialize config values.
|
|
28
28
|
#
|