Module: MiscUtils

Defined in:
lib/buzzcorej/misc_utils.rb

Overview

require 'buzzcorej/logging'

Class Method Summary collapse

Class Method Details

.append_slash(aPath, aSep = nil) ⇒ Object



101
102
103
104
105
106
# File 'lib/buzzcorej/misc_utils.rb', line 101

def self.append_slash(aPath,aSep=nil)
	aSep = sniff_seperator(aPath) unless aSep
	last_char = aPath[-1,1]
	aPath += aSep unless last_char=='\\' || last_char=='/'
	return aPath
end

.canonize_path(aPath, aRootPath = nil) ⇒ Object

takes a path and combines it with a root path (which defaults to Dir.pwd) unless it is absolute the final result is then expanded



142
143
144
145
146
# File 'lib/buzzcorej/misc_utils.rb', line 142

def self.canonize_path(aPath,aRootPath=nil)
	path = path_combine(aRootPath,aPath)
	path = real_path(path) if path
	path
end

.expand_magic_path(aPath, aBasePath = nil) ⇒ Object

allows special symbols in path currently only ... supported, which looks upward in the filesystem for the following relative path from the basepath



159
160
161
162
163
164
165
166
# File 'lib/buzzcorej/misc_utils.rb', line 159

def self.expand_magic_path(aPath,aBasePath=nil)
	aBasePath ||= Dir.pwd
	path = aPath
	if path.begins_with?('...')
		rel_part = StringUtils.split3(path,/\.\.\.[\/\\]/)[2]
		path = find_upwards(aBasePath,rel_part)
	end
end

.file_change_ext(aFile, aExt, aExtend = false) ⇒ Object



199
200
201
# File 'lib/buzzcorej/misc_utils.rb', line 199

def self.file_change_ext(aFile,aExt,aExtend=false)
	file_no_extension(aFile,false)+(aExtend ? '.'+aExt+'.'+file_extension(aFile,false) : '.'+aExt)
end

.file_extension(aFile, aExtended = true) ⇒ Object



188
189
190
191
192
# File 'lib/buzzcorej/misc_utils.rb', line 188

def self.file_extension(aFile,aExtended=true)
	f = File.basename(aFile)
	dot = aExtended ? f.index('.') : f.rindex('.')
	return dot ? f[dot+1..-1] : f
end

.file_list_ancestor(aFiles) ⇒ Object

returns the lowest path containing all files (assumes aFiles contains only absolute paths)



291
292
293
294
295
296
297
298
299
300
301
# File 'lib/buzzcorej/misc_utils.rb', line 291

def self.file_list_ancestor(aFiles)
   files = aFiles.is_a?(Hash) ? aFiles.keys : aFiles
	result = File.dirname(files.first)
	files.each do |fp|
		filedir = File.dirname(fp)
		while path_same(result,filedir)==false && path_ancestor(result,filedir)==false
			result = path_parent(result)
		end
	end		
	result
end

.file_no_extension(aFile, aExtended = true) ⇒ Object



194
195
196
197
# File 'lib/buzzcorej/misc_utils.rb', line 194

def self.file_no_extension(aFile,aExtended=true)
	ext = file_extension(aFile,aExtended)
	return aFile.chomp('.'+ext)
end

.filelist_from_patterns(aPatterns, aBasePath) ⇒ Object



323
324
325
326
327
328
329
330
331
332
# File 'lib/buzzcorej/misc_utils.rb', line 323

def self.filelist_from_patterns(aPatterns,aBasePath)
	return [] unless aPatterns
	aPatterns = [aPatterns] unless aPatterns.is_a? Array

	aPatterns.map do |fp|
		fp = File.expand_path(fp,aBasePath)		# relative to rails root
		fp = FileList[fp] if fp['*'] || fp['?']
		fp
	end.flatten
end

.filter_multilevel_hash(aSource, aInclude = nil, aExclude = nil, &block) ⇒ Object

applies the given block to key/value pairs included/excluded by the given parameters aSource must be a hash, and may contain hashes which will be recursively processed. aInclude/aExclude may be nil, an array of selected keys, or a hash containing arrays of keys for inner hashes of aSource When aInclude/aExclude are a hash, non-hash source values may be selected by passing a value of true. Hash source values will be selected as a whole (all keys) when true is passed. input = { 'a' => 1, 'b' => => 9, 'y' => 8, 'c' => 3 } filter_multilevel_hash(input,['a','b'],'b'=>['y']) {|h,k,v| h[k] = true} input now = { 'a' => true, 'b' => => true, 'y' => 8, 'c' => 3 }



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/buzzcorej/misc_utils.rb', line 21

def self.filter_multilevel_hash(aSource,aInclude=nil,aExclude=nil,&block)
	aSource.each do |key,value|
		next if aInclude.is_a?(Array) and !aInclude.include?(key)		# skip if not in aInclude array
		next if aExclude.is_a?(Array) and aExclude.include?(key)		# skip if in aExclude array
		next if aExclude.is_a?(Hash) and aExclude[key]==true				# skip if in aExclude hash with value=true
		next if aInclude.is_a?(Hash) and !aInclude.include?(key)		# skip if not in aInclude hash at all
		if value.is_a?(Hash)																				# value is hash so recursively apply filter 
			filter_multilevel_hash(
				value,
				aInclude.is_a?(Hash) && (f = aInclude[key]) ? f : nil,	# pass include array if provided for key
				aExclude.is_a?(Hash) && (f = aExclude[key]) ? f : nil,	# pass exclude array if provided for key
				&block
			)
		else
			yield(aSource,key,value)
		end
	end
end

.find_upwards(aStartPath, aPath) ⇒ Object



148
149
150
151
152
153
154
# File 'lib/buzzcorej/misc_utils.rb', line 148

def self.find_upwards(aStartPath,aPath)
	curr_path = File.expand_path(aStartPath)
	while curr_path && !(test_path_exists = File.exists?(test_path = File.join(curr_path,aPath))) do
		curr_path = MiscUtils.path_parent(curr_path)
	end
	curr_path && test_path_exists ? test_path : nil
end

.get_files(aArray, aPath, aFullPath = true, aRootPath = nil, &block) ⇒ Object



245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
# File 'lib/buzzcorej/misc_utils.rb', line 245

def self.get_files(aArray,aPath,aFullPath=true,aRootPath=nil,&block)
	#puts "get_files: aPath='#{aPath}'"
	if aRootPath
		abssrcpath = path_combine(aRootPath,aPath)
	else
		abssrcpath = aRootPath = aPath
		aPath = nil
	end
	return aArray if !File.exists?(abssrcpath)
	#abssrcpath is real path to query
	#aRootPath is highest level path
	#aPath is current path relative to aRootPath
	Dir.new(abssrcpath).to_a.each do |file|
		next if ['.','..'].include? file
		fullpath = File.join(abssrcpath,file)
		resultpath = aFullPath ? fullpath : path_combine(aPath,file)
		if !block_given? || yield(resultpath)
			if FileTest.directory?(fullpath)
				block_given? ? get_files(aArray,path_combine(aPath,file),aFullPath,aRootPath,&block) : get_files(aArray,path_combine(aPath,file),aFullPath,aRootPath)
			else
				aArray << resultpath
			end
		end
	end
	return aArray
end

.hash_to_xml_tag(aName, aHash) ⇒ Object

takes a hash and returns a single closed tag containing the hash pairs as attributes, correctly encoded



315
316
317
318
319
320
321
# File 'lib/buzzcorej/misc_utils.rb', line 315

def self.hash_to_xml_tag(aName,aHash)
	atts = ''
	aHash.each do |k,v| 
		atts += ' ' + k.to_s + "=\"#{v.to_s.to_xs}\""
	end
	"<#{aName}#{atts}/>"		
end

.is_root_path?(aPath) ⇒ Boolean

Returns:

  • (Boolean)


219
220
221
222
223
224
225
# File 'lib/buzzcorej/misc_utils.rb', line 219

def self.is_root_path?(aPath)
	if is_windows?
		(aPath =~ /^[a-zA-Z]\:[\\\/]$/)==0
	else
		aPath == '/'
	end
end

.is_uri?(aString) ⇒ Boolean

Returns:

  • (Boolean)


215
216
217
# File 'lib/buzzcorej/misc_utils.rb', line 215

def self.is_uri?(aString)
	/^[a-zA-Z0-9+_]+\:\/\// =~ aString ? true : false
end

.is_windows?Boolean

Returns:

  • (Boolean)


241
242
243
# File 'lib/buzzcorej/misc_utils.rb', line 241

def self.is_windows?
	platform=='mswin32'
end

.loggerObject



9
10
11
# File 'lib/buzzcorej/misc_utils.rb', line 9

def self.logger
	@logger || @logger = Logger.new(STDERR)
end

.make_temp_dir(aPrefix = '') ⇒ Object



53
54
55
56
57
58
59
60
# File 'lib/buzzcorej/misc_utils.rb', line 53

def self.make_temp_dir(aPrefix='')
	new_dir = nil
   begin
		new_dir = File.join(Dir.tmpdir,aPrefix+("%08X" % rand(0x3FFFFFFF)))
	end until new_dir && !File.exists?(new_dir)
	Dir.mkdir new_dir
	return new_dir
end

.make_temp_file(aName = nil, aDir = nil, aContent = nil) ⇒ Object



45
46
47
48
49
50
51
# File 'lib/buzzcorej/misc_utils.rb', line 45

def self.make_temp_file(aName=nil,aDir=nil,aContent=nil)
	filename = aName ? File.expand_path(aName,aDir || Dir.tmpdir) : temp_file(nil,aDir)
   FileUtils.mkdir_p(File.dirname(filename))
	aContent ||= "content of "+filename
	string_to_file(aContent,filename)
   filename
end

.mkdir?(aPath, aPermissions) ⇒ Boolean

Returns:

  • (Boolean)


62
63
64
65
66
67
68
# File 'lib/buzzcorej/misc_utils.rb', line 62

def self.mkdir?(aPath,aPermissions)
if File.exists?(aPath)
	File.chmod(aPermissions, aPath)
else
	Dir.mkdir(aPath, aPermissions)
  end
end

.native_path(aPath) ⇒ Object



227
228
229
# File 'lib/buzzcorej/misc_utils.rb', line 227

def self.native_path(aPath)
	is_windows? ? windows_path(aPath) : ruby_path(aPath)
end

.path_absolute?(aPath) ⇒ Boolean

Returns:

  • (Boolean)


237
238
239
# File 'lib/buzzcorej/misc_utils.rb', line 237

def self.path_absolute?(aPath)
	!path_relative(aPath)
end

.path_ancestor(aPathParent, aPath) ⇒ Object

returns true if aPath is under aPathParent both must be absolute or both relative



285
286
287
288
# File 'lib/buzzcorej/misc_utils.rb', line 285

def self.path_ancestor(aPathParent,aPath)
	return nil unless path_relative?(aPathParent) == path_relative?(aPath)
	aPath.index(append_slash(aPathParent))==0
end

.path_combine(aBasePath, aPath) ⇒ Object



129
130
131
132
133
# File 'lib/buzzcorej/misc_utils.rb', line 129

def self.path_combine(aBasePath,aPath)
	return aBasePath if !aPath
	return aPath if !aBasePath
	return path_relative?(aPath) ? File.join(aBasePath,aPath) : aPath	
end

.path_debase(aPath, aBase) ⇒ Object

Remove base dir from given path. Result will be relative to base dir and not have a leading or trailing slash '/a/b/c','/a' = 'b/c' '/a/b/c','/' = 'a/b/c' '/','/' = ''



118
119
120
121
122
# File 'lib/buzzcorej/misc_utils.rb', line 118

def self.path_debase(aPath,aBase)
	aBase = MiscUtils::append_slash(aBase)
	aPath = MiscUtils::remove_slash(aPath) unless aPath=='/'
	aPath[0,aBase.length]==aBase ? aPath[aBase.length,aPath.length-aBase.length] : aPath
end

.path_match(aPath, aPatterns) ⇒ Object



303
304
305
306
307
308
309
310
311
312
# File 'lib/buzzcorej/misc_utils.rb', line 303

def self.path_match(aPath,aPatterns)
	aPatterns = [aPatterns] unless aPatterns.is_a? Array
	aPatterns.any? do |pat|
		case pat
			when String then aPath[0,pat.length] == pat
			when Regexp then aPath =~ pat
			else false
		end
	end
end

.path_parent(aPath) ⇒ Object



168
169
170
171
# File 'lib/buzzcorej/misc_utils.rb', line 168

def self.path_parent(aPath)
	return nil if is_root_path?(aPath)
	MiscUtils.append_slash(File.dirname(MiscUtils.remove_slash(File.expand_path(aPath))))
end

.path_parts(aPath) ⇒ Object



183
184
185
186
# File 'lib/buzzcorej/misc_utils.rb', line 183

def self.path_parts(aPath)
	sep = sniff_seperator(aPath)
	aPath.split(sep)
end

.path_rebase(aPath, aOldBase, aNewBase) ⇒ Object



124
125
126
127
# File 'lib/buzzcorej/misc_utils.rb', line 124

def self.path_rebase(aPath,aOldBase,aNewBase)
	rel_path = path_debase(aPath,aOldBase)
	append_slash(aNewBase)+rel_path
end

.path_relative?(aPath) ⇒ Boolean

Returns:

  • (Boolean)


231
232
233
234
235
# File 'lib/buzzcorej/misc_utils.rb', line 231

def self.path_relative?(aPath)
	return false if aPath[0,1]=='/'
	return false if aPath =~ /^[a-zA-Z]:/
	return true
end

.path_same(aPath1, aPath2) ⇒ Object

returns true if aPath1 and aPath2 are the same path (doesn't query file system) both must be absolute or both relative



278
279
280
281
# File 'lib/buzzcorej/misc_utils.rb', line 278

def self.path_same(aPath1,aPath2)
	return nil unless path_relative?(aPath1) == path_relative?(aPath2)
	remove_slash(aPath1) == remove_slash(aPath2)
end

.platformObject



203
204
205
# File 'lib/buzzcorej/misc_utils.rb', line 203

def self.platform
	RUBY_PLATFORM.scan(/-(.+)$/).flatten.first
end

.real_path(aPath) ⇒ Object

make path real according to file system



136
137
138
# File 'lib/buzzcorej/misc_utils.rb', line 136

def self.real_path(aPath)
	(path = Pathname.new(File.expand_path(aPath))) && path.realpath.to_s
end

.recursive_file_list(aPath, aFullPath = true, &block) ⇒ Object



272
273
274
# File 'lib/buzzcorej/misc_utils.rb', line 272

def self.recursive_file_list(aPath,aFullPath=true,&block)
block_given? ? get_files([],aPath,aFullPath,nil,&block) : get_files([],aPath,aFullPath)
end

.remove_slash(aPath) ⇒ Object



108
109
110
111
112
# File 'lib/buzzcorej/misc_utils.rb', line 108

def self.remove_slash(aPath)
	last_char = aPath[-1,1]
	aPath = aPath[0..-2] if last_char=='\\' || last_char=='/'
	return aPath
end

.ruby_path(aPath) ⇒ Object



211
212
213
# File 'lib/buzzcorej/misc_utils.rb', line 211

def self.ruby_path(aPath)
	aPath.gsub('\\','/')
end

.simple_dir_name(aPath) ⇒ Object



173
174
175
# File 'lib/buzzcorej/misc_utils.rb', line 173

def self.simple_dir_name(aPath)
	File.basename(remove_slash(aPath))
end

.simple_file_name(aPath) ⇒ Object



177
178
179
180
181
# File 'lib/buzzcorej/misc_utils.rb', line 177

def self.simple_file_name(aPath)
	f = File.basename(aPath)
	dot = f.index('.')
	return dot ? f[0,dot] : f
end

.sniff_seperator(aPath) ⇒ Object



92
93
94
95
96
97
98
99
# File 'lib/buzzcorej/misc_utils.rb', line 92

def self.sniff_seperator(aPath)
	result = 0.upto(aPath.length-1) do |i|
		char = aPath[i,1]
		break char if char=='\\' || char=='/'
	end
	result = File::SEPARATOR if result==0
	return result
end

.string_from_file(aFilename) ⇒ Object



86
87
88
89
90
# File 'lib/buzzcorej/misc_utils.rb', line 86

def self.string_from_file(aFilename)
	result = nil
	File.open(aFilename, "rb") { |f| result = f.read }
	# return result && result[0..-2]  # quick hack to stop returning false \n at end UPDATE: this is causing problems now
end

.string_to_file(aString, aFilename) ⇒ Object

def self.set_permissions_cmd(aFilepath,aUser=nil,aGroup=nil,aMode=nil,aSetGroupId=false,aSudo=true) cmd = [] if aGroup cmd << (aUser ? "#? sudo : '' chown #aUser:#aGroup" : "#? sudo : '' chgrp #aGroup") + " #aFilepath" else cmd << "#? sudo : '' chown #aUser #aFilepath" if aUser end cmd << "#? sudo : '' chmod #aModeaMode.to_s #aFilepath" if aMode cmd << "#? sudo : '' chmod g+s #aFilepath" if aSetGroupId cmd.join(' && ') end



82
83
84
# File 'lib/buzzcorej/misc_utils.rb', line 82

def self.string_to_file(aString,aFilename)
	File.open(aFilename,'wb') {|file| file.write aString }
end

.temp_file(aExt = nil, aDir = nil) ⇒ Object



40
41
42
43
# File 'lib/buzzcorej/misc_utils.rb', line 40

def self.temp_file(aExt=nil,aDir=nil)
	aExt ||= '.tmp'
	File.expand_path(("%08X" % rand(0x3FFFFFFF)) + aExt, aDir||Dir.tmpdir)
end

.windows_path(aPath) ⇒ Object



207
208
209
# File 'lib/buzzcorej/misc_utils.rb', line 207

def self.windows_path(aPath)
	aPath.gsub('/','\\')
end