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.
- data/MIT-LICENSE +20 -0
- data/TODO +12 -0
- data/bin/sprout +128 -0
- data/doc/Bundle +14 -0
- data/doc/Generator +35 -0
- data/doc/Library +63 -0
- data/doc/Task +21 -0
- data/doc/Tool +20 -0
- data/lib/platform.rb +109 -0
- data/lib/progress_bar.rb +330 -0
- data/lib/sprout.rb +456 -0
- data/lib/sprout/builder.rb +35 -0
- data/lib/sprout/commands/generate.rb +14 -0
- data/lib/sprout/general_tasks.rb +5 -0
- data/lib/sprout/generator.rb +6 -0
- data/lib/sprout/generator/base_mixins.rb +132 -0
- data/lib/sprout/generator/named_base.rb +216 -0
- data/lib/sprout/log.rb +46 -0
- data/lib/sprout/process_runner.rb +46 -0
- data/lib/sprout/project_model.rb +114 -0
- data/lib/sprout/remote_file_loader.rb +233 -0
- data/lib/sprout/remote_file_target.rb +96 -0
- data/lib/sprout/simple_resolver.rb +88 -0
- data/lib/sprout/tasks/gem_wrap_task.rb +192 -0
- data/lib/sprout/tasks/library_task.rb +103 -0
- data/lib/sprout/tasks/sftp_task.rb +245 -0
- data/lib/sprout/tasks/tool_task.rb +541 -0
- data/lib/sprout/tasks/zip_task.rb +158 -0
- data/lib/sprout/template_resolver.rb +207 -0
- data/lib/sprout/user.rb +359 -0
- data/lib/sprout/version.rb +10 -0
- data/lib/sprout/zip_util.rb +61 -0
- data/rakefile.rb +129 -0
- data/samples/gem_wrap/rakefile.rb +17 -0
- metadata +150 -0
@@ -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
|
data/lib/sprout/user.rb
ADDED
@@ -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
|