sprout 0.7.153-x86-linux

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,158 @@
1
+ =begin
2
+ Copyright (c) 2007 Pattern Park
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining
5
+ a copy of this software and associated documentation files (the
6
+ "Software"), to deal in the Software without restriction, including
7
+ without limitation the rights to use, copy, modify, merge, publish,
8
+ distribute, sublicense, and/or sell copies of the Software, and to
9
+ permit persons to whom the Software is furnished to do so, subject to
10
+ the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ =end
23
+
24
+ require 'zip/zipfilesystem'
25
+
26
+ # TODO: Make this task more like a rake FileTask
27
+ # The output should be the task name and the input
28
+ # files should be added as prerequisites
29
+
30
+ module Sprout
31
+ class ZipError < StandardError #:nodoc:
32
+ end
33
+
34
+ # The ZipTask should accept any directory as input and either
35
+ # an expected zip file name or directory where one will be created
36
+ # for output.
37
+ # The resulting zip file will only be generated if a file in the
38
+ # input directory has a newer timestamp than the existing zip file
39
+ class ZipTask < Rake::FileTask
40
+
41
+ # Array of file names that should not be added to the zip archive.
42
+ # The default value of this property is:
43
+ # @excludes = ['.', '..', '.svn', '.cvs', '.DS_Store', '.git', 'CVS', 'Thumbs.db']
44
+ attr_writer :excludes
45
+ # The file or folder that should be archived.
46
+ #
47
+ # If input is a directory, all of it's contents
48
+ # will be recursively added to the archive (excluding any files that match +excludes+ of course).
49
+ #
50
+ # If input is a file, a new archive will be created with a similar file name and only that file
51
+ # will be added to the archive.
52
+ attr_writer :input
53
+ # Zip archive file to create. Usually, the name of the zip task will be used for this property,
54
+ # but in cases where you want a particular task name and a different output file, you can set
55
+ # this parameter.
56
+ attr_writer :output
57
+
58
+ def self.define_task(args, &block) # :nodoc:
59
+ t = super
60
+ yield t if block_given?
61
+ t.define
62
+ end
63
+
64
+ def define # :nodoc:
65
+ @input = define_input(input)
66
+ @output = define_output(output || name)
67
+ end
68
+
69
+ def output
70
+ @output ||= nil
71
+ end
72
+
73
+ def input
74
+ @input ||= nil
75
+ end
76
+
77
+ def execute(*args) # :nodoc:
78
+ create_archive
79
+ end
80
+
81
+ def excludes
82
+ @excludes ||= ['.', '..', '.svn', '.cvs', '.DS_Store', '.git', 'CVS', 'Thumbs.db']
83
+ end
84
+
85
+ private
86
+
87
+ def create_archive(force=false) # :nodoc:
88
+ return unless (force || name == output)
89
+
90
+ start = Dir.pwd
91
+ begin
92
+ full_output = File.expand_path(output)
93
+ full_input = File.expand_path(input)
94
+ Dir.chdir(File.dirname(full_input))
95
+ masked_input = full_input.gsub("#{Dir.pwd}/", '')
96
+
97
+ # Create the containing folder for output
98
+ if(!File.directory?(File.dirname(full_output)))
99
+ FileUtils.mkdir_p(File.dirname(full_output))
100
+ end
101
+
102
+ ZipUtil.pack(masked_input, full_output, excludes)
103
+
104
+ ensure
105
+ Dir.chdir(start)
106
+ end
107
+
108
+ end
109
+
110
+ def define_input(input)
111
+ file input do |t|
112
+ raise ZipError.new("ZipTask '#{name}' could not find valid input at: #{input}") unless (File.exists?(input))
113
+ end
114
+
115
+ input_files = FileList["#{input}/**/**/*"]
116
+ input_files.each do |f|
117
+ prerequisites << f
118
+ end
119
+ prerequisites << input
120
+ return input
121
+ end
122
+
123
+ def define_output(out)
124
+
125
+ # If the provided parent dir doesn't
126
+ # exist, create it
127
+ if(!File.exists?(File.dirname(out)))
128
+ FileUtils.mkdir_p(File.dirname(out))
129
+ end
130
+
131
+ # If the provided output is just a directory
132
+ # and it's parent doesn't yet exist, create the
133
+ # provided output directory before appending
134
+ # the real zip file name
135
+ if(!File.basename(out).index('.'))
136
+ FileUtils.mkdir_p(out)
137
+ end
138
+
139
+ # If out is just a directory, append input's basename
140
+ # to create the zip file
141
+ if(File.directory?(out))
142
+ out = File.join(out, File.basename(input) + '.zip')
143
+ end
144
+
145
+ if(out != name)
146
+ file out do
147
+ create_archive(true)
148
+ end
149
+ prerequisites << out
150
+ end
151
+ return out
152
+ end
153
+ end
154
+ end
155
+
156
+ def zip(args, &block)
157
+ Sprout::ZipTask.define_task(args, &block)
158
+ end
@@ -0,0 +1,207 @@
1
+
2
+ module Sprout
3
+
4
+ class TemplateResolver < Hash #:nodoc:
5
+ include Singleton
6
+
7
+ attr_accessor :replace_all,
8
+ :ignore_all
9
+
10
+ @@SPROUT_FILE_NAME = 'Sprout'
11
+ @@RENDER_IGNORE_FILES = ['asclass_config.rb', 'SWFMillTemplate.erb', 'Template.erb']
12
+ @@BINARY_EXTENSIONS = ['.jpg', '.png', '.gif', '.doc', '.xls', '.exe', '.swf', 'fla', '.psd']
13
+ @@LOG_PREFIX = ">> Created file: "
14
+ @@DELETE_PREFIX = ">> Deleted file: "
15
+
16
+ def initialize
17
+ super
18
+ @replace_all = false
19
+ @ignore_all = false
20
+ end
21
+
22
+ def copy_files(from, to, render=false)
23
+ created_files = Array.new
24
+ if(!File.exists? from)
25
+ raise UsageError.new('TemplateResolver attempted to copy files from (' + from + ') but it does not exist...')
26
+ end
27
+ if(File.directory? from)
28
+ Dir.open(from).each do |filename|
29
+ if(!Sprout.ignore_file? filename)
30
+ fullname = File.join(from, filename)
31
+ new_fullname = File.join(to, filename)
32
+ cleaned_filename = clean_file_name(filename)
33
+ cleaned_fullname = File.join(to, cleaned_filename)
34
+ if(File.directory? fullname)
35
+ Dir.mkdir(new_fullname) unless File.exists? new_fullname
36
+ puts new_fullname
37
+ copy_files(fullname, new_fullname, render)
38
+ else
39
+ file = copy_file(fullname, cleaned_fullname, render)
40
+ end
41
+ end
42
+ end
43
+ else
44
+ raise UsageError.new("copy_files called with a file (" + from + ") instead of a directory!")
45
+ end
46
+
47
+ return created_files
48
+ end
49
+
50
+ def puts(file, is_delete=false)
51
+ prefix = (is_delete) ? @@DELETE_PREFIX : @@LOG_PREFIX
52
+ Log.puts(prefix + file.gsub(Dir.pwd + '/', ''))
53
+ end
54
+
55
+ def b(path)
56
+ (is_binary?(path)) ? 'b' : ''
57
+ end
58
+
59
+ def copy_file(from, to, render=false, delegate=nil)
60
+ if(write_file?(to))
61
+ content = nil
62
+ File.open(from, 'r' + b(from)) do |f|
63
+ content = f.read
64
+ end
65
+ if(render && should_render?(from))
66
+ begin
67
+ bind = (delegate.nil?) ? binding : delegate.get_binding
68
+ content = ERB.new(content, nil, '>').result(bind)
69
+ rescue NameError => e
70
+ Log.puts '>> Template ' + from + ' references a value that is not defined'
71
+ raise e
72
+ end
73
+ end
74
+ FileUtils.makedirs(File.dirname(to))
75
+ File.open(to, 'w' + b(to)) do |f|
76
+ f.write(content)
77
+ end
78
+ puts to
79
+ return to
80
+ end
81
+ return nil
82
+ end
83
+
84
+ def should_render?(file)
85
+ if(is_binary?(file) || @@RENDER_IGNORE_FILES.index(File.basename(file)))
86
+ return false
87
+ end
88
+ return true
89
+ end
90
+
91
+ def write_file?(file)
92
+ if(!File.exists?(file))
93
+ return true
94
+ elsif(@replace_all)
95
+ puts(file, true)
96
+ File.delete(file)
97
+ return true
98
+ elsif(@ignore_all)
99
+ return false
100
+ end
101
+
102
+ relative = file.gsub(Dir.pwd, '')
103
+ msg = <<EOF
104
+
105
+ [WARNING] Sprout Encountered an existing file at [#{relative}], what would you like to do?
106
+ (r)eplace, (i)gnore, (R)eplace all or (I)gnore all?
107
+
108
+ EOF
109
+ if(Log.debug)
110
+ return false
111
+ end
112
+
113
+ $stdout.puts msg
114
+ answer = $stdin.gets.chomp
115
+ if(answer == 'r')
116
+ return true
117
+ elsif(answer == 'i')
118
+ return false
119
+ elsif(answer == 'R')
120
+ msg = <<EOF
121
+
122
+ Are you sure you want to replace ALL duplicate files?
123
+ (y)es or (n)o
124
+
125
+ EOF
126
+ $stdout.puts msg
127
+ answer = $stdin.gets.chomp
128
+ if(answer == 'y')
129
+ @replace_all = true
130
+ else
131
+ write_file?(file)
132
+ end
133
+ elsif(answer == 'I')
134
+ @ignore_all = true
135
+ return false
136
+ else
137
+ $stdout.puts "I didn't understand that response... Please choose from the following choices:\n\n"
138
+ write_file?(file)
139
+ end
140
+ end
141
+
142
+ def render_file filename
143
+ file = File.open(filename, 'r')
144
+ resolved = ERB.new(file.read, nil, '>').result(binding)
145
+ file.close
146
+ file = File.open(filename, 'w')
147
+ file.write(resolved)
148
+ file.close
149
+ end
150
+
151
+ def clean_file_name name
152
+ return name.gsub(@@SPROUT_FILE_NAME, project_name)
153
+ end
154
+
155
+ def project_name
156
+ return Sprout.project_name
157
+ end
158
+
159
+ def instance_name
160
+ return project_name[0,1].downcase + project_name[1,project_name.size]
161
+ end
162
+
163
+ #TODO: Figure out if the file is plain text or not... Possible?
164
+ def is_binary? file
165
+ file_extension = File.extname(file).downcase
166
+ @@BINARY_EXTENSIONS.each do |ext|
167
+ if(file_extension == ext)
168
+ return true
169
+ end
170
+ end
171
+ return false
172
+ end
173
+
174
+ =begin
175
+ Found this code for binary inspection here:
176
+ http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/44940
177
+ it's not 100%, but better than what I'm doing with extensions.
178
+ This should be tested and inserted above
179
+ if it works.
180
+
181
+ NON_ASCII_PRINTABLE = /[^\x20-\x7e\s]/
182
+
183
+ def nonbinary?(io, forbidden, size = 1024)
184
+ while buf = io.read(size)
185
+ return false if forbidden =~ buf
186
+ end
187
+ true
188
+ end
189
+
190
+ # usage: ruby this_script.rb filename ...
191
+ ARGV.each do |fn|
192
+ begin
193
+ open(fn) do |f|
194
+ if nonbinary?(f, NON_ASCII_PRINTABLE)
195
+ puts "#{fn}: ascii printable"
196
+ else
197
+ puts "#{fn}: binary"
198
+ end
199
+ end
200
+ rescue
201
+ puts "#$0: #$!"
202
+ end
203
+ end
204
+ =end
205
+
206
+ end
207
+ end
@@ -0,0 +1,359 @@
1
+ require 'platform'
2
+ require 'sprout/log'
3
+ require 'sprout/process_runner'
4
+
5
+ module Sprout
6
+
7
+ class ExecutionError < StandardError # :nodoc:
8
+ end
9
+
10
+ # The User class provides a single and consistent interface to User based paths
11
+ # and features so that Sprout implementation code doesn't need to be concerned
12
+ # with which Operating system it is running on.
13
+ #
14
+ class User
15
+ @@user = nil
16
+
17
+ # Retrieve a user instance that represents the currently logged in user on this system.
18
+ def User.new(os=nil, impl=nil)
19
+ if(os.nil? && impl.nil? && @@user)
20
+ return @@user
21
+ end
22
+ if(os.nil?)
23
+ os = Platform::OS
24
+ end
25
+ if(impl.nil?)
26
+ impl = Platform::IMPL
27
+ end
28
+ if(os == :win32 && impl == :vista)
29
+ @@user = VistaUser.new
30
+ elsif(os == :win32 && impl == :cygwin)
31
+ @@user = CygwinUser.new
32
+ elsif(os == :win32)
33
+ @@user = WinUser.new
34
+ elsif(os == :unix && impl == :macosx)
35
+ @@user = OSXUser.new
36
+ # elsif(os == :unix && impl == :linux)
37
+ # @@user = UnixUser.new
38
+ else
39
+ @@user = UnixUser.new
40
+ end
41
+ end
42
+
43
+ def User.user=(user) # :nodoc:
44
+ @@user = user
45
+ end
46
+
47
+ def User.home=(path) # :nodoc:
48
+ User.new().home = path
49
+ end
50
+
51
+ # Pass an executable or binary file name and find out if that file exists in the system
52
+ # path or not
53
+ def User.in_path?(executable)
54
+ User.new().in_path?(executable)
55
+ end
56
+
57
+ # Retrieve the full path to an executable that exists in the user path
58
+ def User.get_exe_path(executable)
59
+ return User.new().get_exe_path(executable)
60
+ end
61
+
62
+ # Return the home path for the currently logged in user. If the user name is lbayes, this should be:
63
+ #
64
+ # Windows XP:: C:\Documents And Settings\lbayes
65
+ # Cygwin:: /cygdrive/c/Documents And Settings/lbayes
66
+ # OS X:: /Users/lbayes
67
+ # Linux:: ~/
68
+ def User.home
69
+ User.new().home
70
+ end
71
+
72
+ # Returns the home path for a named application based on the currently logged in user and operating system.
73
+ # If the user name is lbayes and the application name is Sprouts, this path will be:
74
+ #
75
+ # Windows XP:: C:\Documents And Settings\lbayes\Local Settings\Application Data\Sprouts
76
+ # Cygwin:: /cygdrive/c/Documents And Settings/Local Settings/Application Data/Sprouts
77
+ # OS X:: /Users/lbayes/Library/Sprouts
78
+ # Linux:: ~/.sprouts
79
+ def User.application_home(name)
80
+ return User.new().application_home(name)
81
+ end
82
+
83
+ # Returns the library path on the current system. This is the general path where all applications should
84
+ # store configuration or session data.
85
+ #
86
+ # Windows XP:: C:\Documents And Settings\lbayes\Local Settings\Application Data
87
+ # Cygwin:: /cygdrive/c/Documents And Settings/lbayes/Local Settings/Application Data
88
+ # OS X:: /Users/lbayes/Library
89
+ # Linux:: ~/
90
+ def User.library
91
+ return User.new().library
92
+ end
93
+
94
+ # Execute a named tool sprout. The full sprout name should be provided to the tool parameter, and
95
+ # a string of shell parameters that will be sent to the tool itself.
96
+ def User.execute(tool, options='')
97
+ return User.new().execute(tool, options)
98
+ end
99
+
100
+ def User.execute_silent(tool, options='')
101
+ return User.new().execute_silent(tool, options)
102
+ end
103
+
104
+ # Execute a named tool sprout as a new thread and return that thread
105
+ def User.execute_thread(tool, options='')
106
+ if(Log.debug)
107
+ return ThreadMock.new
108
+ else
109
+ return User.new().execute_thread(tool, options)
110
+ end
111
+ end
112
+
113
+ # Clean a path string in such a way that works for each platform. For example, Windows doesn't like
114
+ # it when we backslash to escape spaces in a path because that is the character they use as a delimiter.
115
+ # And OS X doesn't really like it when we wrap paths in quotes.
116
+ def User.clean_path(path)
117
+ return User.new().clean_path(path)
118
+ end
119
+
120
+ end
121
+
122
+ #############################
123
+ # UnixUser class
124
+ class UnixUser # :nodoc:
125
+
126
+ def initialize
127
+ setup_user
128
+ @home = nil
129
+ end
130
+
131
+ def setup_user
132
+ end
133
+
134
+ def home=(path)
135
+ @home = path
136
+ end
137
+
138
+ def home
139
+ if(@home)
140
+ return @home
141
+ end
142
+
143
+ ["HOME", "USERPROFILE"].each do |homekey|
144
+ return @home = ENV[homekey] if ENV[homekey]
145
+ end
146
+
147
+ if ENV["HOMEDRIVE"] && ENV["HOMEPATH"]
148
+ return @home = "#{ENV["HOMEDRIVE"]}:#{ENV["HOMEPATH"]}"
149
+ end
150
+
151
+ begin
152
+ return @home = File.expand_path("~")
153
+ rescue StandardError
154
+ if File::ALT_SEPARATOR
155
+ return @home = "C:\\"
156
+ else
157
+ return @home = "/"
158
+ end
159
+ end
160
+ end
161
+
162
+ def get_exe_path(executable)
163
+ paths = get_paths
164
+ file = nil
165
+ paths.each do |path|
166
+ file = File.join(path, executable)
167
+ if(File.exists?(file))
168
+ return file
169
+ end
170
+ end
171
+ return nil
172
+ end
173
+
174
+ def in_path?(executable)
175
+ return !get_exe_path(executable).nil?
176
+ end
177
+
178
+ def get_paths
179
+ return ENV['PATH'].split(':')
180
+ end
181
+
182
+ def library
183
+ return home
184
+ end
185
+
186
+ def platform
187
+ if(Platform::OS == :win32)
188
+ return :win32
189
+ elsif(Platform::IMPL == :macosx)
190
+ return :macosx
191
+ else
192
+ return Platform::IMPL
193
+ end
194
+ end
195
+
196
+ def execute(tool, options='')
197
+ Log.puts(">> Execute: #{File.basename(tool)} #{options}")
198
+ tool = clean_path(tool)
199
+ runner = ProcessRunner.new("#{tool} #{options}")
200
+
201
+ result = runner.read
202
+ error = runner.read_err
203
+ if(result.size > 0)
204
+ Log.puts result
205
+ end
206
+ if(error.size > 0)
207
+ raise ExecutionError.new("[ERROR] #{error}")
208
+ end
209
+ end
210
+
211
+ def execute_silent(tool, options='')
212
+ tool = clean_path(tool)
213
+ return ProcessRunner.new("#{tool} #{options}")
214
+ end
215
+
216
+ def execute_thread(tool, options='')
217
+ return Thread.new {
218
+ execute(tool, options)
219
+ }
220
+ end
221
+
222
+ def clean_path(path)
223
+ if(path.index(' '))
224
+ return %{'#{path}'}
225
+ end
226
+ return path
227
+ end
228
+
229
+ def application_home(name)
230
+ return File.join(library, format_application_name(name.to_s));
231
+ end
232
+
233
+ def format_application_name(name)
234
+ if(name.index('.') != 0)
235
+ name = '.' + name
236
+ end
237
+ return name.split(" ").join("_").downcase
238
+ end
239
+ end
240
+
241
+ class OSXUser < UnixUser # :nodoc:
242
+ @@LIBRARY = 'Library'
243
+
244
+ def library
245
+ lib = File.join(home, @@LIBRARY)
246
+ if(File.exists?(lib))
247
+ return lib
248
+ else
249
+ return super
250
+ end
251
+ end
252
+
253
+ def format_application_name(name)
254
+ return name.capitalize
255
+ end
256
+ end
257
+
258
+ class WinUser < UnixUser # :nodoc:
259
+ @@LOCAL_SETTINGS = "Local\ Settings"
260
+ @@APPLICATION_DATA = "Application\ Data"
261
+
262
+ def initialize
263
+ super
264
+ @home = nil
265
+ end
266
+
267
+ def setup_user
268
+ end
269
+
270
+ def home
271
+ usr = super
272
+ if(usr.index "My Documents")
273
+ usr = File.dirname(usr)
274
+ end
275
+ return usr
276
+ end
277
+
278
+ def get_paths
279
+ return ENV['PATH'].split(';')
280
+ end
281
+
282
+ def library
283
+ # For some reason, my homepath returns inside 'My Documents'...
284
+ application_data = File.join(home, @@LOCAL_SETTINGS, @@APPLICATION_DATA)
285
+ if(File.exists?(application_data))
286
+ return application_data
287
+ else
288
+ return super
289
+ end
290
+ end
291
+
292
+ def clean_path(path)
293
+ path = path.split('/').join("\\")
294
+ if(path.index(' '))
295
+ return %{"#{path}"}
296
+ end
297
+ return path
298
+ end
299
+
300
+ def format_application_name(name)
301
+ return name.capitalize
302
+ end
303
+ end
304
+
305
+ class CygwinUser < WinUser # :nodoc:
306
+
307
+ def initialize
308
+ super
309
+ @home = nil
310
+ @win_home = nil
311
+ @win_home_cyg_path = nil
312
+ end
313
+
314
+ def setup_user
315
+ end
316
+
317
+ def clean_path(path)
318
+ if(path.index(' '))
319
+ return %{'#{path}'}
320
+ end
321
+ return path
322
+ end
323
+
324
+ def win_home
325
+ if(@win_home.nil?)
326
+ @win_home = ENV['HOMEDRIVE'] + ENV['HOMEPATH']
327
+ end
328
+ return @win_home
329
+ end
330
+
331
+ def home
332
+ if(@home.nil?)
333
+ path = win_home.split('\\').join("/")
334
+ path = path.split(":").join("")
335
+ parts = path.split("/")
336
+ path = parts.shift().downcase + "/" + parts.join("/")
337
+ @home = "/cygdrive/" + path
338
+ end
339
+ return @home
340
+ end
341
+
342
+ end
343
+
344
+ class VistaUser < WinUser # :nodoc:
345
+ def home
346
+ profile = ENV['USERPROFILE']
347
+ if(profile)
348
+ return profile
349
+ end
350
+ return super
351
+ end
352
+ end
353
+
354
+ class ThreadMock # :nodoc:
355
+ def alive?
356
+ return false
357
+ end
358
+ end
359
+ end