thor 0.9.9 → 0.11.5
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 +29 -4
- data/README.rdoc +234 -0
- data/Thorfile +57 -0
- data/VERSION +1 -0
- data/bin/rake2thor +4 -0
- data/bin/thor +1 -1
- data/lib/thor.rb +216 -119
- data/lib/thor/actions.rb +272 -0
- data/lib/thor/actions/create_file.rb +102 -0
- data/lib/thor/actions/directory.rb +87 -0
- data/lib/thor/actions/empty_directory.rb +133 -0
- data/lib/thor/actions/file_manipulation.rb +195 -0
- data/lib/thor/actions/inject_into_file.rb +78 -0
- data/lib/thor/base.rb +510 -0
- data/lib/thor/core_ext/hash_with_indifferent_access.rb +75 -0
- data/lib/thor/core_ext/ordered_hash.rb +100 -0
- data/lib/thor/error.rb +25 -1
- data/lib/thor/group.rb +263 -0
- data/lib/thor/invocation.rb +178 -0
- data/lib/thor/parser.rb +4 -0
- data/lib/thor/parser/argument.rb +67 -0
- data/lib/thor/parser/arguments.rb +145 -0
- data/lib/thor/parser/option.rb +132 -0
- data/lib/thor/parser/options.rb +142 -0
- data/lib/thor/rake_compat.rb +67 -0
- data/lib/thor/runner.rb +232 -242
- data/lib/thor/shell.rb +72 -0
- data/lib/thor/shell/basic.rb +220 -0
- data/lib/thor/shell/color.rb +108 -0
- data/lib/thor/task.rb +97 -60
- data/lib/thor/util.rb +230 -55
- data/spec/actions/create_file_spec.rb +170 -0
- data/spec/actions/directory_spec.rb +118 -0
- data/spec/actions/empty_directory_spec.rb +91 -0
- data/spec/actions/file_manipulation_spec.rb +242 -0
- data/spec/actions/inject_into_file_spec.rb +80 -0
- data/spec/actions_spec.rb +291 -0
- data/spec/base_spec.rb +236 -0
- data/spec/core_ext/hash_with_indifferent_access_spec.rb +43 -0
- data/spec/core_ext/ordered_hash_spec.rb +115 -0
- data/spec/fixtures/bundle/execute.rb +6 -0
- data/spec/fixtures/doc/config.rb +1 -0
- data/spec/group_spec.rb +177 -0
- data/spec/invocation_spec.rb +107 -0
- data/spec/parser/argument_spec.rb +47 -0
- data/spec/parser/arguments_spec.rb +64 -0
- data/spec/parser/option_spec.rb +212 -0
- data/spec/parser/options_spec.rb +255 -0
- data/spec/rake_compat_spec.rb +64 -0
- data/spec/runner_spec.rb +204 -0
- data/spec/shell/basic_spec.rb +206 -0
- data/spec/shell/color_spec.rb +41 -0
- data/spec/shell_spec.rb +25 -0
- data/spec/spec_helper.rb +52 -0
- data/spec/task_spec.rb +82 -0
- data/spec/thor_spec.rb +234 -0
- data/spec/util_spec.rb +196 -0
- metadata +69 -25
- data/README.markdown +0 -76
- data/Rakefile +0 -6
- data/lib/thor/options.rb +0 -242
- data/lib/thor/ordered_hash.rb +0 -64
- data/lib/thor/task_hash.rb +0 -22
- data/lib/thor/tasks.rb +0 -77
- data/lib/thor/tasks/package.rb +0 -18
metadata
CHANGED
@@ -1,53 +1,72 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: thor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.11.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yehuda Katz
|
8
|
+
- "Jos\xC3\xA9 Valim"
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
12
|
|
12
|
-
date:
|
13
|
+
date: 2009-08-05 00:00:00 +02:00
|
13
14
|
default_executable:
|
14
15
|
dependencies: []
|
15
16
|
|
16
|
-
description: A
|
17
|
-
email:
|
17
|
+
description: A scripting framework that replaces rake, sake and rubigen
|
18
|
+
email: ruby-thor@googlegroups.com
|
18
19
|
executables:
|
19
20
|
- thor
|
20
21
|
- rake2thor
|
21
22
|
extensions: []
|
22
23
|
|
23
24
|
extra_rdoc_files:
|
24
|
-
- README.markdown
|
25
|
-
- LICENSE
|
26
25
|
- CHANGELOG.rdoc
|
27
|
-
files:
|
28
|
-
- README.markdown
|
29
26
|
- LICENSE
|
27
|
+
- README.rdoc
|
28
|
+
- Thorfile
|
29
|
+
- VERSION
|
30
|
+
files:
|
30
31
|
- CHANGELOG.rdoc
|
31
|
-
-
|
32
|
+
- LICENSE
|
33
|
+
- README.rdoc
|
34
|
+
- Thorfile
|
35
|
+
- VERSION
|
32
36
|
- bin/rake2thor
|
33
37
|
- bin/thor
|
34
|
-
- lib/thor
|
38
|
+
- lib/thor.rb
|
39
|
+
- lib/thor/actions.rb
|
40
|
+
- lib/thor/actions/create_file.rb
|
41
|
+
- lib/thor/actions/directory.rb
|
42
|
+
- lib/thor/actions/empty_directory.rb
|
43
|
+
- lib/thor/actions/file_manipulation.rb
|
44
|
+
- lib/thor/actions/inject_into_file.rb
|
45
|
+
- lib/thor/base.rb
|
46
|
+
- lib/thor/core_ext/hash_with_indifferent_access.rb
|
47
|
+
- lib/thor/core_ext/ordered_hash.rb
|
35
48
|
- lib/thor/error.rb
|
36
|
-
- lib/thor/
|
37
|
-
- lib/thor/
|
49
|
+
- lib/thor/group.rb
|
50
|
+
- lib/thor/invocation.rb
|
51
|
+
- lib/thor/parser.rb
|
52
|
+
- lib/thor/parser/argument.rb
|
53
|
+
- lib/thor/parser/arguments.rb
|
54
|
+
- lib/thor/parser/option.rb
|
55
|
+
- lib/thor/parser/options.rb
|
56
|
+
- lib/thor/rake_compat.rb
|
38
57
|
- lib/thor/runner.rb
|
58
|
+
- lib/thor/shell.rb
|
59
|
+
- lib/thor/shell/basic.rb
|
60
|
+
- lib/thor/shell/color.rb
|
39
61
|
- lib/thor/task.rb
|
40
|
-
- lib/thor/task_hash.rb
|
41
|
-
- lib/thor/tasks
|
42
|
-
- lib/thor/tasks/package.rb
|
43
|
-
- lib/thor/tasks.rb
|
44
62
|
- lib/thor/util.rb
|
45
|
-
- lib/thor.rb
|
46
63
|
has_rdoc: true
|
47
64
|
homepage: http://yehudakatz.com
|
48
|
-
|
49
|
-
rdoc_options: []
|
65
|
+
licenses: []
|
50
66
|
|
67
|
+
post_install_message:
|
68
|
+
rdoc_options:
|
69
|
+
- --charset=UTF-8
|
51
70
|
require_paths:
|
52
71
|
- lib
|
53
72
|
required_ruby_version: !ruby/object:Gem::Requirement
|
@@ -64,10 +83,35 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
64
83
|
version:
|
65
84
|
requirements: []
|
66
85
|
|
67
|
-
rubyforge_project:
|
68
|
-
rubygems_version: 1.3.
|
86
|
+
rubyforge_project: textmate
|
87
|
+
rubygems_version: 1.3.2
|
69
88
|
signing_key:
|
70
|
-
specification_version:
|
71
|
-
summary: A
|
72
|
-
test_files:
|
73
|
-
|
89
|
+
specification_version: 3
|
90
|
+
summary: A scripting framework that replaces rake, sake and rubigen
|
91
|
+
test_files:
|
92
|
+
- spec/rake_compat_spec.rb
|
93
|
+
- spec/actions/directory_spec.rb
|
94
|
+
- spec/actions/empty_directory_spec.rb
|
95
|
+
- spec/actions/create_file_spec.rb
|
96
|
+
- spec/actions/inject_into_file_spec.rb
|
97
|
+
- spec/actions/file_manipulation_spec.rb
|
98
|
+
- spec/shell_spec.rb
|
99
|
+
- spec/invocation_spec.rb
|
100
|
+
- spec/base_spec.rb
|
101
|
+
- spec/task_spec.rb
|
102
|
+
- spec/spec_helper.rb
|
103
|
+
- spec/actions_spec.rb
|
104
|
+
- spec/shell/basic_spec.rb
|
105
|
+
- spec/shell/color_spec.rb
|
106
|
+
- spec/group_spec.rb
|
107
|
+
- spec/thor_spec.rb
|
108
|
+
- spec/fixtures/doc/config.rb
|
109
|
+
- spec/fixtures/bundle/execute.rb
|
110
|
+
- spec/util_spec.rb
|
111
|
+
- spec/parser/argument_spec.rb
|
112
|
+
- spec/parser/option_spec.rb
|
113
|
+
- spec/parser/options_spec.rb
|
114
|
+
- spec/parser/arguments_spec.rb
|
115
|
+
- spec/runner_spec.rb
|
116
|
+
- spec/core_ext/ordered_hash_spec.rb
|
117
|
+
- spec/core_ext/hash_with_indifferent_access_spec.rb
|
data/README.markdown
DELETED
@@ -1,76 +0,0 @@
|
|
1
|
-
thor
|
2
|
-
====
|
3
|
-
|
4
|
-
Map options to a class. Simply create a class with the appropriate annotations, and have options automatically map
|
5
|
-
to functions and parameters.
|
6
|
-
|
7
|
-
Example:
|
8
|
-
|
9
|
-
class MyApp < Thor # [1]
|
10
|
-
map "-L" => :list # [2]
|
11
|
-
|
12
|
-
desc "install APP_NAME", "install one of the available apps" # [3]
|
13
|
-
method_options :force => :boolean, :alias => :optional # [4]
|
14
|
-
def install(name)
|
15
|
-
user_alias = options[:alias]
|
16
|
-
if options.force?
|
17
|
-
# do something
|
18
|
-
end
|
19
|
-
# ... other code ...
|
20
|
-
end
|
21
|
-
|
22
|
-
desc "list [SEARCH]", "list all of the available apps, limited by SEARCH"
|
23
|
-
def list(search = "")
|
24
|
-
# list everything
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
Thor automatically maps commands as such:
|
29
|
-
|
30
|
-
app install myname --force
|
31
|
-
|
32
|
-
That gets converted to:
|
33
|
-
|
34
|
-
MyApp.new.install("myname")
|
35
|
-
# with {'force' => true} as options hash
|
36
|
-
|
37
|
-
1. Inherit from Thor to turn a class into an option mapper
|
38
|
-
2. Map additional non-valid identifiers to specific methods. In this case,
|
39
|
-
convert -L to :list
|
40
|
-
3. Describe the method immediately below. The first parameter is the usage information,
|
41
|
-
and the second parameter is the description.
|
42
|
-
4. Provide any additional options. These will be marshaled from `--` and `-` params.
|
43
|
-
In this case, a `--force` and a `-f` option is added.
|
44
|
-
|
45
|
-
Types for `method_options`
|
46
|
-
--------------------------
|
47
|
-
|
48
|
-
<dl>
|
49
|
-
<dt><code>:boolean</code></dt>
|
50
|
-
<dd>true if the option is passed</dd>
|
51
|
-
<dt><code>true</code></dt>
|
52
|
-
<dd>same as <code>:boolean</code></dd>
|
53
|
-
<dt><code>:required</code></dt>
|
54
|
-
<dd>the value for this option MUST be provided</dd>
|
55
|
-
<dt><code>:optional</code></dt>
|
56
|
-
<dd>the value for this option MAY be provided</dd>
|
57
|
-
<dt><code>:numeric</code></dt>
|
58
|
-
<dd>the value MAY be provided, but MUST be in numeric form</dd>
|
59
|
-
<dt>a String or Numeric</dt>
|
60
|
-
<dd>same as <code>:optional</code>, but fall back to the given object as default value</dd>
|
61
|
-
</dl>
|
62
|
-
|
63
|
-
In case of unsatisfied requirements, `Thor::Options::Error` is raised.
|
64
|
-
|
65
|
-
Examples of option parsing:
|
66
|
-
|
67
|
-
# let's say this is how we defined options for a method:
|
68
|
-
method_options(:force => :boolean, :retries => :numeric)
|
69
|
-
|
70
|
-
# here is how the following command-line invocations would be parsed:
|
71
|
-
|
72
|
-
command -f --retries 5 # => {'force' => true, 'retries' => 5}
|
73
|
-
command --force -r=5 # => {'force' => true, 'retries' => 5}
|
74
|
-
command -fr 5 # => {'force' => true, 'retries' => 5}
|
75
|
-
command --retries=5 # => {'retries' => 5}
|
76
|
-
command -r5 # => {'retries' => 5}
|
data/Rakefile
DELETED
data/lib/thor/options.rb
DELETED
@@ -1,242 +0,0 @@
|
|
1
|
-
# This is a modified version of Daniel Berger's Getopt::Long class,
|
2
|
-
# licensed under Ruby's license.
|
3
|
-
|
4
|
-
class Thor
|
5
|
-
class Options
|
6
|
-
class Error < StandardError; end
|
7
|
-
|
8
|
-
# simple Hash with indifferent access
|
9
|
-
class Hash < ::Hash
|
10
|
-
def initialize(hash)
|
11
|
-
super()
|
12
|
-
update hash
|
13
|
-
end
|
14
|
-
|
15
|
-
def [](key)
|
16
|
-
super convert_key(key)
|
17
|
-
end
|
18
|
-
|
19
|
-
def values_at(*indices)
|
20
|
-
indices.collect { |key| self[convert_key(key)] }
|
21
|
-
end
|
22
|
-
|
23
|
-
protected
|
24
|
-
def convert_key(key)
|
25
|
-
key.kind_of?(Symbol) ? key.to_s : key
|
26
|
-
end
|
27
|
-
|
28
|
-
# Magic predicates. For instance:
|
29
|
-
# options.force? # => !!options['force']
|
30
|
-
def method_missing(method, *args, &block)
|
31
|
-
method.to_s =~ /^(\w+)\?$/ ? !!self[$1] : super
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
NUMERIC = /(\d*\.\d+|\d+)/
|
36
|
-
LONG_RE = /^(--\w+[-\w+]*)$/
|
37
|
-
SHORT_RE = /^(-[a-z])$/i
|
38
|
-
EQ_RE = /^(--\w+[-\w+]*|-[a-z])=(.*)$/i
|
39
|
-
SHORT_SQ_RE = /^-([a-z]{2,})$/i # Allow either -x -v or -xv style for single char args
|
40
|
-
SHORT_NUM = /^(-[a-z])#{NUMERIC}$/i
|
41
|
-
|
42
|
-
attr_reader :leading_non_opts, :trailing_non_opts
|
43
|
-
|
44
|
-
def non_opts
|
45
|
-
leading_non_opts + trailing_non_opts
|
46
|
-
end
|
47
|
-
|
48
|
-
# Takes an array of switches. Each array consists of up to three
|
49
|
-
# elements that indicate the name and type of switch. Returns a hash
|
50
|
-
# containing each switch name, minus the '-', as a key. The value
|
51
|
-
# for each key depends on the type of switch and/or the value provided
|
52
|
-
# by the user.
|
53
|
-
#
|
54
|
-
# The long switch _must_ be provided. The short switch defaults to the
|
55
|
-
# first letter of the short switch. The default type is :boolean.
|
56
|
-
#
|
57
|
-
# Example:
|
58
|
-
#
|
59
|
-
# opts = Thor::Options.new(
|
60
|
-
# "--debug" => true,
|
61
|
-
# ["--verbose", "-v"] => true,
|
62
|
-
# ["--level", "-l"] => :numeric
|
63
|
-
# ).parse(args)
|
64
|
-
#
|
65
|
-
def initialize(switches)
|
66
|
-
@defaults = {}
|
67
|
-
@shorts = {}
|
68
|
-
|
69
|
-
@leading_non_opts, @trailing_non_opts = [], []
|
70
|
-
|
71
|
-
@switches = switches.inject({}) do |mem, (name, type)|
|
72
|
-
if name.is_a?(Array)
|
73
|
-
name, *shorts = name
|
74
|
-
else
|
75
|
-
name = name.to_s
|
76
|
-
shorts = []
|
77
|
-
end
|
78
|
-
# we need both nice and dasherized form of switch name
|
79
|
-
if name.index('-') == 0
|
80
|
-
nice_name = undasherize name
|
81
|
-
else
|
82
|
-
nice_name = name
|
83
|
-
name = dasherize name
|
84
|
-
end
|
85
|
-
# if there are no shortcuts specified, generate one using the first character
|
86
|
-
shorts << "-" + nice_name[0,1] if shorts.empty? and nice_name.length > 1
|
87
|
-
shorts.each { |short| @shorts[short] = name }
|
88
|
-
|
89
|
-
# normalize type
|
90
|
-
case type
|
91
|
-
when TrueClass then type = :boolean
|
92
|
-
when String
|
93
|
-
@defaults[nice_name] = type
|
94
|
-
type = :optional
|
95
|
-
when Numeric
|
96
|
-
@defaults[nice_name] = type
|
97
|
-
type = :numeric
|
98
|
-
end
|
99
|
-
|
100
|
-
mem[name] = type
|
101
|
-
mem
|
102
|
-
end
|
103
|
-
|
104
|
-
# remove shortcuts that happen to coincide with any of the main switches
|
105
|
-
@shorts.keys.each do |short|
|
106
|
-
@shorts.delete(short) if @switches.key?(short)
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
def parse(args, skip_leading_non_opts = true)
|
111
|
-
@args = args
|
112
|
-
# start with Thor::Options::Hash pre-filled with defaults
|
113
|
-
hash = Hash.new @defaults
|
114
|
-
|
115
|
-
@leading_non_opts = []
|
116
|
-
if skip_leading_non_opts
|
117
|
-
@leading_non_opts << shift until current_is_option? || @args.empty?
|
118
|
-
end
|
119
|
-
|
120
|
-
while current_is_option?
|
121
|
-
case shift
|
122
|
-
when SHORT_SQ_RE
|
123
|
-
unshift $1.split('').map { |f| "-#{f}" }
|
124
|
-
next
|
125
|
-
when EQ_RE, SHORT_NUM
|
126
|
-
unshift $2
|
127
|
-
switch = $1
|
128
|
-
when LONG_RE, SHORT_RE
|
129
|
-
switch = $1
|
130
|
-
end
|
131
|
-
|
132
|
-
switch = normalize_switch(switch)
|
133
|
-
nice_name = undasherize(switch)
|
134
|
-
type = switch_type(switch)
|
135
|
-
|
136
|
-
case type
|
137
|
-
when :required
|
138
|
-
assert_value!(switch)
|
139
|
-
raise Error, "cannot pass switch '#{peek}' as an argument" if valid?(peek)
|
140
|
-
hash[nice_name] = shift
|
141
|
-
when :optional
|
142
|
-
hash[nice_name] = peek.nil? || valid?(peek) || shift
|
143
|
-
when :boolean
|
144
|
-
hash[nice_name] = true
|
145
|
-
when :numeric
|
146
|
-
assert_value!(switch)
|
147
|
-
unless peek =~ NUMERIC and $& == peek
|
148
|
-
raise Error, "expected numeric value for '#{switch}'; got #{peek.inspect}"
|
149
|
-
end
|
150
|
-
hash[nice_name] = $&.index('.') ? shift.to_f : shift.to_i
|
151
|
-
end
|
152
|
-
end
|
153
|
-
|
154
|
-
@trailing_non_opts = @args
|
155
|
-
|
156
|
-
check_required! hash
|
157
|
-
hash.freeze
|
158
|
-
hash
|
159
|
-
end
|
160
|
-
|
161
|
-
def formatted_usage
|
162
|
-
return "" if @switches.empty?
|
163
|
-
@switches.map do |opt, type|
|
164
|
-
case type
|
165
|
-
when :boolean
|
166
|
-
"[#{opt}]"
|
167
|
-
when :required
|
168
|
-
opt + "=" + opt.gsub(/\-/, "").upcase
|
169
|
-
else
|
170
|
-
sample = @defaults[undasherize(opt)]
|
171
|
-
sample ||= case type
|
172
|
-
when :optional then undasherize(opt).gsub(/\-/, "_").upcase
|
173
|
-
when :numeric then "N"
|
174
|
-
end
|
175
|
-
"[" + opt + "=" + sample.to_s + "]"
|
176
|
-
end
|
177
|
-
end.join(" ")
|
178
|
-
end
|
179
|
-
|
180
|
-
alias :to_s :formatted_usage
|
181
|
-
|
182
|
-
private
|
183
|
-
|
184
|
-
def assert_value!(switch)
|
185
|
-
raise Error, "no value provided for argument '#{switch}'" if peek.nil?
|
186
|
-
end
|
187
|
-
|
188
|
-
def undasherize(str)
|
189
|
-
str.sub(/^-{1,2}/, '')
|
190
|
-
end
|
191
|
-
|
192
|
-
def dasherize(str)
|
193
|
-
(str.length > 1 ? "--" : "-") + str
|
194
|
-
end
|
195
|
-
|
196
|
-
def peek
|
197
|
-
@args.first
|
198
|
-
end
|
199
|
-
|
200
|
-
def shift
|
201
|
-
@args.shift
|
202
|
-
end
|
203
|
-
|
204
|
-
def unshift(arg)
|
205
|
-
unless arg.kind_of?(Array)
|
206
|
-
@args.unshift(arg)
|
207
|
-
else
|
208
|
-
@args = arg + @args
|
209
|
-
end
|
210
|
-
end
|
211
|
-
|
212
|
-
def valid?(arg)
|
213
|
-
@switches.key?(arg) or @shorts.key?(arg)
|
214
|
-
end
|
215
|
-
|
216
|
-
def current_is_option?
|
217
|
-
case peek
|
218
|
-
when LONG_RE, SHORT_RE, EQ_RE, SHORT_NUM
|
219
|
-
valid?($1)
|
220
|
-
when SHORT_SQ_RE
|
221
|
-
$1.split('').any? { |f| valid?("-#{f}") }
|
222
|
-
end
|
223
|
-
end
|
224
|
-
|
225
|
-
def normalize_switch(switch)
|
226
|
-
@shorts.key?(switch) ? @shorts[switch] : switch
|
227
|
-
end
|
228
|
-
|
229
|
-
def switch_type(switch)
|
230
|
-
@switches[switch]
|
231
|
-
end
|
232
|
-
|
233
|
-
def check_required!(hash)
|
234
|
-
for name, type in @switches
|
235
|
-
if type == :required and !hash[undasherize(name)]
|
236
|
-
raise Error, "no value provided for required argument '#{name}'"
|
237
|
-
end
|
238
|
-
end
|
239
|
-
end
|
240
|
-
|
241
|
-
end
|
242
|
-
end
|