daemon-kit 0.1.7.12 → 0.1.8pre

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 (144) hide show
  1. data/History.txt +7 -0
  2. data/Manifest.txt +4 -0
  3. data/README.rdoc +11 -9
  4. data/Rakefile +0 -1
  5. data/TODO.txt +1 -2
  6. data/bin/daemon-kit +11 -11
  7. data/daemon-kit.gemspec +109 -78
  8. data/lib/daemon_kit.rb +7 -10
  9. data/lib/daemon_kit/abstract_logger.rb +22 -14
  10. data/lib/daemon_kit/application.rb +0 -1
  11. data/lib/daemon_kit/arguments.rb +1 -6
  12. data/lib/daemon_kit/commands/destroy.rb +10 -0
  13. data/lib/daemon_kit/commands/generate.rb +10 -0
  14. data/lib/daemon_kit/config.rb +7 -2
  15. data/lib/daemon_kit/generators.rb +67 -0
  16. data/lib/daemon_kit/generators/base.rb +60 -0
  17. data/lib/daemon_kit/initializer.rb +1 -1
  18. data/lib/daemon_kit/jabber.rb +1 -0
  19. data/lib/daemon_kit/tasks/framework.rake +6 -1
  20. data/lib/daemon_kit/vendor/thor-0.12.3/CHANGELOG.rdoc +80 -0
  21. data/lib/daemon_kit/vendor/thor-0.12.3/LICENSE +20 -0
  22. data/lib/daemon_kit/vendor/thor-0.12.3/README.rdoc +234 -0
  23. data/lib/daemon_kit/vendor/thor-0.12.3/Thorfile +64 -0
  24. data/lib/daemon_kit/vendor/thor-0.12.3/lib/thor.rb +242 -0
  25. data/lib/daemon_kit/vendor/thor-0.12.3/lib/thor/actions.rb +274 -0
  26. data/lib/daemon_kit/vendor/thor-0.12.3/lib/thor/actions/create_file.rb +103 -0
  27. data/lib/daemon_kit/vendor/thor-0.12.3/lib/thor/actions/directory.rb +91 -0
  28. data/lib/daemon_kit/vendor/thor-0.12.3/lib/thor/actions/empty_directory.rb +134 -0
  29. data/lib/daemon_kit/vendor/thor-0.12.3/lib/thor/actions/file_manipulation.rb +223 -0
  30. data/lib/daemon_kit/vendor/thor-0.12.3/lib/thor/actions/inject_into_file.rb +101 -0
  31. data/lib/daemon_kit/vendor/thor-0.12.3/lib/thor/base.rb +515 -0
  32. data/lib/daemon_kit/vendor/thor-0.12.3/lib/thor/core_ext/file_binary_read.rb +9 -0
  33. data/lib/daemon_kit/vendor/thor-0.12.3/lib/thor/core_ext/hash_with_indifferent_access.rb +75 -0
  34. data/lib/daemon_kit/vendor/thor-0.12.3/lib/thor/core_ext/ordered_hash.rb +100 -0
  35. data/lib/daemon_kit/vendor/thor-0.12.3/lib/thor/error.rb +27 -0
  36. data/lib/daemon_kit/vendor/thor-0.12.3/lib/thor/group.rb +271 -0
  37. data/lib/daemon_kit/vendor/thor-0.12.3/lib/thor/invocation.rb +178 -0
  38. data/lib/daemon_kit/vendor/thor-0.12.3/lib/thor/parser.rb +4 -0
  39. data/lib/daemon_kit/vendor/thor-0.12.3/lib/thor/parser/argument.rb +67 -0
  40. data/lib/daemon_kit/vendor/thor-0.12.3/lib/thor/parser/arguments.rb +145 -0
  41. data/lib/daemon_kit/vendor/thor-0.12.3/lib/thor/parser/option.rb +132 -0
  42. data/lib/daemon_kit/vendor/thor-0.12.3/lib/thor/parser/options.rb +142 -0
  43. data/lib/daemon_kit/vendor/thor-0.12.3/lib/thor/rake_compat.rb +66 -0
  44. data/lib/daemon_kit/vendor/thor-0.12.3/lib/thor/runner.rb +303 -0
  45. data/lib/daemon_kit/vendor/thor-0.12.3/lib/thor/shell.rb +78 -0
  46. data/lib/daemon_kit/vendor/thor-0.12.3/lib/thor/shell/basic.rb +239 -0
  47. data/lib/daemon_kit/vendor/thor-0.12.3/lib/thor/shell/color.rb +108 -0
  48. data/lib/daemon_kit/vendor/thor-0.12.3/lib/thor/task.rb +111 -0
  49. data/lib/daemon_kit/vendor/thor-0.12.3/lib/thor/util.rb +233 -0
  50. data/lib/daemon_kit/vendor/thor-0.12.3/lib/thor/version.rb +3 -0
  51. data/lib/daemon_kit/xmpp.rb +75 -6
  52. data/{daemon_generators → lib/generators/daemon_kit}/amqp/USAGE +0 -0
  53. data/lib/generators/daemon_kit/amqp/amqp_generator.rb +24 -0
  54. data/{daemon_generators → lib/generators/daemon_kit}/amqp/templates/config/amqp.yml +0 -0
  55. data/{daemon_generators/amqp/templates/config/initializers → lib/generators/daemon_kit/amqp/templates/config/pre-daemonize}/amqp.rb +0 -0
  56. data/{daemon_generators/amqp/templates/libexec/daemon.rb → lib/generators/daemon_kit/amqp/templates/libexec/%app_name%-daemon.rb} +0 -0
  57. data/{app_generators/daemon_kit → lib/generators/daemon_kit/app}/USAGE +0 -0
  58. data/lib/generators/daemon_kit/app/app_generator.rb +140 -0
  59. data/lib/generators/daemon_kit/app/templates/Gemfile +8 -0
  60. data/{app_generators/daemon_kit → lib/generators/daemon_kit/app}/templates/README +0 -0
  61. data/{app_generators/daemon_kit → lib/generators/daemon_kit/app}/templates/Rakefile +0 -0
  62. data/lib/generators/daemon_kit/app/templates/bin/daemon.tt +7 -0
  63. data/{app_generators/daemon_kit → lib/generators/daemon_kit/app}/templates/config/arguments.rb +0 -0
  64. data/{app_generators/daemon_kit → lib/generators/daemon_kit/app}/templates/config/boot.rb +10 -3
  65. data/{app_generators/daemon_kit/templates/config/environment.rb → lib/generators/daemon_kit/app/templates/config/environment.rb.tt} +1 -1
  66. data/{app_generators/daemon_kit → lib/generators/daemon_kit/app}/templates/config/environments/development.rb +0 -0
  67. data/{app_generators/daemon_kit → lib/generators/daemon_kit/app}/templates/config/environments/production.rb +0 -0
  68. data/{app_generators/daemon_kit → lib/generators/daemon_kit/app}/templates/config/environments/test.rb +0 -0
  69. data/{app_generators/daemon_kit → lib/generators/daemon_kit/app}/templates/config/post-daemonize/readme +0 -0
  70. data/{app_generators/daemon_kit → lib/generators/daemon_kit/app}/templates/config/pre-daemonize/readme +0 -0
  71. data/{app_generators/daemon_kit/templates/lib/daemon.rb → lib/generators/daemon_kit/app/templates/lib/%app_name%.rb} +0 -0
  72. data/{app_generators/daemon_kit/templates/libexec/daemon.erb → lib/generators/daemon_kit/app/templates/libexec/%app_name%-daemon.rb} +0 -0
  73. data/{app_generators/daemon_kit → lib/generators/daemon_kit/app}/templates/script/console +0 -0
  74. data/lib/generators/daemon_kit/app/templates/script/destroy +2 -0
  75. data/lib/generators/daemon_kit/app/templates/script/generate +2 -0
  76. data/lib/generators/daemon_kit/capistrano/capistrano_generator.rb +21 -0
  77. data/{daemon_generators/deploy_capistrano → lib/generators/daemon_kit/capistrano}/templates/Capfile +0 -0
  78. data/{daemon_generators/deploy_capistrano → lib/generators/daemon_kit/capistrano}/templates/USAGE +0 -0
  79. data/{daemon_generators/deploy_capistrano/templates/config/deploy.rb → lib/generators/daemon_kit/capistrano/templates/config/deploy.rb.tt} +1 -1
  80. data/lib/generators/daemon_kit/capistrano/templates/config/deploy/production.rb.tt +6 -0
  81. data/lib/generators/daemon_kit/capistrano/templates/config/deploy/staging.rb.tt +6 -0
  82. data/{daemon_generators/deploy_capistrano → lib/generators/daemon_kit/capistrano}/templates/config/environments/staging.rb +0 -0
  83. data/{daemon_generators → lib/generators/daemon_kit}/cron/USAGE +0 -0
  84. data/lib/generators/daemon_kit/cron/cron_generator.rb +24 -0
  85. data/{daemon_generators/cron/templates/config/initializers → lib/generators/daemon_kit/cron/templates/config/pre-daemonize}/cron.rb +0 -0
  86. data/{daemon_generators/cron/templates/libexec/daemon.rb → lib/generators/daemon_kit/cron/templates/libexec/%app_name%-daemon.rb} +0 -0
  87. data/{daemon_generators → lib/generators/daemon_kit}/cucumber/USAGE +0 -0
  88. data/lib/generators/daemon_kit/cucumber/cucumber_generator.rb +45 -0
  89. data/{daemon_generators/cucumber/templates/cucumber_environment.rb → lib/generators/daemon_kit/cucumber/templates/config/environments/cucumber.rb} +0 -0
  90. data/lib/generators/daemon_kit/cucumber/templates/features/step_definitions/.empty_directory +0 -0
  91. data/{daemon_generators/cucumber/templates → lib/generators/daemon_kit/cucumber/templates/features/support}/env.rb +0 -0
  92. data/{daemon_generators/cucumber/templates → lib/generators/daemon_kit/cucumber/templates/script}/cucumber +1 -2
  93. data/{daemon_generators/cucumber/templates → lib/generators/daemon_kit/cucumber/templates/tasks}/cucumber.rake +0 -0
  94. data/{daemon_generators/jabber → lib/generators/daemon_kit/nanite_agent}/USAGE +0 -0
  95. data/lib/generators/daemon_kit/nanite_agent/nanite_agent_generator.rb +29 -0
  96. data/{daemon_generators → lib/generators/daemon_kit}/nanite_agent/templates/config/nanite.yml +0 -0
  97. data/{daemon_generators/nanite_agent/templates/config/initializers → lib/generators/daemon_kit/nanite_agent/templates/config/pre-daemonize}/nanite_agent.rb +0 -0
  98. data/{daemon_generators → lib/generators/daemon_kit}/nanite_agent/templates/lib/actors/sample.rb +0 -0
  99. data/{daemon_generators/nanite_agent/templates/libexec/daemon.rb → lib/generators/daemon_kit/nanite_agent/templates/libexec/%app_name%-daemon.rb} +0 -0
  100. data/{daemon_generators/nanite_agent → lib/generators/daemon_kit/rspec}/USAGE +0 -0
  101. data/lib/generators/daemon_kit/rspec/rspec_generator.rb +20 -0
  102. data/{daemon_generators/rspec/templates/spec.rb → lib/generators/daemon_kit/rspec/templates/spec/%app_name%_spec.rb} +0 -0
  103. data/{daemon_generators → lib/generators/daemon_kit}/rspec/templates/spec/spec.opts +0 -0
  104. data/{daemon_generators → lib/generators/daemon_kit}/rspec/templates/spec/spec_helper.rb +0 -0
  105. data/{daemon_generators → lib/generators/daemon_kit}/rspec/templates/tasks/rspec.rake +0 -0
  106. data/{daemon_generators/rspec → lib/generators/daemon_kit/ruote}/USAGE +0 -0
  107. data/lib/generators/daemon_kit/ruote/ruote_generator.rb +29 -0
  108. data/{daemon_generators → lib/generators/daemon_kit}/ruote/templates/config/amqp.yml +0 -0
  109. data/{daemon_generators/ruote/templates/config/initializers → lib/generators/daemon_kit/ruote/templates/config/pre-daemonize}/ruote.rb +0 -0
  110. data/{daemon_generators → lib/generators/daemon_kit}/ruote/templates/config/ruote.yml +0 -0
  111. data/{daemon_generators/ruote/templates/lib/daemon.rb → lib/generators/daemon_kit/ruote/templates/lib/%app_name%.rb} +0 -0
  112. data/{daemon_generators → lib/generators/daemon_kit}/ruote/templates/lib/sample.rb +0 -0
  113. data/{daemon_generators/ruote/templates/libexec/daemon.rb → lib/generators/daemon_kit/ruote/templates/libexec/%app_name%-daemon.rb} +0 -0
  114. data/{daemon_generators/ruote → lib/generators/daemon_kit/test_unit}/USAGE +0 -0
  115. data/{daemon_generators → lib/generators/daemon_kit}/test_unit/templates/tasks/test_unit.rake +0 -0
  116. data/{daemon_generators/test_unit/templates/test/test.rb → lib/generators/daemon_kit/test_unit/templates/test/%app_name%_test.rb.tt} +1 -1
  117. data/{daemon_generators → lib/generators/daemon_kit}/test_unit/templates/test/test_helper.rb +0 -0
  118. data/lib/generators/daemon_kit/test_unit/test_unit_generator.rb +20 -0
  119. data/lib/generators/daemon_kit/xmpp/templates/config/pre-daemonize/xmpp.rb +6 -0
  120. data/{daemon_generators/jabber/templates/config/jabber.yml → lib/generators/daemon_kit/xmpp/templates/config/xmpp.yml} +5 -2
  121. data/lib/generators/daemon_kit/xmpp/templates/libexec/%app_name%-daemon.rb +27 -0
  122. data/lib/generators/daemon_kit/xmpp/xmpp_generator.rb +24 -0
  123. data/spec/argument_spec.rb +1 -1
  124. data/spec/config_spec.rb +7 -3
  125. metadata +110 -86
  126. data/app_generators/daemon_kit/daemon_kit_generator.rb +0 -178
  127. data/app_generators/daemon_kit/templates/bin/daemon.erb +0 -7
  128. data/app_generators/daemon_kit/templates/script/destroy +0 -14
  129. data/app_generators/daemon_kit/templates/script/generate +0 -14
  130. data/daemon_generators/amqp/amqp_generator.rb +0 -65
  131. data/daemon_generators/cron/cron_generator.rb +0 -64
  132. data/daemon_generators/cucumber/cucumber_generator.rb +0 -38
  133. data/daemon_generators/deploy_capistrano/deploy_capistrano_generator.rb +0 -35
  134. data/daemon_generators/deploy_capistrano/templates/config/deploy/production.rb +0 -6
  135. data/daemon_generators/deploy_capistrano/templates/config/deploy/staging.rb +0 -6
  136. data/daemon_generators/jabber/jabber_generator.rb +0 -65
  137. data/daemon_generators/jabber/templates/config/initializers/jabber.rb +0 -7
  138. data/daemon_generators/jabber/templates/libexec/daemon.rb +0 -27
  139. data/daemon_generators/nanite_agent/nanite_agent_generator.rb +0 -68
  140. data/daemon_generators/rspec/rspec_generator.rb +0 -55
  141. data/daemon_generators/ruote/ruote_generator.rb +0 -67
  142. data/daemon_generators/test_unit/USAGE +0 -5
  143. data/daemon_generators/test_unit/test_unit_generator.rb +0 -51
  144. data/test/test_jabber_generator.rb +0 -49
@@ -0,0 +1,64 @@
1
+ # enconding: utf-8
2
+
3
+ require File.join(File.dirname(__FILE__), "lib", "thor", "version")
4
+ require 'rubygems'
5
+ require 'thor/rake_compat'
6
+ require 'spec/rake/spectask'
7
+ require 'rdoc/task'
8
+
9
+ GEM_NAME = 'thor'
10
+ EXTRA_RDOC_FILES = ["README.rdoc", "LICENSE", "CHANGELOG.rdoc", "VERSION", "Thorfile"]
11
+
12
+ class Default < Thor
13
+ include Thor::RakeCompat
14
+
15
+ Spec::Rake::SpecTask.new(:spec) do |t|
16
+ t.libs << 'lib'
17
+ t.spec_opts = ['--options', "spec/spec.opts"]
18
+ t.spec_files = FileList['spec/**/*_spec.rb']
19
+ end
20
+
21
+ Spec::Rake::SpecTask.new(:rcov) do |t|
22
+ t.libs << 'lib'
23
+ t.spec_opts = ['--options', "spec/spec.opts"]
24
+ t.spec_files = FileList['spec/**/*_spec.rb']
25
+ t.rcov = true
26
+ t.rcov_dir = "rcov"
27
+ end
28
+
29
+ RDoc::Task.new do |rdoc|
30
+ rdoc.main = "README.rdoc"
31
+ rdoc.rdoc_dir = "rdoc"
32
+ rdoc.title = GEM_NAME
33
+ rdoc.rdoc_files.include(*EXTRA_RDOC_FILES)
34
+ rdoc.rdoc_files.include('lib/**/*.rb')
35
+ rdoc.options << '--line-numbers' << '--inline-source'
36
+ end
37
+
38
+ begin
39
+ require 'jeweler'
40
+ Jeweler::Tasks.new do |s|
41
+ s.name = GEM_NAME
42
+ s.version = Thor::VERSION
43
+ s.rubyforge_project = "textmate"
44
+ s.platform = Gem::Platform::RUBY
45
+ s.summary = "A scripting framework that replaces rake, sake and rubigen"
46
+ s.email = "ruby-thor@googlegroups.com"
47
+ s.homepage = "http://yehudakatz.com"
48
+ s.description = "A scripting framework that replaces rake, sake and rubigen"
49
+ s.authors = ['Yehuda Katz', 'José Valim']
50
+ s.has_rdoc = true
51
+ s.extra_rdoc_files = EXTRA_RDOC_FILES
52
+ s.require_path = 'lib'
53
+ s.bindir = "bin"
54
+ s.executables = %w( thor rake2thor )
55
+ s.files = s.extra_rdoc_files + Dir.glob("{bin,lib}/**/*")
56
+ s.test_files.include 'spec/**/*'
57
+ s.test_files.exclude 'spec/sandbox/**/*'
58
+ end
59
+
60
+ Jeweler::GemcutterTasks.new
61
+ rescue LoadError
62
+ puts "Jeweler, or one of its dependencies, is not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
63
+ end
64
+ end
@@ -0,0 +1,242 @@
1
+ require 'thor/base'
2
+ require 'thor/group'
3
+ require 'thor/actions'
4
+
5
+ # TODO: Update thor to allow for git-style CLI (git bisect run)
6
+ class Thor
7
+ class << self
8
+ # Sets the default task when thor is executed without an explicit task to be called.
9
+ #
10
+ # ==== Parameters
11
+ # meth<Symbol>:: name of the defaut task
12
+ #
13
+ def default_task(meth=nil)
14
+ case meth
15
+ when :none
16
+ @default_task = 'help'
17
+ when nil
18
+ @default_task ||= from_superclass(:default_task, 'help')
19
+ else
20
+ @default_task = meth.to_s
21
+ end
22
+ end
23
+
24
+ # Defines the usage and the description of the next task.
25
+ #
26
+ # ==== Parameters
27
+ # usage<String>
28
+ # description<String>
29
+ #
30
+ def desc(usage, description, options={})
31
+ if options[:for]
32
+ task = find_and_refresh_task(options[:for])
33
+ task.usage = usage if usage
34
+ task.description = description if description
35
+ else
36
+ @usage, @desc = usage, description
37
+ end
38
+ end
39
+
40
+ # Maps an input to a task. If you define:
41
+ #
42
+ # map "-T" => "list"
43
+ #
44
+ # Running:
45
+ #
46
+ # thor -T
47
+ #
48
+ # Will invoke the list task.
49
+ #
50
+ # ==== Parameters
51
+ # Hash[String|Array => Symbol]:: Maps the string or the strings in the array to the given task.
52
+ #
53
+ def map(mappings=nil)
54
+ @map ||= from_superclass(:map, {})
55
+
56
+ if mappings
57
+ mappings.each do |key, value|
58
+ if key.respond_to?(:each)
59
+ key.each {|subkey| @map[subkey] = value}
60
+ else
61
+ @map[key] = value
62
+ end
63
+ end
64
+ end
65
+
66
+ @map
67
+ end
68
+
69
+ # Declares the options for the next task to be declared.
70
+ #
71
+ # ==== Parameters
72
+ # Hash[Symbol => Object]:: The hash key is the name of the option and the value
73
+ # is the type of the option. Can be :string, :array, :hash, :boolean, :numeric
74
+ # or :required (string). If you give a value, the type of the value is used.
75
+ #
76
+ def method_options(options=nil)
77
+ @method_options ||= {}
78
+ build_options(options, @method_options) if options
79
+ @method_options
80
+ end
81
+
82
+ # Adds an option to the set of method options. If :for is given as option,
83
+ # it allows you to change the options from a previous defined task.
84
+ #
85
+ # def previous_task
86
+ # # magic
87
+ # end
88
+ #
89
+ # method_option :foo => :bar, :for => :previous_task
90
+ #
91
+ # def next_task
92
+ # # magic
93
+ # end
94
+ #
95
+ # ==== Parameters
96
+ # name<Symbol>:: The name of the argument.
97
+ # options<Hash>:: Described below.
98
+ #
99
+ # ==== Options
100
+ # :desc - Description for the argument.
101
+ # :required - If the argument is required or not.
102
+ # :default - Default value for this argument. It cannot be required and have default values.
103
+ # :aliases - Aliases for this option.
104
+ # :type - The type of the argument, can be :string, :hash, :array, :numeric or :boolean.
105
+ # :banner - String to show on usage notes.
106
+ #
107
+ def method_option(name, options={})
108
+ scope = if options[:for]
109
+ find_and_refresh_task(options[:for]).options
110
+ else
111
+ method_options
112
+ end
113
+
114
+ build_option(name, options, scope)
115
+ end
116
+
117
+ # Parses the task and options from the given args, instantiate the class
118
+ # and invoke the task. This method is used when the arguments must be parsed
119
+ # from an array. If you are inside Ruby and want to use a Thor class, you
120
+ # can simply initialize it:
121
+ #
122
+ # script = MyScript.new(args, options, config)
123
+ # script.invoke(:task, first_arg, second_arg, third_arg)
124
+ #
125
+ def start(given_args=ARGV, config={})
126
+ super do
127
+ meth = normalize_task_name(given_args.shift)
128
+ task = all_tasks[meth]
129
+
130
+ if task
131
+ args, opts = Thor::Options.split(given_args)
132
+ config.merge!(:task_options => task.options)
133
+ else
134
+ args, opts = given_args, {}
135
+ end
136
+
137
+ task ||= Thor::Task::Dynamic.new(meth)
138
+ trailing = args[Range.new(arguments.size, -1)]
139
+ new(args, opts, config).invoke(task, trailing || [])
140
+ end
141
+ end
142
+
143
+ # Prints help information for the given task.
144
+ #
145
+ # ==== Parameters
146
+ # shell<Thor::Shell>
147
+ # task_name<String>
148
+ #
149
+ def task_help(shell, task_name)
150
+ task = all_tasks[task_name]
151
+ raise UndefinedTaskError, "task '#{task_name}' could not be found in namespace '#{self.namespace}'" unless task
152
+
153
+ shell.say "Usage:"
154
+ shell.say " #{banner(task)}"
155
+ shell.say
156
+ class_options_help(shell, nil => task.options.map { |_, o| o })
157
+ shell.say task.description
158
+ end
159
+
160
+ # Prints help information for this class.
161
+ #
162
+ # ==== Parameters
163
+ # shell<Thor::Shell>
164
+ #
165
+ def help(shell)
166
+ list = printable_tasks
167
+ Thor::Util.thor_classes_in(self).each do |klass|
168
+ list += klass.printable_tasks(false)
169
+ end
170
+ list.sort!{ |a,b| a[0] <=> b[0] }
171
+
172
+ shell.say "Tasks:"
173
+ shell.print_table(list, :ident => 2, :truncate => true)
174
+ shell.say
175
+ class_options_help(shell)
176
+ end
177
+
178
+ # Returns tasks ready to be printed.
179
+ def printable_tasks(all=true)
180
+ (all ? all_tasks : tasks).map do |_, task|
181
+ item = []
182
+ item << banner(task)
183
+ item << (task.description ? "# #{task.description.gsub(/\s+/m,' ')}" : "")
184
+ item
185
+ end
186
+ end
187
+
188
+ protected
189
+
190
+ # The banner for this class. You can customize it if you are invoking the
191
+ # thor class by another ways which is not the Thor::Runner. It receives
192
+ # the task that is going to be invoked and a boolean which indicates if
193
+ # the namespace should be displayed as arguments.
194
+ #
195
+ def banner(task)
196
+ base = $thor_runner ? "thor" : File.basename($0.split(" ").first)
197
+ "#{base} #{task.formatted_usage(self, base == "thor")}"
198
+ end
199
+
200
+ def baseclass #:nodoc:
201
+ Thor
202
+ end
203
+
204
+ def create_task(meth) #:nodoc:
205
+ if @usage && @desc
206
+ tasks[meth.to_s] = Thor::Task.new(meth, @desc, @usage, method_options)
207
+ @usage, @desc, @method_options = nil
208
+ true
209
+ elsif self.all_tasks[meth.to_s] || meth.to_sym == :method_missing
210
+ true
211
+ else
212
+ puts "[WARNING] Attempted to create task #{meth.inspect} without usage or description. " <<
213
+ "Call desc if you want this method to be available as task or declare it inside a " <<
214
+ "no_tasks{} block. Invoked from #{caller[1].inspect}."
215
+ false
216
+ end
217
+ end
218
+
219
+ def initialize_added #:nodoc:
220
+ class_options.merge!(method_options)
221
+ @method_options = nil
222
+ end
223
+
224
+ # Receives a task name (can be nil), and try to get a map from it.
225
+ # If a map can't be found use the sent name or the default task.
226
+ #
227
+ def normalize_task_name(meth) #:nodoc:
228
+ mapping = map[meth.to_s]
229
+ meth = mapping || meth || default_task
230
+ meth.to_s.gsub('-','_') # treat foo-bar > foo_bar
231
+ end
232
+ end
233
+
234
+ include Thor::Base
235
+
236
+ map HELP_MAPPINGS => :help
237
+
238
+ desc "help [TASK]", "Describe available tasks or one specific task"
239
+ def help(task=nil)
240
+ task ? self.class.task_help(shell, task) : self.class.help(shell)
241
+ end
242
+ end
@@ -0,0 +1,274 @@
1
+ require 'fileutils'
2
+ require 'thor/core_ext/file_binary_read'
3
+
4
+ Dir[File.join(File.dirname(__FILE__), "actions", "*.rb")].each do |action|
5
+ require action
6
+ end
7
+
8
+ class Thor
9
+ module Actions
10
+ attr_accessor :behavior
11
+
12
+ def self.included(base) #:nodoc:
13
+ base.extend ClassMethods
14
+ end
15
+
16
+ module ClassMethods
17
+ # Hold source paths for one Thor instance. source_paths_for_search is the
18
+ # method responsible to gather source_paths from this current class,
19
+ # inherited paths and the source root.
20
+ #
21
+ def source_paths
22
+ @source_paths ||= []
23
+ end
24
+
25
+ # Returns the source paths in the following order:
26
+ #
27
+ # 1) This class source paths
28
+ # 2) Source root
29
+ # 3) Parents source paths
30
+ #
31
+ def source_paths_for_search
32
+ paths = []
33
+ paths += self.source_paths
34
+ paths << self.source_root if self.respond_to?(:source_root)
35
+ paths += from_superclass(:source_paths, [])
36
+ paths
37
+ end
38
+
39
+ # Add runtime options that help actions execution.
40
+ #
41
+ def add_runtime_options!
42
+ class_option :force, :type => :boolean, :aliases => "-f", :group => :runtime,
43
+ :desc => "Overwrite files that already exist"
44
+
45
+ class_option :pretend, :type => :boolean, :aliases => "-p", :group => :runtime,
46
+ :desc => "Run but do not make any changes"
47
+
48
+ class_option :quiet, :type => :boolean, :aliases => "-q", :group => :runtime,
49
+ :desc => "Supress status output"
50
+
51
+ class_option :skip, :type => :boolean, :aliases => "-s", :group => :runtime,
52
+ :desc => "Skip files that already exist"
53
+ end
54
+ end
55
+
56
+ # Extends initializer to add more configuration options.
57
+ #
58
+ # ==== Configuration
59
+ # behavior<Symbol>:: The actions default behavior. Can be :invoke or :revoke.
60
+ # It also accepts :force, :skip and :pretend to set the behavior
61
+ # and the respective option.
62
+ #
63
+ # destination_root<String>:: The root directory needed for some actions.
64
+ #
65
+ def initialize(args=[], options={}, config={})
66
+ self.behavior = case config[:behavior].to_s
67
+ when "force", "skip"
68
+ _cleanup_options_and_set(options, config[:behavior])
69
+ :invoke
70
+ when "revoke"
71
+ :revoke
72
+ else
73
+ :invoke
74
+ end
75
+
76
+ super
77
+ self.destination_root = config[:destination_root]
78
+ end
79
+
80
+ # Wraps an action object and call it accordingly to the thor class behavior.
81
+ #
82
+ def action(instance) #:nodoc:
83
+ if behavior == :revoke
84
+ instance.revoke!
85
+ else
86
+ instance.invoke!
87
+ end
88
+ end
89
+
90
+ # Returns the root for this thor class (also aliased as destination root).
91
+ #
92
+ def destination_root
93
+ @destination_stack.last
94
+ end
95
+
96
+ # Sets the root for this thor class. Relatives path are added to the
97
+ # directory where the script was invoked and expanded.
98
+ #
99
+ def destination_root=(root)
100
+ @destination_stack ||= []
101
+ @destination_stack[0] = File.expand_path(root || '')
102
+ end
103
+
104
+ # Returns the given path relative to the absolute root (ie, root where
105
+ # the script started).
106
+ #
107
+ def relative_to_original_destination_root(path, remove_dot=true)
108
+ path = path.gsub(@destination_stack[0], '.')
109
+ remove_dot ? (path[2..-1] || '') : path
110
+ end
111
+
112
+ # Holds source paths in instance so they can be manipulated.
113
+ #
114
+ def source_paths
115
+ @source_paths ||= self.class.source_paths_for_search
116
+ end
117
+
118
+ # Receives a file or directory and search for it in the source paths.
119
+ #
120
+ def find_in_source_paths(file)
121
+ relative_root = relative_to_original_destination_root(destination_root, false)
122
+
123
+ source_paths.each do |source|
124
+ source_file = File.expand_path(file, File.join(source, relative_root))
125
+ return source_file if File.exists?(source_file)
126
+ end
127
+
128
+ if source_paths.empty?
129
+ raise Error, "You don't have any source path defined for class #{self.class.name}. To fix this, " <<
130
+ "you can define a source_root in your class."
131
+ else
132
+ raise Error, "Could not find #{file.inspect} in source paths."
133
+ end
134
+ end
135
+
136
+ # Do something in the root or on a provided subfolder. If a relative path
137
+ # is given it's referenced from the current root. The full path is yielded
138
+ # to the block you provide. The path is set back to the previous path when
139
+ # the method exits.
140
+ #
141
+ # ==== Parameters
142
+ # dir<String>:: the directory to move to.
143
+ # config<Hash>:: give :verbose => true to log and use padding.
144
+ #
145
+ def inside(dir='', config={}, &block)
146
+ verbose = config.fetch(:verbose, false)
147
+
148
+ say_status :inside, dir, verbose
149
+ shell.padding += 1 if verbose
150
+ @destination_stack.push File.expand_path(dir, destination_root)
151
+
152
+ FileUtils.mkdir_p(destination_root) unless File.exist?(destination_root)
153
+ FileUtils.cd(destination_root) { block.arity == 1 ? yield(destination_root) : yield }
154
+
155
+ @destination_stack.pop
156
+ shell.padding -= 1 if verbose
157
+ end
158
+
159
+ # Goes to the root and execute the given block.
160
+ #
161
+ def in_root
162
+ inside(@destination_stack.first) { yield }
163
+ end
164
+
165
+ # Loads an external file and execute it in the instance binding.
166
+ #
167
+ # ==== Parameters
168
+ # path<String>:: The path to the file to execute. Can be a web address or
169
+ # a relative path from the source root.
170
+ #
171
+ # ==== Examples
172
+ #
173
+ # apply "http://gist.github.com/103208"
174
+ #
175
+ # apply "recipes/jquery.rb"
176
+ #
177
+ def apply(path, config={})
178
+ verbose = config.fetch(:verbose, true)
179
+ path = find_in_source_paths(path) unless path =~ /^http\:\/\//
180
+
181
+ say_status :apply, path, verbose
182
+ shell.padding += 1 if verbose
183
+ instance_eval(open(path).read)
184
+ shell.padding -= 1 if verbose
185
+ end
186
+
187
+ # Executes a command.
188
+ #
189
+ # ==== Parameters
190
+ # command<String>:: the command to be executed.
191
+ # config<Hash>:: give :verbose => false to not log the status. Specify :with
192
+ # to append an executable to command executation.
193
+ #
194
+ # ==== Example
195
+ #
196
+ # inside('vendor') do
197
+ # run('ln -s ~/edge rails')
198
+ # end
199
+ #
200
+ def run(command, config={})
201
+ return unless behavior == :invoke
202
+
203
+ destination = relative_to_original_destination_root(destination_root, false)
204
+ desc = "#{command} from #{destination.inspect}"
205
+
206
+ if config[:with]
207
+ desc = "#{File.basename(config[:with].to_s)} #{desc}"
208
+ command = "#{config[:with]} #{command}"
209
+ end
210
+
211
+ say_status :run, desc, config.fetch(:verbose, true)
212
+ system(command) unless options[:pretend]
213
+ end
214
+
215
+ # Executes a ruby script (taking into account WIN32 platform quirks).
216
+ #
217
+ # ==== Parameters
218
+ # command<String>:: the command to be executed.
219
+ # config<Hash>:: give :verbose => false to not log the status.
220
+ #
221
+ def run_ruby_script(command, config={})
222
+ return unless behavior == :invoke
223
+ run "#{command}", config.merge(:with => Thor::Util.ruby_command)
224
+ end
225
+
226
+ # Run a thor command. A hash of options can be given and it's converted to
227
+ # switches.
228
+ #
229
+ # ==== Parameters
230
+ # task<String>:: the task to be invoked
231
+ # args<Array>:: arguments to the task
232
+ # config<Hash>:: give :verbose => false to not log the status. Other options
233
+ # are given as parameter to Thor.
234
+ #
235
+ # ==== Examples
236
+ #
237
+ # thor :install, "http://gist.github.com/103208"
238
+ # #=> thor install http://gist.github.com/103208
239
+ #
240
+ # thor :list, :all => true, :substring => 'rails'
241
+ # #=> thor list --all --substring=rails
242
+ #
243
+ def thor(task, *args)
244
+ config = args.last.is_a?(Hash) ? args.pop : {}
245
+ verbose = config.key?(:verbose) ? config.delete(:verbose) : true
246
+
247
+ args.unshift task
248
+ args.push Thor::Options.to_switches(config)
249
+ command = args.join(' ').strip
250
+
251
+ run command, :with => :thor, :verbose => verbose
252
+ end
253
+
254
+ protected
255
+
256
+ # Allow current root to be shared between invocations.
257
+ #
258
+ def _shared_configuration #:nodoc:
259
+ super.merge!(:destination_root => self.destination_root)
260
+ end
261
+
262
+ def _cleanup_options_and_set(options, key) #:nodoc:
263
+ case options
264
+ when Array
265
+ %w(--force -f --skip -s).each { |i| options.delete(i) }
266
+ options << "--#{key}"
267
+ when Hash
268
+ [:force, :skip, "force", "skip"].each { |i| options.delete(i) }
269
+ options.merge!(key => true)
270
+ end
271
+ end
272
+
273
+ end
274
+ end