sprout 1.0.32.pre → 1.0.35.pre

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of sprout might be problematic. Click here for more details.

Files changed (208) hide show
  1. data/Gemfile +2 -1
  2. data/Gemfile.lock +4 -2
  3. data/README.textile +12 -13
  4. data/VERSION +1 -0
  5. data/doc/Dir.html +288 -0
  6. data/doc/Rake/Task.html +184 -0
  7. data/doc/Sprout.html +144 -0
  8. data/doc/Sprout/ArchiveUnpacker.html +1246 -0
  9. data/doc/Sprout/Base.html +126 -0
  10. data/doc/Sprout/Base/ClassMethods.html +434 -0
  11. data/doc/Sprout/Concern.html +353 -0
  12. data/doc/Sprout/Daemon.html +166 -0
  13. data/doc/Sprout/Daemon/ClassMethods.html +244 -0
  14. data/doc/Sprout/Daemon/InstanceMethods.html +601 -0
  15. data/doc/Sprout/Errors.html +101 -0
  16. data/doc/Sprout/Errors/ArchiveUnpackerError.html +125 -0
  17. data/doc/Sprout/Errors/DestinationExistsError.html +133 -0
  18. data/doc/Sprout/Errors/DuplicateMemberError.html +132 -0
  19. data/doc/Sprout/Errors/ExecutableError.html +125 -0
  20. data/doc/Sprout/Errors/ExecutableRegistrationError.html +132 -0
  21. data/doc/Sprout/Errors/ExecutionError.html +121 -0
  22. data/doc/Sprout/Errors/GeneratorError.html +125 -0
  23. data/doc/Sprout/Errors/InvalidArgumentError.html +132 -0
  24. data/doc/Sprout/Errors/LoadError.html +121 -0
  25. data/doc/Sprout/Errors/MissingArgumentError.html +132 -0
  26. data/doc/Sprout/Errors/MissingExecutableError.html +132 -0
  27. data/doc/Sprout/Errors/MissingGeneratorError.html +132 -0
  28. data/doc/Sprout/Errors/MissingTemplateError.html +132 -0
  29. data/doc/Sprout/Errors/ProcessRunnerError.html +121 -0
  30. data/doc/Sprout/Errors/RemoteFileLoaderError.html +110 -0
  31. data/doc/Sprout/Errors/SproutError.html +114 -0
  32. data/doc/Sprout/Errors/UnknownArchiveType.html +122 -0
  33. data/doc/Sprout/Errors/UsageError.html +121 -0
  34. data/doc/Sprout/Errors/ValidationError.html +121 -0
  35. data/doc/Sprout/Errors/VersionRequirementNotMetError.html +121 -0
  36. data/doc/Sprout/Executable.html +173 -0
  37. data/doc/Sprout/Executable/Boolean.html +483 -0
  38. data/doc/Sprout/Executable/ClassMethods.html +417 -0
  39. data/doc/Sprout/Executable/CollectionParam.html +483 -0
  40. data/doc/Sprout/Executable/FileParam.html +484 -0
  41. data/doc/Sprout/Executable/Files.html +292 -0
  42. data/doc/Sprout/Executable/InstanceMethods.html +2006 -0
  43. data/doc/Sprout/Executable/Number.html +141 -0
  44. data/doc/Sprout/Executable/Param.html +2818 -0
  45. data/doc/Sprout/Executable/ParameterFactory.html +232 -0
  46. data/doc/Sprout/Executable/Path.html +223 -0
  47. data/doc/Sprout/Executable/Paths.html +253 -0
  48. data/doc/Sprout/Executable/StringParam.html +213 -0
  49. data/doc/Sprout/Executable/Strings.html +167 -0
  50. data/doc/Sprout/Executable/Url.html +160 -0
  51. data/doc/Sprout/Executable/Urls.html +170 -0
  52. data/doc/Sprout/FileTarget.html +1109 -0
  53. data/doc/Sprout/Generator.html +689 -0
  54. data/doc/Sprout/Generator/Base.html +1626 -0
  55. data/doc/Sprout/Generator/Command.html +690 -0
  56. data/doc/Sprout/Generator/DirectoryManifest.html +476 -0
  57. data/doc/Sprout/Generator/FileManifest.html +572 -0
  58. data/doc/Sprout/Generator/Manifest.html +377 -0
  59. data/doc/Sprout/Generator/TemplateManifest.html +196 -0
  60. data/doc/Sprout/GeneratorGenerator.html +1018 -0
  61. data/doc/Sprout/Library.html +1141 -0
  62. data/doc/Sprout/LibraryGenerator.html +309 -0
  63. data/doc/Sprout/Log.html +496 -0
  64. data/doc/Sprout/MXMLC.html +6373 -0
  65. data/doc/Sprout/Platform.html +714 -0
  66. data/doc/Sprout/ProcessRunner.html +1352 -0
  67. data/doc/Sprout/ProgressBar.html +376 -0
  68. data/doc/Sprout/ProgressBarImpl.html +2119 -0
  69. data/doc/Sprout/ProgressBarManager.html +434 -0
  70. data/doc/Sprout/ProgressBarOutputStream.html +416 -0
  71. data/doc/Sprout/RDocParser.html +211 -0
  72. data/doc/Sprout/RemoteFileLoader.html +172 -0
  73. data/doc/Sprout/RemoteFileTarget.html +679 -0
  74. data/doc/Sprout/ReversedProgressBar.html +194 -0
  75. data/doc/Sprout/RubyFeature.html +155 -0
  76. data/doc/Sprout/RubyFeature/ClassMethods.html +1065 -0
  77. data/doc/Sprout/RubyGenerator.html +764 -0
  78. data/doc/Sprout/Specification.html +767 -0
  79. data/doc/Sprout/System.html +191 -0
  80. data/doc/Sprout/System/BaseSystem.html +1455 -0
  81. data/doc/Sprout/System/JavaSystem.html +122 -0
  82. data/doc/Sprout/System/OSXSystem.html +335 -0
  83. data/doc/Sprout/System/ThreadMock.html +193 -0
  84. data/doc/Sprout/System/UnixSystem.html +584 -0
  85. data/doc/Sprout/System/VistaSystem.html +251 -0
  86. data/doc/Sprout/System/WinNixSystem.html +325 -0
  87. data/doc/Sprout/System/WinSystem.html +571 -0
  88. data/doc/Sprout/ToolGenerator.html +931 -0
  89. data/doc/Sprout/VERSION.html +128 -0
  90. data/doc/SproutTestCase.html +1412 -0
  91. data/doc/String.html +286 -0
  92. data/doc/_index.html +1035 -0
  93. data/doc/class_list.html +36 -0
  94. data/doc/css/common.css +1 -0
  95. data/doc/css/full_list.css +53 -0
  96. data/doc/css/style.css +310 -0
  97. data/doc/file.README.html +96 -0
  98. data/doc/file.archive_unpacker.html +288 -0
  99. data/doc/file.base.html +208 -0
  100. data/doc/file.base_system.html +278 -0
  101. data/doc/file.boolean.html +135 -0
  102. data/doc/file.collection_param.html +139 -0
  103. data/doc/file.command.html +126 -0
  104. data/doc/file.concern.html +136 -0
  105. data/doc/file.daemon.html +309 -0
  106. data/doc/file.dir.html +76 -0
  107. data/doc/file.directory_manifest.html +122 -0
  108. data/doc/file.errors.html +147 -0
  109. data/doc/file.executable.html +638 -0
  110. data/doc/file.file_manifest.html +109 -0
  111. data/doc/file.file_param.html +120 -0
  112. data/doc/file.file_target.html +140 -0
  113. data/doc/file.files.html +85 -0
  114. data/doc/file.generator.html +296 -0
  115. data/doc/file.generator_class.html +72 -0
  116. data/doc/file.generator_generator.html +137 -0
  117. data/doc/file.generator_test.html +92 -0
  118. data/doc/file.generator_test_helper.html +67 -0
  119. data/doc/file.java_system.html +62 -0
  120. data/doc/file.library.html +291 -0
  121. data/doc/file.library_generator.html +74 -0
  122. data/doc/file.log.html +100 -0
  123. data/doc/file.manifest.html +67 -0
  124. data/doc/file.mxmlc.html +740 -0
  125. data/doc/file.number.html +67 -0
  126. data/doc/file.osx_system.html +79 -0
  127. data/doc/file.param.html +491 -0
  128. data/doc/file.parameter_factory.html +119 -0
  129. data/doc/file.path.html +81 -0
  130. data/doc/file.paths.html +80 -0
  131. data/doc/file.platform.html +124 -0
  132. data/doc/file.process_runner.html +224 -0
  133. data/doc/file.progress_bar.html +390 -0
  134. data/doc/file.rdoc_parser.html +145 -0
  135. data/doc/file.remote_file_loader.html +117 -0
  136. data/doc/file.remote_file_target.html +176 -0
  137. data/doc/file.ruby_base.html +64 -0
  138. data/doc/file.ruby_feature.html +244 -0
  139. data/doc/file.ruby_generator.html +118 -0
  140. data/doc/file.ruby_input.html +62 -0
  141. data/doc/file.ruby_test_case.html +78 -0
  142. data/doc/file.ruby_test_helper.html +61 -0
  143. data/doc/file.specification.html +248 -0
  144. data/doc/file.sprout.html +64 -0
  145. data/doc/file.sprout_test_case.html +280 -0
  146. data/doc/file.string.html +72 -0
  147. data/doc/file.string_param.html +76 -0
  148. data/doc/file.strings.html +71 -0
  149. data/doc/file.system.html +86 -0
  150. data/doc/file.template_manifest.html +67 -0
  151. data/doc/file.tool.html +92 -0
  152. data/doc/file.tool_generator.html +90 -0
  153. data/doc/file.unix_system.html +128 -0
  154. data/doc/file.url.html +71 -0
  155. data/doc/file.urls.html +70 -0
  156. data/doc/file.version.html +71 -0
  157. data/doc/file.vista_system.html +69 -0
  158. data/doc/file.win_nix_system.html +88 -0
  159. data/doc/file.win_system.html +129 -0
  160. data/doc/file_list.html +230 -0
  161. data/doc/frames.html +13 -0
  162. data/doc/index.html +96 -0
  163. data/doc/js/app.js +202 -0
  164. data/doc/js/full_list.js +149 -0
  165. data/doc/js/jquery.js +154 -0
  166. data/doc/method_list.html +3355 -0
  167. data/doc/top-level-namespace.html +192 -0
  168. data/lib/sprout/archive_unpacker.rb +203 -137
  169. data/lib/sprout/base.rb +38 -11
  170. data/lib/sprout/concern.rb +51 -0
  171. data/lib/sprout/daemon.rb +256 -0
  172. data/lib/sprout/executable.rb +40 -11
  173. data/lib/sprout/executable/boolean.rb +47 -1
  174. data/lib/sprout/executable/collection_param.rb +33 -1
  175. data/lib/sprout/executable/file_param.rb +16 -3
  176. data/lib/sprout/executable/files.rb +5 -0
  177. data/lib/sprout/executable/number.rb +5 -1
  178. data/lib/sprout/executable/param.rb +232 -16
  179. data/lib/sprout/executable/parameter_factory.rb +39 -1
  180. data/lib/sprout/executable/path.rb +7 -1
  181. data/lib/sprout/executable/paths.rb +6 -1
  182. data/lib/sprout/executable/string_param.rb +8 -1
  183. data/lib/sprout/executable/strings.rb +7 -1
  184. data/lib/sprout/executable/url.rb +8 -1
  185. data/lib/sprout/executable/urls.rb +7 -1
  186. data/lib/sprout/file_target.rb +11 -11
  187. data/lib/sprout/generator.rb +244 -0
  188. data/lib/sprout/generator/base.rb +0 -94
  189. data/lib/sprout/generators/generator/generator_generator.rb +35 -1
  190. data/lib/sprout/generators/generator/templates/generator_class.rb +3 -3
  191. data/lib/sprout/library.rb +75 -0
  192. data/lib/sprout/log.rb +11 -12
  193. data/lib/sprout/process_runner.rb +29 -9
  194. data/lib/sprout/remote_file_target.rb +20 -9
  195. data/lib/sprout/system/base_system.rb +11 -3
  196. data/lib/sprout/test/sprout_test_case.rb +1 -0
  197. data/lib/sprout/version.rb +7 -11
  198. data/rakefile.rb +7 -12
  199. data/script/add_param_handler.rb +43 -0
  200. data/sprout.gemspec +2 -3
  201. data/test/fixtures/executable/fdb.rb +764 -0
  202. data/test/fixtures/executable/flex3sdk_gem/fdb +60 -0
  203. data/test/fixtures/executable/mxmlc.rb +9 -11
  204. data/test/unit/daemon_test.rb +61 -0
  205. data/test/unit/process_runner_test.rb +21 -0
  206. data/test/unit/remote_file_target_test.rb +45 -11
  207. data/test/unit/sprout_test_helper.rb +1 -1
  208. metadata +210 -29
data/lib/sprout/base.rb CHANGED
@@ -15,6 +15,7 @@ require 'sprout/process_runner'
15
15
  require 'sprout/system'
16
16
  require 'sprout/ruby_feature'
17
17
 
18
+ ##
18
19
  # This is a fix for Issue #106
19
20
  # http://code.google.com/p/projectsprouts/issues/detail?id=106
20
21
  # Which is created because the new version (1.0.1) of RubyGems
@@ -36,36 +37,64 @@ require 'sprout/remote_file_target'
36
37
  require 'sprout/rdoc_parser'
37
38
  require 'sprout/specification'
38
39
  require 'sprout/executable'
40
+ require 'sprout/daemon'
39
41
 
40
42
  # Generators
41
- require 'sprout/generator/command'
42
- require 'sprout/generator/manifest'
43
- require 'sprout/generator/file_manifest'
44
- require 'sprout/generator/template_manifest'
45
- require 'sprout/generator/directory_manifest'
46
- require 'sprout/generator/base'
43
+ require 'sprout/generator'
47
44
 
48
45
  # Libraries
49
46
  require 'sprout/library'
50
47
 
51
48
  module Sprout
49
+
50
+ ##
51
+ # This is the badly-named module that we use to hang our globally-accessible
52
+ # interface from.
53
+ #
54
+ # @see: Sprout::Base::ClassMethods
52
55
  module Base
53
56
  extend Concern
54
57
 
55
58
  module ClassMethods
56
59
 
60
+ ##
61
+ # Returns the system-specific path to the writeable cache directory
62
+ # where Sprouts will look for downloaded archives.
63
+ #
64
+ # puts ">> Sprout Cache: #{Sprout::Base.cache}"
65
+ #
57
66
  def cache
58
67
  File.join(sprout_home, 'cache')
59
68
  end
60
69
 
70
+ ##
71
+ # Returns the location where the currently-running version of Sprouts
72
+ # will write files and generators and their templates.
73
+ #
74
+ # puts ">> Sprout home: #{Sprout::Base.sprout_home}"
75
+ #
61
76
  def sprout_home
62
77
  File.join(current_system.application_home('sprouts'), Sprout::VERSION::MAJOR_MINOR)
63
78
  end
64
79
 
80
+ ##
81
+ # Returns the location where Sprouts will look for generators and their
82
+ # templates.
83
+ #
84
+ # puts ">> Generator Cache: #{Sprout::Base.generator_cache}"
85
+ #
65
86
  def generator_cache
66
87
  File.join cache, 'generators'
67
88
  end
68
89
 
90
+ ##
91
+ # Return the Sprout::System that is currently being used to
92
+ # determine features like the cache path and how external processes
93
+ # are executed.
94
+ #
95
+ # system = Sprout::Base.current_system
96
+ # puts ">> System: #{system.inspect}"
97
+ #
69
98
  def current_system
70
99
  Sprout::System.create
71
100
  end
@@ -74,8 +103,9 @@ module Sprout
74
103
  # Get the file name from the 'caller' property of
75
104
  # a Ruby exception.
76
105
  #
77
- # Note: It's a bummer that this string is colon delimited -
78
- # The value on Windows can include a colon...
106
+ # Note: It's a real bummer that this string is colon delimited -
107
+ # The value on Windows often includes a colon...
108
+ # Once again, Windows is dissed by fundamental Ruby decisions.
79
109
  def file_from_caller caller_string
80
110
  parts = caller_string.split(':')
81
111
  str = parts.shift
@@ -89,6 +119,3 @@ module Sprout
89
119
  end
90
120
  end
91
121
 
92
- # TODO: the included 'files' should get modified by the following expressions:
93
- #included_files = FileList["**/*"].exclude /.DS_Store|generated|.svn|.git|airglobal.swc|airframework.swc/
94
-
@@ -1,9 +1,35 @@
1
1
  module Sprout
2
+
3
+ ##
4
+ # This class was copied from Rails source code and provides
5
+ # our RubyFeature with the ability to more clearly mix in
6
+ # functionality against a class and behave as if inheritance
7
+ # works at the class mixin level.
8
+ #
9
+ # TODO: I'd like to update our system so that this
10
+ # functionality is no longer necessary - if you have ideas
11
+ # or opinions about this code, please let me know!
2
12
  module Concern
13
+
14
+ ##
15
+ # Callback handler when a class is extended. This
16
+ # handler will set the @_dependencies array on the
17
+ # concrete class that just extended a
18
+ # 'Concern'.
19
+ #
20
+ # This callback is often triggered with:
21
+ #
22
+ # class Foo
23
+ # extend Concern
24
+ # end
25
+ #
3
26
  def self.extended(base)
4
27
  base.instance_variable_set("@_dependencies", [])
5
28
  end
6
29
 
30
+ ##
31
+ # Apply both class and instance features found in the
32
+ # base class to the new subclass.
7
33
  def append_features(base)
8
34
  if base.instance_variable_defined?("@_dependencies")
9
35
  base.instance_variable_get("@_dependencies") << self
@@ -18,6 +44,8 @@ module Sprout
18
44
  end
19
45
  end
20
46
 
47
+ ##
48
+ # Handle inclusion of this module.
21
49
  def included(base = nil, &block)
22
50
  if base.nil?
23
51
  @_included_block = block
@@ -28,3 +56,26 @@ module Sprout
28
56
  end
29
57
  end
30
58
 
59
+ =begin
60
+ Copyright (c) 2004-2010 David Heinemeier Hansson
61
+
62
+ Permission is hereby granted, free of charge, to any person obtaining
63
+ a copy of this software and associated documentation files (the
64
+ "Software"), to deal in the Software without restriction, including
65
+ without limitation the rights to use, copy, modify, merge, publish,
66
+ distribute, sublicense, and/or sell copies of the Software, and to
67
+ permit persons to whom the Software is furnished to do so, subject to
68
+ the following conditions:
69
+
70
+ The above copyright notice and this permission notice shall be
71
+ included in all copies or substantial portions of the Software.
72
+
73
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
74
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
75
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
76
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
77
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
78
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
79
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
80
+ =end
81
+
@@ -0,0 +1,256 @@
1
+
2
+ module Sprout
3
+
4
+ ##
5
+ # The Sprout::Daemon module exposes the Domain Specific Language
6
+ # provided by the Sprout::Executable module, but with
7
+ # enhancements (and modifications) to support long-lived processes
8
+ # (like FDB and FCSH).
9
+ #
10
+ # NOTE: Any class that includes Sprout::Daemon should first include
11
+ # Sprout::Executable. This is an admittedly smelly constraint, but it works
12
+ # for now.
13
+ #
14
+ # class Foo
15
+ # include Sprout::Executable
16
+ # include Sprout::Daemon
17
+ #
18
+ # ##
19
+ # # Keep in mind that we're still working
20
+ # # with Executable, so add_param is available
21
+ # # for the initialization of the process.
22
+ # add_param :input, File
23
+ #
24
+ # ##
25
+ # # Expose the do_something action after
26
+ # # the process is started.
27
+ # add_action :do_something
28
+ #
29
+ # ##
30
+ # # Expose the do_something_else action after
31
+ # # the process is started.
32
+ # add_action :do_something_else
33
+ # end
34
+ #
35
+ # You can also create a globally-accessible rake task to expose
36
+ # your new Daemon instance to Rake by creating a method like the following:
37
+ #
38
+ # def foo *args, &block
39
+ # foo_tool = Foo.new
40
+ # foo_tool.to_rake *args, &block
41
+ # end
42
+ #
43
+ # Note: The aforementioned rake helper is usually written at the bottom of
44
+ # the class file that is referenced.
45
+ #
46
+ # The aforementioned Rake task could be used like:
47
+ #
48
+ # foo :bar do |t|
49
+ # t.do_something
50
+ # t.do_something_else
51
+ # end
52
+ #
53
+ # @see: Sprout::Daemon::ClassMethods
54
+ # @see: Sprout::Daemon::InstanceMethods
55
+ #
56
+ module Daemon
57
+
58
+ extend Concern
59
+
60
+ ##
61
+ # These are the methods that will be available
62
+ # on any class that includes Sprout::Daemon.
63
+ module ClassMethods
64
+
65
+ ##
66
+ # Add an action that can be called while
67
+ # the long-lived process is active.
68
+ #
69
+ # This method should raise a Sprout::Errors::UsageError
70
+ # if the provided action name is already defined for
71
+ # the provided instance.
72
+ def add_action name, arguments=nil, options=nil
73
+ options ||= {}
74
+ options[:name] = name
75
+ options[:arguments] = arguments
76
+ create_action_method options
77
+ end
78
+
79
+ ##
80
+ # Create an (often shorter) alias to another
81
+ # action name.
82
+ def add_action_alias alias_name, source_name
83
+ define_method(alias_name) do |*params|
84
+ self.send(source_name, params)
85
+ end
86
+ end
87
+
88
+ private
89
+
90
+ ##
91
+ # Actually create the method for a provided
92
+ # action.
93
+ #
94
+ # This method should explode if the method name
95
+ # already exists.
96
+ def create_action_method options
97
+ name = options[:name]
98
+ accessor_can_be_defined_at name
99
+
100
+ define_method(name) do |*params|
101
+ action = name.to_s
102
+ action = "y" if name == :confirm # Convert affirmation
103
+ action << " #{params.join(' ')}" unless params.nil?
104
+ action_stack << action
105
+ end
106
+ end
107
+
108
+ ##
109
+ # TODO: Raise an exception if the name is
110
+ # already taken?
111
+ def accessor_can_be_defined_at name
112
+ end
113
+
114
+ end
115
+
116
+ ##
117
+ # Instance methods that will be available on any
118
+ # class that includes Sprout::Daemon.
119
+ module InstanceMethods
120
+
121
+ ##
122
+ # The prompt expression for this daemon process.
123
+ #
124
+ # When executing a series of commands, the
125
+ # wrapper will wait until it matches this expression
126
+ # on stdout before continuing the series.
127
+ #
128
+ # For FDB, this value is set like:
129
+ #
130
+ # set :prompt, /^\(fdb\) /
131
+ #
132
+ # Most processes can trigger a variety of different
133
+ # prompts, these can be expressed here using the | (or) operator.
134
+ #
135
+ # FDB actually uses the following:
136
+ #
137
+ # set :prompt, /^\(fdb\) |\(y or n\) /
138
+ #
139
+ attr_accessor :prompt
140
+
141
+ ##
142
+ # This is the array of actions that have
143
+ # been provided at the class level to this instance.
144
+ attr_reader :action_stack
145
+
146
+ def initialize
147
+ super
148
+ @action_stack = []
149
+ end
150
+
151
+ ##
152
+ # Execute the Daemon executable, followed
153
+ # by the collection of stored actions in
154
+ # the order they were called.
155
+ #
156
+ # If none of the stored actions result in
157
+ # terminating the process, the underlying
158
+ # daemon will be connected to the terminal
159
+ # for user (manual) input.
160
+ def execute
161
+ runner = super
162
+ execute_actions runner
163
+ handle_user_session runner
164
+ Process.wait runner.pid
165
+ end
166
+
167
+ protected
168
+
169
+ ##
170
+ # This is the override of the underlying
171
+ # Sprout::Executable template method so that we
172
+ # create a 'task' instead of a 'file' task.
173
+ def create_outer_task *args
174
+ task *args do
175
+ execute
176
+ end
177
+ end
178
+
179
+ ##
180
+ # This is the override of the underlying
181
+ # Sprout::Executable template method so that we
182
+ # are NOT added to the CLEAN collection.
183
+ # (Work performed in the Executable)
184
+ def update_rake_task_name_from_args *args
185
+ self.rake_task_name = parse_rake_task_arg args.last
186
+ end
187
+
188
+ ##
189
+ # This is the override of the underlying
190
+ # Sprout::Executable template method so that we
191
+ # create the process in a thread
192
+ # in order to read and write to it.
193
+ def system_execute binary, params
194
+ Sprout.current_system.execute_thread binary, params
195
+ end
196
+
197
+ private
198
+
199
+ ##
200
+ # Execute the collection of provided actions.
201
+ def execute_actions runner
202
+ action_stack.each do |action|
203
+ if wait_for_prompt runner
204
+ Sprout::Log.puts action
205
+ execute_action runner, action
206
+ end
207
+ end
208
+ end
209
+
210
+ ##
211
+ # Execute a single action.
212
+ def execute_action runner, action
213
+ runner.puts action.strip
214
+ end
215
+
216
+ ##
217
+ # Expose the running process to manual
218
+ # input on the terminal, and write stdout
219
+ # back to the user.
220
+ def handle_user_session runner
221
+ while !runner.r.eof?
222
+ if wait_for_prompt runner
223
+ input = $stdin.gets.chomp!
224
+ execute_action runner, input
225
+ end
226
+ end
227
+ end
228
+
229
+ ##
230
+ # Wait for the underlying process to present
231
+ # an input prompt, so that another action
232
+ # can be submitted, or user input can be
233
+ # collected.
234
+ def wait_for_prompt runner, expected_prompt=nil
235
+ ##
236
+ # TODO: This should also check for a variety of prompts...
237
+ expected_prompt = expected_prompt || prompt
238
+ line = ''
239
+
240
+ while runner.alive? do
241
+ Sprout::Log.flush
242
+ return false if runner.r.eof?
243
+ char = runner.readpartial 1
244
+ line << char
245
+ if char == "\n"
246
+ line = ''
247
+ end
248
+ Sprout::Log.printf char
249
+ return true if line.match expected_prompt
250
+ end
251
+ end
252
+
253
+ end
254
+ end
255
+ end
256
+
@@ -27,7 +27,7 @@ module Sprout
27
27
  # Following is an example of how one could define an executable Ruby
28
28
  # application using this module:
29
29
  #
30
- # :include: ../../test/fixtures/examples/echo_inputs.rb
30
+ # :include: ../../test/fixtures/examples/echo_inputs.rb
31
31
  #
32
32
  module Executable
33
33
  include RubyFeature
@@ -77,7 +77,7 @@ module Sprout
77
77
  # in the order they are defined using +add_param+.
78
78
  #
79
79
  def add_param(name, type, options=nil) # :yields: Sprout::Executable::Param
80
- raise Sprout::Errors::UsageError.new("[DEPRECATED] add_param no longer uses closures, you can provide the same values as a hash in the optional last argument.") if block_given?
80
+ raise Sprout::Errors::UsageError.new "[DEPRECATED] add_param no longer uses closures, you can provide the same values as a hash in the optional last argument." if block_given?
81
81
  raise Sprout::Errors::UsageError.new "The first parameter (name:SymbolOrString) is required" if name.nil?
82
82
  raise Sprout::Errors::UsageError.new "The second parameter (type:Class) is required" if type.nil?
83
83
  raise Sprout::Errors::UsageError.new "The type parameter must be a Class by reference" if !type.is_a?(Class)
@@ -295,8 +295,7 @@ module Sprout
295
295
  # This method is generally called from Rake task wrappers.
296
296
  #
297
297
  def execute_delegate
298
- exe = Sprout::Executable.load(executable, pkg_name, pkg_version).path
299
- Sprout.current_system.execute exe, to_shell
298
+ system_execute binary_path, to_shell
300
299
  end
301
300
 
302
301
  def prepare
@@ -308,9 +307,7 @@ module Sprout
308
307
  def to_rake *args
309
308
  # Define the file task first - so that
310
309
  # desc blocks hook up to it...
311
- file_task = file *args do
312
- execute
313
- end
310
+ outer_task = create_outer_task *args
314
311
  update_rake_task_name_from_args *args
315
312
  yield self if block_given?
316
313
  prepare
@@ -318,15 +315,15 @@ module Sprout
318
315
  # TODO: Tried auto-updating with library
319
316
  # prerequisites, but this led to strange
320
317
  # behavior with multiple registrations.
321
- handle_library_prerequisites file_task.prerequisites
318
+ handle_library_prerequisites outer_task.prerequisites
322
319
 
323
320
  # Add the library resolution rake task
324
321
  # as a prerequisite
325
- file_task.prerequisites << task(Sprout::Library::TASK_NAME)
322
+ outer_task.prerequisites << task(Sprout::Library::TASK_NAME)
326
323
  prerequisites.each do |prereq|
327
- file_task.prerequisites << prereq
324
+ outer_task.prerequisites << prereq
328
325
  end
329
- file_task
326
+ outer_task
330
327
  end
331
328
 
332
329
  ##
@@ -382,9 +379,33 @@ module Sprout
382
379
 
383
380
  protected
384
381
 
382
+ ##
383
+ # Create the outer rake task.
384
+ # For most executables, this will be a Rake::File task,
385
+ # This is a template method that should be overridden
386
+ # for executables that do not result in the creation of
387
+ # a file.
388
+ #
389
+ # @see update_rake_task_name_from_args
390
+ def create_outer_task *args
391
+ file *args do
392
+ execute
393
+ end
394
+ end
395
+
396
+ ##
397
+ # This method will add the current task to the Rake CLEAN
398
+ # collection.
399
+ #
400
+ # Any Executable that does not create a Rake::File task
401
+ # should also override this method and prevent it from
402
+ # calling +CLEAN.add+.
403
+ #
404
+ # @see create_outer_task
385
405
  def update_rake_task_name_from_args *args
386
406
  self.rake_task_name = parse_rake_task_arg args.last
387
407
  CLEAN.add(self.rake_task_name)
408
+ self.rake_task_name
388
409
  end
389
410
 
390
411
  def parse_rake_task_arg arg
@@ -417,8 +438,16 @@ module Sprout
417
438
  def library_added path_or_paths
418
439
  end
419
440
 
441
+ def system_execute binary, params
442
+ Sprout.current_system.execute binary, params
443
+ end
444
+
420
445
  private
421
446
 
447
+ def binary_path
448
+ Sprout::Executable.load(executable, pkg_name, pkg_version).path
449
+ end
450
+
422
451
  def handle_library_prerequisites items
423
452
  items.each do |task_name|
424
453
  t = Rake.application[task_name]