textgoeshere-daemon-kit 0.1.8rc3

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.
Files changed (185) hide show
  1. data/.gitignore +5 -0
  2. data/Configuration.txt +110 -0
  3. data/Deployment.txt +113 -0
  4. data/History.txt +124 -0
  5. data/Logging.txt +96 -0
  6. data/PostInstall.txt +6 -0
  7. data/README.rdoc +128 -0
  8. data/Rakefile +29 -0
  9. data/RuoteParticipants.txt +113 -0
  10. data/TODO.txt +27 -0
  11. data/bin/daemon-kit +18 -0
  12. data/config/website.yml +2 -0
  13. data/daemon-kit.gemspec +265 -0
  14. data/lib/daemon_kit/abstract_logger.rb +249 -0
  15. data/lib/daemon_kit/amqp.rb +39 -0
  16. data/lib/daemon_kit/application.rb +230 -0
  17. data/lib/daemon_kit/arguments.rb +165 -0
  18. data/lib/daemon_kit/commands/console.rb +38 -0
  19. data/lib/daemon_kit/commands/destroy.rb +10 -0
  20. data/lib/daemon_kit/commands/generate.rb +10 -0
  21. data/lib/daemon_kit/config.rb +113 -0
  22. data/lib/daemon_kit/console_daemon.rb +2 -0
  23. data/lib/daemon_kit/core_ext/configurable.rb +96 -0
  24. data/lib/daemon_kit/core_ext/string.rb +22 -0
  25. data/lib/daemon_kit/core_ext.rb +1 -0
  26. data/lib/daemon_kit/cron.rb +48 -0
  27. data/lib/daemon_kit/cucumber/world.rb +38 -0
  28. data/lib/daemon_kit/deployment/capistrano.rb +516 -0
  29. data/lib/daemon_kit/em.rb +43 -0
  30. data/lib/daemon_kit/error_handlers/base.rb +32 -0
  31. data/lib/daemon_kit/error_handlers/hoptoad.rb +180 -0
  32. data/lib/daemon_kit/exceptions.rb +15 -0
  33. data/lib/daemon_kit/generators/base.rb +60 -0
  34. data/lib/daemon_kit/generators.rb +67 -0
  35. data/lib/daemon_kit/initializer.rb +453 -0
  36. data/lib/daemon_kit/jabber.rb +171 -0
  37. data/lib/daemon_kit/nanite/agent.rb +77 -0
  38. data/lib/daemon_kit/nanite.rb +7 -0
  39. data/lib/daemon_kit/pid_file.rb +61 -0
  40. data/lib/daemon_kit/ruote_participants.rb +125 -0
  41. data/lib/daemon_kit/ruote_pseudo_participant.rb +68 -0
  42. data/lib/daemon_kit/ruote_workitem.rb +187 -0
  43. data/lib/daemon_kit/safety.rb +84 -0
  44. data/lib/daemon_kit/tasks/environment.rake +10 -0
  45. data/lib/daemon_kit/tasks/framework.rake +123 -0
  46. data/lib/daemon_kit/tasks/god.rake +62 -0
  47. data/lib/daemon_kit/tasks/log.rake +8 -0
  48. data/lib/daemon_kit/tasks/monit.rake +29 -0
  49. data/lib/daemon_kit/tasks.rb +2 -0
  50. data/lib/daemon_kit/vendor/thor-0.13.6/CHANGELOG.rdoc +89 -0
  51. data/lib/daemon_kit/vendor/thor-0.13.6/LICENSE +20 -0
  52. data/lib/daemon_kit/vendor/thor-0.13.6/README.rdoc +297 -0
  53. data/lib/daemon_kit/vendor/thor-0.13.6/Thorfile +69 -0
  54. data/lib/daemon_kit/vendor/thor-0.13.6/lib/thor/actions/create_file.rb +103 -0
  55. data/lib/daemon_kit/vendor/thor-0.13.6/lib/thor/actions/directory.rb +91 -0
  56. data/lib/daemon_kit/vendor/thor-0.13.6/lib/thor/actions/empty_directory.rb +134 -0
  57. data/lib/daemon_kit/vendor/thor-0.13.6/lib/thor/actions/file_manipulation.rb +223 -0
  58. data/lib/daemon_kit/vendor/thor-0.13.6/lib/thor/actions/inject_into_file.rb +104 -0
  59. data/lib/daemon_kit/vendor/thor-0.13.6/lib/thor/actions.rb +296 -0
  60. data/lib/daemon_kit/vendor/thor-0.13.6/lib/thor/base.rb +540 -0
  61. data/lib/daemon_kit/vendor/thor-0.13.6/lib/thor/core_ext/file_binary_read.rb +9 -0
  62. data/lib/daemon_kit/vendor/thor-0.13.6/lib/thor/core_ext/hash_with_indifferent_access.rb +75 -0
  63. data/lib/daemon_kit/vendor/thor-0.13.6/lib/thor/core_ext/ordered_hash.rb +100 -0
  64. data/lib/daemon_kit/vendor/thor-0.13.6/lib/thor/error.rb +30 -0
  65. data/lib/daemon_kit/vendor/thor-0.13.6/lib/thor/group.rb +271 -0
  66. data/lib/daemon_kit/vendor/thor-0.13.6/lib/thor/invocation.rb +180 -0
  67. data/lib/daemon_kit/vendor/thor-0.13.6/lib/thor/parser/argument.rb +67 -0
  68. data/lib/daemon_kit/vendor/thor-0.13.6/lib/thor/parser/arguments.rb +150 -0
  69. data/lib/daemon_kit/vendor/thor-0.13.6/lib/thor/parser/option.rb +128 -0
  70. data/lib/daemon_kit/vendor/thor-0.13.6/lib/thor/parser/options.rb +169 -0
  71. data/lib/daemon_kit/vendor/thor-0.13.6/lib/thor/parser.rb +4 -0
  72. data/lib/daemon_kit/vendor/thor-0.13.6/lib/thor/rake_compat.rb +66 -0
  73. data/lib/daemon_kit/vendor/thor-0.13.6/lib/thor/runner.rb +314 -0
  74. data/lib/daemon_kit/vendor/thor-0.13.6/lib/thor/shell/basic.rb +239 -0
  75. data/lib/daemon_kit/vendor/thor-0.13.6/lib/thor/shell/color.rb +108 -0
  76. data/lib/daemon_kit/vendor/thor-0.13.6/lib/thor/shell.rb +83 -0
  77. data/lib/daemon_kit/vendor/thor-0.13.6/lib/thor/task.rb +102 -0
  78. data/lib/daemon_kit/vendor/thor-0.13.6/lib/thor/util.rb +224 -0
  79. data/lib/daemon_kit/vendor/thor-0.13.6/lib/thor/version.rb +3 -0
  80. data/lib/daemon_kit/vendor/thor-0.13.6/lib/thor.rb +244 -0
  81. data/lib/daemon_kit/xmpp.rb +100 -0
  82. data/lib/daemon_kit.rb +59 -0
  83. data/lib/generators/daemon_kit/amqp/USAGE +5 -0
  84. data/lib/generators/daemon_kit/amqp/amqp_generator.rb +24 -0
  85. data/lib/generators/daemon_kit/amqp/templates/config/amqp.yml +28 -0
  86. data/lib/generators/daemon_kit/amqp/templates/config/pre-daemonize/amqp.rb +7 -0
  87. data/lib/generators/daemon_kit/amqp/templates/libexec/%app_name%-daemon.rb +37 -0
  88. data/lib/generators/daemon_kit/app/USAGE +7 -0
  89. data/lib/generators/daemon_kit/app/app_generator.rb +140 -0
  90. data/lib/generators/daemon_kit/app/templates/Gemfile +8 -0
  91. data/lib/generators/daemon_kit/app/templates/README.tt +58 -0
  92. data/lib/generators/daemon_kit/app/templates/Rakefile +6 -0
  93. data/lib/generators/daemon_kit/app/templates/bin/daemon.tt +7 -0
  94. data/lib/generators/daemon_kit/app/templates/config/arguments.rb +12 -0
  95. data/lib/generators/daemon_kit/app/templates/config/boot.rb +70 -0
  96. data/lib/generators/daemon_kit/app/templates/config/environment.rb.tt +26 -0
  97. data/lib/generators/daemon_kit/app/templates/config/environments/development.rb +2 -0
  98. data/lib/generators/daemon_kit/app/templates/config/environments/production.rb +5 -0
  99. data/lib/generators/daemon_kit/app/templates/config/environments/test.rb +2 -0
  100. data/lib/generators/daemon_kit/app/templates/config/post-daemonize/readme +5 -0
  101. data/lib/generators/daemon_kit/app/templates/config/pre-daemonize/readme +12 -0
  102. data/lib/generators/daemon_kit/app/templates/lib/%app_name%.rb +2 -0
  103. data/lib/generators/daemon_kit/app/templates/libexec/%app_name%-daemon.rb +18 -0
  104. data/lib/generators/daemon_kit/app/templates/script/console +3 -0
  105. data/lib/generators/daemon_kit/app/templates/script/destroy +3 -0
  106. data/lib/generators/daemon_kit/app/templates/script/generate +3 -0
  107. data/lib/generators/daemon_kit/capistrano/capistrano_generator.rb +26 -0
  108. data/lib/generators/daemon_kit/capistrano/templates/Capfile +10 -0
  109. data/lib/generators/daemon_kit/capistrano/templates/USAGE +10 -0
  110. data/lib/generators/daemon_kit/capistrano/templates/config/deploy/logrotate.erb +13 -0
  111. data/lib/generators/daemon_kit/capistrano/templates/config/deploy/production.rb.tt +6 -0
  112. data/lib/generators/daemon_kit/capistrano/templates/config/deploy/staging.rb.tt +6 -0
  113. data/lib/generators/daemon_kit/capistrano/templates/config/deploy.rb.tt +67 -0
  114. data/lib/generators/daemon_kit/capistrano/templates/config/environments/staging.rb +0 -0
  115. data/lib/generators/daemon_kit/cron/USAGE +5 -0
  116. data/lib/generators/daemon_kit/cron/cron_generator.rb +24 -0
  117. data/lib/generators/daemon_kit/cron/templates/config/pre-daemonize/cron.rb +11 -0
  118. data/lib/generators/daemon_kit/cron/templates/libexec/%app_name%-daemon.rb +43 -0
  119. data/lib/generators/daemon_kit/cucumber/USAGE +11 -0
  120. data/lib/generators/daemon_kit/cucumber/cucumber_generator.rb +45 -0
  121. data/lib/generators/daemon_kit/cucumber/templates/config/environments/cucumber.rb +2 -0
  122. data/lib/generators/daemon_kit/cucumber/templates/features/step_definitions/.empty_directory +0 -0
  123. data/lib/generators/daemon_kit/cucumber/templates/features/support/env.rb +7 -0
  124. data/lib/generators/daemon_kit/cucumber/templates/script/cucumber +7 -0
  125. data/lib/generators/daemon_kit/cucumber/templates/tasks/cucumber.rake +13 -0
  126. data/lib/generators/daemon_kit/nanite_agent/USAGE +5 -0
  127. data/lib/generators/daemon_kit/nanite_agent/nanite_agent_generator.rb +29 -0
  128. data/lib/generators/daemon_kit/nanite_agent/templates/config/nanite.yml +35 -0
  129. data/lib/generators/daemon_kit/nanite_agent/templates/config/pre-daemonize/nanite_agent.rb +6 -0
  130. data/lib/generators/daemon_kit/nanite_agent/templates/lib/actors/sample.rb +11 -0
  131. data/lib/generators/daemon_kit/nanite_agent/templates/libexec/%app_name%-daemon.rb +31 -0
  132. data/lib/generators/daemon_kit/rspec/USAGE +5 -0
  133. data/lib/generators/daemon_kit/rspec/rspec_generator.rb +20 -0
  134. data/lib/generators/daemon_kit/rspec/templates/spec/%app_name%_spec.rb +11 -0
  135. data/lib/generators/daemon_kit/rspec/templates/spec/spec.opts +1 -0
  136. data/lib/generators/daemon_kit/rspec/templates/spec/spec_helper.rb +23 -0
  137. data/lib/generators/daemon_kit/rspec/templates/tasks/rspec.rake +19 -0
  138. data/lib/generators/daemon_kit/ruote/USAGE +5 -0
  139. data/lib/generators/daemon_kit/ruote/ruote_generator.rb +29 -0
  140. data/lib/generators/daemon_kit/ruote/templates/config/amqp.yml +30 -0
  141. data/lib/generators/daemon_kit/ruote/templates/config/pre-daemonize/ruote.rb +13 -0
  142. data/lib/generators/daemon_kit/ruote/templates/config/ruote.yml +23 -0
  143. data/lib/generators/daemon_kit/ruote/templates/lib/%app_name%.rb +4 -0
  144. data/lib/generators/daemon_kit/ruote/templates/lib/sample.rb +26 -0
  145. data/lib/generators/daemon_kit/ruote/templates/libexec/%app_name%-daemon.rb +33 -0
  146. data/lib/generators/daemon_kit/test_unit/USAGE +5 -0
  147. data/lib/generators/daemon_kit/test_unit/templates/tasks/test_unit.rake +7 -0
  148. data/lib/generators/daemon_kit/test_unit/templates/test/%app_name%_test.rb.tt +9 -0
  149. data/lib/generators/daemon_kit/test_unit/templates/test/test_helper.rb +6 -0
  150. data/lib/generators/daemon_kit/test_unit/test_unit_generator.rb +20 -0
  151. data/lib/generators/daemon_kit/xmpp/templates/config/pre-daemonize/xmpp.rb +6 -0
  152. data/lib/generators/daemon_kit/xmpp/templates/config/xmpp.yml +29 -0
  153. data/lib/generators/daemon_kit/xmpp/templates/libexec/%app_name%-daemon.rb +27 -0
  154. data/lib/generators/daemon_kit/xmpp/xmpp_generator.rb +24 -0
  155. data/script/console +10 -0
  156. data/script/destroy +14 -0
  157. data/script/generate +14 -0
  158. data/script/txt2html +71 -0
  159. data/spec/abstract_logger_spec.rb +126 -0
  160. data/spec/argument_spec.rb +70 -0
  161. data/spec/config_spec.rb +83 -0
  162. data/spec/configurable_spec.rb +56 -0
  163. data/spec/daemon_kit_spec.rb +7 -0
  164. data/spec/error_handlers_spec.rb +23 -0
  165. data/spec/fixtures/env.yml +15 -0
  166. data/spec/fixtures/noenv.yml +4 -0
  167. data/spec/initializer_spec.rb +26 -0
  168. data/spec/spec.opts +1 -0
  169. data/spec/spec_helper.rb +27 -0
  170. data/tasks/cucumber.rake +13 -0
  171. data/tasks/rspec.rake +21 -0
  172. data/tasks/tests.rake +6 -0
  173. data/templates/god/god.erb +69 -0
  174. data/templates/monit/monit.erb +14 -0
  175. data/test/test_amqp_generator.rb +48 -0
  176. data/test/test_cron_generator.rb +45 -0
  177. data/test/test_daemon-kit_generator.rb +84 -0
  178. data/test/test_daemon_kit_config.rb +28 -0
  179. data/test/test_deploy_capistrano_generator.rb +48 -0
  180. data/test/test_generator_helper.rb +29 -0
  181. data/test/test_helper.rb +7 -0
  182. data/test/test_nanite_agent_generator.rb +49 -0
  183. data/test/test_ruote_generator.rb +51 -0
  184. data/test/test_test_unit_generator.rb +46 -0
  185. metadata +325 -0
@@ -0,0 +1,224 @@
1
+ require 'rbconfig'
2
+
3
+ class Thor
4
+ module Sandbox #:nodoc:
5
+ end
6
+
7
+ # This module holds several utilities:
8
+ #
9
+ # 1) Methods to convert thor namespaces to constants and vice-versa.
10
+ #
11
+ # Thor::Utils.namespace_from_thor_class(Foo::Bar::Baz) #=> "foo:bar:baz"
12
+ #
13
+ # 2) Loading thor files and sandboxing:
14
+ #
15
+ # Thor::Utils.load_thorfile("~/.thor/foo")
16
+ #
17
+ module Util
18
+
19
+ # Receives a namespace and search for it in the Thor::Base subclasses.
20
+ #
21
+ # ==== Parameters
22
+ # namespace<String>:: The namespace to search for.
23
+ #
24
+ def self.find_by_namespace(namespace)
25
+ namespace = "default#{namespace}" if namespace.empty? || namespace =~ /^:/
26
+ Thor::Base.subclasses.find { |klass| klass.namespace == namespace }
27
+ end
28
+
29
+ # Receives a constant and converts it to a Thor namespace. Since Thor tasks
30
+ # can be added to a sandbox, this method is also responsable for removing
31
+ # the sandbox namespace.
32
+ #
33
+ # This method should not be used in general because it's used to deal with
34
+ # older versions of Thor. On current versions, if you need to get the
35
+ # namespace from a class, just call namespace on it.
36
+ #
37
+ # ==== Parameters
38
+ # constant<Object>:: The constant to be converted to the thor path.
39
+ #
40
+ # ==== Returns
41
+ # String:: If we receive Foo::Bar::Baz it returns "foo:bar:baz"
42
+ #
43
+ def self.namespace_from_thor_class(constant)
44
+ constant = constant.to_s.gsub(/^Thor::Sandbox::/, "")
45
+ constant = snake_case(constant).squeeze(":")
46
+ constant
47
+ end
48
+
49
+ # Given the contents, evaluate it inside the sandbox and returns the
50
+ # namespaces defined in the sandbox.
51
+ #
52
+ # ==== Parameters
53
+ # contents<String>
54
+ #
55
+ # ==== Returns
56
+ # Array[Object]
57
+ #
58
+ def self.namespaces_in_content(contents, file=__FILE__)
59
+ old_constants = Thor::Base.subclasses.dup
60
+ Thor::Base.subclasses.clear
61
+
62
+ load_thorfile(file, contents)
63
+
64
+ new_constants = Thor::Base.subclasses.dup
65
+ Thor::Base.subclasses.replace(old_constants)
66
+
67
+ new_constants.map!{ |c| c.namespace }
68
+ new_constants.compact!
69
+ new_constants
70
+ end
71
+
72
+ # Returns the thor classes declared inside the given class.
73
+ #
74
+ def self.thor_classes_in(klass)
75
+ stringfied_constants = klass.constants.map { |c| c.to_s }
76
+ Thor::Base.subclasses.select do |subclass|
77
+ next unless subclass.name
78
+ stringfied_constants.include?(subclass.name.gsub("#{klass.name}::", ''))
79
+ end
80
+ end
81
+
82
+ # Receives a string and convert it to snake case. SnakeCase returns snake_case.
83
+ #
84
+ # ==== Parameters
85
+ # String
86
+ #
87
+ # ==== Returns
88
+ # String
89
+ #
90
+ def self.snake_case(str)
91
+ return str.downcase if str =~ /^[A-Z_]+$/
92
+ str.gsub(/\B[A-Z]/, '_\&').squeeze('_') =~ /_*(.*)/
93
+ return $+.downcase
94
+ end
95
+
96
+ # Receives a string and convert it to camel case. camel_case returns CamelCase.
97
+ #
98
+ # ==== Parameters
99
+ # String
100
+ #
101
+ # ==== Returns
102
+ # String
103
+ #
104
+ def self.camel_case(str)
105
+ return str if str !~ /_/ && str =~ /[A-Z]+.*/
106
+ str.split('_').map { |i| i.capitalize }.join
107
+ end
108
+
109
+ # Receives a namespace and tries to retrieve a Thor or Thor::Group class
110
+ # from it. It first searches for a class using the all the given namespace,
111
+ # if it's not found, removes the highest entry and searches for the class
112
+ # again. If found, returns the highest entry as the class name.
113
+ #
114
+ # ==== Examples
115
+ #
116
+ # class Foo::Bar < Thor
117
+ # def baz
118
+ # end
119
+ # end
120
+ #
121
+ # class Baz::Foo < Thor::Group
122
+ # end
123
+ #
124
+ # Thor::Util.namespace_to_thor_class("foo:bar") #=> Foo::Bar, nil # will invoke default task
125
+ # Thor::Util.namespace_to_thor_class("baz:foo") #=> Baz::Foo, nil
126
+ # Thor::Util.namespace_to_thor_class("foo:bar:baz") #=> Foo::Bar, "baz"
127
+ #
128
+ # ==== Parameters
129
+ # namespace<String>
130
+ #
131
+ def self.find_class_and_task_by_namespace(namespace, fallback = true)
132
+ if namespace.include?(?:) # look for a namespaced task
133
+ pieces = namespace.split(":")
134
+ task = pieces.pop
135
+ klass = Thor::Util.find_by_namespace(pieces.join(":"))
136
+ end
137
+ unless klass # look for a Thor::Group with the right name
138
+ klass, task = Thor::Util.find_by_namespace(namespace), nil
139
+ end
140
+ if !klass && fallback # try a task in the default namespace
141
+ task = namespace
142
+ klass = Thor::Util.find_by_namespace('')
143
+ end
144
+ return klass, task
145
+ end
146
+
147
+ # Receives a path and load the thor file in the path. The file is evaluated
148
+ # inside the sandbox to avoid namespacing conflicts.
149
+ #
150
+ def self.load_thorfile(path, content=nil)
151
+ content ||= File.binread(path)
152
+
153
+ begin
154
+ Thor::Sandbox.class_eval(content, path)
155
+ rescue Exception => e
156
+ $stderr.puts "WARNING: unable to load thorfile #{path.inspect}: #{e.message}"
157
+ end
158
+ end
159
+
160
+ def self.user_home
161
+ @@user_home ||= if ENV["HOME"]
162
+ ENV["HOME"]
163
+ elsif ENV["USERPROFILE"]
164
+ ENV["USERPROFILE"]
165
+ elsif ENV["HOMEDRIVE"] && ENV["HOMEPATH"]
166
+ File.join(ENV["HOMEDRIVE"], ENV["HOMEPATH"])
167
+ elsif ENV["APPDATA"]
168
+ ENV["APPDATA"]
169
+ else
170
+ begin
171
+ File.expand_path("~")
172
+ rescue
173
+ if File::ALT_SEPARATOR
174
+ "C:/"
175
+ else
176
+ "/"
177
+ end
178
+ end
179
+ end
180
+ end
181
+
182
+ # Returns the root where thor files are located, dependending on the OS.
183
+ #
184
+ def self.thor_root
185
+ File.join(user_home, ".thor").gsub(/\\/, '/')
186
+ end
187
+
188
+ # Returns the files in the thor root. On Windows thor_root will be something
189
+ # like this:
190
+ #
191
+ # C:\Documents and Settings\james\.thor
192
+ #
193
+ # If we don't #gsub the \ character, Dir.glob will fail.
194
+ #
195
+ def self.thor_root_glob
196
+ files = Dir["#{thor_root}/*"]
197
+
198
+ files.map! do |file|
199
+ File.directory?(file) ? File.join(file, "main.thor") : file
200
+ end
201
+ end
202
+
203
+ # Where to look for Thor files.
204
+ #
205
+ def self.globs_for(path)
206
+ ["#{path}/Thorfile", "#{path}/*.thor", "#{path}/tasks/*.thor", "#{path}/lib/tasks/*.thor"]
207
+ end
208
+
209
+ # Return the path to the ruby interpreter taking into account multiple
210
+ # installations and windows extensions.
211
+ #
212
+ def self.ruby_command
213
+ @ruby_command ||= begin
214
+ ruby = File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name'])
215
+ ruby << Config::CONFIG['EXEEXT']
216
+
217
+ # escape string in case path to ruby executable contain spaces.
218
+ ruby.sub!(/.*\s.*/m, '"\&"')
219
+ ruby
220
+ end
221
+ end
222
+
223
+ end
224
+ end
@@ -0,0 +1,3 @@
1
+ class Thor
2
+ VERSION = "0.13.6".freeze
3
+ end
@@ -0,0 +1,244 @@
1
+ require 'thor/base'
2
+
3
+ # TODO: Update thor to allow for git-style CLI (git bisect run)
4
+ class Thor
5
+ class << self
6
+ # Sets the default task when thor is executed without an explicit task to be called.
7
+ #
8
+ # ==== Parameters
9
+ # meth<Symbol>:: name of the defaut task
10
+ #
11
+ def default_task(meth=nil)
12
+ case meth
13
+ when :none
14
+ @default_task = 'help'
15
+ when nil
16
+ @default_task ||= from_superclass(:default_task, 'help')
17
+ else
18
+ @default_task = meth.to_s
19
+ end
20
+ end
21
+
22
+ # Defines the usage and the description of the next task.
23
+ #
24
+ # ==== Parameters
25
+ # usage<String>
26
+ # description<String>
27
+ #
28
+ def desc(usage, description, options={})
29
+ if options[:for]
30
+ task = find_and_refresh_task(options[:for])
31
+ task.usage = usage if usage
32
+ task.description = description if description
33
+ else
34
+ @usage, @desc = usage, description
35
+ end
36
+ end
37
+
38
+ # Maps an input to a task. If you define:
39
+ #
40
+ # map "-T" => "list"
41
+ #
42
+ # Running:
43
+ #
44
+ # thor -T
45
+ #
46
+ # Will invoke the list task.
47
+ #
48
+ # ==== Parameters
49
+ # Hash[String|Array => Symbol]:: Maps the string or the strings in the array to the given task.
50
+ #
51
+ def map(mappings=nil)
52
+ @map ||= from_superclass(:map, {})
53
+
54
+ if mappings
55
+ mappings.each do |key, value|
56
+ if key.respond_to?(:each)
57
+ key.each {|subkey| @map[subkey] = value}
58
+ else
59
+ @map[key] = value
60
+ end
61
+ end
62
+ end
63
+
64
+ @map
65
+ end
66
+
67
+ # Declares the options for the next task to be declared.
68
+ #
69
+ # ==== Parameters
70
+ # Hash[Symbol => Object]:: The hash key is the name of the option and the value
71
+ # is the type of the option. Can be :string, :array, :hash, :boolean, :numeric
72
+ # or :required (string). If you give a value, the type of the value is used.
73
+ #
74
+ def method_options(options=nil)
75
+ @method_options ||= {}
76
+ build_options(options, @method_options) if options
77
+ @method_options
78
+ end
79
+
80
+ # Adds an option to the set of method options. If :for is given as option,
81
+ # it allows you to change the options from a previous defined task.
82
+ #
83
+ # def previous_task
84
+ # # magic
85
+ # end
86
+ #
87
+ # method_option :foo => :bar, :for => :previous_task
88
+ #
89
+ # def next_task
90
+ # # magic
91
+ # end
92
+ #
93
+ # ==== Parameters
94
+ # name<Symbol>:: The name of the argument.
95
+ # options<Hash>:: Described below.
96
+ #
97
+ # ==== Options
98
+ # :desc - Description for the argument.
99
+ # :required - If the argument is required or not.
100
+ # :default - Default value for this argument. It cannot be required and have default values.
101
+ # :aliases - Aliases for this option.
102
+ # :type - The type of the argument, can be :string, :hash, :array, :numeric or :boolean.
103
+ # :banner - String to show on usage notes.
104
+ #
105
+ def method_option(name, options={})
106
+ scope = if options[:for]
107
+ find_and_refresh_task(options[:for]).options
108
+ else
109
+ method_options
110
+ end
111
+
112
+ build_option(name, options, scope)
113
+ end
114
+
115
+ # Parses the task and options from the given args, instantiate the class
116
+ # and invoke the task. This method is used when the arguments must be parsed
117
+ # from an array. If you are inside Ruby and want to use a Thor class, you
118
+ # can simply initialize it:
119
+ #
120
+ # script = MyScript.new(args, options, config)
121
+ # script.invoke(:task, first_arg, second_arg, third_arg)
122
+ #
123
+ def start(original_args=ARGV, config={})
124
+ super do |given_args|
125
+ meth = normalize_task_name(given_args.shift)
126
+ task = all_tasks[meth]
127
+
128
+ if task
129
+ args, opts = Thor::Options.split(given_args)
130
+ config.merge!(:task_options => task.options)
131
+ else
132
+ args, opts = given_args, {}
133
+ end
134
+
135
+ task ||= Thor::Task::Dynamic.new(meth)
136
+ trailing = args[Range.new(arguments.size, -1)]
137
+ new(args, opts, config).invoke(task, trailing || [])
138
+ end
139
+ end
140
+
141
+ # Prints help information for the given task.
142
+ #
143
+ # ==== Parameters
144
+ # shell<Thor::Shell>
145
+ # task_name<String>
146
+ #
147
+ def task_help(shell, task_name)
148
+ meth = normalize_task_name(task_name)
149
+ task = all_tasks[meth]
150
+ handle_no_task_error(meth) unless task
151
+
152
+ shell.say "Usage:"
153
+ shell.say " #{banner(task)}"
154
+ shell.say
155
+ class_options_help(shell, nil => task.options.map { |_, o| o })
156
+ shell.say task.description
157
+ end
158
+
159
+ # Prints help information for this class.
160
+ #
161
+ # ==== Parameters
162
+ # shell<Thor::Shell>
163
+ #
164
+ def help(shell)
165
+ list = printable_tasks
166
+ Thor::Util.thor_classes_in(self).each do |klass|
167
+ list += klass.printable_tasks(false)
168
+ end
169
+ list.sort!{ |a,b| a[0] <=> b[0] }
170
+
171
+ shell.say "Tasks:"
172
+ shell.print_table(list, :ident => 2, :truncate => true)
173
+ shell.say
174
+ class_options_help(shell)
175
+ end
176
+
177
+ # Returns tasks ready to be printed.
178
+ def printable_tasks(all=true)
179
+ (all ? all_tasks : tasks).map do |_, task|
180
+ item = []
181
+ item << banner(task)
182
+ item << (task.description ? "# #{task.description.gsub(/\s+/m,' ')}" : "")
183
+ item
184
+ end
185
+ end
186
+
187
+ def handle_argument_error(task, error) #:nodoc:
188
+ raise InvocationError, "#{task.name.inspect} was called incorrectly. Call as #{task.formatted_usage(self, banner_base == "thor").inspect}."
189
+ end
190
+
191
+ protected
192
+
193
+ # The banner for this class. You can customize it if you are invoking the
194
+ # thor class by another ways which is not the Thor::Runner. It receives
195
+ # the task that is going to be invoked and a boolean which indicates if
196
+ # the namespace should be displayed as arguments.
197
+ #
198
+ def banner(task)
199
+ "#{banner_base} #{task.formatted_usage(self, banner_base == "thor")}"
200
+ end
201
+
202
+ def baseclass #:nodoc:
203
+ Thor
204
+ end
205
+
206
+ def create_task(meth) #:nodoc:
207
+ if @usage && @desc
208
+ tasks[meth.to_s] = Thor::Task.new(meth, @desc, @usage, method_options)
209
+ @usage, @desc, @method_options = nil
210
+ true
211
+ elsif self.all_tasks[meth.to_s] || meth.to_sym == :method_missing
212
+ true
213
+ else
214
+ puts "[WARNING] Attempted to create task #{meth.inspect} without usage or description. " <<
215
+ "Call desc if you want this method to be available as task or declare it inside a " <<
216
+ "no_tasks{} block. Invoked from #{caller[1].inspect}."
217
+ false
218
+ end
219
+ end
220
+
221
+ def initialize_added #:nodoc:
222
+ class_options.merge!(method_options)
223
+ @method_options = nil
224
+ end
225
+
226
+ # Receives a task name (can be nil), and try to get a map from it.
227
+ # If a map can't be found use the sent name or the default task.
228
+ #
229
+ def normalize_task_name(meth) #:nodoc:
230
+ mapping = map[meth.to_s]
231
+ meth = mapping || meth || default_task
232
+ meth.to_s.gsub('-','_') # treat foo-bar > foo_bar
233
+ end
234
+ end
235
+
236
+ include Thor::Base
237
+
238
+ map HELP_MAPPINGS => :help
239
+
240
+ desc "help [TASK]", "Describe available tasks or one specific task"
241
+ def help(task=nil)
242
+ task ? self.class.task_help(shell, task) : self.class.help(shell)
243
+ end
244
+ end