rUtilAnts 0.1.1.20091105 → 0.2.0.20101109
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/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.
|