rUtilAnts 0.2.1.20101110 → 0.2.2.20101125
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog +5 -0
- data/ReleaseInfo +1 -1
- data/lib/rUtilAnts/Archive.rb +356 -0
- data/lib/rUtilAnts/Platforms/i386-mingw32/PlatformInfo.rb +149 -0
- data/lib/rUtilAnts/Platforms/i386-mswin32/PlatformInfo.rb +1 -0
- metadata +24 -20
data/ChangeLog
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
= rUtilAnts Release History
|
2
2
|
|
3
|
+
== 0.2.2.20101125 (Beta)
|
4
|
+
|
5
|
+
* Archive: Implemented a new module that provides archiving strings, objects and files with compression and encryption
|
6
|
+
* Platforms: Added support for i386-mingw32 (current Ruby installations on Windows use this platform)
|
7
|
+
|
3
8
|
== 0.2.1.20101110 (Beta)
|
4
9
|
|
5
10
|
* Changed copyright mentions.
|
data/ReleaseInfo
CHANGED
@@ -0,0 +1,356 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2009-2010 Muriel Salvan (murielsalvan@users.sourceforge.net)
|
3
|
+
# Licensed under the terms specified in LICENSE file. No warranty is provided.
|
4
|
+
#++
|
5
|
+
|
6
|
+
require 'ezcrypto'
|
7
|
+
require 'zlib'
|
8
|
+
require 'fileutils'
|
9
|
+
|
10
|
+
module RUtilAnts
|
11
|
+
|
12
|
+
module Archive
|
13
|
+
|
14
|
+
# Class used to give the encoders a streaming interface
|
15
|
+
class StringWriter
|
16
|
+
|
17
|
+
# Buffer size used in bytes
|
18
|
+
BUFFER_SIZE = 8388608
|
19
|
+
|
20
|
+
# Constructor
|
21
|
+
#
|
22
|
+
# Parameters:
|
23
|
+
# * *iPassword* (_String_): Password encrypting data
|
24
|
+
# * *iSalt* (_String_): Salt encoding data
|
25
|
+
# * *oFile* (_IO_): The IO that will receive encrypted data
|
26
|
+
def initialize(iPassword, iSalt, oFile)
|
27
|
+
@Password, @Salt, @File = iPassword, iSalt, oFile
|
28
|
+
@Buffer = ''
|
29
|
+
end
|
30
|
+
|
31
|
+
# Add a string to write
|
32
|
+
#
|
33
|
+
# Parameters:
|
34
|
+
# * *iData* (_String_): The data to encrypt and write
|
35
|
+
def <<(iData)
|
36
|
+
# Add to the buffer
|
37
|
+
if (@Buffer.size + iData.size < BUFFER_SIZE)
|
38
|
+
@Buffer.concat(iData)
|
39
|
+
else
|
40
|
+
# Flush the completed buffer
|
41
|
+
lIdxData = BUFFER_SIZE-@Buffer.size
|
42
|
+
@Buffer.concat(iData[0..lIdxData-1])
|
43
|
+
flush
|
44
|
+
# And now flush new data buffers
|
45
|
+
@Buffer = iData[lIdxData..lIdxData+BUFFER_SIZE-1]
|
46
|
+
while (@Buffer.size == BUFFER_SIZE)
|
47
|
+
flush
|
48
|
+
lIdxData += BUFFER_SIZE
|
49
|
+
@Buffer = iData[lIdxData..lIdxData+BUFFER_SIZE-1]
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# Flush current data in the file
|
55
|
+
def flush
|
56
|
+
if (!@Buffer.empty?)
|
57
|
+
# Compress
|
58
|
+
lZippedData = Zlib::Deflate.new.deflate(@Buffer, Zlib::FINISH)
|
59
|
+
# Encrypt
|
60
|
+
lEncryptedData = EzCrypto::Key.encrypt_with_password(@Password, @Salt, lZippedData)
|
61
|
+
# Write
|
62
|
+
@File.write([lEncryptedData.size].pack('l'))
|
63
|
+
@File.write(lEncryptedData)
|
64
|
+
@Buffer = ''
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
# Class used to give the decoders a streaming interface
|
71
|
+
class StringReader
|
72
|
+
|
73
|
+
# Constructor
|
74
|
+
#
|
75
|
+
# Parameters:
|
76
|
+
# * *iPassword* (_String_): Password encrypting data
|
77
|
+
# * *iSalt* (_String_): Salt encoding data
|
78
|
+
# * *iFile* (_IO_): The IO that will send encrypted data
|
79
|
+
def initialize(iPassword, iSalt, iFile)
|
80
|
+
@Password, @Salt, @File = iPassword, iSalt, iFile
|
81
|
+
end
|
82
|
+
|
83
|
+
# Get the next string encrypted
|
84
|
+
#
|
85
|
+
# Return:
|
86
|
+
# * _String_: The next string encrypted (or nil if none)
|
87
|
+
def get
|
88
|
+
rObject = nil
|
89
|
+
|
90
|
+
# Read
|
91
|
+
lStrChunkSize = @File.read(4)
|
92
|
+
if (lStrChunkSize != nil)
|
93
|
+
lChunkSize = lStrChunkSize.unpack('l')[0]
|
94
|
+
lData = @File.read(lChunkSize)
|
95
|
+
# Decrypt
|
96
|
+
lDecryptedData = EzCrypto::Key.decrypt_with_password(@Password, @Salt, lData)
|
97
|
+
# Uncompress
|
98
|
+
rObject = Zlib::Inflate.new.inflate(lDecryptedData)
|
99
|
+
end
|
100
|
+
|
101
|
+
return rObject
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
TYPE_OBJECT = 'O'
|
107
|
+
TYPE_STRING = 'S'
|
108
|
+
|
109
|
+
# Class used to write a Ruby object
|
110
|
+
class ObjectWriter
|
111
|
+
|
112
|
+
# Constructor
|
113
|
+
#
|
114
|
+
# Parameters:
|
115
|
+
# * *iPassword* (_String_): Password encrypting data
|
116
|
+
# * *iSalt* (_String_): Salt encoding data
|
117
|
+
# * *oFile* (_IO_): The IO that will receive encrypted data
|
118
|
+
def initialize(iPassword, iSalt, oFile)
|
119
|
+
@StringWriter = StringWriter.new(iPassword, iSalt, oFile)
|
120
|
+
end
|
121
|
+
|
122
|
+
# Add an object to write
|
123
|
+
#
|
124
|
+
# Parameters:
|
125
|
+
# * *iObject* (_Object_): The object to write
|
126
|
+
def <<(iObject)
|
127
|
+
lStrType = nil
|
128
|
+
lStrObject = nil
|
129
|
+
if (iObject.is_a?(String))
|
130
|
+
lStrType = TYPE_STRING
|
131
|
+
lStrObject = iObject
|
132
|
+
else
|
133
|
+
lStrType = TYPE_OBJECT
|
134
|
+
lStrObject = Marshal.dump(iObject)
|
135
|
+
end
|
136
|
+
# Write it along with its length
|
137
|
+
@StringWriter << (lStrType + [lStrObject.size].pack('l') + lStrObject)
|
138
|
+
end
|
139
|
+
|
140
|
+
# Flush
|
141
|
+
def flush
|
142
|
+
@StringWriter.flush
|
143
|
+
end
|
144
|
+
|
145
|
+
end
|
146
|
+
|
147
|
+
# Class used to read a Ruby object
|
148
|
+
class ObjectReader
|
149
|
+
|
150
|
+
# Size of the object header
|
151
|
+
OBJECT_HEADER_SIZE = 5
|
152
|
+
|
153
|
+
# Constructor
|
154
|
+
#
|
155
|
+
# Parameters:
|
156
|
+
# * *iPassword* (_String_): Password encrypting data
|
157
|
+
# * *iSalt* (_String_): Salt encoding data
|
158
|
+
# * *iFile* (_IO_): The IO that will send encrypted data
|
159
|
+
def initialize(iPassword, iSalt, iFile)
|
160
|
+
@StringReader = StringReader.new(iPassword, iSalt, iFile)
|
161
|
+
@BufferRead = ''
|
162
|
+
end
|
163
|
+
|
164
|
+
# Get the next object encrypted
|
165
|
+
#
|
166
|
+
# Return:
|
167
|
+
# * _Object_: The next object encrypted (or nil if none)
|
168
|
+
def get
|
169
|
+
rObject = nil
|
170
|
+
|
171
|
+
# Read the size first
|
172
|
+
while (@BufferRead.size < OBJECT_HEADER_SIZE)
|
173
|
+
@BufferRead.concat(@StringReader.get)
|
174
|
+
end
|
175
|
+
lObjectType = @BufferRead[0..0]
|
176
|
+
lObjectSize = @BufferRead[1..OBJECT_HEADER_SIZE-1].unpack('l')[0]
|
177
|
+
# Then read the data
|
178
|
+
while (@BufferRead.size < OBJECT_HEADER_SIZE+lObjectSize)
|
179
|
+
@BufferRead.concat(@StringReader.get)
|
180
|
+
end
|
181
|
+
case lObjectType
|
182
|
+
when TYPE_OBJECT
|
183
|
+
rObject = Marshal.load(@BufferRead[OBJECT_HEADER_SIZE..OBJECT_HEADER_SIZE+lObjectSize-1])
|
184
|
+
when TYPE_STRING
|
185
|
+
rObject = @BufferRead[OBJECT_HEADER_SIZE..OBJECT_HEADER_SIZE+lObjectSize-1]
|
186
|
+
else
|
187
|
+
raise RuntimeError.new("Unknown object type: #{lObjectType}")
|
188
|
+
end
|
189
|
+
@BufferRead = @BufferRead[OBJECT_HEADER_SIZE+lObjectSize..-1]
|
190
|
+
|
191
|
+
return rObject
|
192
|
+
end
|
193
|
+
|
194
|
+
end
|
195
|
+
|
196
|
+
# Class used to write files and directories
|
197
|
+
class FilesWriter
|
198
|
+
|
199
|
+
# Size of the buffer used to write files contents
|
200
|
+
FILE_BUFFER_SIZE = 8388608
|
201
|
+
|
202
|
+
# Constructor
|
203
|
+
#
|
204
|
+
# Parameters:
|
205
|
+
# * *iPassword* (_String_): Password encrypting data
|
206
|
+
# * *iSalt* (_String_): Salt encoding data
|
207
|
+
# * *oFile* (_IO_): The IO that will receive encrypted data
|
208
|
+
def initialize(iPassword, iSalt, oFile)
|
209
|
+
@ObjectWriter = ObjectWriter.new(iPassword, iSalt, oFile)
|
210
|
+
# The list of empty directories
|
211
|
+
# list< String >
|
212
|
+
@EmptyDirs = []
|
213
|
+
# The list of files, along with their size
|
214
|
+
# list< [ String, Integer ] >
|
215
|
+
@LstFiles = []
|
216
|
+
# The total size of bytes
|
217
|
+
# Integer
|
218
|
+
@TotalSize = 0
|
219
|
+
end
|
220
|
+
|
221
|
+
# Add a single file to write
|
222
|
+
#
|
223
|
+
# Parameters:
|
224
|
+
# * *iFileName* (_String_): File to add
|
225
|
+
def addFile(iFileName)
|
226
|
+
lFileSize = File.size(iFileName)
|
227
|
+
@LstFiles << [ iFileName, lFileSize ]
|
228
|
+
@TotalSize += lFileSize
|
229
|
+
end
|
230
|
+
|
231
|
+
# Add a directory with all its recursive content
|
232
|
+
#
|
233
|
+
# Parameters:
|
234
|
+
# * *iDirName* (_String_): Name of the directory
|
235
|
+
def addDir(iDirName)
|
236
|
+
lEmpty = true
|
237
|
+
lRealDir = iDirName
|
238
|
+
if (iDirName == '')
|
239
|
+
lRealDir = '.'
|
240
|
+
end
|
241
|
+
Dir.foreach(lRealDir) do |iFileName|
|
242
|
+
if ((iFileName != '.') and
|
243
|
+
(iFileName != '..'))
|
244
|
+
lEmpty = false
|
245
|
+
lCompleteFileName = "#{iDirName}/#{iFileName}"
|
246
|
+
if (iDirName == '')
|
247
|
+
lCompleteFileName = iFileName
|
248
|
+
end
|
249
|
+
if (File.directory?(lCompleteFileName))
|
250
|
+
addDir(lCompleteFileName)
|
251
|
+
else
|
252
|
+
addFile(lCompleteFileName)
|
253
|
+
end
|
254
|
+
end
|
255
|
+
end
|
256
|
+
if (lEmpty)
|
257
|
+
@EmptyDirs << iDirName
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
# Add a files filter
|
262
|
+
#
|
263
|
+
# Parameters:
|
264
|
+
# * *iFilesFilter* (_String_): The files filter, to be used with glob
|
265
|
+
def addFiles(iFilesFilter)
|
266
|
+
Dir.glob(iFilesFilter).each do |iFileName|
|
267
|
+
if (!File.directory?(iFileName))
|
268
|
+
addFile(iFileName)
|
269
|
+
end
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
# Dump files to write on screen
|
274
|
+
def dump
|
275
|
+
logMsg "#{@EmptyDirs.size} empty directories:"
|
276
|
+
@EmptyDirs.each_with_index do |iDirName, iIdxDir|
|
277
|
+
logMsg "* [#{iIdxdir}]: #{iDirName}"
|
278
|
+
end
|
279
|
+
logMsg "#{@LstFiles.size} files (#{@TotalSize} bytes):"
|
280
|
+
@LstFiles.each_with_index do |iFileInfo, iIdxFile|
|
281
|
+
iFileName, iFileSize = iFileInfo
|
282
|
+
logMsg "* [#{iIdxFile}]: #{iFileName} (#{iFileSize} bytes)"
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
# Write everything in the file
|
287
|
+
def write
|
288
|
+
# First, the list of empty directories and the header
|
289
|
+
@ObjectWriter << [ @EmptyDirs, @LstFiles.size, @TotalSize ]
|
290
|
+
# Then each file
|
291
|
+
lEncodedSize = 0
|
292
|
+
@LstFiles.each do |iFileInfo|
|
293
|
+
iFileName, iFileSize = iFileInfo
|
294
|
+
lNbrChunks = iFileSize/FILE_BUFFER_SIZE
|
295
|
+
if (iFileSize % FILE_BUFFER_SIZE != 0)
|
296
|
+
lNbrChunks += 1
|
297
|
+
end
|
298
|
+
logDebug "Writing file #{iFileName} (#{iFileSize} bytes, #{lNbrChunks} chunks) ..."
|
299
|
+
@ObjectWriter << [ iFileName, lNbrChunks ]
|
300
|
+
File.open(iFileName, 'rb') do |iFile|
|
301
|
+
lNbrChunks.times do |iIdxChunk|
|
302
|
+
lFileDataChunk = iFile.read(FILE_BUFFER_SIZE)
|
303
|
+
@ObjectWriter << lFileDataChunk
|
304
|
+
lEncodedSize += lFileDataChunk.size
|
305
|
+
$stdout.write("#{(lEncodedSize*100)/@TotalSize} %\015")
|
306
|
+
end
|
307
|
+
end
|
308
|
+
end
|
309
|
+
@ObjectWriter.flush
|
310
|
+
end
|
311
|
+
|
312
|
+
end
|
313
|
+
|
314
|
+
# Class used to read files and directories
|
315
|
+
class FilesReader
|
316
|
+
|
317
|
+
# Constructor
|
318
|
+
#
|
319
|
+
# Parameters:
|
320
|
+
# * *iPassword* (_String_): Password encrypting data
|
321
|
+
# * *iSalt* (_String_): Salt encoding data
|
322
|
+
# * *iFile* (_IO_): The IO that will send encrypted data
|
323
|
+
def initialize(iPassword, iSalt, iFile)
|
324
|
+
@ObjectReader = ObjectReader.new(iPassword, iSalt, iFile)
|
325
|
+
end
|
326
|
+
|
327
|
+
# Read the files and write them in the current directory
|
328
|
+
def read
|
329
|
+
# First, read the archive header
|
330
|
+
lEmptyDirs, lNbrFiles, lTotalSize = @ObjectReader.get
|
331
|
+
# Create the empty directories
|
332
|
+
lEmptyDirs.each do |iDirName|
|
333
|
+
FileUtils::mkdir_p(iDirName)
|
334
|
+
end
|
335
|
+
# Read each file
|
336
|
+
lDecodedSize = 0
|
337
|
+
lNbrFiles.times do |iIdxFile|
|
338
|
+
lFileName, lNbrChunks = @ObjectReader.get
|
339
|
+
logDebug "Reading file #{lFileName} (#{lNbrChunks} chunks) ..."
|
340
|
+
FileUtils::mkdir_p(File.dirname(lFileName))
|
341
|
+
File.open(lFileName, 'wb') do |oFile|
|
342
|
+
lNbrChunks.times do |iIdxChunk|
|
343
|
+
lFileDataChunk = @ObjectReader.get
|
344
|
+
oFile.write(lFileDataChunk)
|
345
|
+
lDecodedSize += lFileDataChunk.size
|
346
|
+
$stdout.write("#{(lDecodedSize*100)/lTotalSize} %\015")
|
347
|
+
end
|
348
|
+
end
|
349
|
+
end
|
350
|
+
end
|
351
|
+
|
352
|
+
end
|
353
|
+
|
354
|
+
end
|
355
|
+
|
356
|
+
end
|
@@ -0,0 +1,149 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2009-2010 Muriel Salvan (murielsalvan@users.sourceforge.net)
|
3
|
+
# Licensed under the terms specified in LICENSE file. No warranty is provided.
|
4
|
+
#++
|
5
|
+
|
6
|
+
module RUtilAnts
|
7
|
+
|
8
|
+
module Platform
|
9
|
+
|
10
|
+
class PlatformInfo
|
11
|
+
|
12
|
+
# Return the ID of the OS
|
13
|
+
# Applications may adapt their behavior based on it.
|
14
|
+
#
|
15
|
+
# Return:
|
16
|
+
# * _Integer_: OS ID
|
17
|
+
def os
|
18
|
+
return OS_WINDOWS
|
19
|
+
end
|
20
|
+
|
21
|
+
# Return the list of directories where we look for executables
|
22
|
+
#
|
23
|
+
# Return:
|
24
|
+
# * <em>list<String></em>: List of directories
|
25
|
+
def getSystemExePath
|
26
|
+
return ENV['PATH'].split(';')
|
27
|
+
end
|
28
|
+
|
29
|
+
# Set the list of directories where we look for executables
|
30
|
+
#
|
31
|
+
# Parameters:
|
32
|
+
# * *iNewDirsList* (<em>list<String></em>): List of directories
|
33
|
+
def setSystemExePath(iNewDirsList)
|
34
|
+
ENV['PATH'] = iNewDirsList.join(';')
|
35
|
+
end
|
36
|
+
|
37
|
+
# Return the list of file extensions that might be discretely happened to executable files.
|
38
|
+
# This is the optional extensions that can be happened when invoked from a terminal.
|
39
|
+
#
|
40
|
+
# Return:
|
41
|
+
# * <em>list<String></em>: List of extensions (including .)
|
42
|
+
def getDiscreteExeExtensions
|
43
|
+
rExtList = []
|
44
|
+
|
45
|
+
ENV['PATHEXT'].split(';').each do |iExt|
|
46
|
+
rExtList << iExt.downcase
|
47
|
+
end
|
48
|
+
|
49
|
+
return rExtList
|
50
|
+
end
|
51
|
+
|
52
|
+
# Return the list of directories where we look for libraries
|
53
|
+
#
|
54
|
+
# Return:
|
55
|
+
# * <em>list<String></em>: List of directories
|
56
|
+
def getSystemLibsPath
|
57
|
+
return ENV['PATH'].split(';')
|
58
|
+
end
|
59
|
+
|
60
|
+
# Set the list of directories where we look for libraries
|
61
|
+
#
|
62
|
+
# Parameters:
|
63
|
+
# * *iNewDirsList* (<em>list<String></em>): List of directories
|
64
|
+
def setSystemLibsPath(iNewDirsList)
|
65
|
+
ENV['PATH'] = iNewDirsList.join(';')
|
66
|
+
end
|
67
|
+
|
68
|
+
# This method sends a message (platform dependent) to the user, without the use of wxruby
|
69
|
+
#
|
70
|
+
# Parameters:
|
71
|
+
# * *iMsg* (_String_): The message to display
|
72
|
+
def sendMsg(iMsg)
|
73
|
+
# iMsg must not be longer than 255 characters
|
74
|
+
# \n must be escaped.
|
75
|
+
if (iMsg.size > 255)
|
76
|
+
system("msg \"#{ENV['USERNAME']}\" /W \"#{iMsg[0..254]}\"")
|
77
|
+
else
|
78
|
+
system("msg \"#{ENV['USERNAME']}\" /W \"#{iMsg}\"")
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
# Execute a Shell command.
|
83
|
+
# Do not wait for its termination.
|
84
|
+
#
|
85
|
+
# Parameters:
|
86
|
+
# * *iCmd* (_String_): The command to execute
|
87
|
+
# * *iInTerminal* (_Boolean_): Do we execute this command in a separate terminal ?
|
88
|
+
# Return:
|
89
|
+
# * _Exception_: Error, or nil if success
|
90
|
+
def execShellCmdNoWait(iCmd, iInTerminal)
|
91
|
+
rException = nil
|
92
|
+
|
93
|
+
if (iInTerminal)
|
94
|
+
if (!system("start cmd /c #{iCmd}"))
|
95
|
+
rException = RuntimeError.new
|
96
|
+
end
|
97
|
+
else
|
98
|
+
begin
|
99
|
+
IO.popen(iCmd)
|
100
|
+
rescue Exception
|
101
|
+
rException = $!
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
return rException
|
106
|
+
end
|
107
|
+
|
108
|
+
# Execute a given URL to be launched in a browser
|
109
|
+
#
|
110
|
+
# Parameters:
|
111
|
+
# * *iURL* (_String_): The URL to launch
|
112
|
+
# Return:
|
113
|
+
# * _String_: Error message, or nil if success
|
114
|
+
def launchURL(iURL)
|
115
|
+
rError = nil
|
116
|
+
|
117
|
+
# We must put " around the URL after the http:// prefix, as otherwise & symbol will not be recognized
|
118
|
+
lMatch = iURL.match(/^(http|https|ftp|ftps):\/\/(.*)$/)
|
119
|
+
if (lMatch == nil)
|
120
|
+
rError = "URL #{iURL} is not one of http://, https://, ftp:// or ftps://. Can't invoke it."
|
121
|
+
else
|
122
|
+
IO.popen("start #{lMatch[1]}://\"#{lMatch[2]}\"")
|
123
|
+
end
|
124
|
+
|
125
|
+
return rError
|
126
|
+
end
|
127
|
+
|
128
|
+
# Get file extensions specifics to executable files
|
129
|
+
#
|
130
|
+
# Return:
|
131
|
+
# * <em>list<String></em>: List of extensions (including . character). It can be empty.
|
132
|
+
def getExecutableExtensions
|
133
|
+
# TODO: Use PATHEXT environment variable if possible
|
134
|
+
return [ '.exe', '.com', '.bat' ]
|
135
|
+
end
|
136
|
+
|
137
|
+
# Get prohibited characters from file names
|
138
|
+
#
|
139
|
+
# Return:
|
140
|
+
# * _String_: String of prohibited characters in file names
|
141
|
+
def getProhibitedFileNamesCharacters
|
142
|
+
return '\\/:*?"<>|'
|
143
|
+
end
|
144
|
+
|
145
|
+
end
|
146
|
+
|
147
|
+
end
|
148
|
+
|
149
|
+
end
|
@@ -130,6 +130,7 @@ module RUtilAnts
|
|
130
130
|
# Return:
|
131
131
|
# * <em>list<String></em>: List of extensions (including . character). It can be empty.
|
132
132
|
def getExecutableExtensions
|
133
|
+
# TODO: Use PATHEXT environment variable if possible
|
133
134
|
return [ '.exe', '.com', '.bat' ]
|
134
135
|
end
|
135
136
|
|
metadata
CHANGED
@@ -5,9 +5,9 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 2
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.2.
|
8
|
+
- 2
|
9
|
+
- 20101125
|
10
|
+
version: 0.2.2.20101125
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Muriel Salvan
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-11-
|
18
|
+
date: 2010-11-25 00:00:00 +01:00
|
19
19
|
default_executable:
|
20
20
|
dependencies: []
|
21
21
|
|
@@ -28,31 +28,33 @@ extensions: []
|
|
28
28
|
extra_rdoc_files: []
|
29
29
|
|
30
30
|
files:
|
31
|
-
-
|
32
|
-
-
|
33
|
-
-
|
34
|
-
- lib/rUtilAnts/
|
31
|
+
- AUTHORS
|
32
|
+
- ChangeLog
|
33
|
+
- Credits
|
34
|
+
- lib/rUtilAnts/Archive.rb
|
35
|
+
- lib/rUtilAnts/ForeignProcess.rb
|
35
36
|
- lib/rUtilAnts/GUI/Bug.png
|
36
37
|
- lib/rUtilAnts/GUI/BugReportDialog.rb
|
38
|
+
- lib/rUtilAnts/GUI.rb
|
39
|
+
- lib/rUtilAnts/Logging.rb
|
40
|
+
- lib/rUtilAnts/Misc.rb
|
41
|
+
- lib/rUtilAnts/Platform.rb
|
42
|
+
- lib/rUtilAnts/Platforms/i386-cygwin/PlatformInfo.rb
|
37
43
|
- lib/rUtilAnts/Platforms/i386-linux/PlatformInfo.rb
|
44
|
+
- lib/rUtilAnts/Platforms/i386-mingw32/PlatformInfo.rb
|
38
45
|
- lib/rUtilAnts/Platforms/i386-mswin32/PlatformInfo.rb
|
39
46
|
- lib/rUtilAnts/Platforms/x86_64-linux/PlatformInfo.rb
|
40
|
-
- lib/rUtilAnts/Platforms/i386-cygwin/PlatformInfo.rb
|
41
47
|
- lib/rUtilAnts/Plugins.rb
|
42
|
-
- lib/rUtilAnts/GUI.rb
|
43
|
-
- lib/rUtilAnts/Platform.rb
|
44
48
|
- lib/rUtilAnts/URLAccess.rb
|
45
|
-
- lib/rUtilAnts/Logging.rb
|
46
49
|
- lib/rUtilAnts/URLCache.rb
|
47
|
-
- lib/rUtilAnts/
|
48
|
-
- lib/rUtilAnts/
|
49
|
-
-
|
50
|
-
-
|
50
|
+
- lib/rUtilAnts/URLHandlers/DataImage.rb
|
51
|
+
- lib/rUtilAnts/URLHandlers/FTP.rb
|
52
|
+
- lib/rUtilAnts/URLHandlers/HTTP.rb
|
53
|
+
- lib/rUtilAnts/URLHandlers/LocalFile.rb
|
51
54
|
- LICENSE
|
52
|
-
-
|
53
|
-
-
|
55
|
+
- README
|
56
|
+
- ReleaseInfo
|
54
57
|
- TODO
|
55
|
-
- ChangeLog
|
56
58
|
has_rdoc: true
|
57
59
|
homepage: http://rutilants.sourceforge.net/
|
58
60
|
licenses: []
|
@@ -63,6 +65,7 @@ rdoc_options: []
|
|
63
65
|
require_paths:
|
64
66
|
- lib
|
65
67
|
required_ruby_version: !ruby/object:Gem::Requirement
|
68
|
+
none: false
|
66
69
|
requirements:
|
67
70
|
- - ">="
|
68
71
|
- !ruby/object:Gem::Version
|
@@ -70,6 +73,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
70
73
|
- 0
|
71
74
|
version: "0"
|
72
75
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
76
|
+
none: false
|
73
77
|
requirements:
|
74
78
|
- - ">="
|
75
79
|
- !ruby/object:Gem::Version
|
@@ -79,7 +83,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
79
83
|
requirements: []
|
80
84
|
|
81
85
|
rubyforge_project: rutilants
|
82
|
-
rubygems_version: 1.3.
|
86
|
+
rubygems_version: 1.3.7
|
83
87
|
signing_key:
|
84
88
|
specification_version: 3
|
85
89
|
summary: A collection of various utility libraries.
|