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,167 @@
1
+
2
+ module Sprout
3
+
4
+ ##
5
+ # This class represents a Feature that is written in
6
+ # Ruby code that exists on the other side of the
7
+ # Ruby load path.
8
+ #
9
+ # The idea here, is that one can +include+ the Sprout::RubyFeature
10
+ # module into their concrete class, and then accept
11
+ # requests to +register+ and +load+ from clients that
12
+ # are interested in pluggable features.
13
+ #
14
+ # An example is as follows:
15
+ #
16
+ # require 'sprout'
17
+ #
18
+ # class MyClass
19
+ # include Sprout::RubyFeature
20
+ # end
21
+ #
22
+ # In some other Ruby file:
23
+ #
24
+ # MyClass.load :other, 'other_gem', '>= 1.0pre'
25
+ #
26
+ # In the desired Ruby file:
27
+ #
28
+ # class OtherClass
29
+ # include Sprout::Executable
30
+ #
31
+ # set :name, :other
32
+ # set :pkg_name, 'other_gem'
33
+ # set :pkg_version, '1.0.pre'
34
+ #
35
+ # # do something...
36
+ # end
37
+ #
38
+ # MyClass.register OtherClass.new
39
+ #
40
+ module RubyFeature
41
+
42
+ extend Concern
43
+
44
+ module ClassMethods
45
+
46
+ ##
47
+ # Register a new feature for future lookups
48
+ def register entity
49
+ validate_registration entity
50
+ registered_entities.unshift entity
51
+ entity
52
+ end
53
+
54
+ ##
55
+ # Load a feature by name.
56
+ def load name_or_names, pkg_name=nil, version_requirement=nil
57
+ entity = entity_for name_or_names, pkg_name, version_requirement
58
+ if(entity.nil?)
59
+ # Try to require the pkg_name:
60
+ require_ruby_package pkg_name unless pkg_name.nil?
61
+ # Update any entities that registered from our require:
62
+ update_registered_entities
63
+ # search for the requested entity:
64
+ entity = entity_for name_or_names, pkg_name, version_requirement
65
+ end
66
+
67
+ if(entity.nil?)
68
+ message = "The requested entity: (#{name_or_names}) with pkg_name: (#{pkg_name}) and version: "
69
+ message << "(#{version_requirement}) does not appear to be loaded."
70
+ message << "\n"
71
+ message << "We did find (#{registered_entities.size}) registered entities in that package:\n\n"
72
+ registered_entities.each do |other|
73
+ message << ">> name: (#{other.name}) pkg_name: (#{other.pkg_name}) pkg_version: (#{other.pkg_version})\n"
74
+ end
75
+ message << "\n\nYou may need to update your Gemfile and run 'bundle install' "
76
+ message << "to update your local gems.\n\n"
77
+ raise Sprout::Errors::LoadError.new message
78
+ end
79
+ entity
80
+ end
81
+
82
+ def clear_entities!
83
+ @registered_entities = []
84
+ end
85
+
86
+ protected
87
+
88
+ def validate_registration entity
89
+ if(!entity.respond_to?(:name) || entity.name.nil?)
90
+ raise Sprout::Errors::UsageError.new "Cannot register a RubyFeature without a 'name' getter"
91
+ end
92
+ end
93
+
94
+ ##
95
+ # Used by the Generator::Base to update inputs from
96
+ # empty class definitions to instances..
97
+ def update_registered_entities
98
+ end
99
+
100
+ def entity_for name_or_names, pkg_name, version_requirement
101
+ #puts "+++++++++++++++++++++++++++"
102
+ #puts ">> entity_for #{name} pkg_name: #{pkg_name} version: #{version_requirement}"
103
+ #registered_entities.each do |entity|
104
+ #puts ">> entity: #{entity.name} pkg_name: #{entity.pkg_name} version: #{entity.pkg_version}"
105
+ #end
106
+ registered_entities.select do |entity|
107
+ satisfies_name?(entity, name_or_names) &&
108
+ satisfies_platform?(entity) &&
109
+ satisfies_pkg_name?(entity, pkg_name) &&
110
+ satisfies_version?(entity, version_requirement)
111
+ end.first
112
+ end
113
+ def satisfies_environment? entity, environment
114
+ #puts ">> env: #{entity.environment} vs. #{environment}"
115
+ environment.nil? || !entity.respond_to?(:environment) || entity.environment.to_s == environment.to_s
116
+ end
117
+
118
+ def satisfies_pkg_name? entity, expected
119
+ #puts ">> pkg_name: #{entity.pkg_name} vs. #{expected}"
120
+ expected.nil? || !entity.respond_to?(:pkg_name) || entity.pkg_name.to_s == expected.to_s
121
+ end
122
+
123
+ def satisfies_name? entity, expected
124
+ #puts ">> name: #{entity.name} vs. #{expected}"
125
+ return true if expected.nil? || !entity.respond_to?(:name)
126
+ if expected.is_a?(Array)
127
+ return expected.include? entity.name
128
+ end
129
+ return expected.to_s == entity.name.to_s
130
+ end
131
+
132
+ def satisfies_platform? entity
133
+ #puts">> satisfies platform?"
134
+ return true if !entity.respond_to?(:platform) || entity.platform.nil?
135
+ #puts ">> platform: #{entity.platform}"
136
+ Sprout.current_system.can_execute?(entity.platform)
137
+ end
138
+
139
+ def satisfies_version? entity, version_requirement=nil
140
+ return true if version_requirement.nil?
141
+ req_version = Gem::Requirement.create version_requirement
142
+ req_version.satisfied_by?(Gem::Version.create(entity.pkg_version))
143
+ end
144
+
145
+ def require_ruby_package name
146
+ begin
147
+ require name
148
+ rescue LoadError => e
149
+ raise Sprout::Errors::LoadError.new "Could not load the required file (#{name}) - Maybe you need to run 'gem install #{name}' or maybe 'bundle install'?"
150
+ end
151
+ end
152
+
153
+ ##
154
+ # An entity has the following parameters:
155
+ # name
156
+ # pkg_name
157
+ # pkg_version
158
+ # platform
159
+ #
160
+ def registered_entities
161
+ @registered_entities ||= []
162
+ end
163
+ end
164
+
165
+ end
166
+ end
167
+
@@ -0,0 +1,197 @@
1
+
2
+ module Sprout
3
+
4
+ ##
5
+ # Sprouts provides us with the ability to distribute source files,
6
+ # precompiled libraries, and remote executables. It does all of
7
+ # this by (ab)using RubyGems.
8
+ #
9
+ # RubyGems gives us the ability to version-manage, and distribute
10
+ # arbitrary text and binary payloads.
11
+ #
12
+ # In order to support Flash development, we have one major problem
13
+ # that RubyGems does not solve for us. This is the fact that
14
+ # many elements of our executable chain are not open-source, and we do
15
+ # not have the rights to directly distribute them.
16
+ #
17
+ # This restriction means that many of our tools and dependencies cannot be
18
+ # packaged and distributed _directly_ within a RubyGem (or from
19
+ # any server other than Adobe's as a matter of fact).
20
+ #
21
+ # In order to overcome this restriction, we have introduced
22
+ # a Sprout::Specification. This is a regular Ruby file with regular
23
+ # Ruby code in it. The main idea behind this file, is that it
24
+ # needs to be given a name and available in your load path.
25
+ #
26
+ # Whenever a rake build task (Sprout::Executable) or library task,
27
+ # (Sprout::Library) is encountered, it will call
28
+ # Sprout::Executable.load or Sprout::Library.load (respectively).
29
+ #
30
+ # These methods will attempt to +require+ the provided
31
+ # specification and - if it's in your load path - the specification
32
+ # will be loaded, and any relevant file targets will be returned.
33
+ #
34
+ # There are many ways to get Ruby code into your load path.
35
+ # One of the easiest to package it up in a RubyGem and
36
+ # configure the +require_paths+ parameter of your Gem::Specification.
37
+ #
38
+ # http://docs.rubygems.org/read/chapter/20#require_paths
39
+ #
40
+ # To learn more about packaging RubyGems:
41
+ #
42
+ # http://docs.rubygems.org/read/chapter/20#page85
43
+ # http://rubygems.rubyforge.org/rdoc/Gem/Specification.html
44
+ #
45
+ # To learn more about published RubyGems:
46
+ #
47
+ # http://rubygems.org/pages/gem_docs
48
+ #
49
+ # To package a SWC library into a Sprout RubyGem, you would create a file (usually)
50
+ # named [project_name.spec] in the root of the project.
51
+ #
52
+ # This is your Gem::Specification.
53
+ #
54
+ # You would also create a file named [projet_name.rb] and put that
55
+ # into the root of the project or some other folder that you have added to
56
+ # the Gem::Specification.require_paths parameter.
57
+ #
58
+ # == Example: Include a file directly in the RubyGem
59
+ #
60
+ # In the case of AsUnit, this file would be named asunit4.rb and it's contents
61
+ # are as follows:
62
+ #
63
+ # :include:../../test/fixtures/specification/asunit4.rb
64
+ #
65
+ # == Example: Refer to files that are not in the RubyGem
66
+ #
67
+ # For projects like the Flex SDK, we can't distribute many of the required files,
68
+ # so we can refer to these files in our Sprout::Specification as +remote_file_targets+.
69
+ #
70
+ # :include:../../test/fixtures/specification/flex4sdk.rb
71
+ #
72
+ # == Example: Create custom downloads for each supported platform
73
+ #
74
+ # For projects like the Flash Player itself, we need to refer to different
75
+ # downloadable content for each supported platform.
76
+ #
77
+ # :include:../../test/fixtures/specification/flashplayer.rb
78
+ #
79
+ # == Packaging and Sharing
80
+ #
81
+ # Public RubyGems are hosted at http://rubygems.org.
82
+ class Specification
83
+
84
+ attr_accessor :name
85
+ attr_accessor :version
86
+
87
+ attr_reader :file_targets
88
+ attr_reader :load_path
89
+
90
+ ##
91
+ # Create a new Sprout::Specification.
92
+ #
93
+ # This method will yield the new Sprout::Specification to the provided block,
94
+ # and delegate most configuration parameters to a {Gem::Specification}[http://rubygems.rubyforge.org/rdoc/Gem/Specification.html].
95
+ #
96
+ # To learn more about what parameters are available and/or required, please
97
+ # check out RubyGems documentation for their {Gem::Specification}[http://rubygems.rubyforge.org/rdoc/Gem/Specification.html].
98
+ #
99
+ def initialize
100
+ filename = Sprout.file_from_caller caller.first
101
+ @load_path = File.dirname filename
102
+ @name = File.basename(filename).gsub('.rb', '')
103
+ yield self if block_given?
104
+ end
105
+
106
+ ##
107
+ # Add a remote file target to this RubyGem so that when it
108
+ # is loaded, Sprouts will go fetch this file from the network.
109
+ #
110
+ # Each time this method is called, a new Sprout::RemoteFiletarget instance will be yielded to
111
+ # the provided block and resolved after the block completes.
112
+ #
113
+ # After this block is evaluated, Sprouts will first check the collection
114
+ # of env_names to see if the expected paths are available. If a valid
115
+ # env_name is found, Sprouts will return the path to the requested
116
+ # executable from the environment variable.
117
+ #
118
+ # If no env_names are set, or the requested executable is not found within
119
+ # any that are identified, Sprouts will check to see if the archive
120
+ # has already been unpacked into the expected location:
121
+ #
122
+ # #{SPROUT_HOME}/cache/#{SPROUT_VERSION}/flex4sdk/#{md5}/4.0.pre
123
+ #
124
+ # If the archive been unpacked, Sprouts will return the path to the
125
+ # requested executable.
126
+ #
127
+ # If the archive has not been unpacked, Sprouts will check to see if the
128
+ # archive has been downloaded to:
129
+ #
130
+ # #{SPROUT_HOME}/cache/#{SPROUT_VERSION}/flex4sdk/#{md5}.zip
131
+ #
132
+ # If the archive has been downloaded, it will be unpacked and the path
133
+ # to the requested executable will be returned.
134
+ #
135
+ # If the archive has not been downloaded, it will be downloaded, unpacked
136
+ # and the path to the requested executable will be returned.
137
+ def add_remote_file_target &block
138
+ target = RemoteFileTarget.new do |t|
139
+ configure_target t, &block
140
+ end
141
+ target.resolve
142
+ register_file_target target
143
+ end
144
+
145
+ # Add a file to the RubyGem itself. This is a great way to package smallish libraries in either
146
+ # source or already-packaged form. For example, one might add a SWC to a RubyGem library.
147
+ #
148
+ # Each time this method is called, a new Sprout::FileTarget instance will be yielded to the
149
+ # provided block, and added to a collection for packaging.
150
+ #
151
+ # Sprout::Specification.new do |s|
152
+ # ...
153
+ # s.add_file_target do |t|
154
+ # t.platform = :universal
155
+ # t.add_executable :asdoc, 'bin/asdoc'
156
+ # end
157
+ # end
158
+ #
159
+ def add_file_target &block
160
+ target = FileTarget.new do |t|
161
+ configure_target t, &block
162
+ end
163
+ register_file_target target
164
+ end
165
+
166
+ private
167
+
168
+ def configure_target t, &block
169
+ t.load_path = load_path
170
+ t.pkg_name = name
171
+ t.pkg_version = version
172
+ yield t if block_given?
173
+ end
174
+
175
+ def register_file_target target
176
+ register_items target.executables, Sprout::Executable, target
177
+ # Reversing the libraries makes it so that definitions like:
178
+ #
179
+ # target.add_library :swc, 'abcd'
180
+ # target.add_library :src, 'efgh'
181
+ #
182
+ # When loading, if no name is specified, the :swc will be
183
+ # returned to clients.
184
+ register_items target.libraries.reverse, Sprout::Library, target
185
+ end
186
+
187
+ def register_items collection, source, target
188
+ collection.each do |item|
189
+ item.pkg_name = target.pkg_name
190
+ item.pkg_version = target.pkg_version
191
+ source.register item
192
+ end
193
+ end
194
+
195
+ end
196
+ end
197
+
@@ -0,0 +1,19 @@
1
+
2
+ class String
3
+
4
+ # "FooBar".snake_case #=> "foo_bar"
5
+ def snake_case
6
+ gsub(/\B[A-Z]/, '_\&').downcase
7
+ end
8
+
9
+ # "foo_bar".camel_case #=> "FooBar"
10
+ def camel_case
11
+ str = gsub(/^[a-z]|_+[a-z]/) { |a| a.upcase }
12
+ str.gsub(/_/, '')
13
+ end
14
+
15
+ def dash_case
16
+ self.snake_case.gsub('_', '-')
17
+ end
18
+ end
19
+
@@ -0,0 +1,35 @@
1
+ require 'sprout/system/base_system'
2
+ require 'sprout/system/unix_system'
3
+ require 'sprout/system/java_system'
4
+ require 'sprout/system/osx_system'
5
+ require 'sprout/system/win_system'
6
+ require 'sprout/system/win_nix_system'
7
+ require 'sprout/system/vista_system'
8
+
9
+ module Sprout
10
+
11
+ module System
12
+
13
+ # This is the factory that one should
14
+ # generally be used to create new, concrete
15
+ # System objects.
16
+ #
17
+ # A typical example follows:
18
+ #
19
+ # system = System.create
20
+ # Dir.chdir system.home
21
+ # system.execute "pwd" # /home/yourusername
22
+ #
23
+ def self.create
24
+ p = Sprout::Platform.new
25
+ return VistaSystem.new if p.vista?
26
+ return WinNixSystem.new if p.windows_nix?
27
+ return WinSystem.new if p.windows?
28
+ return JavaSystem.new if p.java?
29
+ return OSXSystem.new if p.mac?
30
+ return UnixSystem.new
31
+ end
32
+
33
+ end
34
+ end
35
+
@@ -0,0 +1,225 @@
1
+
2
+ module Sprout::System
3
+
4
+ # The abstract base class for all supported system/platform types.
5
+ # In general, users are created by calling the +create+ factory method
6
+ # on the +System+ module.
7
+ #
8
+ # System.create
9
+ #
10
+ # Assuming you call the create method, you should wind up with
11
+ # a concrete system that matches your system, and these concrete
12
+ # users will generally be derived from this base class.
13
+ #
14
+ class BaseSystem
15
+
16
+ ##
17
+ # Get the home path for a system on a particular operating system.
18
+ #
19
+ # This path will be different, depending on which system owns
20
+ # the curren process, and which operating system they are on.
21
+ #
22
+ def home
23
+ @home ||= find_home
24
+ end
25
+
26
+ ##
27
+ # Set the home path for a system on a particular operating system.
28
+ #
29
+ # If you request the home path before setting it, we will
30
+ # attempt to determine the home path of the current system for
31
+ # the current operating system.
32
+ #
33
+ # This is just a simple way to override the default behavior.
34
+ #
35
+ def home=(home)
36
+ @home = home
37
+ end
38
+
39
+ ##
40
+ # Some operating systems (like OS X and Windows) have a
41
+ # specific location where applications are expected to store
42
+ # files for a particular system. This location is generally
43
+ # a subdirectory of +home+.
44
+ #
45
+ # The value of this location will usually be overridden in
46
+ # concrete System classes.
47
+ #
48
+ def library
49
+ return home
50
+ end
51
+
52
+ ##
53
+ # Instantiate and return a new Sprout::ProcessRunner so
54
+ # that we can execute it.
55
+ #
56
+ def get_process_runner
57
+ Sprout::ProcessRunner.new
58
+ end
59
+
60
+ def can_execute? platform
61
+ platform == :universal
62
+ end
63
+
64
+ ##
65
+ # Creates a new process, executes the command
66
+ # and returns whatever the process wrote to stdout, or stderr.
67
+ #
68
+ # Raises a +Sprout::Errors::ExecutionError+ if the process writes to stderr
69
+ #
70
+ def execute(tool, options='')
71
+ Sprout::Log.puts(">> Execute: #{tool} options: #{options}")
72
+ runner = get_and_execute_process_runner(tool, options)
73
+ error = runner.read_err
74
+ result = runner.read
75
+
76
+ if(result.size > 0)
77
+ Sprout::Log.puts result
78
+ end
79
+
80
+ if(error.size > 0)
81
+ raise Sprout::Errors::ExecutionError.new("[ERROR] #{error}")
82
+ end
83
+
84
+ result || error
85
+ end
86
+
87
+ ##
88
+ # Creates and returns the process without
89
+ # attempting to read or write to the stream.
90
+ # This is useful for interacting with
91
+ # long-lived CLI processes like FCSH or FDB.
92
+ #
93
+ def execute_silent(tool, options='')
94
+ return get_and_execute_process_runner(tool, options)
95
+ end
96
+
97
+ ##
98
+ # Execute a new process in a separate thread.
99
+ # This can be useful for processes that take
100
+ # an especially long time to execute.
101
+ #
102
+ # Threads are complicated - use with caution...
103
+ #
104
+ def execute_thread(tool, options='')
105
+ if(Log.debug)
106
+ return ThreadMock.new
107
+ else
108
+ return Thread.new do
109
+ execute(tool, options)
110
+ end
111
+ end
112
+ end
113
+
114
+ ##
115
+ # Clean the provided +path+ String for the current
116
+ # operating system.
117
+ #
118
+ # Each operating system behaves differently when we
119
+ # attempt to execute a file with spaces in the +path+
120
+ # to the file.
121
+ #
122
+ # Subclasses will generally override this method and
123
+ # clean the path appropriately for their operating
124
+ # system.
125
+ #
126
+ def clean_path(path)
127
+ end
128
+
129
+ ##
130
+ # Different operating systems will store Application data
131
+ # different default locations.
132
+ #
133
+ # Subclasses will generally override this method and
134
+ # return the appropriate location for their operating system.
135
+ #
136
+ # +name+ String value of the Application name for which we'd
137
+ # like to store data.
138
+ #
139
+ def application_home(name)
140
+ return File.join(library, format_application_name(name.to_s));
141
+ end
142
+
143
+ ##
144
+ # Template method that should be overridden by
145
+ # subclasses.
146
+ #
147
+ def format_application_name(name)
148
+ name
149
+ end
150
+
151
+ protected
152
+
153
+ def env_homedrive
154
+ ENV['HOMEDRIVE']
155
+ end
156
+
157
+ def env_homepath
158
+ ENV['HOMEPATH']
159
+ end
160
+
161
+ def env_homedrive_and_homepath
162
+ drive = env_homedrive
163
+ path = env_homepath
164
+ "#{drive}:#{path}" if drive && path
165
+ end
166
+
167
+ def env_userprofile
168
+ ENV['USERPROFILE']
169
+ end
170
+
171
+ def env_home
172
+ ENV['HOME']
173
+ end
174
+
175
+ def tilde_home
176
+ File.expand_path("~")
177
+ end
178
+
179
+ def alt_separator?
180
+ File::ALT_SEPARATOR
181
+ end
182
+
183
+ def worst_case_home
184
+ return "C:\\" if alt_separator?
185
+ return "/"
186
+ end
187
+
188
+ def find_home
189
+ [:env_userprofile, :env_home, :env_homedrive_and_homepath].each do |key|
190
+ value = self.send(key)
191
+ return value unless value.nil?
192
+ end
193
+
194
+ begin
195
+ return tilde_home
196
+ rescue StandardError
197
+ worst_case_home
198
+ end
199
+ end
200
+
201
+ protected
202
+
203
+ ##
204
+ # Get a process runner and execute the provided +executable+,
205
+ # with the provided +options+.
206
+ #
207
+ # +executable+ String path to the external executable file.
208
+ #
209
+ # +options+ String commandline options to send to the +executable+.
210
+ #
211
+ def get_and_execute_process_runner tool, options=nil
212
+ runner = get_process_runner
213
+ runner.execute_open4 clean_path(tool), options
214
+ runner
215
+ end
216
+
217
+ end
218
+
219
+ class ThreadMock # :nodoc:
220
+ def alive?
221
+ return false
222
+ end
223
+ end
224
+ end
225
+