sprout 0.7.191-mswin32

Sign up to get free protection for your applications and to get access to all the features.
@@ -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