rUtilAnts 0.1.1.20091105 → 0.2.0.20101109
Sign up to get free protection for your applications and to get access to all the features.
- data/ReleaseInfo +1 -1
- data/lib/rUtilAnts/ForeignProcess.rb +205 -0
- data/lib/rUtilAnts/GUI.rb +1 -1
- data/lib/rUtilAnts/Logging.rb +158 -32
- data/lib/rUtilAnts/Misc.rb +19 -1
- data/lib/rUtilAnts/Platform.rb +7 -3
- data/lib/rUtilAnts/Platforms/i386-mswin32/PlatformInfo.rb +12 -5
- data/lib/rUtilAnts/Platforms/x86_64-linux/PlatformInfo.rb +149 -0
- data/lib/rUtilAnts/URLAccess.rb +9 -5
- data/lib/rUtilAnts/URLHandlers/HTTP.rb +2 -1
- metadata +29 -19
data/ReleaseInfo
CHANGED
@@ -0,0 +1,205 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 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
|
+
# This module defines a method to run a given Ruby's object and parameters in a separate process.
|
9
|
+
# This can be useful when $LD_LIBRARY_PATH has to be changed before continuing.
|
10
|
+
module ForeignProcess
|
11
|
+
|
12
|
+
# Class containing info for serialized method calls
|
13
|
+
class MethodCallInfo
|
14
|
+
|
15
|
+
# Log file
|
16
|
+
# String
|
17
|
+
attr_accessor :LogFile
|
18
|
+
|
19
|
+
# Lib root dir
|
20
|
+
# String
|
21
|
+
attr_accessor :LibRootDir
|
22
|
+
|
23
|
+
# Bug tracker URL
|
24
|
+
# String
|
25
|
+
attr_accessor :BugTrackerURL
|
26
|
+
|
27
|
+
# Load path
|
28
|
+
# list<String>
|
29
|
+
attr_accessor :LoadPath
|
30
|
+
|
31
|
+
# List of files to require
|
32
|
+
# list<String>
|
33
|
+
attr_accessor :RequireFiles
|
34
|
+
|
35
|
+
# Serialized MethodDetails
|
36
|
+
# It is stored serialized as to unserialize it we first need to unserialize the RequireFiles
|
37
|
+
# String
|
38
|
+
attr_accessor :SerializedMethodDetails
|
39
|
+
|
40
|
+
class MethodDetails
|
41
|
+
|
42
|
+
# Object to call the function on
|
43
|
+
# Object
|
44
|
+
attr_accessor :Object
|
45
|
+
|
46
|
+
# Method to call
|
47
|
+
# Symbol
|
48
|
+
attr_accessor :Method
|
49
|
+
|
50
|
+
# Parameters
|
51
|
+
# list<Object>
|
52
|
+
attr_accessor :Parameters
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
# Execute a command in another Ruby session, executing some Shell commands before invocation.
|
59
|
+
#
|
60
|
+
# Parameters:
|
61
|
+
# * *iShellCmd* (_String_): Shell command to invoke before Ruby
|
62
|
+
# * *iObject* (_Object_): Object that will have a function to call in the new session
|
63
|
+
# * *iMethod* (_Symbol_): Method to call on the object
|
64
|
+
# * *Parameters* (<em>list<Object></em>): Remaining parameters
|
65
|
+
# Return:
|
66
|
+
# * _Exception_: An error, or nil if success
|
67
|
+
# * _Object_: The result of the function call (valid only if no error returned)
|
68
|
+
def self.execCmdOtherSession(iShellCmd, iObject, iMethod, iParameters)
|
69
|
+
rError = nil
|
70
|
+
rResult = nil
|
71
|
+
|
72
|
+
# Protect it from exceptions, to ensure that a valid error message will be returned
|
73
|
+
begin
|
74
|
+
logDebug "Execute method #{iMethod}(#{iParameters.join(', ')}) in a new process with shell command: #{iShellCmd} ..."
|
75
|
+
|
76
|
+
# Create an object that we will serialize, containing all needed information for the session
|
77
|
+
lInfo = MethodCallInfo.new
|
78
|
+
lInfo.LogFile = getLogFile
|
79
|
+
lInfo.LibRootDir = getLibRootDir
|
80
|
+
lInfo.BugTrackerURL = getBugTrackerURL
|
81
|
+
lInfo.RequireFiles = []
|
82
|
+
# Do not store ForeignProcess require
|
83
|
+
$".each do |iRequireName|
|
84
|
+
if (iRequireName.match(/ForeignProcess/) == nil)
|
85
|
+
lInfo.RequireFiles << iRequireName
|
86
|
+
end
|
87
|
+
end
|
88
|
+
lInfo.LoadPath = $LOAD_PATH.clone
|
89
|
+
lMethodDetails = MethodCallInfo::MethodDetails.new
|
90
|
+
lMethodDetails.Parameters = iParameters
|
91
|
+
lMethodDetails.Method = iMethod
|
92
|
+
lMethodDetails.Object = iObject
|
93
|
+
logDebug "Method to be marshalled: #{lMethodDetails.inspect}"
|
94
|
+
lInfo.SerializedMethodDetails = Marshal.dump(lMethodDetails)
|
95
|
+
lCurrentThread = Thread.current
|
96
|
+
# Dump this object in a temporary file
|
97
|
+
require 'tmpdir'
|
98
|
+
lInfoFileName = "#{Dir.tmpdir}/RubyExec_#{lCurrentThread.object_id}_Info"
|
99
|
+
File.open(lInfoFileName, 'w') do |oFile|
|
100
|
+
oFile.write(Marshal.dump(lInfo))
|
101
|
+
end
|
102
|
+
# For security reasons, ensure that only us can read this file. It can contain passwords.
|
103
|
+
require 'fileutils'
|
104
|
+
FileUtils.chmod(0700, lInfoFileName)
|
105
|
+
# Generate the Ruby file that will run everything
|
106
|
+
lExecFileName = "#{Dir.tmpdir}/RubyExec_#{lCurrentThread.object_id}_Exec.rb"
|
107
|
+
File.open(lExecFileName, 'w') do |oFile|
|
108
|
+
oFile << "
|
109
|
+
\# This is a generated file that should not stay persistent. You can delete it.
|
110
|
+
\# It has been generated by rUtilAnts::ForeignProcess module. Check http://rutilants.sourceforge.net for further details.
|
111
|
+
require '#{File.expand_path(__FILE__)}'
|
112
|
+
RUtilAnts::ForeignProcess::executeEmbeddedFunction(ARGV[0], ARGV[1])
|
113
|
+
"
|
114
|
+
end
|
115
|
+
# For security reasons, ensure that only us can read and execute this file.
|
116
|
+
FileUtils.chmod(0700, lExecFileName)
|
117
|
+
# Name the file that will receive the result of the function call
|
118
|
+
lResultFileName = "#{Dir.tmpdir}/RubyExec_#{lCurrentThread.object_id}_Result"
|
119
|
+
|
120
|
+
# Call this Ruby file by first executing the Shell command
|
121
|
+
lCmd = "#{iShellCmd}; ruby -w #{lExecFileName} #{lInfoFileName} #{lResultFileName} 2>&1"
|
122
|
+
lOutput = `#{lCmd}`
|
123
|
+
lErrorCode = $?
|
124
|
+
if (lErrorCode == 0)
|
125
|
+
# Read the result file
|
126
|
+
File.open(lResultFileName, 'r') do |iFile|
|
127
|
+
rResult = Marshal.load(iFile.read)
|
128
|
+
end
|
129
|
+
else
|
130
|
+
rError = RuntimeError.new("Error while running command \"#{lCmd}\". Here is the output:\n#{lOutput}.")
|
131
|
+
end
|
132
|
+
|
133
|
+
# Remove files
|
134
|
+
File.unlink(lInfoFileName)
|
135
|
+
File.unlink(lExecFileName)
|
136
|
+
if (File.exists?(lResultFileName))
|
137
|
+
File.unlink(lResultFileName)
|
138
|
+
end
|
139
|
+
rescue Exception
|
140
|
+
rError = $!
|
141
|
+
end
|
142
|
+
|
143
|
+
logDebug "Method executed with error #{rError} and result #{rResult}."
|
144
|
+
|
145
|
+
return rError, rResult
|
146
|
+
end
|
147
|
+
|
148
|
+
# Execute a function along with its parameters stored in a file.
|
149
|
+
# This method is used by the file generated by execCmdOtherSession.
|
150
|
+
# It should not be called directly.
|
151
|
+
#
|
152
|
+
# Parameters:
|
153
|
+
# * *iInfoFileName* (_String_): The file containing info
|
154
|
+
# * *iResultFileName* (_String_): The file used to store the result serialized
|
155
|
+
def self.executeEmbeddedFunction(iInfoFileName, iResultFileName)
|
156
|
+
begin
|
157
|
+
# Read the file
|
158
|
+
lInfo = nil
|
159
|
+
File.open(iInfoFileName, 'r') do |iFile|
|
160
|
+
lInfo = Marshal.load(iFile.read)
|
161
|
+
end
|
162
|
+
# Set the load path
|
163
|
+
lInfo.LoadPath.each do |iDir|
|
164
|
+
if (!$LOAD_PATH.include?(iDir))
|
165
|
+
$LOAD_PATH << iDir
|
166
|
+
end
|
167
|
+
end
|
168
|
+
# Require all given files
|
169
|
+
lInfo.RequireFiles.each do |iRequireName|
|
170
|
+
require iRequireName
|
171
|
+
end
|
172
|
+
# Initialize logging
|
173
|
+
RUtilAnts::Logging::initializeLogging(lInfo.LibRootDir, lInfo.BugTrackerURL)
|
174
|
+
setLogFile(lInfo.LogFile)
|
175
|
+
logDebug "New process spawned with requires: #{lInfo.RequireFiles.join(', ')}."
|
176
|
+
# Unserialize the method details
|
177
|
+
lMethodDetails = Marshal.load(lInfo.SerializedMethodDetails)
|
178
|
+
# Call the method on the object with all its parameters
|
179
|
+
logDebug "Calling method #{lMethodDetails.Method}(#{lMethodDetails.Parameters.join(', ')}) ..."
|
180
|
+
lResult = lMethodDetails.Object.send(lMethodDetails.Method, *lMethodDetails.Parameters)
|
181
|
+
logDebug "Method returned #{lResult}."
|
182
|
+
rescue Exception
|
183
|
+
lResult = RuntimeError.new("Error occurred while executing foreign call: #{$!}. Backtrace: #{$!.backtrace.join("\n")}")
|
184
|
+
end
|
185
|
+
begin
|
186
|
+
# Store the result in the file for return
|
187
|
+
File.open(iResultFileName, 'w') do |oFile|
|
188
|
+
oFile.write(Marshal.dump(lResult))
|
189
|
+
end
|
190
|
+
# For security reasons, ensure that only us can read this file. It can contain passwords.
|
191
|
+
require 'fileutils'
|
192
|
+
FileUtils.chmod(0700, iResultFileName)
|
193
|
+
rescue Exception
|
194
|
+
logErr "Error while writing result in to #{iResultFileName}: #{$!}."
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
# Initialize the ForeignProcess methods in the Object namespace
|
199
|
+
def self.initializeForeignProcess
|
200
|
+
Object.module_eval('include RUtilAnts::ForeignProcess')
|
201
|
+
end
|
202
|
+
|
203
|
+
end
|
204
|
+
|
205
|
+
end
|
data/lib/rUtilAnts/GUI.rb
CHANGED
data/lib/rUtilAnts/Logging.rb
CHANGED
@@ -65,6 +65,22 @@ module RUtilAnts
|
|
65
65
|
end
|
66
66
|
end
|
67
67
|
|
68
|
+
# Mute or unmute standard output
|
69
|
+
#
|
70
|
+
# Parameters:
|
71
|
+
# * *iMute* (_Boolean_): Do we mute standard output ? [optional = true]
|
72
|
+
def muteStdOut(iMute = true)
|
73
|
+
@ScreenOutput = (!iMute)
|
74
|
+
end
|
75
|
+
|
76
|
+
# Mute or unmute error output
|
77
|
+
#
|
78
|
+
# Parameters:
|
79
|
+
# * *iMute* (_Boolean_): Do we mute error output ? [optional = true]
|
80
|
+
def muteStdErr(iMute = true)
|
81
|
+
@ScreenOutputErr = (!iMute)
|
82
|
+
end
|
83
|
+
|
68
84
|
# Set the log file to use (can be nil to stop logging into a file)
|
69
85
|
#
|
70
86
|
# Parameters:
|
@@ -73,6 +89,30 @@ module RUtilAnts
|
|
73
89
|
@LogFile = iFileName
|
74
90
|
end
|
75
91
|
|
92
|
+
# Get the log file used (can be nil)
|
93
|
+
#
|
94
|
+
# Return:
|
95
|
+
# * _String_: Log file name (can be nil)
|
96
|
+
def getLogFile
|
97
|
+
return @LogFile
|
98
|
+
end
|
99
|
+
|
100
|
+
# Get the library root dir
|
101
|
+
#
|
102
|
+
# Return:
|
103
|
+
# * _String_: The library root dir, as defined when initialized
|
104
|
+
def getLibRootDir
|
105
|
+
return @LibRootDir
|
106
|
+
end
|
107
|
+
|
108
|
+
# Get the bug tracker URL
|
109
|
+
#
|
110
|
+
# Return:
|
111
|
+
# * _String_: The bug tracker URL, as defined when initialized
|
112
|
+
def getBugTrackerURL
|
113
|
+
return @BugTrackerURL
|
114
|
+
end
|
115
|
+
|
76
116
|
# Indicate which GUI to be used to display dialogs.
|
77
117
|
#
|
78
118
|
# Parameters:
|
@@ -86,14 +126,24 @@ module RUtilAnts
|
|
86
126
|
# Parameters:
|
87
127
|
# * *iDebugMode* (_Boolean_): Are we in debug mode ?
|
88
128
|
def activateLogDebug(iDebugMode)
|
89
|
-
@DebugMode
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
129
|
+
if (@DebugMode != iDebugMode)
|
130
|
+
@DebugMode = iDebugMode
|
131
|
+
if (iDebugMode)
|
132
|
+
logInfo 'Activated log debug'
|
133
|
+
else
|
134
|
+
logInfo 'Deactivated log debug'
|
135
|
+
end
|
94
136
|
end
|
95
137
|
end
|
96
138
|
|
139
|
+
# Is debug mode activated ?
|
140
|
+
#
|
141
|
+
# Return:
|
142
|
+
# * _Boolean_: Are we in debug mode ?
|
143
|
+
def debugActivated?
|
144
|
+
return @DebugMode
|
145
|
+
end
|
146
|
+
|
97
147
|
# Set the stack of the errors to fill.
|
98
148
|
# If set to nil, errors will be displayed as they appear.
|
99
149
|
# If set to a stack, errors will silently be added to the list.
|
@@ -147,7 +197,7 @@ Stack:
|
|
147
197
|
# Display Bug dialog
|
148
198
|
if (showModalWxAvailable?)
|
149
199
|
# We require the file here, as we hope it will not be required often
|
150
|
-
require '
|
200
|
+
require 'rUtilAnts/GUI/BugReportDialog'
|
151
201
|
showModal(GUI::BugReportDialog, nil, lCompleteMsg, @BugTrackerURL) do |iModalResult, iDialog|
|
152
202
|
# Nothing to do
|
153
203
|
end
|
@@ -175,12 +225,13 @@ Details:
|
|
175
225
|
# Parameters:
|
176
226
|
# * *iMsg* (_String_): Message to log
|
177
227
|
def logErr(iMsg)
|
228
|
+
lMsg = "!!! ERR !!! #{iMsg}"
|
178
229
|
# Log into stderr
|
179
230
|
if (@ScreenOutputErr)
|
180
|
-
$stderr << "
|
231
|
+
$stderr << "#{lMsg}\n"
|
181
232
|
end
|
182
233
|
if (@LogFile != nil)
|
183
|
-
logFile(
|
234
|
+
logFile(lMsg)
|
184
235
|
end
|
185
236
|
# Display dialog only if we are not redirecting messages to a stack
|
186
237
|
if (@ErrorsStack == nil)
|
@@ -249,6 +300,22 @@ Details:
|
|
249
300
|
end
|
250
301
|
end
|
251
302
|
|
303
|
+
# Log a warning.
|
304
|
+
# Warnings are not errors but still should be highlighted.
|
305
|
+
#
|
306
|
+
# Parameters:
|
307
|
+
# * *iMsg* (_String_): Message to log
|
308
|
+
def logWarn(iMsg)
|
309
|
+
# Log into stdout
|
310
|
+
lMsg = "!!! WARNING !!! - #{iMsg}"
|
311
|
+
if (@ScreenOutput)
|
312
|
+
$stdout << "#{lMsg}\n"
|
313
|
+
end
|
314
|
+
if (@LogFile != nil)
|
315
|
+
logFile(lMsg)
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
252
319
|
# Log a debugging info.
|
253
320
|
# This is used when debug is activated
|
254
321
|
#
|
@@ -292,36 +359,38 @@ Details:
|
|
292
359
|
# Remove @LibRootDir paths from it.
|
293
360
|
#
|
294
361
|
# Parameters:
|
295
|
-
# * *iCaller* (<em>list<String></em>): The caller
|
362
|
+
# * *iCaller* (<em>list<String></em>): The caller, or nil if no caller
|
296
363
|
# * *iReferenceCaller* (<em>list<String></em>): The reference caller: we will not display lines from iCaller that also belong to iReferenceCaller [optional = nil]
|
297
364
|
# Return:
|
298
365
|
# * <em>list<String></em>): The simple stack
|
299
366
|
def getSimpleCaller(iCaller, iReferenceCaller = nil)
|
300
367
|
rSimpleCaller = []
|
301
368
|
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
lIdxCaller = iCaller.size - 1
|
308
|
-
lIdxRef = iReferenceCaller.size - 1
|
309
|
-
while ((lIdxCaller >= 0) and
|
310
|
-
(lIdxRef >= 0) and
|
311
|
-
(iCaller[lIdxCaller] == iReferenceCaller[lIdxRef]))
|
312
|
-
lIdxCaller -= 1
|
313
|
-
lIdxRef -= 1
|
314
|
-
end
|
315
|
-
# Here we have either one of the indexes that is -1, or the indexes point to different lines between the caller and its reference.
|
316
|
-
lCaller = iCaller[0..lIdxCaller+1]
|
317
|
-
end
|
318
|
-
lCaller.each do |iCallerLine|
|
319
|
-
lMatch = iCallerLine.match(/^(.*):([[:digit:]]*):in (.*)$/)
|
320
|
-
if (lMatch == nil)
|
321
|
-
# Did not get which format. Just add it blindly.
|
322
|
-
rSimpleCaller << iCallerLine
|
369
|
+
if (iCaller != nil)
|
370
|
+
lCaller = nil
|
371
|
+
# If there is a reference caller, remove the lines from lCaller that are also in iReferenceCaller
|
372
|
+
if (iReferenceCaller == nil)
|
373
|
+
lCaller = iCaller
|
323
374
|
else
|
324
|
-
|
375
|
+
lIdxCaller = iCaller.size - 1
|
376
|
+
lIdxRef = iReferenceCaller.size - 1
|
377
|
+
while ((lIdxCaller >= 0) and
|
378
|
+
(lIdxRef >= 0) and
|
379
|
+
(iCaller[lIdxCaller] == iReferenceCaller[lIdxRef]))
|
380
|
+
lIdxCaller -= 1
|
381
|
+
lIdxRef -= 1
|
382
|
+
end
|
383
|
+
# Here we have either one of the indexes that is -1, or the indexes point to different lines between the caller and its reference.
|
384
|
+
lCaller = iCaller[0..lIdxCaller+1]
|
385
|
+
end
|
386
|
+
lCaller.each do |iCallerLine|
|
387
|
+
lMatch = iCallerLine.match(/^(.*):([[:digit:]]*):in (.*)$/)
|
388
|
+
if (lMatch == nil)
|
389
|
+
# Did not get which format. Just add it blindly.
|
390
|
+
rSimpleCaller << iCallerLine
|
391
|
+
else
|
392
|
+
rSimpleCaller << "#{File.expand_path(lMatch[1]).gsub(@LibRootDir, '')}:#{lMatch[2]}:in #{lMatch[3]}"
|
393
|
+
end
|
325
394
|
end
|
326
395
|
end
|
327
396
|
|
@@ -340,10 +409,26 @@ Details:
|
|
340
409
|
# * *iSilentOutputs* (_Boolean_): Do we silent outputs (nothing sent to $stdout or $stderr) ? [optional = false]
|
341
410
|
def self.initializeLogging(iLibRootDir, iBugTrackerURL, iSilentOutputs = false)
|
342
411
|
$rUtilAnts_Logging_Logger = RUtilAnts::Logging::Logger.new(iLibRootDir, iBugTrackerURL, iSilentOutputs)
|
343
|
-
# Add the module accessible from the
|
412
|
+
# Add the module accessible from the Object namespace
|
344
413
|
Object.module_eval('include RUtilAnts::Logging')
|
345
414
|
end
|
346
415
|
|
416
|
+
# Mute or unmute standard output
|
417
|
+
#
|
418
|
+
# Parameters:
|
419
|
+
# * *iMute* (_Boolean_): Do we mute standard output ? [optional = true]
|
420
|
+
def muteStdOut(iMute = true)
|
421
|
+
$rUtilAnts_Logging_Logger.muteStdOut(iMute)
|
422
|
+
end
|
423
|
+
|
424
|
+
# Mute or unmute error output
|
425
|
+
#
|
426
|
+
# Parameters:
|
427
|
+
# * *iMute* (_Boolean_): Do we mute error output ? [optional = true]
|
428
|
+
def muteStdErr(iMute = true)
|
429
|
+
$rUtilAnts_Logging_Logger.muteStdErr(iMute)
|
430
|
+
end
|
431
|
+
|
347
432
|
# Set the log file to use (can be nil to stop logging into a file)
|
348
433
|
#
|
349
434
|
# Parameters:
|
@@ -352,6 +437,30 @@ Details:
|
|
352
437
|
$rUtilAnts_Logging_Logger.setLogFile(iFileName)
|
353
438
|
end
|
354
439
|
|
440
|
+
# Get the log file used (can be nil)
|
441
|
+
#
|
442
|
+
# Return:
|
443
|
+
# * _String_: Log file name (can be nil)
|
444
|
+
def getLogFile
|
445
|
+
return $rUtilAnts_Logging_Logger.getLogFile
|
446
|
+
end
|
447
|
+
|
448
|
+
# Get the library root dir
|
449
|
+
#
|
450
|
+
# Return:
|
451
|
+
# * _String_: The library root dir, as defined when initialized
|
452
|
+
def getLibRootDir
|
453
|
+
return $rUtilAnts_Logging_Logger.getLibRootDir
|
454
|
+
end
|
455
|
+
|
456
|
+
# Get the bug tracker URL
|
457
|
+
#
|
458
|
+
# Return:
|
459
|
+
# * _String_: The bug tracker URL, as defined when initialized
|
460
|
+
def getBugTrackerURL
|
461
|
+
return $rUtilAnts_Logging_Logger.getBugTrackerURL
|
462
|
+
end
|
463
|
+
|
355
464
|
# Indicate which GUI to be used to display dialogs.
|
356
465
|
#
|
357
466
|
# Parameters:
|
@@ -368,6 +477,14 @@ Details:
|
|
368
477
|
$rUtilAnts_Logging_Logger.activateLogDebug(iDebugMode)
|
369
478
|
end
|
370
479
|
|
480
|
+
# Is debug mode activated ?
|
481
|
+
#
|
482
|
+
# Return:
|
483
|
+
# * _Boolean_: Are we in debug mode ?
|
484
|
+
def debugActivated?
|
485
|
+
return $rUtilAnts_Logging_Logger.debugActivated?
|
486
|
+
end
|
487
|
+
|
371
488
|
# Set the stack of the errors to fill.
|
372
489
|
# If set to nil, errors will be displayed as they appear.
|
373
490
|
# If set to a stack, errors will silently be added to the list.
|
@@ -434,6 +551,15 @@ Details:
|
|
434
551
|
$rUtilAnts_Logging_Logger.logInfo(iMsg)
|
435
552
|
end
|
436
553
|
|
554
|
+
# Log a warning.
|
555
|
+
# Warnings are not errors but still should be highlighted.
|
556
|
+
#
|
557
|
+
# Parameters:
|
558
|
+
# * *iMsg* (_String_): Message to log
|
559
|
+
def logWarn(iMsg)
|
560
|
+
$rUtilAnts_Logging_Logger.logWarn(iMsg)
|
561
|
+
end
|
562
|
+
|
437
563
|
# Log a debugging info.
|
438
564
|
# This is used when debug is activated
|
439
565
|
#
|
data/lib/rUtilAnts/Misc.rb
CHANGED
@@ -7,7 +7,7 @@ module RUtilAnts
|
|
7
7
|
|
8
8
|
module Misc
|
9
9
|
|
10
|
-
# Set these methods into the
|
10
|
+
# Set these methods into the Object namespace
|
11
11
|
def self.initializeMisc
|
12
12
|
Object.module_eval('include RUtilAnts::Misc')
|
13
13
|
end
|
@@ -127,6 +127,24 @@ module RUtilAnts
|
|
127
127
|
return rError
|
128
128
|
end
|
129
129
|
|
130
|
+
# Execute a code block after having changed current directory.
|
131
|
+
# Ensure the directory will be changed back at the end of the block, even if exceptions are thrown.
|
132
|
+
#
|
133
|
+
# Parameters:
|
134
|
+
# * *iDir* (_String_): The directory to change into
|
135
|
+
# * *CodeBlock*: Code called once the current directory has been changed
|
136
|
+
def changeDir(iDir)
|
137
|
+
lOldDir = Dir.getwd
|
138
|
+
Dir.chdir(iDir)
|
139
|
+
begin
|
140
|
+
yield
|
141
|
+
rescue Exception
|
142
|
+
Dir.chdir(lOldDir)
|
143
|
+
raise
|
144
|
+
end
|
145
|
+
Dir.chdir(lOldDir)
|
146
|
+
end
|
147
|
+
|
130
148
|
end
|
131
149
|
|
132
150
|
end
|
data/lib/rUtilAnts/Platform.rb
CHANGED
@@ -15,10 +15,14 @@ module RUtilAnts
|
|
15
15
|
def self.initializePlatform
|
16
16
|
# Require the platform info
|
17
17
|
begin
|
18
|
-
require "
|
18
|
+
require "rUtilAnts/Platforms/#{RUBY_PLATFORM}/PlatformInfo"
|
19
19
|
rescue Exception
|
20
|
-
logBug
|
21
|
-
|
20
|
+
if (!defined?(logBug))
|
21
|
+
require 'rUtilAnts/Logging'
|
22
|
+
RUtilAnts::Logging::initializeLogging(File.expand_path(File.dirname(__FILE__)), '')
|
23
|
+
end
|
24
|
+
logBug "Current platform #{RUBY_PLATFORM} is not supported (#{$!})."
|
25
|
+
raise RuntimeError, "Current platform #{RUBY_PLATFORM} is not supported (#{$!})."
|
22
26
|
end
|
23
27
|
# Create the corresponding object
|
24
28
|
$rUtilAnts_Platform_Info = PlatformInfo.new
|
@@ -40,7 +40,13 @@ module RUtilAnts
|
|
40
40
|
# Return:
|
41
41
|
# * <em>list<String></em>: List of extensions (including .)
|
42
42
|
def getDiscreteExeExtensions
|
43
|
-
|
43
|
+
rExtList = []
|
44
|
+
|
45
|
+
ENV['PATHEXT'].split(';').each do |iExt|
|
46
|
+
rExtList << iExt.downcase
|
47
|
+
end
|
48
|
+
|
49
|
+
return rExtList
|
44
50
|
end
|
45
51
|
|
46
52
|
# Return the list of directories where we look for libraries
|
@@ -64,11 +70,12 @@ module RUtilAnts
|
|
64
70
|
# Parameters:
|
65
71
|
# * *iMsg* (_String_): The message to display
|
66
72
|
def sendMsg(iMsg)
|
67
|
-
#
|
68
|
-
|
69
|
-
|
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]}\"")
|
70
77
|
else
|
71
|
-
system("msg \"#{ENV['USERNAME']}\" /W #{iMsg}")
|
78
|
+
system("msg \"#{ENV['USERNAME']}\" /W \"#{iMsg}\"")
|
72
79
|
end
|
73
80
|
end
|
74
81
|
|
@@ -0,0 +1,149 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2009 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_LINUX
|
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
|
+
return []
|
44
|
+
end
|
45
|
+
|
46
|
+
# Return the list of directories where we look for libraries
|
47
|
+
#
|
48
|
+
# Return:
|
49
|
+
# * <em>list<String></em>: List of directories
|
50
|
+
def getSystemLibsPath
|
51
|
+
rList = ENV['PATH'].split(':')
|
52
|
+
|
53
|
+
if (ENV['LD_LIBRARY_PATH'] != nil)
|
54
|
+
rList += ENV['LD_LIBRARY_PATH'].split(':')
|
55
|
+
end
|
56
|
+
|
57
|
+
return rList
|
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['LD_LIBRARY_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
|
+
# TODO: Handle case of xmessage not installed
|
74
|
+
# Create a temporary file with the content to display
|
75
|
+
require 'tmpdir'
|
76
|
+
lTmpFileName = "#{Dir.tmpdir}/RUA_MSG"
|
77
|
+
File.open(lTmpFileName, 'w') do |oFile|
|
78
|
+
oFile.write(iMsg)
|
79
|
+
end
|
80
|
+
system("xmessage -file #{lTmpFileName}")
|
81
|
+
File.unlink(lTmpFileName)
|
82
|
+
end
|
83
|
+
|
84
|
+
# Execute a Shell command.
|
85
|
+
# Do not wait for its termination.
|
86
|
+
#
|
87
|
+
# Parameters:
|
88
|
+
# * *iCmd* (_String_): The command to execute
|
89
|
+
# * *iInTerminal* (_Boolean_): Do we execute this command in a separate terminal ?
|
90
|
+
# Return:
|
91
|
+
# * _Exception_: Error, or nil if success
|
92
|
+
def execShellCmdNoWait(iCmd, iInTerminal)
|
93
|
+
rException = nil
|
94
|
+
|
95
|
+
if (iInTerminal)
|
96
|
+
# TODO: Handle case of xterm not installed
|
97
|
+
if (!system("xterm -e \"#{iCmd}\""))
|
98
|
+
rException = RuntimeError.new
|
99
|
+
end
|
100
|
+
else
|
101
|
+
begin
|
102
|
+
IO.popen(iCmd)
|
103
|
+
rescue Exception
|
104
|
+
rException = $!
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
return rException
|
109
|
+
end
|
110
|
+
|
111
|
+
# Execute a given URL to be launched in a browser
|
112
|
+
#
|
113
|
+
# Parameters:
|
114
|
+
# * *iURL* (_String_): The URL to launch
|
115
|
+
# Return:
|
116
|
+
# * _String_: Error message, or nil if success
|
117
|
+
def launchURL(iURL)
|
118
|
+
rError = nil
|
119
|
+
|
120
|
+
begin
|
121
|
+
IO.popen("xdg-open '#{iURL}'")
|
122
|
+
rescue Exception
|
123
|
+
rError = $!.to_s
|
124
|
+
end
|
125
|
+
|
126
|
+
return rError
|
127
|
+
end
|
128
|
+
|
129
|
+
# Get file extensions specifics to executable files
|
130
|
+
#
|
131
|
+
# Return:
|
132
|
+
# * <em>list<String></em>: List of extensions (including . character). It can be empty.
|
133
|
+
def getExecutableExtensions
|
134
|
+
return []
|
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
|
data/lib/rUtilAnts/URLAccess.rb
CHANGED
@@ -27,10 +27,10 @@ module RUtilAnts
|
|
27
27
|
# map< String, [ list<Regexp>, String ] >
|
28
28
|
# map< PluginName, [ List of matching regexps, Plugin class name ] >
|
29
29
|
@Plugins = {}
|
30
|
-
Dir.glob("#{File.dirname(__FILE__)}/URLHandlers/*.rb").each do |iFileName|
|
30
|
+
Dir.glob(File.expand_path("#{File.dirname(__FILE__)}/URLHandlers/*.rb")).each do |iFileName|
|
31
31
|
begin
|
32
32
|
lPluginName = File.basename(iFileName)[0..-4]
|
33
|
-
require "
|
33
|
+
require "rUtilAnts/URLHandlers/#{lPluginName}"
|
34
34
|
@Plugins[lPluginName] = [
|
35
35
|
eval("RUtilAnts::URLCache::URLHandlers::#{lPluginName}::getMatchingRegexps"),
|
36
36
|
"RUtilAnts::URLCache::URLHandlers::#{lPluginName}"
|
@@ -55,8 +55,10 @@ module RUtilAnts
|
|
55
55
|
# * _CodeBlock_: The code returning the object corresponding to the content:
|
56
56
|
# ** *iContent* (_String_): File content, or file name if :LocalFileAccess was true
|
57
57
|
# ** *iFileBaseName* (_String_): The base name the file could have. Useful to get file name extensions.
|
58
|
-
# **
|
58
|
+
# ** Return:
|
59
59
|
# ** _Exception_: The error encountered, or nil in case of success
|
60
|
+
# Return:
|
61
|
+
# * _Exception_: The error encountered, or nil in case of success
|
60
62
|
def accessFile(iURL, iParameters = {})
|
61
63
|
rError = nil
|
62
64
|
|
@@ -200,13 +202,15 @@ module RUtilAnts
|
|
200
202
|
# * *iParameters* (<em>map<Symbol,Object></em>): Additional parameters:
|
201
203
|
# ** *:FollowRedirections* (_Boolean_): Do we follow redirections ? [optional = true]
|
202
204
|
# ** *:NbrRedirectionsAllowed* (_Integer_): Number of redirections allowed [optional = 10]
|
203
|
-
# ** *:LocalFileAccess* (_Boolean_): Do we need a local file to read the content from ? If not, the content
|
205
|
+
# ** *:LocalFileAccess* (_Boolean_): Do we need a local file to read the content from ? If not, the content itself will be given the code block. [optional = false]
|
204
206
|
# ** *:URLHandler* (_Object_): The URL handler, if it has already been instantiated, or nil otherwise [optional = nil]
|
205
207
|
# * _CodeBlock_: The code returning the object corresponding to the content:
|
206
208
|
# ** *iContent* (_String_): File content, or file name if :LocalFileAccess was true
|
207
209
|
# ** *iFileBaseName* (_String_): The base name the file could have. Useful to get file name extensions.
|
208
|
-
# **
|
210
|
+
# ** Return:
|
209
211
|
# ** _Exception_: The error encountered, or nil in case of success
|
212
|
+
# Return:
|
213
|
+
# * _Exception_: The error encountered, or nil in case of success
|
210
214
|
def accessFile(iURL, iParameters = {})
|
211
215
|
return $rUtilAnts_URLAccess_Manager.accessFile(iURL, iParameters) do |iContent, iBaseName|
|
212
216
|
yield(iContent, iBaseName)
|
@@ -85,7 +85,8 @@ module RUtilAnts
|
|
85
85
|
begin
|
86
86
|
require 'net/http'
|
87
87
|
Net::HTTP.start(@URLServer) do |iHTTPConnection|
|
88
|
-
|
88
|
+
# Some websites filter out the default user agent (commons.mediawiki.org for example). Set another one.
|
89
|
+
lResponse = iHTTPConnection.request_get("/#{@URLPath}", {'User-Agent' => 'RUtilAnts'})
|
89
90
|
if ((iFollowRedirections) and
|
90
91
|
(lResponse.is_a?(Net::HTTPRedirection)))
|
91
92
|
# We access the file through a new URL
|
metadata
CHANGED
@@ -1,7 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rUtilAnts
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 2
|
8
|
+
- 0
|
9
|
+
- 20101109
|
10
|
+
version: 0.2.0.20101109
|
5
11
|
platform: ruby
|
6
12
|
authors:
|
7
13
|
- Muriel Salvan
|
@@ -9,7 +15,7 @@ autorequire:
|
|
9
15
|
bindir: bin
|
10
16
|
cert_chain: []
|
11
17
|
|
12
|
-
date:
|
18
|
+
date: 2010-11-09 00:00:00 +01:00
|
13
19
|
default_executable:
|
14
20
|
dependencies: []
|
15
21
|
|
@@ -22,20 +28,6 @@ extensions: []
|
|
22
28
|
extra_rdoc_files: []
|
23
29
|
|
24
30
|
files:
|
25
|
-
- ReleaseInfo
|
26
|
-
- README
|
27
|
-
- LICENSE
|
28
|
-
- AUTHORS
|
29
|
-
- Credits
|
30
|
-
- TODO
|
31
|
-
- ChangeLog
|
32
|
-
- lib/rUtilAnts/Plugins.rb
|
33
|
-
- lib/rUtilAnts/GUI.rb
|
34
|
-
- lib/rUtilAnts/Platform.rb
|
35
|
-
- lib/rUtilAnts/URLAccess.rb
|
36
|
-
- lib/rUtilAnts/Logging.rb
|
37
|
-
- lib/rUtilAnts/URLCache.rb
|
38
|
-
- lib/rUtilAnts/Misc.rb
|
39
31
|
- lib/rUtilAnts/URLHandlers/HTTP.rb
|
40
32
|
- lib/rUtilAnts/URLHandlers/FTP.rb
|
41
33
|
- lib/rUtilAnts/URLHandlers/LocalFile.rb
|
@@ -44,6 +36,22 @@ files:
|
|
44
36
|
- lib/rUtilAnts/GUI/BugReportDialog.rb
|
45
37
|
- lib/rUtilAnts/Platforms/i386-linux/PlatformInfo.rb
|
46
38
|
- lib/rUtilAnts/Platforms/i386-mswin32/PlatformInfo.rb
|
39
|
+
- lib/rUtilAnts/Platforms/x86_64-linux/PlatformInfo.rb
|
40
|
+
- lib/rUtilAnts/Plugins.rb
|
41
|
+
- lib/rUtilAnts/GUI.rb
|
42
|
+
- lib/rUtilAnts/Platform.rb
|
43
|
+
- lib/rUtilAnts/URLAccess.rb
|
44
|
+
- lib/rUtilAnts/Logging.rb
|
45
|
+
- lib/rUtilAnts/URLCache.rb
|
46
|
+
- lib/rUtilAnts/Misc.rb
|
47
|
+
- lib/rUtilAnts/ForeignProcess.rb
|
48
|
+
- ReleaseInfo
|
49
|
+
- README
|
50
|
+
- LICENSE
|
51
|
+
- AUTHORS
|
52
|
+
- Credits
|
53
|
+
- TODO
|
54
|
+
- ChangeLog
|
47
55
|
has_rdoc: true
|
48
56
|
homepage: http://rutilants.sourceforge.net/
|
49
57
|
licenses: []
|
@@ -57,18 +65,20 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
57
65
|
requirements:
|
58
66
|
- - ">="
|
59
67
|
- !ruby/object:Gem::Version
|
68
|
+
segments:
|
69
|
+
- 0
|
60
70
|
version: "0"
|
61
|
-
version:
|
62
71
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
63
72
|
requirements:
|
64
73
|
- - ">="
|
65
74
|
- !ruby/object:Gem::Version
|
75
|
+
segments:
|
76
|
+
- 0
|
66
77
|
version: "0"
|
67
|
-
version:
|
68
78
|
requirements: []
|
69
79
|
|
70
80
|
rubyforge_project: rutilants
|
71
|
-
rubygems_version: 1.3.
|
81
|
+
rubygems_version: 1.3.6
|
72
82
|
signing_key:
|
73
83
|
specification_version: 3
|
74
84
|
summary: A collection of various utility libraries.
|