sprout 0.7.206 → 0.7.210
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.
- data/lib/progress_bar.rb +31 -7
- data/lib/sprout.rb +23 -2
- data/lib/sprout/archive_unpacker.rb +225 -0
- data/lib/sprout/builder.rb +16 -7
- data/lib/sprout/generator/base_mixins.rb +7 -2
- data/lib/sprout/generator/named_base.rb +1 -1
- data/lib/sprout/process_runner.rb +16 -0
- data/lib/sprout/remote_file_loader.rb +5 -181
- data/lib/sprout/remote_file_target.rb +76 -21
- data/lib/sprout/tasks/gem_wrap_task.rb +9 -1
- data/lib/sprout/tasks/git_task.rb +6 -1
- data/lib/sprout/tasks/library_task.rb +6 -1
- data/lib/sprout/template_resolver.rb +2 -2
- data/lib/sprout/user.rb +1 -1
- data/lib/sprout/version.rb +1 -1
- data/rakefile.rb +8 -56
- metadata +7 -16
data/lib/progress_bar.rb
CHANGED
@@ -15,9 +15,30 @@ require 'singleton'
|
|
15
15
|
|
16
16
|
class ProgressBar # :nodoc:[all]
|
17
17
|
VERSION = "0.9"
|
18
|
+
@@debug = false
|
19
|
+
@@outio = $stderr
|
20
|
+
|
18
21
|
def self.new(title, total)
|
19
22
|
return ProgressBarManager.instance.add(title, total)
|
20
23
|
end
|
24
|
+
|
25
|
+
def self.debug?
|
26
|
+
@@debug
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.debug=(debug)
|
30
|
+
@@debug = debug
|
31
|
+
if(debug)
|
32
|
+
@@outio = StringIO.new
|
33
|
+
else
|
34
|
+
@@outio = $stderr
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.outio
|
39
|
+
@@outio
|
40
|
+
end
|
41
|
+
|
21
42
|
end
|
22
43
|
|
23
44
|
class ProgressBarImpl # :nodoc:[all]
|
@@ -45,7 +66,7 @@ class ProgressBarImpl # :nodoc:[all]
|
|
45
66
|
attr_accessor :start_time,
|
46
67
|
:title_width,
|
47
68
|
:bar_mark
|
48
|
-
|
69
|
+
|
49
70
|
def fmt_bar
|
50
71
|
bar_width = do_percentage * @terminal_width / 100
|
51
72
|
sprintf("|%s%s|",
|
@@ -99,9 +120,9 @@ class ProgressBarImpl # :nodoc:[all]
|
|
99
120
|
sec = t % 60
|
100
121
|
min = (t / 60) % 60
|
101
122
|
hour = t / 3600
|
102
|
-
sprintf("%02d:%02d:%02d", hour, min, sec)
|
123
|
+
sprintf("%02d:%02d:%02d", hour, min, sec)
|
103
124
|
end
|
104
|
-
|
125
|
+
|
105
126
|
# ETA stands for Estimated Time of Arrival.
|
106
127
|
def eta
|
107
128
|
if @current == 0
|
@@ -290,7 +311,6 @@ class ProgressBarManager # :nodoc:[all]
|
|
290
311
|
include Singleton
|
291
312
|
|
292
313
|
def initialize
|
293
|
-
@outio = $stderr
|
294
314
|
@finished = {}
|
295
315
|
@bars = {}
|
296
316
|
@outs = {}
|
@@ -308,8 +328,12 @@ class ProgressBarManager # :nodoc:[all]
|
|
308
328
|
str = ''
|
309
329
|
str += @outs[title].to_s
|
310
330
|
str += "\r"
|
311
|
-
|
312
|
-
|
331
|
+
outio.print "\r"
|
332
|
+
outio.print str
|
333
|
+
end
|
334
|
+
|
335
|
+
def outio
|
336
|
+
ProgressBar.outio
|
313
337
|
end
|
314
338
|
|
315
339
|
def flush
|
@@ -320,7 +344,7 @@ class ProgressBarManager # :nodoc:[all]
|
|
320
344
|
@bars.values.each do |bar|
|
321
345
|
if(bar.finished?)
|
322
346
|
print(bar.title)
|
323
|
-
|
347
|
+
outio.print "\n"
|
324
348
|
@outs.delete(bar.title)
|
325
349
|
@bars.delete(bar.title)
|
326
350
|
end
|
data/lib/sprout.rb
CHANGED
@@ -18,8 +18,9 @@ require 'progress_bar'
|
|
18
18
|
require 'sprout/log'
|
19
19
|
require 'sprout/user'
|
20
20
|
require 'sprout/zip_util'
|
21
|
-
require 'sprout/remote_file_target'
|
22
21
|
require 'sprout/remote_file_loader'
|
22
|
+
require 'sprout/archive_unpacker'
|
23
|
+
require 'sprout/remote_file_target'
|
23
24
|
require 'sprout/simple_resolver'
|
24
25
|
require 'sprout/template_resolver'
|
25
26
|
|
@@ -40,6 +41,9 @@ module Sprout
|
|
40
41
|
SUDO_INSTALL_GEMS = 'false' == ENV['SUDO_INSTALL_GEMS'] ? false : true
|
41
42
|
end
|
42
43
|
|
44
|
+
class UsageError < StandardError #:nodoc
|
45
|
+
end
|
46
|
+
|
43
47
|
class SproutError < StandardError #:nodoc:
|
44
48
|
end
|
45
49
|
|
@@ -127,6 +131,9 @@ module Sprout
|
|
127
131
|
# This Rakefile will usually be loaded by the referenced Generator, and it should have a configured ProjectModel
|
128
132
|
# defined in it.
|
129
133
|
def self.generate(sprout_name, generator_name, params, project_path=nil)
|
134
|
+
# params.each_index do |index|
|
135
|
+
# params[index] = clean_project_name(params[index])
|
136
|
+
# end
|
130
137
|
RubiGen::Base.use_sprout_sources!(sprout_name, project_path)
|
131
138
|
generator = RubiGen::Base.instance(generator_name, params)
|
132
139
|
generator.command(:create).invoke!
|
@@ -234,7 +241,7 @@ EOF
|
|
234
241
|
# Retrieve the file target to an executable by sprout name. Usually, these are tool sprouts.
|
235
242
|
# * +name+ Full sprout gem name that contains an executable file
|
236
243
|
# * +archive_path+ Optional parameter for tools that contain more than one executable, or for
|
237
|
-
# when you don't want to use the default executable presented by the tool. For example, the Flex
|
244
|
+
# when you don't want to use the default executable presented by the tool. For example, the Flex SDK
|
238
245
|
# has many executables, when this method is called for them, one might use something like:
|
239
246
|
# Sprout::Sprout.get_executable('sprout-flex3sdk-tool', 'bin/mxmlc')
|
240
247
|
# * +version+ Optional parameter to specify a particular gem version for this executable
|
@@ -255,6 +262,12 @@ EOF
|
|
255
262
|
exe = target.archive_path
|
256
263
|
end
|
257
264
|
|
265
|
+
|
266
|
+
|
267
|
+
if(!File.exists?(exe))
|
268
|
+
raise UsageError.new("Could not retrieve requested executable from path: #{exe}")
|
269
|
+
end
|
270
|
+
|
258
271
|
if(File.exists?(exe) && !File.directory?(exe) && File.stat(exe).executable?)
|
259
272
|
File.chmod 0755, exe
|
260
273
|
end
|
@@ -310,6 +323,14 @@ EOF
|
|
310
323
|
# * +Windows+ C:/Documents And Settings/foo/Local Settings/Application Data/Sprouts/cache/0.7
|
311
324
|
# * +Linux+ ~/.sprouts/cache/0.7
|
312
325
|
def self.sprout_cache
|
326
|
+
@@sprout_cache ||= self.inferred_sprout_cache
|
327
|
+
end
|
328
|
+
|
329
|
+
def self.sprout_cache=(cache)
|
330
|
+
@@sprout_cache = cache
|
331
|
+
end
|
332
|
+
|
333
|
+
def self.inferred_sprout_cache
|
313
334
|
home = User.application_home(@@name)
|
314
335
|
return File.join(home, @@cache, "#{VERSION::MAJOR}.#{VERSION::MINOR}")
|
315
336
|
end
|
@@ -0,0 +1,225 @@
|
|
1
|
+
|
2
|
+
module Sprout
|
3
|
+
class ArchiveUnpackerError < StandardError #:nodoc:
|
4
|
+
end
|
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 'dmg'
|
40
|
+
unpack_dmg(file_name, dir)
|
41
|
+
when 'exe'
|
42
|
+
FileUtils.mkdir_p(dir)
|
43
|
+
File.mv(file_name, dir)
|
44
|
+
when 'swc' || 'rb'
|
45
|
+
return
|
46
|
+
else
|
47
|
+
raise ArchiveUnpackerError.new("ArchiveUnpacker does not know how to unpack files of type: #{archive_type} for file_name: #{file_name}")
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def unpack_zip(zip_file, dir)
|
53
|
+
# Avoid the rubyzip Segmentation Fault bug
|
54
|
+
# at least on os x...
|
55
|
+
if(RUBY_PLATFORM =~ /darwin/)
|
56
|
+
# Unzipping on OS X
|
57
|
+
FileUtils.makedirs(dir)
|
58
|
+
zip_dir = File.expand_path(File.dirname(zip_file))
|
59
|
+
zip_name = File.basename(zip_file)
|
60
|
+
output = File.expand_path(dir)
|
61
|
+
# puts ">> zip_dir: #{zip_dir} zip_name: #{zip_name} output: #{output}"
|
62
|
+
%x(cd #{zip_dir};unzip #{zip_name} -d #{output})
|
63
|
+
else
|
64
|
+
retries = 0
|
65
|
+
begin
|
66
|
+
retries += 1
|
67
|
+
Zip::ZipFile::open(zip_file) do |zf|
|
68
|
+
zf.each do |e|
|
69
|
+
fpath = File.join(dir, e.name)
|
70
|
+
FileUtils.mkdir_p(File.dirname(fpath))
|
71
|
+
# Disgusting, Gross Hack to fix DOS/Ruby Bug
|
72
|
+
# That makes the zip library throw a ZipDestinationFileExistsError
|
73
|
+
# When the zip archive includes two files whose names
|
74
|
+
# differ only by extension.
|
75
|
+
# This bug actually appears in the File.exists? implementation
|
76
|
+
# throwing false positives!
|
77
|
+
# If you're going to use this code, be sure you extract
|
78
|
+
# into a new, empty directory as existing files will be
|
79
|
+
# clobbered...
|
80
|
+
begin
|
81
|
+
if(File.exists?(fpath) && !File.directory?(fpath))
|
82
|
+
hackpath = fpath + 'hack'
|
83
|
+
zf.extract(e, hackpath)
|
84
|
+
File.copy(hackpath, fpath)
|
85
|
+
File.delete(hackpath)
|
86
|
+
else
|
87
|
+
zf.extract(e, fpath)
|
88
|
+
end
|
89
|
+
rescue NotImplementedError => ni_err
|
90
|
+
puts "[WARNING] #{ni_err} for: #{e}"
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
rescue StandardError => err
|
95
|
+
FileUtils.rm_rf(dir)
|
96
|
+
if(retries < 3)
|
97
|
+
FileUtils.makedirs(dir)
|
98
|
+
retry
|
99
|
+
end
|
100
|
+
raise err
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def unpacked_file_name(file, dir, suffix=nil)
|
106
|
+
basename = File.basename(file, suffix)
|
107
|
+
path = File.expand_path(dir)
|
108
|
+
return File.join(path, basename)
|
109
|
+
end
|
110
|
+
|
111
|
+
def unpack_targz(tgz_file, dir)
|
112
|
+
if(!File.exists?(dir))
|
113
|
+
FileUtils.makedirs(dir)
|
114
|
+
end
|
115
|
+
tar = Zlib::GzipReader.new(File.open(tgz_file, 'rb'))
|
116
|
+
Minitar.unpack(tar, dir)
|
117
|
+
|
118
|
+
# Recurse and unpack gzipped children (Adobe did this double
|
119
|
+
# gzip with the Linux FlashPlayer for some reason)
|
120
|
+
Dir.glob("#{dir}/**/*.tar.gz").each do |child|
|
121
|
+
if(child != tgz_file)
|
122
|
+
unpack_targz(child, File.dirname(child))
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
end
|
127
|
+
|
128
|
+
# This is actually not unpacking the FlashPlayer
|
129
|
+
# Binary file as expected...
|
130
|
+
# OSX is treated the player binary as if it is
|
131
|
+
# a regular text file, but if it is copied manually,
|
132
|
+
# the command works fine!?
|
133
|
+
def unpack_dmg(dmg_file, dir)
|
134
|
+
# 1) Mount the dmg in place
|
135
|
+
# 2) Recursively Copy its contents to asproject_home
|
136
|
+
# 3) Unmount the dmg
|
137
|
+
if(mounted_path.nil?)
|
138
|
+
raise StandardError.new('DMG file downloaded, but the RemoteFileTask needs a mounted_path in order to mount it')
|
139
|
+
end
|
140
|
+
|
141
|
+
if(!File.exists?(full_mounted_path))
|
142
|
+
system("hdiutil mount #{dmg_file}")
|
143
|
+
end
|
144
|
+
|
145
|
+
begin
|
146
|
+
mounted_target = File.join(full_mounted_path, extracted_file)
|
147
|
+
|
148
|
+
# Copy the DMG contents using system copy rather than ruby utils
|
149
|
+
# Because OS X does something special with .app files that the
|
150
|
+
# Ruby FileUtils and File classes break...
|
151
|
+
from = mounted_target
|
152
|
+
# from = File.join(full_mounted_path, extracted_file)
|
153
|
+
to = File.join(@user.downloads, @name.to_s, extracted_file)
|
154
|
+
FileUtils.makedirs(File.dirname(to))
|
155
|
+
|
156
|
+
if(File.exists?(from))
|
157
|
+
`ditto '#{from}' '#{to}'`
|
158
|
+
end
|
159
|
+
rescue StandardError => e
|
160
|
+
if(File.exists?(full_mounted_path))
|
161
|
+
system("hdiutil unmount -force \"#{full_mounted_path}\"")
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
def suffix_for_archive_type(type)
|
167
|
+
if(type == :targz)
|
168
|
+
return '.tar.gz'
|
169
|
+
else
|
170
|
+
return ".#{type.to_s}"
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
def inferred_archive_type(file_name)
|
175
|
+
if is_zip?(file_name)
|
176
|
+
return :zip
|
177
|
+
elsif is_targz?(file_name)
|
178
|
+
return :targz
|
179
|
+
elsif is_gzip?(file_name)
|
180
|
+
return :gz
|
181
|
+
elsif is_swc?(file_name)
|
182
|
+
return :swc
|
183
|
+
elsif is_rb?(file_name)
|
184
|
+
return :rb
|
185
|
+
elsif is_dmg?(file_name)
|
186
|
+
return :dmg
|
187
|
+
elsif is_exe?(file_name)
|
188
|
+
return :exe
|
189
|
+
else
|
190
|
+
return nil
|
191
|
+
end
|
192
|
+
|
193
|
+
end
|
194
|
+
|
195
|
+
def is_zip?(file)
|
196
|
+
return (file.split('.').pop == 'zip')
|
197
|
+
end
|
198
|
+
|
199
|
+
def is_targz?(file)
|
200
|
+
parts = file.split('.')
|
201
|
+
part = parts.pop
|
202
|
+
return (part == 'tgz' || part == 'gz' && parts.pop == 'tar')
|
203
|
+
end
|
204
|
+
|
205
|
+
def is_gzip?(file)
|
206
|
+
return (file.split('.').pop == 'gz')
|
207
|
+
end
|
208
|
+
|
209
|
+
def is_swc?(file)
|
210
|
+
return (file.split('.').pop == 'swc')
|
211
|
+
end
|
212
|
+
|
213
|
+
def is_rb?(file)
|
214
|
+
return (file.split('.').pop == 'rb')
|
215
|
+
end
|
216
|
+
|
217
|
+
def is_dmg?(file)
|
218
|
+
return (file.split('.').pop == 'dmg')
|
219
|
+
end
|
220
|
+
|
221
|
+
def is_exe?(file)
|
222
|
+
return (file.split('.').pop == 'exe')
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
data/lib/sprout/builder.rb
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
|
2
2
|
module Sprout
|
3
3
|
|
4
|
+
class BuilderError < StandardError #:nodoc:
|
5
|
+
end
|
6
|
+
|
4
7
|
# accepts a destination path and a sprout specification
|
5
8
|
# and will download and unpack the platform-specific
|
6
9
|
# archives that are identified in the spec
|
7
10
|
class Builder # :nodoc:
|
8
11
|
|
9
|
-
class BuilderError < StandardError #:nodoc:
|
10
|
-
end
|
11
|
-
|
12
12
|
def self.build(file_targets_yaml, destination)
|
13
13
|
data = nil
|
14
14
|
|
@@ -16,12 +16,15 @@ module Sprout
|
|
16
16
|
data = f.read
|
17
17
|
end
|
18
18
|
|
19
|
-
usr = User.new
|
20
|
-
platform = usr.platform.to_s
|
21
|
-
|
22
19
|
targets = YAML.load(data)
|
23
20
|
targets.each do |target|
|
24
|
-
|
21
|
+
# iterate over the provided RemoteFileTargets until we
|
22
|
+
# encounter one that is appropriate for our platform,
|
23
|
+
# or one that claims to be universal.
|
24
|
+
# When authoring a sprout.spec for libraries or tools,
|
25
|
+
# put the most specific RemoteFileTargets first, then
|
26
|
+
# universals to catch unexpected platforms.
|
27
|
+
if(target.platform == platform || target.platform == 'universal')
|
25
28
|
target.install_path = FileUtils.mkdir_p(destination)
|
26
29
|
target.resolve
|
27
30
|
return target
|
@@ -30,6 +33,12 @@ module Sprout
|
|
30
33
|
raise BuilderError.new("Sprout::Builder.build failed, unsupported platform or unexpected yaml")
|
31
34
|
end
|
32
35
|
|
36
|
+
private
|
37
|
+
|
38
|
+
def self.platform
|
39
|
+
@@platform ||= User.new.platform.to_s
|
40
|
+
end
|
41
|
+
|
33
42
|
end
|
34
43
|
end
|
35
44
|
|
@@ -48,8 +48,13 @@ class Gem::SourceIndex
|
|
48
48
|
Gem::Platform.match spec.platform
|
49
49
|
end
|
50
50
|
end
|
51
|
-
|
52
|
-
|
51
|
+
|
52
|
+
begin
|
53
|
+
specs.sort_by { |s| s.sort_obj }
|
54
|
+
rescue NoMethodError => e
|
55
|
+
puts "It looks like your RubyGems installation is not compatible with this version of Sprouts.\n\nTo update, run:\ngem update --system\n\n"
|
56
|
+
raise e
|
57
|
+
end
|
53
58
|
end
|
54
59
|
end
|
55
60
|
|
@@ -27,6 +27,9 @@ module Sprout #:nodoc:
|
|
27
27
|
require 'open4'
|
28
28
|
@pid, @w, @r, @e = open4.popen4(*@command)
|
29
29
|
end
|
30
|
+
rescue Errno::EACCES => e
|
31
|
+
update_executable_mode(*@command)
|
32
|
+
@pid, @w, @r, @e = open4.popen4(*@command)
|
30
33
|
rescue Errno::ENOENT => e
|
31
34
|
@alive = false
|
32
35
|
part = command[0].split(' ').shift
|
@@ -34,6 +37,19 @@ module Sprout #:nodoc:
|
|
34
37
|
end
|
35
38
|
end
|
36
39
|
|
40
|
+
def update_executable_mode(*command)
|
41
|
+
parts = command.join(' ').split(' ')
|
42
|
+
str = parts.shift
|
43
|
+
while(parts.size > 0)
|
44
|
+
if(File.exists?(str))
|
45
|
+
FileUtils.chmod(744, str)
|
46
|
+
return
|
47
|
+
else
|
48
|
+
str << " #{parts.shift}"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
37
53
|
def alive?
|
38
54
|
@alive = update_status
|
39
55
|
end
|
@@ -2,16 +2,13 @@
|
|
2
2
|
module Sprout
|
3
3
|
class RemoteFileLoaderError < StandardError #:nodoc:
|
4
4
|
end
|
5
|
-
|
5
|
+
|
6
6
|
class RemoteFileLoader #:nodoc:
|
7
|
-
include Archive::Tar
|
8
7
|
|
9
|
-
def get_remote_file(uri,
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
write(response, target, force)
|
14
|
-
end
|
8
|
+
def get_remote_file(uri, force=false, md5=nil)
|
9
|
+
response = fetch(uri.to_s)
|
10
|
+
if(force || response_is_valid?(response, md5))
|
11
|
+
return response
|
15
12
|
end
|
16
13
|
end
|
17
14
|
|
@@ -34,22 +31,8 @@ module Sprout
|
|
34
31
|
return true
|
35
32
|
end
|
36
33
|
|
37
|
-
def write(response, target, force=false)
|
38
|
-
FileUtils.makedirs(File.dirname(target))
|
39
|
-
if(force && File.exists?(target))
|
40
|
-
File.delete(target)
|
41
|
-
end
|
42
|
-
File.open(target, 'wb') do |f|
|
43
|
-
f.write(response)
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
34
|
def fetch(uri)
|
48
35
|
uri = URI.parse(uri)
|
49
|
-
# Download the file now to the downloads dir
|
50
|
-
# If the file is an archive (zip, gz, tar, tar.gz, dmg), extract to
|
51
|
-
# Sprouts/cache/@type/@name
|
52
|
-
# Check the location again...
|
53
36
|
progress = nil
|
54
37
|
response = nil
|
55
38
|
name = uri.path.split("/").pop
|
@@ -84,164 +67,5 @@ module Sprout
|
|
84
67
|
return response
|
85
68
|
end
|
86
69
|
|
87
|
-
def unpack_downloaded_file(file_name, dir)
|
88
|
-
if(!File.exists?(dir))
|
89
|
-
if(is_zip?(file_name))
|
90
|
-
unpack_zip(file_name, dir)
|
91
|
-
elsif(is_targz?(file_name))
|
92
|
-
unpack_targz(file_name, dir)
|
93
|
-
elsif(is_dmg?(file_name))
|
94
|
-
unpack_dmg(file_name, dir)
|
95
|
-
elsif(is_swc?(file_name))
|
96
|
-
# just copy the swc...
|
97
|
-
elsif(is_rb?(file_name))
|
98
|
-
return
|
99
|
-
elsif(is_exe?(file_name))
|
100
|
-
FileUtils.mkdir_p(dir)
|
101
|
-
File.mv(file_name, dir)
|
102
|
-
else
|
103
|
-
raise UsageError.new("RemoteFileTask does not know how to unpack files of type: #{file_name}")
|
104
|
-
end
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
def unpack_zip(zip_file, dir)
|
109
|
-
# Avoid the rubyzip Segmentation Fault bug
|
110
|
-
# at least on os x...
|
111
|
-
if(RUBY_PLATFORM =~ /darwin/)
|
112
|
-
# Unzipping on OS X
|
113
|
-
FileUtils.makedirs(dir)
|
114
|
-
zip_dir = File.expand_path(File.dirname(zip_file))
|
115
|
-
zip_name = File.basename(zip_file)
|
116
|
-
output = File.expand_path(dir)
|
117
|
-
#puts ">> zip_dir: #{zip_dir} zip_name: #{zip_name} output: #{output}"
|
118
|
-
%x(cd #{zip_dir};unzip #{zip_name} -d #{output})
|
119
|
-
else
|
120
|
-
retries = 0
|
121
|
-
begin
|
122
|
-
retries += 1
|
123
|
-
Zip::ZipFile::open(zip_file) do |zf|
|
124
|
-
zf.each do |e|
|
125
|
-
fpath = File.join(dir, e.name)
|
126
|
-
FileUtils.mkdir_p(File.dirname(fpath))
|
127
|
-
# Disgusting, Gross Hack to fix DOS/Ruby Bug
|
128
|
-
# That makes the zip library throw a ZipDestinationFileExistsError
|
129
|
-
# When the zip archive includes two files whose names
|
130
|
-
# differ only by extension.
|
131
|
-
# This bug actually appears in the File.exists? implementation
|
132
|
-
# throwing false positives!
|
133
|
-
# If you're going to use this code, be sure you extract
|
134
|
-
# into a new, empty directory as existing files will be
|
135
|
-
# clobbered...
|
136
|
-
begin
|
137
|
-
if(File.exists?(fpath) && !File.directory?(fpath))
|
138
|
-
hackpath = fpath + 'hack'
|
139
|
-
zf.extract(e, hackpath)
|
140
|
-
File.copy(hackpath, fpath)
|
141
|
-
File.delete(hackpath)
|
142
|
-
else
|
143
|
-
zf.extract(e, fpath)
|
144
|
-
end
|
145
|
-
rescue NotImplementedError => ni_err
|
146
|
-
puts "[WARNING] #{ni_err} for: #{e}"
|
147
|
-
end
|
148
|
-
end
|
149
|
-
end
|
150
|
-
rescue StandardError => err
|
151
|
-
FileUtils.rm_rf(dir)
|
152
|
-
if(retries < 3)
|
153
|
-
puts ">> [ZIP ERROR ENCOUNTERED] trying again with: #{dir}"
|
154
|
-
FileUtils.makedirs(dir)
|
155
|
-
retry
|
156
|
-
end
|
157
|
-
raise err
|
158
|
-
end
|
159
|
-
end
|
160
|
-
end
|
161
|
-
|
162
|
-
def unpack_targz(tgz_file, dir)
|
163
|
-
if(!File.exists?(dir))
|
164
|
-
FileUtils.makedirs(dir)
|
165
|
-
end
|
166
|
-
tar = Zlib::GzipReader.new(File.open(tgz_file, 'rb'))
|
167
|
-
Minitar.unpack(tar, dir)
|
168
|
-
|
169
|
-
# Recurse and unpack gzipped children (Adobe did this double
|
170
|
-
# gzip with the Linux FlashPlayer for some reason)
|
171
|
-
Dir.glob("#{dir}/**/*.tar.gz").each do |child|
|
172
|
-
if(child != tgz_file)
|
173
|
-
unpack_targz(child, File.dirname(child))
|
174
|
-
end
|
175
|
-
end
|
176
|
-
|
177
|
-
end
|
178
|
-
|
179
|
-
# This is actually not unpacking the FlashPlayer
|
180
|
-
# Binary file as expected...
|
181
|
-
# OSX is treated the player binary as if it is
|
182
|
-
# a regular text file, but if it is copied manually,
|
183
|
-
# the command works fine!?
|
184
|
-
def unpack_dmg(dmg_file, dir)
|
185
|
-
# 1) Mount the dmg in place
|
186
|
-
# 2) Recursively Copy its contents to asproject_home
|
187
|
-
# 3) Unmount the dmg
|
188
|
-
if(mounted_path.nil?)
|
189
|
-
raise StandardError.new('DMG file downloaded, but the RemoteFileTask needs a mounted_path in order to mount it')
|
190
|
-
end
|
191
|
-
|
192
|
-
if(!File.exists?(full_mounted_path))
|
193
|
-
system("hdiutil mount #{dmg_file}")
|
194
|
-
end
|
195
|
-
|
196
|
-
begin
|
197
|
-
mounted_target = File.join(full_mounted_path, extracted_file)
|
198
|
-
|
199
|
-
# Copy the DMG contents using system copy rather than ruby utils
|
200
|
-
# Because OS X does something special with .app files that the
|
201
|
-
# Ruby FileUtils and File classes break...
|
202
|
-
from = mounted_target
|
203
|
-
# from = File.join(full_mounted_path, extracted_file)
|
204
|
-
to = File.join(@user.downloads, @name.to_s, extracted_file)
|
205
|
-
FileUtils.makedirs(File.dirname(to))
|
206
|
-
|
207
|
-
if(File.exists?(from))
|
208
|
-
`ditto '#{from}' '#{to}'`
|
209
|
-
end
|
210
|
-
rescue
|
211
|
-
if(File.exists?(full_mounted_path))
|
212
|
-
system("hdiutil unmount -force \"#{full_mounted_path}\"")
|
213
|
-
end
|
214
|
-
end
|
215
|
-
end
|
216
|
-
|
217
|
-
def is_exe?(file)
|
218
|
-
return (file.split('.').pop == 'exe')
|
219
|
-
end
|
220
|
-
|
221
|
-
def is_zip?(file)
|
222
|
-
return (file.split('.').pop == 'zip')
|
223
|
-
end
|
224
|
-
|
225
|
-
def is_targz?(file)
|
226
|
-
parts = file.split('.')
|
227
|
-
part = parts.pop
|
228
|
-
return (part == 'tgz' || part == 'gz' && parts.pop == 'tar')
|
229
|
-
end
|
230
|
-
|
231
|
-
def is_gzip?(file)
|
232
|
-
return (file.split('.').pop == 'gz')
|
233
|
-
end
|
234
|
-
|
235
|
-
def is_swc?(file)
|
236
|
-
return (file.split('.').pop == 'swc')
|
237
|
-
end
|
238
|
-
|
239
|
-
def is_rb?(file)
|
240
|
-
return (file.split('.').pop == 'rb')
|
241
|
-
end
|
242
|
-
|
243
|
-
def is_dmg?(file)
|
244
|
-
return (file.split('.').pop == 'dmg')
|
245
|
-
end
|
246
70
|
end
|
247
71
|
end
|
@@ -7,6 +7,9 @@ module Sprout
|
|
7
7
|
|
8
8
|
attr_writer :archive_path
|
9
9
|
|
10
|
+
# The string environment variable name to check before downloading anything.
|
11
|
+
attr_accessor :environment
|
12
|
+
|
10
13
|
# The user path where this gem will download and install files
|
11
14
|
# This value is set by the Sprout::Builder that creates this RemoteFileTarget
|
12
15
|
attr_accessor :install_path
|
@@ -29,6 +32,21 @@ module Sprout
|
|
29
32
|
|
30
33
|
# URL where Sprouts can go to download the RemoteFileTarget archive
|
31
34
|
attr_accessor :url
|
35
|
+
|
36
|
+
# If the archive type cannot be assumed from the returned file name,
|
37
|
+
# it must be provided as one of the following:
|
38
|
+
# :exe
|
39
|
+
# :zip
|
40
|
+
# :targz
|
41
|
+
# :gzip
|
42
|
+
# :swc
|
43
|
+
# :rb
|
44
|
+
# :dmg
|
45
|
+
# @see ArchiveUnpacker
|
46
|
+
attr_accessor :archive_type
|
47
|
+
|
48
|
+
# Filename for the downloaded file. Introduced to fix railsy URL issues.
|
49
|
+
attr_accessor :filename
|
32
50
|
|
33
51
|
# Relative path within the archive to the executable or binary of interest
|
34
52
|
def archive_path
|
@@ -36,18 +54,30 @@ module Sprout
|
|
36
54
|
end
|
37
55
|
|
38
56
|
# Resolve this RemoteFileTarget now. This method is called by the Sprout::Builder
|
39
|
-
# and will download, install and unpack the described archive
|
57
|
+
# and will download, install and unpack the described archive, unless it is
|
58
|
+
# already installed
|
40
59
|
def resolve(update=false)
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
60
|
+
# Wanted to raise, but it seems we support RemoteFileTargets that are actually self-installed binaries...
|
61
|
+
# like SWFMill on Linux. @see the BuilderTest.test_build_no_install for more info.
|
62
|
+
# raise RemoteFileTargetError.new('Cannot retrieve a RemoteFileTarget without a url') if url.nil?
|
63
|
+
return if url.nil?
|
64
|
+
|
65
|
+
if(filename)
|
66
|
+
self.downloaded_path = File.join(File.dirname(downloaded_path), filename)
|
67
|
+
end
|
68
|
+
|
69
|
+
if(url && (update || !File.exists?(downloaded_path)))
|
70
|
+
content = download(url, update)
|
71
|
+
FileUtils.makedirs(File.dirname(downloaded_path))
|
72
|
+
FileUtils.touch(downloaded_path)
|
73
|
+
File.open(downloaded_path, 'r+') do |file|
|
74
|
+
file.write(content)
|
45
75
|
end
|
76
|
+
end
|
46
77
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
end
|
78
|
+
if(!File.exists?(installed_path) || !File.exists?(File.join(installed_path, archive_path) ))
|
79
|
+
archive_root = File.join(install_path, 'archive')
|
80
|
+
install(downloaded_path, archive_root, update, archive_type)
|
51
81
|
end
|
52
82
|
end
|
53
83
|
|
@@ -59,37 +89,62 @@ module Sprout
|
|
59
89
|
# The root path to the unpacked archive files. This is the base path that will be added to any
|
60
90
|
# +archive_path+ relative paths
|
61
91
|
def installed_path
|
62
|
-
@installed_path ||=
|
92
|
+
@installed_path ||= inferred_installed_path
|
63
93
|
return @installed_path
|
64
94
|
end
|
65
95
|
|
96
|
+
def downloaded_path=(path)
|
97
|
+
@downloaded_path = path
|
98
|
+
end
|
99
|
+
|
66
100
|
# Parent directory where archives are downloaded
|
67
101
|
# can be something like: ~/Library/Sprouts/cache/0.7/sprout-somesprout-tool.x.x.x/
|
68
102
|
def downloaded_path
|
69
|
-
@downloaded_path ||= File.join(install_path, file_name)
|
103
|
+
@downloaded_path ||= File.join(install_path, file_name(url))
|
70
104
|
return @downloaded_path
|
71
105
|
end
|
72
106
|
|
73
107
|
# Base file name represented by the provided +url+
|
74
108
|
# Will strip off any ? arguments and trailing slashes. May not play nice with Rails URLS,
|
75
109
|
# We expect archive file name suffixes like, zip, gzip, tar.gz, dmg, etc.
|
76
|
-
def file_name
|
77
|
-
if(
|
78
|
-
|
110
|
+
def file_name(url=nil)
|
111
|
+
return @filename if(@filename)
|
112
|
+
|
113
|
+
url ||= self.url
|
114
|
+
url = url.split('?').shift
|
115
|
+
|
116
|
+
parts = url.split('/')
|
117
|
+
if(parts.last == '/')
|
118
|
+
parts.pop
|
79
119
|
end
|
80
|
-
|
81
|
-
file =
|
120
|
+
|
121
|
+
file = parts.pop
|
122
|
+
|
123
|
+
if(!archive_type.nil? && file.match(/\.#{archive_type.to_s}$/).nil?)
|
124
|
+
file << ".#{archive_type.to_s}"
|
125
|
+
end
|
126
|
+
|
82
127
|
return file
|
83
128
|
end
|
84
129
|
|
85
130
|
private
|
86
|
-
|
87
|
-
|
88
|
-
|
131
|
+
|
132
|
+
def inferred_installed_path
|
133
|
+
if(!environment.nil? && !ENV[environment].nil? && File.exists?(ENV[environment]))
|
134
|
+
return ENV[environment]
|
135
|
+
end
|
136
|
+
|
137
|
+
return File.join(install_path, 'archive')
|
138
|
+
end
|
139
|
+
|
140
|
+
def download(url, update=false)
|
141
|
+
loader = RemoteFileLoader.new
|
142
|
+
loader.get_remote_file(url, update, md5)
|
89
143
|
end
|
90
144
|
|
91
|
-
def install(from, to)
|
92
|
-
|
145
|
+
def install(from, to, force, archive_type=nil)
|
146
|
+
unpacker = ArchiveUnpacker.new
|
147
|
+
unpacker.unpack_archive(from, to, force, archive_type)
|
93
148
|
end
|
94
149
|
|
95
150
|
end
|
@@ -105,10 +105,18 @@ module Sprout
|
|
105
105
|
s.email = @email
|
106
106
|
s.homepage = @homepage
|
107
107
|
s.rubyforge_project = 'sprout'
|
108
|
-
s.requirements << {'sprout', '>= 0.7.1'}
|
109
108
|
gem_dependencies.each do |dep|
|
110
109
|
s.requirements << dep
|
111
110
|
end
|
111
|
+
|
112
|
+
sprout_requirement = s.requirements.collect { |req|
|
113
|
+
(req[0] == 'sprout')
|
114
|
+
}
|
115
|
+
|
116
|
+
if(!sprout_requirement)
|
117
|
+
s.add_dependency('sprout', '>= 0.7.209')
|
118
|
+
end
|
119
|
+
|
112
120
|
if(File.exists?('sprout.spec'))
|
113
121
|
files << 'sprout.spec'
|
114
122
|
end
|
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'git'
|
2
1
|
require 'sprout/version_file'
|
3
2
|
|
4
3
|
module Sprout
|
@@ -58,6 +57,12 @@ module Sprout
|
|
58
57
|
end
|
59
58
|
|
60
59
|
def self.define_task(args, &block)
|
60
|
+
begin
|
61
|
+
require 'git'
|
62
|
+
rescue LoadError => e
|
63
|
+
puts "You need to install the 'git' gem. Try running: sudo gem install git"
|
64
|
+
raise e
|
65
|
+
end
|
61
66
|
t = super
|
62
67
|
yield t if block_given?
|
63
68
|
t.define
|
@@ -99,7 +99,12 @@ module Sprout
|
|
99
99
|
|
100
100
|
def define_file_task(source, destination)
|
101
101
|
file destination do |t|
|
102
|
-
|
102
|
+
lib_path = library_path
|
103
|
+
FileUtils.makedirs(destination)
|
104
|
+
if(File.directory?(lib_path))
|
105
|
+
lib_path = "#{lib_path}/."
|
106
|
+
end
|
107
|
+
FileUtils.cp_r(lib_path, destination)
|
103
108
|
end
|
104
109
|
prerequisites << destination
|
105
110
|
end
|
data/lib/sprout/user.rb
CHANGED
data/lib/sprout/version.rb
CHANGED
data/rakefile.rb
CHANGED
@@ -32,7 +32,7 @@ PKG_LIST.each do |file|
|
|
32
32
|
task :package => file
|
33
33
|
end
|
34
34
|
|
35
|
-
|
35
|
+
spec = Gem::Specification.new do |s|
|
36
36
|
s.summary = SUMMARY
|
37
37
|
s.description = DESCRIPTION
|
38
38
|
s.name = NAME
|
@@ -58,48 +58,15 @@ def apply_shared_spec(s)
|
|
58
58
|
s.add_dependency('rubigen', '= 1.3.3')
|
59
59
|
s.add_dependency('net-sftp')
|
60
60
|
s.add_dependency('net-ssh')
|
61
|
+
|
62
|
+
if(RUBY_PLATFORM.match('mswin'))
|
63
|
+
s.add_dependency('win32-open3', '0.2.5')
|
64
|
+
else
|
65
|
+
s.add_dependency('open4', '>= 0.9.6')
|
66
|
+
end
|
61
67
|
end
|
62
68
|
|
63
|
-
|
64
|
-
apply_shared_spec(s)
|
65
|
-
s.platform = 'darwin'
|
66
|
-
# Add osx-specific dependencies here
|
67
|
-
|
68
|
-
# Can't really depend on rb-appscript b/c this requires OS X dev-tool disk
|
69
|
-
#s.add_dependency('rb-appscript', '>= 0.5.0')
|
70
|
-
s.add_dependency('open4', '>= 0.9.6')
|
71
|
-
end
|
72
|
-
|
73
|
-
nix_spec = Gem::Specification.new do |s|
|
74
|
-
apply_shared_spec(s)
|
75
|
-
s.platform = 'x86-linux'
|
76
|
-
# Add nix-specific dependencies here
|
77
|
-
s.add_dependency('open4', '>= 0.9.6')
|
78
|
-
end
|
79
|
-
|
80
|
-
win_spec = Gem::Specification.new do |s|
|
81
|
-
apply_shared_spec(s)
|
82
|
-
s.platform = 'mswin32'
|
83
|
-
# Add win-specific dependencies here
|
84
|
-
s.add_dependency('win32-open3', '0.2.5')
|
85
|
-
end
|
86
|
-
|
87
|
-
ruby_spec = Gem::Specification.new do |s|
|
88
|
-
apply_shared_spec(s)
|
89
|
-
s.platform = Gem::Platform::RUBY
|
90
|
-
s.add_dependency('open4', '>= 0.9.6')
|
91
|
-
end
|
92
|
-
|
93
|
-
Rake::GemPackageTask.new(osx_spec) do |pkg|
|
94
|
-
end
|
95
|
-
|
96
|
-
Rake::GemPackageTask.new(nix_spec) do |pkg|
|
97
|
-
end
|
98
|
-
|
99
|
-
Rake::GemPackageTask.new(win_spec) do |pkg|
|
100
|
-
end
|
101
|
-
|
102
|
-
Rake::GemPackageTask.new(ruby_spec) do |pkg|
|
69
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
103
70
|
end
|
104
71
|
|
105
72
|
Rake::RDocTask.new do |t|
|
@@ -113,21 +80,6 @@ Rake::RDocTask.new do |t|
|
|
113
80
|
end
|
114
81
|
|
115
82
|
CLEAN.add('rdoc')
|
116
|
-
|
117
|
-
|
118
83
|
require File.dirname(__FILE__) + '/script/build_helpers'
|
119
84
|
|
120
|
-
def fix_x86_mswin
|
121
|
-
files = Dir.glob('pkg/*x86-mswin*')
|
122
|
-
files.each do |name|
|
123
|
-
new_name = name.gsub('-x86', '')
|
124
|
-
puts "Renaming x86-mswin gem from #{name} to #{new_name}"
|
125
|
-
File.mv(name, new_name)
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
129
|
-
task :package do
|
130
|
-
fix_x86_mswin
|
131
|
-
end
|
132
|
-
|
133
85
|
#task :release => :release_rubyforge
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sprout
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.210
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Luke Bayes
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-07-15 00:00:00 -07:00
|
13
13
|
default_executable: sprout
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -81,28 +81,18 @@ extensions: []
|
|
81
81
|
extra_rdoc_files: []
|
82
82
|
|
83
83
|
files:
|
84
|
-
- bin
|
85
|
-
- doc
|
86
|
-
- lib
|
87
84
|
- MIT-LICENSE
|
88
|
-
- pkg
|
89
85
|
- rakefile.rb
|
90
|
-
- samples
|
91
|
-
- script
|
92
|
-
- test
|
93
86
|
- TODO
|
94
|
-
- samples/gem_wrap
|
95
87
|
- samples/gem_wrap/rakefile.rb
|
96
88
|
- bin/sprout
|
97
89
|
- lib/corelib.swc
|
98
90
|
- lib/platform.rb
|
99
91
|
- lib/progress_bar.rb
|
100
|
-
- lib/sprout
|
92
|
+
- lib/sprout/archive_unpacker.rb
|
101
93
|
- lib/sprout/builder.rb
|
102
|
-
- lib/sprout/commands
|
103
94
|
- lib/sprout/commands/generate.rb
|
104
95
|
- lib/sprout/general_tasks.rb
|
105
|
-
- lib/sprout/generator
|
106
96
|
- lib/sprout/generator/base_mixins.rb
|
107
97
|
- lib/sprout/generator/named_base.rb
|
108
98
|
- lib/sprout/generator.rb
|
@@ -112,7 +102,6 @@ files:
|
|
112
102
|
- lib/sprout/remote_file_loader.rb
|
113
103
|
- lib/sprout/remote_file_target.rb
|
114
104
|
- lib/sprout/simple_resolver.rb
|
115
|
-
- lib/sprout/tasks
|
116
105
|
- lib/sprout/tasks/gem_wrap_task.rb
|
117
106
|
- lib/sprout/tasks/git_task.rb
|
118
107
|
- lib/sprout/tasks/library_task.rb
|
@@ -133,6 +122,8 @@ files:
|
|
133
122
|
- doc/Tool
|
134
123
|
has_rdoc: true
|
135
124
|
homepage: http://www.projectsprouts.org
|
125
|
+
licenses: []
|
126
|
+
|
136
127
|
post_install_message:
|
137
128
|
rdoc_options:
|
138
129
|
- --title
|
@@ -162,9 +153,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
162
153
|
requirements: []
|
163
154
|
|
164
155
|
rubyforge_project: sprout
|
165
|
-
rubygems_version: 1.3.
|
156
|
+
rubygems_version: 1.3.4
|
166
157
|
signing_key:
|
167
|
-
specification_version:
|
158
|
+
specification_version: 3
|
168
159
|
summary: Sprouts is an open-source, cross-platform project generation, configuration and build tool.
|
169
160
|
test_files: []
|
170
161
|
|