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
@@ -1,235 +1,151 @@
1
+ require 'zip/zip'
2
+ require 'archive/tar/minitar'
1
3
 
2
4
  module Sprout
3
- class ArchiveUnpackerError < StandardError #:nodoc:
4
- end
5
5
 
6
- # Unpack downloaded files from a variety of common archive types.
7
- # This library should efficiently extract archived files
8
- # on OS X, Win XP, Vista, DOS, Cygwin, and Linux.
9
- #
10
- # It will attempt to infer the archive type by standard mime-type file
11
- # extensions, but if there is a file with no extension, the unpack_archive
12
- # method can be provided with an @archive_type symbol argument that is one
13
- # of the following values:
14
- # :exe
15
- # :zip
16
- # :targz
17
- # :gzip
18
- # :swc
19
- # :rb
20
- # :dmg
21
- class ArchiveUnpacker #:nodoc:
22
- include Archive::Tar
23
-
24
- def unpack_archive(file_name, dir, force=false, archive_type=nil)
25
- archive_type ||= inferred_archive_type(file_name)
26
- suffix = suffix_for_archive_type(archive_type)
27
-
28
- unpacked = unpacked_file_name(file_name, dir, suffix)
29
- if(File.exists?(unpacked) && force)
30
- FileUtils.rm_rf(unpacked)
31
- end
32
-
33
- if(!File.exists?(unpacked))
34
- case archive_type.to_s
35
- when 'zip'
36
- unpack_zip(file_name, dir)
37
- when 'targz'
38
- unpack_targz(file_name, dir)
39
- when 'tbz2'
40
- unpack_tbz2(file_name, dir)
41
- when 'dmg'
42
- unpack_dmg(file_name, dir)
43
- when 'exe'
44
- FileUtils.mkdir_p(dir)
45
- FileUtils.move(file_name, dir)
46
- when 'swc' || 'rb'
47
- return
48
- else
49
- raise ArchiveUnpackerError.new("ArchiveUnpacker does not know how to unpack files of type: #{archive_type} for file_name: #{file_name}")
50
- end
51
- end
6
+ # Given a source, destination and type (or ability to infer it),
7
+ # unpack downloaded archives.
8
+ class ArchiveUnpacker
9
+
10
+ # Figure out what kind of archive you have from the file name,
11
+ # and unpack it using the appropriate scheme.
12
+ def unpack archive, destination, type=nil, clobber=nil
13
+ return unpack_zip(archive, destination, clobber) if is_zip?(archive, type)
14
+ return unpack_tgz(archive, destination, clobber) if is_tgz?(archive, type)
15
+
16
+ # This is definitely debatable, should we copy the file even if it's
17
+ # not an archive that we're about to unpack?
18
+ # If so, why would we only do this with some subset of file types?
19
+ # Opinions welcome here...
20
+ return copy_file(archive, destination, clobber) if is_copyable?(archive)
21
+
22
+ raise Sprout::Errors::UnknownArchiveType.new("Unsupported or unknown archive type encountered with: #{archive}")
52
23
  end
53
-
54
- def unpack_zip(zip_file, dir)
55
- # Avoid the rubyzip Segmentation Fault bug
56
- # at least on os x...
57
- if(RUBY_PLATFORM =~ /darwin/)
58
- # Unzipping on OS X
59
- FileUtils.makedirs(dir)
60
- zip_dir = File.expand_path(File.dirname(zip_file))
61
- zip_name = File.basename(zip_file)
62
- output = File.expand_path(dir)
63
- # puts ">> zip_dir: #{zip_dir} zip_name: #{zip_name} output: #{output}"
64
- %x(cd #{zip_dir};unzip #{zip_name} -d #{output})
65
- else
66
- retries = 0
67
- begin
68
- retries += 1
69
- Zip::ZipFile::open(zip_file) do |zf|
70
- zf.each do |e|
71
- fpath = File.join(dir, e.name)
72
- FileUtils.mkdir_p(File.dirname(fpath))
73
- # Disgusting, Gross Hack to fix DOS/Ruby Bug
74
- # That makes the zip library throw a ZipDestinationFileExistsError
75
- # When the zip archive includes two files whose names
76
- # differ only by extension.
77
- # This bug actually appears in the File.exists? implementation
78
- # throwing false positives!
79
- # If you're going to use this code, be sure you extract
80
- # into a new, empty directory as existing files will be
81
- # clobbered...
82
- begin
83
- if(File.exists?(fpath) && !File.directory?(fpath))
84
- hackpath = fpath + 'hack'
85
- zf.extract(e, hackpath)
86
- File.copy(hackpath, fpath)
87
- File.delete(hackpath)
88
- else
89
- zf.extract(e, fpath)
90
- end
91
- rescue NotImplementedError => ni_err
92
- puts "[WARNING] #{ni_err} for: #{e}"
93
- end
94
- end
95
- end
96
- rescue StandardError => err
97
- FileUtils.rm_rf(dir)
98
- if(retries < 3)
99
- FileUtils.makedirs(dir)
100
- retry
101
- end
102
- raise err
24
+
25
+ # Unpack zip archives on any platform.
26
+ def unpack_zip archive, destination, clobber=nil
27
+ validate archive, destination
28
+
29
+ Zip::ZipFile.open archive do |zipfile|
30
+ zipfile.each do |entry|
31
+ next if entry.name =~ /__MACOSX/ or entry.name =~ /\.DS_Store/
32
+ unpack_zip_entry entry, destination, clobber
103
33
  end
104
34
  end
105
35
  end
106
-
107
- def unpacked_file_name(file, dir, suffix=nil)
108
- basename = File.basename(file, suffix)
109
- path = File.expand_path(dir)
110
- return File.join(path, basename)
111
- end
112
36
 
113
- def unpack_tbz2(tgz_file, dir)
114
- unpack_tar_zip tgz_file, dir, 'tar.bz2'
115
- end
37
+ # Unpack tar.gz or .tgz files on any platform.
38
+ def unpack_tgz archive, destination, clobber=nil
39
+ validate archive, destination
116
40
 
117
- def unpack_targz(tgz_file, dir)
118
- unpack_tar_zip tgz_file, dir, 'tar.gz'
119
- end
120
-
121
- def unpack_tar_zip(tgz_file, dir, ext)
122
- if(!File.exists?(dir))
123
- FileUtils.makedirs(dir)
41
+ tar = Zlib::GzipReader.new(File.open(archive, 'rb'))
42
+ if(!should_unpack_tgz?(destination, clobber))
43
+ raise Sprout::Errors::DestinationExistsError.new "Unable to unpack #{archive} into #{destination} without explicit :clobber argument"
124
44
  end
125
- tar = Zlib::GzipReader.new(File.open(tgz_file, 'rb'))
126
- Minitar.unpack(tar, dir)
127
-
45
+
46
+ Archive::Tar::Minitar.unpack(tar, destination)
47
+
128
48
  # Recurse and unpack gzipped children (Adobe did this double
129
- # gzip with the Linux FlashPlayer for some reason)
130
- Dir.glob("#{dir}/**/*.#{ext}").each do |child|
131
- if(child != tgz_file && dir != File.dirname(child))
132
- unpack_targz(child, File.dirname(child))
49
+ # gzip with the Linux FlashPlayer for some weird reason)
50
+ ["#{destination}/**/*.tgz", "#{destination}/**/*.tar.gz"].each do |pattern|
51
+ Dir.glob(pattern).each do |child|
52
+ if(child != archive && dir != File.dirname(child))
53
+ unpack_tgz(child, File.dirname(child))
54
+ end
133
55
  end
134
56
  end
135
-
136
57
  end
137
-
138
- # This is actually not unpacking the FlashPlayer
139
- # Binary file as expected...
140
- # OSX is treated the player binary as if it is
141
- # a regular text file, but if it is copied manually,
142
- # the command works fine!?
143
- def unpack_dmg(dmg_file, dir)
144
- # 1) Mount the dmg in place
145
- # 2) Recursively Copy its contents to asproject_home
146
- # 3) Unmount the dmg
147
- if(mounted_path.nil?)
148
- raise StandardError.new('DMG file downloaded, but the RemoteFileTask needs a mounted_path in order to mount it')
149
- end
150
58
 
151
- if(!File.exists?(full_mounted_path))
152
- system("hdiutil mount #{dmg_file}")
153
- end
154
-
155
- begin
156
- mounted_target = File.join(full_mounted_path, extracted_file)
157
-
158
- # Copy the DMG contents using system copy rather than ruby utils
159
- # Because OS X does something special with .app files that the
160
- # Ruby FileUtils and File classes break...
161
- from = mounted_target
162
- # from = File.join(full_mounted_path, extracted_file)
163
- to = File.join(@user.downloads, @name.to_s, extracted_file)
164
- FileUtils.makedirs(File.dirname(to))
165
-
166
- if(File.exists?(from))
167
- `ditto '#{from}' '#{to}'`
168
- end
169
- rescue StandardError => e
170
- if(File.exists?(full_mounted_path))
171
- system("hdiutil unmount -force \"#{full_mounted_path}\"")
172
- end
59
+ # Rather than unpacking, safely copy the file from one location
60
+ # to another.
61
+ def copy_file file, destination, clobber=nil
62
+ validate file, destination
63
+ target = File.expand_path( File.join(destination, File.basename(file)) )
64
+ if(File.exists?(target) && clobber != :clobber)
65
+ raise Sprout::Errors::DestinationExistsError.new "Unable to copy #{file} to #{target} because target already exists and we were not asked to :clobber it"
173
66
  end
67
+ FileUtils.mkdir_p destination
68
+ FileUtils.cp_r file, destination
69
+
70
+ destination
174
71
  end
175
-
176
- def suffix_for_archive_type(type)
177
- if(type == :targz)
178
- return '.tar.gz'
179
- else
180
- return ".#{type.to_s}"
181
- end
72
+
73
+ # Return true if the provided file name looks like a zip file.
74
+ def is_zip? archive, type=nil
75
+ type == :zip || !archive.match(/\.zip$/).nil?
182
76
  end
183
-
184
- def inferred_archive_type(file_name)
185
- if is_zip?(file_name)
186
- return :zip
187
- elsif is_targz?(file_name)
188
- return :targz
189
- elsif is_gzip?(file_name)
190
- return :gz
191
- elsif is_swc?(file_name)
192
- return :swc
193
- elsif is_rb?(file_name)
194
- return :rb
195
- elsif is_dmg?(file_name)
196
- return :dmg
197
- elsif is_exe?(file_name)
198
- return :exe
199
- else
200
- return nil
201
- end
202
-
77
+
78
+ # Return true if the provided file name looks like a tar.gz file.
79
+ def is_tgz? archive, type=nil
80
+ type == :tgz || !archive.match(/\.tgz$/).nil? || !archive.match(/\.tar.gz$/).nil?
203
81
  end
204
-
205
- def is_zip?(file)
206
- return (file.split('.').pop == 'zip')
82
+
83
+ def is_exe? archive, type=nil
84
+ type == :exe || !archive.match(/\.exe$/).nil?
207
85
  end
208
86
 
209
- def is_targz?(file)
210
- parts = file.split('.')
211
- part = parts.pop
212
- return (part == 'tgz' || part == 'gz' && parts.pop == 'tar')
87
+ def is_swc? archive, type=nil
88
+ type == :swc || !archive.match(/\.swc$/).nil?
213
89
  end
214
-
215
- def is_gzip?(file)
216
- return (file.split('.').pop == 'gz')
90
+
91
+ def is_rb? archive, type=nil
92
+ type == :rb || !archive.match(/\.rb$/).nil?
217
93
  end
218
-
219
- def is_swc?(file)
220
- return (file.split('.').pop == 'swc')
94
+
95
+ private
96
+
97
+ def is_copyable? archive
98
+ (is_exe?(archive) || is_swc?(archive) || is_rb?(archive))
221
99
  end
222
-
223
- def is_rb?(file)
224
- return (file.split('.').pop == 'rb')
100
+
101
+ def should_unpack_tgz? dir, clobber=nil
102
+ return !directory_has_children?(dir) || clobber == :clobber
103
+
225
104
  end
226
-
227
- def is_dmg?(file)
228
- return (file.split('.').pop == 'dmg')
229
- end
230
105
 
231
- def is_exe?(file)
232
- return (file.split('.').pop == 'exe')
106
+ def directory_has_children? dir
107
+ (Dir.entries(dir) - ['.', '..']).size > 0
233
108
  end
109
+
110
+ def validate archive, destination
111
+ validate_archive archive
112
+ validate_destination destination
113
+ end
114
+
115
+ def validate_archive archive
116
+ message = "Archive could not be found at: #{archive}"
117
+ raise Sprout::Errors::ArchiveUnpackerError.new(message) if archive.nil? || !File.exists?(archive)
118
+ end
119
+
120
+ def validate_destination path
121
+ message = "Archive destination could not be found at: #{path}"
122
+ raise Sprout::Errors::ArchiveUnpackerError.new(message) if path.nil? || !File.exists?(path)
123
+ end
124
+
125
+ def unpack_zip_entry entry, destination, clobber
126
+ # Ensure hidden mac files don't get written to disk:
127
+ path = File.join destination, entry.name
128
+
129
+ if entry.directory?
130
+ # If an archive has empty directories:
131
+ FileUtils.mkdir_p path
132
+ elsif entry.file?
133
+ # On Windows, we don't get the entry for
134
+ # each parent directory:
135
+ FileUtils.mkdir_p File.dirname(path)
136
+ begin
137
+ entry.extract path
138
+ rescue Zip::ZipDestinationFileExistsError => zip_dest_error
139
+ if(clobber == :clobber)
140
+ FileUtils.rm_rf path
141
+ entry.extract path
142
+ else
143
+ raise Sprout::Errors::DestinationExistsError.new zip_dest_error.message
144
+ end
145
+ end
146
+ end
147
+ end
148
+
234
149
  end
235
150
  end
151
+
@@ -0,0 +1,90 @@
1
+ # External tools and std libs:
2
+ require 'rake'
3
+ require 'delegate'
4
+
5
+ # Core, Process and Platform support:
6
+ require 'sprout/version'
7
+ require 'sprout/progress_bar'
8
+ require 'sprout/dir'
9
+ require 'sprout/string'
10
+ require 'sprout/concern'
11
+ require 'sprout/log'
12
+ require 'sprout/errors'
13
+ require 'sprout/platform'
14
+ require 'sprout/process_runner'
15
+ require 'sprout/system'
16
+ require 'sprout/ruby_feature'
17
+
18
+ # This is a fix for Issue #106
19
+ # http://code.google.com/p/projectsprouts/issues/detail?id=106
20
+ # Which is created because the new version (1.0.1) of RubyGems
21
+ # includes open-uri, while older versions do not.
22
+ # When open-uri is included twice, we get a bunch of nasty
23
+ # warnings because constants are being overwritten.
24
+ gem_version = Gem::Version.new(Gem::RubyGemsVersion)
25
+ if(gem_version != Gem::Version.new('1.0.1'))
26
+ require 'open-uri'
27
+ end
28
+
29
+ # File, Archive and Network support:
30
+ require 'sprout/archive_unpacker'
31
+ require 'sprout/file_target'
32
+ require 'sprout/remote_file_loader'
33
+ require 'sprout/remote_file_target'
34
+
35
+ # External Packaging and distribution support:
36
+ require 'sprout/rdoc_parser'
37
+ require 'sprout/specification'
38
+ require 'sprout/executable'
39
+
40
+ # 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'
47
+
48
+ # Libraries
49
+ require 'sprout/library'
50
+
51
+ module Sprout
52
+ module Base
53
+ extend Concern
54
+
55
+ module ClassMethods
56
+
57
+ def cache
58
+ File.join(sprout_home, 'cache')
59
+ end
60
+
61
+ def sprout_home
62
+ File.join(current_system.application_home('sprouts'), Sprout::VERSION::MAJOR_MINOR)
63
+ end
64
+
65
+ def generator_cache
66
+ File.join cache, 'generators'
67
+ end
68
+
69
+ def current_system
70
+ Sprout::System.create
71
+ end
72
+
73
+ def file_from_caller caller_string
74
+ # NOTE: It's a bummer that this string is colon delimited -
75
+ # The value on Windows sometimes includes a colon...
76
+ parts = caller_string.split(':')
77
+ str = parts.shift
78
+ while(parts.size > 0 && !File.exists?(str))
79
+ str << ":#{parts.shift}"
80
+ end
81
+ str
82
+ end
83
+
84
+ end
85
+ end
86
+ end
87
+
88
+ # TODO: the included 'files' should get modified by the following expressions:
89
+ #included_files = FileList["**/*"].exclude /.DS_Store|generated|.svn|.git|airglobal.swc|airframework.swc/
90
+
@@ -0,0 +1,30 @@
1
+ module Sprout
2
+ module Concern
3
+ def self.extended(base)
4
+ base.instance_variable_set("@_dependencies", [])
5
+ end
6
+
7
+ def append_features(base)
8
+ if base.instance_variable_defined?("@_dependencies")
9
+ base.instance_variable_get("@_dependencies") << self
10
+ return false
11
+ else
12
+ return false if base < self
13
+ @_dependencies.each { |dep| base.send(:include, dep) }
14
+ super
15
+ base.extend const_get("ClassMethods") if const_defined?("ClassMethods")
16
+ base.send :include, const_get("InstanceMethods") if const_defined?("InstanceMethods")
17
+ base.class_eval(&@_included_block) if instance_variable_defined?("@_included_block")
18
+ end
19
+ end
20
+
21
+ def included(base = nil, &block)
22
+ if base.nil?
23
+ @_included_block = block
24
+ else
25
+ super
26
+ end
27
+ end
28
+ end
29
+ end
30
+