sprout 0.7.191-mswin32

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.

@@ -0,0 +1,82 @@
1
+
2
+ module Sprout #:nodoc:
3
+ class ProcessRunnerError < StandardError # :nodoc:
4
+ end
5
+
6
+ class ProcessRunner #:nodoc:
7
+ attr_reader :pid,
8
+ :r,
9
+ :w,
10
+ :e
11
+
12
+ def initialize(*command)
13
+ @command = command
14
+ begin
15
+ @alive = true
16
+ usr = User.new()
17
+ if(usr.is_a?(WinUser) && !usr.is_a?(CygwinUser))
18
+ require_gem 'win32/open3', '0.2.5'
19
+ Open3.popen3(*@command) do |w, r, e, pid|
20
+ @w = w
21
+ @r = r
22
+ @e = e
23
+ @pid = pid
24
+ end
25
+ else
26
+ require 'open4'
27
+ @pid, @w, @r, @e = open4.popen4(*@command)
28
+ end
29
+ rescue Errno::ENOENT => e
30
+ @alive = false
31
+ part = command[0].split(' ').shift
32
+ raise ProcessRunnerError.new("The expected executable was not found for command [#{part}], please check your system path and/or sprout definition")
33
+ end
34
+ end
35
+
36
+ def alive?
37
+ @alive = update_status
38
+ end
39
+
40
+ def update_status
41
+ pid_int = Integer("#{ @pid }")
42
+ begin
43
+ Process::kill 0, pid_int
44
+ true
45
+ rescue Errno::ESRCH
46
+ false
47
+ end
48
+ end
49
+
50
+ def readpartial(count)
51
+ @r.readpartial(count)
52
+ end
53
+
54
+ def readlines
55
+ @r.readlines
56
+ end
57
+
58
+ def flush
59
+ @w.flush
60
+ end
61
+
62
+ def getc
63
+ @r.getc
64
+ end
65
+
66
+ def print(msg)
67
+ @w.print msg
68
+ end
69
+
70
+ def puts(msg)
71
+ @w.puts(msg)
72
+ end
73
+
74
+ def read
75
+ return @r.read
76
+ end
77
+
78
+ def read_err
79
+ return @e.read
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,270 @@
1
+
2
+ module Sprout
3
+ # The ProjectModel gives you a place to describe your project so that you
4
+ # don't need to repeat yourself throughout a rakefile.
5
+ #
6
+ # The default set of properties are also used from code generators, library tasks and sometimes tools.
7
+ #
8
+ # The ProjectModel can be configured as follows:
9
+ # project_model :model do |p|
10
+ # p.name = 'SomeProject'
11
+ # p.source_path << 'somedir/otherdir'
12
+ # p.library_path << 'somedir'
13
+ # end
14
+ #
15
+ # This class should have some reasonable default values, but can be modified from any rakefile.
16
+ # If you don't find some properties that you'd like on the ProjectModel, you can simply add
17
+ # new properties and use them however you wish.
18
+ #
19
+ # Arbitrary properties can be added as follows:
20
+ # m = project_model :model do |p|
21
+ # p.unknown_property = 'someValue'
22
+ # end
23
+ #
24
+ # puts "Unknown Property: #{m.unknown_property}"
25
+ #
26
+ # The ProjectModel is typically treated as if it is a Singleton, and many helper tasks
27
+ # will automatically go look for their model at:
28
+ #
29
+ # Sprout::ProjectModel.instance
30
+ #
31
+ # Unlike a real Singleton, this static property will actually be populated with the most
32
+ # recently instantiated ProjectModel, and any well-behaved helper task will also
33
+ # allow you to send in a model as a prerequisite.
34
+ #
35
+ # project_model :model_a
36
+ # project_model :model_b
37
+ #
38
+ # desc 'Compile and run a'
39
+ # debug :debug_a => :model_a
40
+ #
41
+ # desc 'Compile and run b'
42
+ # debug :debug_b => :model_b
43
+ #
44
+ class ProjectModel < Hash
45
+
46
+ # Relative path to the folder where compile time assets will be stored
47
+ attr_accessor :asset_dir
48
+ # The folder where binary files will be created. Usually this is where any build artifacts like SWF files get placed.
49
+ attr_accessor :bin_dir
50
+ # The Background Color of the SWF file
51
+ attr_accessor :background_color
52
+ # Contributors to the SWF file
53
+ attr_accessor :contributors
54
+ # If you don't want to use the default compiler for your language
55
+ # set it manually here.
56
+ # Possible values are:
57
+ # * sprout-flex2sdk-tool
58
+ # * sprout-flex3sdk-tool
59
+ # * sprout-flex4sdk-tool (Experimental)
60
+ # * sprout-mtasc-tool
61
+ attr_accessor :compiler_gem_name
62
+ # The version number of the compiler gem to use
63
+ attr_accessor :compiler_gem_version
64
+ # The primary creator of the SWF file
65
+ attr_accessor :creator
66
+ # Directory where documentation should be placed.
67
+ attr_accessor :doc_dir
68
+ # CSS documents that should be individually compiled
69
+ # for runtime stylesheet loading.
70
+ attr_accessor :external_css
71
+ # The default frame rate of the SWF file
72
+ attr_accessor :frame_rate
73
+ # The default height of the SWF file
74
+ # _(This value is overridden when embedded in an HTML page)_
75
+ attr_accessor :height
76
+ # The technology language that is being used, right now this value can be 'as2', 'as3' or 'mxml'.
77
+ # Code generators take advantage of this setting to determine which templates to use
78
+ # and build tasks use this setting to determin the input file suffix (.as or .mxml).
79
+ attr_accessor :language
80
+ # The relative path to your library directory. Defaults to 'lib'
81
+ #
82
+ # Any remote .SWC and source libraries that are referenced in your rakefile will be installed
83
+ # into this directory. Source libraries will be placed in a folder that matches the library name,
84
+ # while SWCs will be simply placed directly into the lib_dir.
85
+ attr_accessor :lib_dir
86
+ # Array of sprout library symbols
87
+ attr_accessor :libraries
88
+ # The Array of SWC paths to add to all compilation tasks
89
+ attr_accessor :library_path
90
+ # The locale for the SWF file
91
+ attr_accessor :locale
92
+ # A collection of Flex Module root source files. If this collection
93
+ # has items added to it, the deploy task will generate a 'link_report' from
94
+ # the main application compilation and then consume it as 'load_externs' for
95
+ # each module compilation.
96
+ attr_accessor :modules
97
+ # Organization responsible for this SWF file
98
+ attr_accessor :organization
99
+ # The production file that this Project will generate
100
+ attr_accessor :output
101
+ # The real name of the project, usually capitalized like a class name 'SomeProject'
102
+ attr_accessor :project_name
103
+ # The folder where compile time skins can be loaded from
104
+ attr_accessor :skin_dir
105
+ # The skin file that will be generated
106
+ attr_accessor :skin_output
107
+ # The Array of source paths to add to all compilation tasks
108
+ # _Do not add task-specific paths (like lib/asunit) to this value_
109
+ attr_accessor :source_path
110
+ # The relative path to your main source directory. Defaults to 'src'
111
+ attr_accessor :src_dir
112
+ # Enforce strict type checking
113
+ attr_accessor :strict
114
+ # The relative path to the directory where swc files should be kept.
115
+ # This value defaults to lib_dir
116
+ attr_accessor :swc_dir
117
+ # Relative path to the folder that contains your test cases
118
+ attr_accessor :test_dir
119
+ # The test executable
120
+ attr_accessor :test_output
121
+ # The test runner SWF height
122
+ attr_accessor :test_height
123
+ # The test runner SWF width
124
+ attr_accessor :test_width
125
+ # The default width of the SWF file
126
+ # _(This value is overridden when embedded in an HTML page)_
127
+ attr_accessor :width
128
+
129
+ # Static method that returns the most recently instantiated ProjectModel,
130
+ # or instantiates one if none have been created yet.
131
+ def self.instance
132
+ @@instance ||= ProjectModel.new
133
+ yield @@instance if block_given?
134
+ return @@instance
135
+ end
136
+
137
+ # Decorates the static instance method.
138
+ def self.setup
139
+ @@instance ||= ProjectModel.new
140
+ yield @@instance if block_given?
141
+ return @@instance
142
+ end
143
+
144
+ def self.destroy # :nodoc:
145
+ @@instance = nil
146
+ end
147
+
148
+ def initialize
149
+ super
150
+ @project_name = ''
151
+ @doc_dir = 'doc'
152
+ @src_dir = 'src'
153
+ @lib_dir = 'lib'
154
+ @swc_dir = 'lib'
155
+ @bin_dir = 'bin'
156
+ @test_dir = 'test'
157
+ @asset_dir = 'assets'
158
+ @skin_dir = File.join(@asset_dir, 'skins')
159
+ @frame_rate = 24
160
+ @language = 'as3'
161
+
162
+ @external_css = []
163
+ @libraries = []
164
+ @library_path = []
165
+ @modules = []
166
+ @source_path = []
167
+
168
+ @model_dir = nil
169
+ @view_dir = nil
170
+ @controller_dir = nil
171
+
172
+ @test_height = 550
173
+ @test_width = 900
174
+ @@instance = self
175
+ end
176
+
177
+ # Path to the project directory from which all other paths are created
178
+ def project_path
179
+ return Sprout.project_path
180
+ end
181
+
182
+ def model_dir=(dir)
183
+ @model_dir = dir
184
+ end
185
+
186
+ # Simple MVC helper for project-wide models if your project is called 'SomeProject'
187
+ # this will default to:
188
+ # SomeProject/src/someproject/models
189
+ def model_dir
190
+ if(@model_dir.nil?)
191
+ @model_dir = File.join(src_dir, project_name.downcase, 'models')
192
+ end
193
+ return @model_dir
194
+ end
195
+
196
+ def view_dir=(dir)
197
+ @view_dir = dir
198
+ end
199
+
200
+ # Simple MVC helper for project-wide views if your project is called 'SomeProject'
201
+ # this will default to:
202
+ # SomeProject/src/someproject/views
203
+ def view_dir
204
+ if(@view_dir.nil?)
205
+ @view_dir = File.join(src_dir, project_name.downcase, 'views')
206
+ end
207
+ return @view_dir
208
+ end
209
+
210
+ def controller_dir=(dir)
211
+ @controller_dir = dir
212
+ end
213
+
214
+ # Simple MVC helper for project-wide views if your project is called 'SomeProject'
215
+ # this will default to:
216
+ # SomeProject/src/someproject/controllers
217
+ def controller_dir
218
+ if(@controller_dir.nil?)
219
+ @controller_dir = File.join(src_dir, project_name.downcase, 'controllers')
220
+ end
221
+ return @controller_dir
222
+ end
223
+
224
+ # Alias for project_name
225
+ def name=(name)
226
+ @project_name = name
227
+ end
228
+
229
+ def name
230
+ @project_name
231
+ end
232
+
233
+ def to_s
234
+ return "[Sprout::ProjectModel project_name=#{project_name}]"
235
+ end
236
+
237
+ protected
238
+
239
+ def method_missing(method_name, *args)
240
+ method_name = method_name.to_s
241
+ if method_name =~ /=$/
242
+ super if args.size > 1
243
+ self[method_name[0...-1]] = args[0]
244
+ else
245
+ super unless has_key?(method_name) and args.empty?
246
+ self[method_name]
247
+ end
248
+ end
249
+ end
250
+ end
251
+
252
+ # Helper method to expose the project model as a Rake Task
253
+ def project_model(task_name)
254
+ model = Sprout::ProjectModel.new
255
+ yield model if block_given?
256
+
257
+ t = task task_name
258
+
259
+ def t.project_model=(model)
260
+ @model = model
261
+ end
262
+
263
+ def t.project_model
264
+ return @model
265
+ end
266
+
267
+ t.project_model = model
268
+ return model
269
+ end
270
+
@@ -0,0 +1,247 @@
1
+
2
+ module Sprout
3
+ class RemoteFileLoaderError < StandardError #:nodoc:
4
+ end
5
+
6
+ class RemoteFileLoader #:nodoc:
7
+ include Archive::Tar
8
+
9
+ def get_remote_file(uri, target, force=false, md5=nil)
10
+ if(force || !File.exists?(target))
11
+ response = fetch(uri.to_s)
12
+ if(response_is_valid?(response, md5))
13
+ write(response, target, force)
14
+ end
15
+ end
16
+ end
17
+
18
+ def response_is_valid?(response, expected_md5sum=nil)
19
+ if(expected_md5sum)
20
+ md5 = Digest::MD5.new
21
+ md5 << response
22
+
23
+ if(expected_md5sum != md5.hexdigest)
24
+ puts "The MD5 Sum of the downloaded file (#{md5.hexdigest}) does not match what was expected (#{expected_md5sum})."
25
+ puts "Would you like to install anyway? [Yn]"
26
+ response = $stdin.gets.chomp!
27
+ if(response.downcase == 'y')
28
+ return true
29
+ else
30
+ raise RemoteFileLoaderError.new('MD5 Checksum failed')
31
+ end
32
+ end
33
+ end
34
+ return true
35
+ end
36
+
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
+ def fetch(uri)
48
+ 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
+ progress = nil
54
+ response = nil
55
+ name = uri.path.split("/").pop
56
+
57
+ raise RemoteFileLoaderError.new("The RemoteFileTask failed for #{name}. We can only handle HTTP requests at this time, it seems you were trying: '#{uri.scheme}'") if uri.scheme != 'http'
58
+ begin
59
+ open(uri.to_s, :content_length_proc => lambda {|t|
60
+ if t && t > 0
61
+ progress = ProgressBar.new(name, t)
62
+ progress.file_transfer_mode
63
+ progress.set(0)
64
+ else
65
+ progress = ProgressBar.new(name, 0)
66
+ progress.file_transfer_mode
67
+ progress.set(0)
68
+ end
69
+ },
70
+ :progress_proc => lambda {|s|
71
+ progress.set s if progress
72
+ }) {|f|
73
+ response = f.read
74
+ progress.finish
75
+ }
76
+ rescue SocketError => sock_err
77
+ raise RemoteFileLoaderError.new("[ERROR] #{sock_err.to_s}")
78
+ rescue OpenURI::HTTPError => http_err
79
+ raise RemoteFileLoaderError.new("[ERROR] Failed to load file from: '#{uri.to_s}'\n[REMOTE ERROR] #{http_err.io.read.strip}")
80
+ rescue Errno::ECONNREFUSED => econ_err
81
+ raise Errno::ECONNREFUSED.new("[ERROR] Connection refused at: '#{uri.to_s}'")
82
+ end
83
+
84
+ return response
85
+ end
86
+
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 it's 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
+ end
247
+ end