botanicus-thor 0.9.8
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 +52 -0
- data/LICENSE +20 -0
- data/README.markdown +76 -0
- data/Rakefile +6 -0
- data/bin/rake2thor +88 -0
- data/bin/thor +7 -0
- data/lib/thor/error.rb +5 -0
- data/lib/thor/options.rb +269 -0
- data/lib/thor/runner.rb +344 -0
- data/lib/thor/task.rb +85 -0
- data/lib/thor/task_hash.rb +23 -0
- data/lib/thor/tasks/package.rb +20 -0
- data/lib/thor/tasks.rb +88 -0
- data/lib/thor/util.rb +77 -0
- data/lib/thor.rb +177 -0
- metadata +72 -0
data/lib/thor.rb
ADDED
@@ -0,0 +1,177 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
$:.unshift File.expand_path(File.dirname(__FILE__))
|
4
|
+
|
5
|
+
require "thor/options"
|
6
|
+
require "thor/util"
|
7
|
+
require "thor/task"
|
8
|
+
require "thor/task_hash"
|
9
|
+
|
10
|
+
class Thor
|
11
|
+
attr_accessor :options
|
12
|
+
|
13
|
+
def self.default_task(meth=nil)
|
14
|
+
unless meth.nil?
|
15
|
+
@default_task = (meth == :none) ? 'help' : meth.to_s
|
16
|
+
end
|
17
|
+
@default_task ||= (self == Thor ? 'help' : superclass.default_task)
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.map(map)
|
21
|
+
@map ||= superclass.instance_variable_get("@map") || {}
|
22
|
+
map.each do |key, value|
|
23
|
+
if key.respond_to?(:each)
|
24
|
+
key.each {|subkey| @map[subkey] = value}
|
25
|
+
else
|
26
|
+
@map[key] = value
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.desc(usage, description)
|
32
|
+
@usage, @desc = usage, description
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.group(name)
|
36
|
+
@group_name = name.to_s
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.group_name
|
40
|
+
@group_name || 'standard'
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.method_options(opts)
|
44
|
+
@method_options = (@method_options || {}).merge(opts)
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.subclass_files
|
48
|
+
@subclass_files ||= Hash.new {|h,k| h[k] = []}
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.subclasses
|
52
|
+
@subclasses ||= []
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.tasks
|
56
|
+
@tasks ||= TaskHash.new(self)
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.opts
|
60
|
+
(@opts || {}).merge(self == Thor ? {} : superclass.opts)
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.[](task)
|
64
|
+
namespaces = task.split(":")
|
65
|
+
klass = Thor::Util.constant_from_thor_path(namespaces[0...-1].join(":"))
|
66
|
+
raise Error, "`#{klass}' is not a Thor class" unless klass <= Thor
|
67
|
+
klass.tasks[namespaces.last]
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.maxima
|
71
|
+
@maxima ||= begin
|
72
|
+
max_usage = tasks.map {|_, t| t.usage}.max {|x,y| x.to_s.size <=> y.to_s.size}.size
|
73
|
+
max_desc = tasks.map {|_, t| t.description}.max {|x,y| x.to_s.size <=> y.to_s.size}.size
|
74
|
+
max_opts = tasks.map {|_, t| t.opts ? t.opts.formatted_usage : ""}.max {|x,y| x.to_s.size <=> y.to_s.size}.size
|
75
|
+
Struct.new(:description, :usage, :opt).new(max_desc, max_usage, max_opts)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def self.start(args = ARGV)
|
80
|
+
|
81
|
+
options = Thor::Options.new(self.opts)
|
82
|
+
opts = options.parse(args, false)
|
83
|
+
args = options.trailing_non_opts
|
84
|
+
|
85
|
+
meth = args.first
|
86
|
+
meth = @map[meth].to_s if @map && @map[meth]
|
87
|
+
meth ||= default_task
|
88
|
+
meth = meth.to_s.gsub('-','_') # treat foo-bar > foo_bar
|
89
|
+
|
90
|
+
tasks[meth].parse new(opts, *args), args[1..-1]
|
91
|
+
rescue Thor::Error => e
|
92
|
+
$stderr.puts e.message
|
93
|
+
end
|
94
|
+
|
95
|
+
# Invokes a specific task. You can use this method instead of start()
|
96
|
+
# to run a thor task if you know the specific task you want to invoke.
|
97
|
+
def self.invoke(task_name=nil, args = ARGV)
|
98
|
+
args = args.dup
|
99
|
+
args.unshift(task_name || default_task)
|
100
|
+
start(args)
|
101
|
+
end
|
102
|
+
|
103
|
+
# Main entry point method that should actually invoke the method. You
|
104
|
+
# can override this to provide some class-wide processing. The default
|
105
|
+
# implementation simply invokes the named method
|
106
|
+
def invoke(meth, *args)
|
107
|
+
self.send(meth, *args)
|
108
|
+
end
|
109
|
+
|
110
|
+
class << self
|
111
|
+
protected
|
112
|
+
def inherited(klass)
|
113
|
+
register_klass_file klass
|
114
|
+
end
|
115
|
+
|
116
|
+
def method_added(meth)
|
117
|
+
meth = meth.to_sym # for Ruby 1.8
|
118
|
+
if meth == :initialize
|
119
|
+
@opts = @method_options
|
120
|
+
@method_options = nil
|
121
|
+
return
|
122
|
+
end
|
123
|
+
|
124
|
+
if RUBY_VERSION.match(/^1.9/)
|
125
|
+
return if !public_instance_methods.include?(meth) || !@usage
|
126
|
+
else
|
127
|
+
return if !public_instance_methods.include?(meth.to_s) || !@usage
|
128
|
+
end
|
129
|
+
|
130
|
+
register_klass_file self
|
131
|
+
|
132
|
+
tasks[meth] = Task.new(meth, @desc, @usage, @method_options)
|
133
|
+
|
134
|
+
@usage, @desc, @method_options = nil
|
135
|
+
end
|
136
|
+
|
137
|
+
def register_klass_file(klass, file = caller[1].match(/(.*):\d+/)[1])
|
138
|
+
unless self == Thor
|
139
|
+
superclass.register_klass_file(klass, file)
|
140
|
+
return
|
141
|
+
end
|
142
|
+
|
143
|
+
file_subclasses = subclass_files[File.expand_path(file)]
|
144
|
+
file_subclasses << klass unless file_subclasses.include?(klass)
|
145
|
+
subclasses << klass unless subclasses.include?(klass)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
def initialize(opts = {}, *args)
|
150
|
+
end
|
151
|
+
|
152
|
+
map ["-h", "-?", "--help", "-D"] => :help
|
153
|
+
|
154
|
+
desc "help [TASK]", "describe available tasks or one specific task"
|
155
|
+
def help(task = nil)
|
156
|
+
if task
|
157
|
+
if task.include? ?:
|
158
|
+
task = self.class[task]
|
159
|
+
namespace = true
|
160
|
+
else
|
161
|
+
task = self.class.tasks[task]
|
162
|
+
end
|
163
|
+
|
164
|
+
puts task.formatted_usage(namespace)
|
165
|
+
puts task.description
|
166
|
+
else
|
167
|
+
puts "Options"
|
168
|
+
puts "-------"
|
169
|
+
self.class.tasks.each do |_, task|
|
170
|
+
format = "%-" + (self.class.maxima.usage + self.class.maxima.opt + 4).to_s + "s"
|
171
|
+
print format % ("#{task.formatted_usage}")
|
172
|
+
puts task.description.split("\n").first
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
end
|
metadata
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: botanicus-thor
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.9.8
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Yehuda Katz
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-08-27 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: A gem that maps options to a class
|
17
|
+
email: wycats@gmail.com
|
18
|
+
executables:
|
19
|
+
- thor
|
20
|
+
- rake2thor
|
21
|
+
extensions: []
|
22
|
+
|
23
|
+
extra_rdoc_files:
|
24
|
+
- README.markdown
|
25
|
+
- CHANGELOG.rdoc
|
26
|
+
- LICENSE
|
27
|
+
files:
|
28
|
+
- README.markdown
|
29
|
+
- LICENSE
|
30
|
+
- CHANGELOG.rdoc
|
31
|
+
- Rakefile
|
32
|
+
- bin/rake2thor
|
33
|
+
- bin/thor
|
34
|
+
- lib/thor
|
35
|
+
- lib/thor/error.rb
|
36
|
+
- lib/thor/options.rb
|
37
|
+
- lib/thor/runner.rb
|
38
|
+
- lib/thor/task.rb
|
39
|
+
- lib/thor/task_hash.rb
|
40
|
+
- lib/thor/tasks
|
41
|
+
- lib/thor/tasks/package.rb
|
42
|
+
- lib/thor/tasks.rb
|
43
|
+
- lib/thor/util.rb
|
44
|
+
- lib/thor.rb
|
45
|
+
has_rdoc: true
|
46
|
+
homepage: http://yehudakatz.com
|
47
|
+
post_install_message:
|
48
|
+
rdoc_options: []
|
49
|
+
|
50
|
+
require_paths:
|
51
|
+
- lib
|
52
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: "0"
|
57
|
+
version:
|
58
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: "0"
|
63
|
+
version:
|
64
|
+
requirements: []
|
65
|
+
|
66
|
+
rubyforge_project: thor
|
67
|
+
rubygems_version: 1.2.0
|
68
|
+
signing_key:
|
69
|
+
specification_version: 2
|
70
|
+
summary: A gem that maps options to a class
|
71
|
+
test_files: []
|
72
|
+
|