sprout 0.7.246 → 1.0.0.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 (211) hide show
  1. data/CHANGELOG.md +10 -0
  2. data/Gemfile +28 -0
  3. data/MIT-LICENSE +3 -2
  4. data/POSTINSTALL.rdoc +28 -0
  5. data/README.textile +152 -0
  6. data/bin/sprout +1 -131
  7. data/bin/sprout-generator +10 -0
  8. data/bin/sprout-library +11 -0
  9. data/bin/sprout-tool +10 -0
  10. data/lib/sprout.rb +4 -500
  11. data/lib/sprout/archive_unpacker.rb +122 -206
  12. data/lib/sprout/base.rb +90 -0
  13. data/lib/sprout/concern.rb +30 -0
  14. data/lib/sprout/dir.rb +23 -0
  15. data/lib/sprout/errors.rb +94 -0
  16. data/lib/sprout/executable.rb +496 -0
  17. data/lib/sprout/executable/boolean.rb +35 -0
  18. data/lib/sprout/executable/collection_param.rb +53 -0
  19. data/lib/sprout/executable/file_param.rb +53 -0
  20. data/lib/sprout/executable/files.rb +26 -0
  21. data/lib/sprout/executable/number.rb +10 -0
  22. data/lib/sprout/executable/param.rb +222 -0
  23. data/lib/sprout/executable/parameter_factory.rb +28 -0
  24. data/lib/sprout/executable/path.rb +21 -0
  25. data/lib/sprout/executable/paths.rb +21 -0
  26. data/lib/sprout/executable/string_param.rb +15 -0
  27. data/lib/sprout/executable/strings.rb +11 -0
  28. data/lib/sprout/executable/url.rb +10 -0
  29. data/lib/sprout/executable/urls.rb +10 -0
  30. data/lib/sprout/file_target.rb +76 -0
  31. data/lib/sprout/generator/base.rb +233 -0
  32. data/lib/sprout/generator/command.rb +67 -0
  33. data/lib/sprout/generator/directory_manifest.rb +49 -0
  34. data/lib/sprout/generator/file_manifest.rb +55 -0
  35. data/lib/sprout/generator/manifest.rb +13 -0
  36. data/lib/sprout/generator/template_manifest.rb +13 -0
  37. data/lib/sprout/generators/generator/generator_generator.rb +48 -0
  38. data/lib/sprout/generators/generator/templates/generator_class.rb +17 -0
  39. data/lib/sprout/generators/generator/templates/generator_executable +9 -0
  40. data/lib/sprout/generators/generator/templates/generator_template +1 -0
  41. data/lib/sprout/generators/generator/templates/generator_test.rb +37 -0
  42. data/lib/sprout/generators/generator/templates/generator_test_helper.rb +16 -0
  43. data/lib/sprout/generators/library/library_generator.rb +20 -0
  44. data/lib/sprout/generators/library/templates/library.gemspec +19 -0
  45. data/lib/sprout/generators/library/templates/library.rb +15 -0
  46. data/lib/sprout/generators/ruby/ruby_generator.rb +59 -0
  47. data/lib/sprout/generators/ruby/templates/ruby_base.rb +10 -0
  48. data/lib/sprout/generators/ruby/templates/ruby_executable +6 -0
  49. data/lib/sprout/generators/ruby/templates/ruby_gemfile +4 -0
  50. data/lib/sprout/generators/ruby/templates/ruby_input.rb +7 -0
  51. data/lib/sprout/generators/tool/templates/Gemfile +4 -0
  52. data/lib/sprout/generators/tool/templates/tool.gemspec +22 -0
  53. data/lib/sprout/generators/tool/templates/tool.rb +38 -0
  54. data/lib/sprout/generators/tool/tool_generator.rb +36 -0
  55. data/lib/sprout/library.rb +111 -0
  56. data/lib/sprout/log.rb +1 -0
  57. data/lib/sprout/platform.rb +71 -0
  58. data/lib/sprout/process_runner.rb +80 -40
  59. data/lib/sprout/progress_bar.rb +341 -0
  60. data/lib/sprout/rdoc_parser.rb +91 -0
  61. data/lib/sprout/remote_file_loader.rb +72 -50
  62. data/lib/sprout/remote_file_target.rb +44 -152
  63. data/lib/sprout/ruby_feature.rb +167 -0
  64. data/lib/sprout/specification.rb +197 -0
  65. data/lib/sprout/string.rb +19 -0
  66. data/lib/sprout/system.rb +35 -0
  67. data/lib/sprout/system/base_system.rb +225 -0
  68. data/lib/sprout/system/java_system.rb +9 -0
  69. data/lib/sprout/system/osx_system.rb +26 -0
  70. data/lib/sprout/system/unix_system.rb +72 -0
  71. data/lib/sprout/system/vista_system.rb +16 -0
  72. data/lib/sprout/system/win_nix_system.rb +41 -0
  73. data/lib/sprout/system/win_system.rb +76 -0
  74. data/lib/sprout/test/sprout_test_case.rb +211 -0
  75. data/lib/sprout/version.rb +9 -4
  76. data/rakefile.rb +85 -144
  77. data/script/console +10 -0
  78. data/script/destroy +14 -0
  79. data/script/generate +14 -0
  80. data/sprout.gemspec +26 -0
  81. data/test/fixtures/archive_unpacker/copyable/some_file.exe +0 -0
  82. data/test/fixtures/archive_unpacker/copyable/some_file.rb +0 -0
  83. data/test/fixtures/archive_unpacker/copyable/some_file.swc +0 -0
  84. data/test/fixtures/archive_unpacker/tgz/some folder.tgz +0 -0
  85. data/test/fixtures/archive_unpacker/tgz/some_file.tgz +0 -0
  86. data/test/fixtures/archive_unpacker/zip/some folder.zip +0 -0
  87. data/test/fixtures/archive_unpacker/zip/some_file.zip +0 -0
  88. data/test/fixtures/examples/app_generator.rb +127 -0
  89. data/test/fixtures/examples/echo_inputs.rb +151 -0
  90. data/test/fixtures/executable/echochamber_gem/bin/echochamber +3 -0
  91. data/test/fixtures/executable/echochamber_gem/echo_chamber.rb +10 -0
  92. data/test/fixtures/executable/flex3sdk_gem/flex3sdk.rb +11 -0
  93. data/test/fixtures/executable/flex3sdk_gem/mxmlc +3 -0
  94. data/test/fixtures/executable/flex3sdk_gem/mxmlc.bat +3 -0
  95. data/test/fixtures/executable/mxmlc.rb +805 -0
  96. data/test/fixtures/executable/params/input.as +0 -0
  97. data/test/fixtures/executable/params/input2.as +0 -0
  98. data/test/fixtures/executable/params/input3.as +0 -0
  99. data/test/fixtures/executable/params/mxmlc +5 -0
  100. data/test/fixtures/executable/path with spaces/input.as b/data/test/fixtures/executable/path with → spaces/input.as +0 -0
  101. data/test/fixtures/executable/path with spaces/input2.as b/data/test/fixtures/executable/path with → spaces/input2.as +0 -0
  102. data/test/fixtures/executable/path with spaces/input3.as b/data/test/fixtures/executable/path with → spaces/input3.as +0 -0
  103. data/test/fixtures/executable/paths/folder1/file1 +0 -0
  104. data/test/fixtures/executable/paths/folder1/file2 +0 -0
  105. data/test/fixtures/executable/paths/folder1/file3 +0 -0
  106. data/test/fixtures/executable/paths/folder2/file4 +0 -0
  107. data/test/fixtures/executable/paths/folder2/file5 +0 -0
  108. data/test/fixtures/executable/paths/folder3/file6 +0 -0
  109. data/test/fixtures/executable/src/Main.as +0 -0
  110. data/test/fixtures/executable/windows_line_endings +47 -0
  111. data/test/fixtures/generators/song_generator.rb +11 -0
  112. data/test/fixtures/generators/song_subclass/least_favorite.rb +10 -0
  113. data/test/fixtures/generators/song_subclass/templates/Song.txt +3 -0
  114. data/test/fixtures/generators/temp_generator.rb +24 -0
  115. data/test/fixtures/generators/templates/Main.as +9 -0
  116. data/test/fixtures/generators/templates/OtherFileTemplate +1 -0
  117. data/test/fixtures/generators/templates/SomeFile +1 -0
  118. data/test/fixtures/generators/templates/SomeSubclassFile +2 -0
  119. data/test/fixtures/generators/templates/Song.txt +3 -0
  120. data/test/fixtures/generators/templates/destroy +0 -0
  121. data/test/fixtures/generators/templates/generate +0 -0
  122. data/test/fixtures/library/archive/Archive.swc +0 -0
  123. data/test/fixtures/library/sources/lib/a/A.as +0 -0
  124. data/test/fixtures/library/sources/lib/b/B.as +0 -0
  125. data/test/fixtures/library/sources/src/Source.as +0 -0
  126. data/test/fixtures/process_runner/chmod_script.sh +3 -0
  127. data/test/fixtures/process_runner/dir with spaces/chmod_script.sh +3 -0
  128. data/test/fixtures/process_runner/failure +5 -0
  129. data/test/fixtures/process_runner/success +4 -0
  130. data/test/fixtures/remote_file_loader/md5/echochamber-test.zip +0 -0
  131. data/test/fixtures/remote_file_loader/md5/file_with_known_md5 +0 -0
  132. data/test/fixtures/remote_file_target/bin/echochamber +3 -0
  133. data/test/fixtures/remote_file_target/bin/echochamber.bat +3 -0
  134. data/test/fixtures/remote_file_target/echochamber-test.zip +0 -0
  135. data/test/fixtures/specification/asunit4.rb +25 -0
  136. data/test/fixtures/specification/ext/AsUnit-4.1.pre.swc +0 -0
  137. data/test/fixtures/specification/flashplayer.rb +30 -0
  138. data/test/fixtures/specification/flex4sdk.rb +72 -0
  139. data/test/fixtures/specification/flexunit4.sproutspec +17 -0
  140. data/test/fixtures/specification/lib/as3reflection/Reflection.as +0 -0
  141. data/test/fixtures/specification/src/AsUnit.as +0 -0
  142. data/test/fixtures/user/mxmlc_crlf +3 -0
  143. data/test/unit/archive_unpacker_test.rb +108 -0
  144. data/test/unit/boolean_param_test.rb +38 -0
  145. data/test/unit/executable_option_parser_test.rb +142 -0
  146. data/test/unit/executable_param_test.rb +76 -0
  147. data/test/unit/executable_test.rb +237 -0
  148. data/test/unit/fake_executable_task.rb +22 -0
  149. data/test/unit/fake_other_executable.rb +20 -0
  150. data/test/unit/fake_process_runner.rb +29 -0
  151. data/test/unit/file_param_test.rb +61 -0
  152. data/test/unit/file_target_test.rb +42 -0
  153. data/test/unit/files_param_test.rb +72 -0
  154. data/test/unit/generator_generator_test.rb +85 -0
  155. data/test/unit/generator_test.rb +333 -0
  156. data/test/unit/library_generator_test.rb +41 -0
  157. data/test/unit/library_test.rb +88 -0
  158. data/test/unit/osx_system_test.rb +20 -0
  159. data/test/unit/path_param_test.rb +43 -0
  160. data/test/unit/paths_param_test.rb +53 -0
  161. data/test/unit/platform_test.rb +76 -0
  162. data/test/unit/process_runner_test.rb +104 -0
  163. data/test/unit/rdoc_parser_test.rb +15 -0
  164. data/test/unit/remote_file_loader_test.rb +34 -0
  165. data/test/unit/remote_file_target_test.rb +105 -0
  166. data/test/unit/ruby_feature_test.rb +108 -0
  167. data/test/unit/ruby_generator_test.rb +70 -0
  168. data/test/unit/specification_test.rb +73 -0
  169. data/test/unit/sprout_test.rb +170 -0
  170. data/test/unit/sprout_test_helper.rb +18 -0
  171. data/test/unit/string_param_test.rb +19 -0
  172. data/test/unit/string_test.rb +20 -0
  173. data/test/unit/strings_param_test.rb +27 -0
  174. data/test/unit/test_helper.rb +1 -0
  175. data/test/unit/tool_generator_test.rb +43 -0
  176. data/test/unit/unix_system_test.rb +52 -0
  177. data/test/unit/user_test.rb +147 -0
  178. data/test/unit/vista_system_test.rb +40 -0
  179. data/test/unit/win_nix_system_test.rb +26 -0
  180. data/test/unit/win_system_test.rb +61 -0
  181. metadata +318 -113
  182. data/doc/Bundle +0 -14
  183. data/doc/Generator +0 -35
  184. data/doc/Library +0 -63
  185. data/doc/Task +0 -21
  186. data/doc/Tool +0 -20
  187. data/lib/platform.rb +0 -113
  188. data/lib/progress_bar.rb +0 -354
  189. data/lib/sprout/builder.rb +0 -51
  190. data/lib/sprout/bundle_resolver.rb +0 -349
  191. data/lib/sprout/commands/generate.rb +0 -9
  192. data/lib/sprout/dynamic_accessors.rb +0 -40
  193. data/lib/sprout/general_tasks.rb +0 -6
  194. data/lib/sprout/generator.rb +0 -7
  195. data/lib/sprout/generator/base_mixins.rb +0 -186
  196. data/lib/sprout/generator/named_base.rb +0 -227
  197. data/lib/sprout/project_model.rb +0 -278
  198. data/lib/sprout/simple_resolver.rb +0 -88
  199. data/lib/sprout/tasks/erb_resolver.rb +0 -118
  200. data/lib/sprout/tasks/gem_wrap_task.rb +0 -214
  201. data/lib/sprout/tasks/git_task.rb +0 -134
  202. data/lib/sprout/tasks/library_task.rb +0 -118
  203. data/lib/sprout/tasks/sftp_task.rb +0 -248
  204. data/lib/sprout/tasks/ssh_task.rb +0 -153
  205. data/lib/sprout/tasks/tool_task.rb +0 -836
  206. data/lib/sprout/tasks/zip_task.rb +0 -158
  207. data/lib/sprout/tool_task_model.rb +0 -19
  208. data/lib/sprout/user.rb +0 -415
  209. data/lib/sprout/version_file.rb +0 -89
  210. data/lib/sprout/zip_util.rb +0 -61
  211. data/samples/gem_wrap/rakefile.rb +0 -17
@@ -0,0 +1,21 @@
1
+ module Sprout
2
+
3
+ module Executable
4
+
5
+ ##
6
+ # Concrete param object for collections of paths
7
+ class Paths < Files
8
+
9
+ def prepare_prerequisites
10
+ value.each do |path|
11
+ files = FileList[path + file_expression]
12
+ files.each do |f|
13
+ file f
14
+ belongs_to.prerequisites << f
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+
@@ -0,0 +1,15 @@
1
+ module Sprout
2
+
3
+ module Executable
4
+
5
+ # Concrete param object for :string values
6
+ class StringParam < Executable::Param
7
+
8
+ def shell_value
9
+ value.gsub(/ /, '\ ')
10
+ end
11
+
12
+ end
13
+ end
14
+ end
15
+
@@ -0,0 +1,11 @@
1
+ module Sprout
2
+
3
+ module Executable
4
+
5
+ # Concrete param object for collections of strings
6
+ class Strings < Executable::Param
7
+ include CollectionParam
8
+ end
9
+ end
10
+ end
11
+
@@ -0,0 +1,10 @@
1
+ module Sprout
2
+
3
+ module Executable
4
+
5
+ # Concrete param object for collections of files
6
+ class Url < StringParam
7
+ end
8
+ end
9
+ end
10
+
@@ -0,0 +1,10 @@
1
+ module Sprout
2
+
3
+ module Executable
4
+
5
+ # Concrete param object for collections of files
6
+ class Urls < Strings
7
+ end
8
+ end
9
+ end
10
+
@@ -0,0 +1,76 @@
1
+
2
+ module Sprout
3
+
4
+ # This is a class that is generally used by the Sprout::Specification::add_file_target method.
5
+ #
6
+ # File targets are files that are embedded into (or referred to by) a RubyGem in such a way
7
+ # that Sprouts can use them as a library or executable.
8
+ #
9
+ # A given FileTarget may be configured to work on a specific platform, or it may be
10
+ # universal.
11
+ #
12
+ class FileTarget
13
+
14
+ attr_accessor :load_path
15
+ attr_accessor :pkg_name
16
+ attr_accessor :pkg_version
17
+ attr_accessor :platform
18
+
19
+ attr_reader :executables
20
+ attr_reader :libraries
21
+
22
+ def initialize
23
+ @executables = []
24
+ @libraries = []
25
+ @load_path = '.'
26
+ @platform = :universal
27
+ yield self if block_given?
28
+ end
29
+
30
+ ##
31
+ # Add a library to the RubyGem package.
32
+ #
33
+ # @name Symbol that will be used to retrieve this library later.
34
+ # @path File, Path or Array of files that will be associated with this
35
+ # library and copied to the target lib.
36
+ #
37
+ # If the path is a directory, all files forward of that directory
38
+ # will be copied into the RubyGem.
39
+ #
40
+ def add_library name, path
41
+ if path.is_a?(Array)
42
+ path = path.collect { |p| expand_executable_path(p) }
43
+ else
44
+ path = expand_executable_path path
45
+ end
46
+ libraries << OpenStruct.new( :name => name, :path => path, :file_target => self )
47
+ end
48
+
49
+ ##
50
+ # Add an executable to the RubyGem package.
51
+ #
52
+ # @name Symbol that will be used to retrieve this executable later.
53
+ # @target The relative path to the executable that will be associated
54
+ # with this name.
55
+ #
56
+ def add_executable name, path
57
+ path = expand_executable_path path
58
+ executables << OpenStruct.new( :name => name, :path => path, :file_target => self )
59
+ end
60
+
61
+ def to_s
62
+ "[FileTarget type=#{type} platform=#{platform}]"
63
+ end
64
+
65
+ def validate
66
+ raise Sprout::Errors::UsageError.new "FileTarget.pkg_name is required" if pkg_name.nil?
67
+ raise Sprout::Errors::UsageError.new "FileTarget.pkg_version is required" if pkg_version.nil?
68
+ end
69
+
70
+ def expand_executable_path path
71
+ File.join load_path, path
72
+ end
73
+
74
+ end
75
+ end
76
+
@@ -0,0 +1,233 @@
1
+ module Sprout
2
+
3
+ module Generator
4
+ include RubyFeature
5
+
6
+ class << self
7
+
8
+ def register generator_class, templates_path=nil
9
+ generator_paths << { :class => generator_class, :templates => templates_path } unless templates_path.nil?
10
+ super(generator_class)
11
+ end
12
+
13
+ def template_folder_for clazz
14
+ # Search the potential matches in reverse order
15
+ # because subclasses have registered AFTER their
16
+ # superclasses and superclasses match the ===
17
+ # check...
18
+ generator_paths.reverse.each do |options|
19
+ if options[:class] === clazz
20
+ return options[:templates]
21
+ end
22
+ end
23
+ nil
24
+ end
25
+
26
+ ##
27
+ # Returns a new collection of paths to search within for generator declarations
28
+ # and more importantly, folders named, 'templates'.
29
+ #
30
+ # The collection of search_paths will be a subset of the following
31
+ # that will include only those directories that exist:
32
+ #
33
+ # ./config/generators
34
+ # ./vendor/generators
35
+ # ~/Library/Sprouts/1.0/generators # OS X only
36
+ # ~/.sprouts/1.0/generators # Unix only
37
+ # [USER_HOME]/Application Data/Sprouts/cache/1.0/generators # Windows only
38
+ # ENV['SPROUT_GENERATORS'] # Only if defined
39
+ # [Generator Declaration __FILE__]/templates
40
+ #
41
+ # When the generators attempt to resolve templates, each of the preceding
42
+ # folders will be scanned for a child directory named 'templates'. Within
43
+ # that directory, the requested template name will be scanned and the first
44
+ # found template file will be used. This process will be repeated for each
45
+ # template file that is requested.
46
+ #
47
+ # The idea is that you may wish to override some template files that a
48
+ # generator creates, but leave others unchanged.
49
+ #
50
+ def search_paths
51
+ # NOTE: Do not cache this list, specific generators
52
+ # will modify it with their own lookups
53
+ create_search_paths.select { |path| File.directory?(path) }
54
+ end
55
+
56
+ private
57
+
58
+ def create_search_paths
59
+ paths = [
60
+ File.join('config', 'generators'),
61
+ File.join('vendor', 'generators'),
62
+ Sprout.generator_cache
63
+ ]
64
+ paths << ENV['SPROUT_GENERATORS'] unless ENV['SPROUT_GENERATORS'].nil?
65
+ paths
66
+ end
67
+
68
+ ##
69
+ # I know this seems weird - but we can't instantiate the classes
70
+ # during registration because they register before they've been fully
71
+ # interpreted...
72
+ def update_registered_entities
73
+ registered_entities.collect! do |gen|
74
+ (gen.is_a?(Class)) ? gen.new : gen
75
+ end
76
+ end
77
+
78
+ def configure_instance generator
79
+ generator
80
+ end
81
+
82
+ def generator_paths
83
+ @generator_paths ||= []
84
+ end
85
+
86
+ end
87
+
88
+ class Base
89
+ include Sprout::Executable
90
+
91
+ def self.inherited base
92
+ # NOTE: We can NOT instantiate the class here,
93
+ # because only it's first line has been interpreted, if we
94
+ # instantiate here, none of the code declared in the class body will
95
+ # be associated with this instance.
96
+ #
97
+ # Go ahead and register the class and update instances afterwards.
98
+ Sprout::Generator.register base, template_from_caller(caller.first)
99
+ end
100
+
101
+ ##
102
+ # The directory where files will be created.
103
+ add_param :path, Path, { :default => Dir.pwd }
104
+
105
+ ##
106
+ # Insteast of creating, destroy the files.
107
+ add_param :destroy, Boolean
108
+
109
+ ##
110
+ # Force the creation of files without prompting.
111
+ add_param :force, Boolean
112
+
113
+ ##
114
+ # Run the generator in Quiet mode - do not write
115
+ # status to standard output.
116
+ add_param :quiet, Boolean
117
+
118
+ ##
119
+ # A collection of paths to look in for named templates.
120
+ add_param :templates, Paths
121
+
122
+ ##
123
+ # The primary input for the application or component.
124
+ add_param :input, String, { :hidden_name => true, :required => true }
125
+
126
+
127
+ ##
128
+ # Set the default name for generators.
129
+ set :name, :application
130
+
131
+ ##
132
+ # The symbol name for which this generator is most
133
+ # appropriate.
134
+ #
135
+ # This value defaults to :application so, if you're working on an
136
+ # application generator, you can leave it as the default.
137
+ #
138
+ # For all other generator types, you'll want to select the most
139
+ # general project type that this generator may be useful in.
140
+ #
141
+ # Following are some example values:
142
+ #
143
+ # :as3, :flex3, :flex4, :air2
144
+ #
145
+ # or core libraries:
146
+ #
147
+ # :asunit4, :flexunit4
148
+ #
149
+ # or even other libraries:
150
+ #
151
+ # :puremvc, :robotlegs, :swizz
152
+ #
153
+ attr_accessor :name
154
+ attr_accessor :logger
155
+ attr_accessor :pkg_name
156
+ attr_accessor :pkg_version
157
+
158
+ ##
159
+ # Record the actions and trigger them
160
+ def execute
161
+ return prepare_command.unexecute if destroy
162
+ prepare_command.execute
163
+ end
164
+
165
+ ##
166
+ # Rollback the generator
167
+ def unexecute
168
+ prepare_command.unexecute
169
+ end
170
+
171
+ def say message
172
+ logger.puts message.gsub("#{path}", '.') unless quiet
173
+ end
174
+
175
+ ##
176
+ # TODO: Add support for arbitrary templating languages.
177
+ # For now, just support ERB...
178
+ #
179
+ # TODO: This is also a possible spot where those of you that don't want
180
+ # to snuggle might put pretty-print code or some such
181
+ # modifiers...
182
+ def resolve_template content
183
+ require 'erb'
184
+ ERB.new(content, nil, '>').result(binding)
185
+ end
186
+
187
+ ##
188
+ # Returns a collection of templates that were provided on the
189
+ # command line, followed by templates that are created by a
190
+ # concrete generator, followed by the
191
+ # Sprout::Generator.search_paths + 'templates' folders.
192
+ #
193
+ def template_paths
194
+ templates << Sprout::Generator::template_folder_for(self)
195
+ templates.concat default_search_paths
196
+ end
197
+
198
+ protected
199
+
200
+ def default_search_paths
201
+ Sprout::Generator.search_paths.collect { |path| File.join(path, 'templates') }
202
+ end
203
+
204
+ def prepare_command
205
+ @logger ||= $stdout
206
+ @command = Command.new self
207
+ manifest
208
+ @command
209
+ end
210
+
211
+ def directory name, &block
212
+ @command.directory name, &block
213
+ end
214
+
215
+ def file name, template=nil
216
+ @command.file name, template
217
+ end
218
+
219
+ def template name, template=nil
220
+ @command.template name, template
221
+ end
222
+
223
+ private
224
+
225
+ def self.template_from_caller caller_string
226
+ file = Sprout.file_from_caller caller_string
227
+ File.join(File.dirname(file), 'templates')
228
+ end
229
+
230
+ end
231
+ end
232
+ end
233
+
@@ -0,0 +1,67 @@
1
+
2
+ module Sprout::Generator
3
+ class Command
4
+ attr_accessor :logger
5
+ attr_accessor :working_dir
6
+
7
+ attr_reader :generator
8
+
9
+ def initialize generator
10
+ @generator = generator
11
+ @working_dir = DirectoryManifest.new
12
+ @working_dir.generator = generator
13
+ @working_dir.path = generator.path
14
+ end
15
+
16
+ def directory path, &block
17
+ raise Sprout::Errors::GeneratorError.new "Cannot create directory with nil path" if path.nil?
18
+ manifest = DirectoryManifest.new
19
+ manifest.generator = generator
20
+ manifest.path = File.join(@working_dir.path, path)
21
+ @working_dir.children << manifest
22
+ parent = @working_dir
23
+ @working_dir = manifest
24
+ yield if block_given?
25
+ @working_dir = parent
26
+ end
27
+
28
+ def template path, template=nil
29
+ raise Sprout::Errors::GeneratorError.new "Cannot create file with nil path" if path.nil?
30
+ manifest = TemplateManifest.new
31
+ manifest.generator = generator
32
+ manifest.path = File.join( working_dir.path, path )
33
+ manifest.template = template
34
+ manifest.templates = generator.template_paths
35
+ working_dir.children << manifest
36
+ end
37
+
38
+ def file path, template=nil
39
+ raise Sprout::Errors::GeneratorError.new "Cannot create file with nil path" if path.nil?
40
+ manifest = FileManifest.new
41
+ manifest.generator = generator
42
+ manifest.path = File.join( working_dir.path, path )
43
+ manifest.template = template
44
+ manifest.templates = generator.template_paths
45
+ working_dir.children << manifest
46
+ end
47
+
48
+ def execute
49
+ begin
50
+ working_dir.children.each do |child|
51
+ child.create
52
+ end
53
+ rescue StandardError => e
54
+ generator.say "[#{e.class}] #{e.message}"
55
+ working_dir.children.each do |child|
56
+ child.destroy
57
+ end
58
+ raise e
59
+ end
60
+ end
61
+
62
+ def unexecute
63
+ working_dir.destroy
64
+ end
65
+ end
66
+ end
67
+