rUtilAnts 0.2.1.20101110 → 0.2.2.20101125
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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.
|