dataMetaXtra 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.yardopts +1 -0
- data/History.md +5 -0
- data/Manifest.txt +8 -0
- data/PostInstall.txt +2 -0
- data/README.md +32 -0
- data/Rakefile +13 -0
- data/lib/dataMetaXtra/fileSys.rb +335 -0
- data/lib/dataMetaXtra.rb +212 -0
- metadata +52 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 00761eca06212bd8aeb1fc0a7314ea2c6b617d0b
|
4
|
+
data.tar.gz: 0494fe83175c12733454a2be40b8830dfe80b255
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 49dfcb62a7601f35d4a4438c78c4a993587571b2629300468edad1532d62b41fe18cb09bcfbb36d1fedb6f879b30c6e0ca3f6ffe953aa451f397dd6489fbb86f
|
7
|
+
data.tar.gz: 5392d0eced309ab9a28c7de1da92b69b3423b350062d3fbbfc1d148cba38eb4e22a4fe5e97fd5ed000ca1d55828bd19ffcc15840047e787ebf3281351db9ad5f
|
data/.yardopts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--title "DataMeta Ruby Extras" -r README.md --charset UTF-8 lib/**/* - README.md
|
data/History.md
ADDED
data/Manifest.txt
ADDED
data/PostInstall.txt
ADDED
data/README.md
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# dataMetaXtra
|
2
|
+
|
3
|
+
A few small enhancements to some standard Ruby classes in one convenient place.
|
4
|
+
|
5
|
+
References to this gem's:
|
6
|
+
|
7
|
+
* [Source](https://https://github.com/eBayDataMeta/DataMeta-gems)
|
8
|
+
|
9
|
+
## DESCRIPTION:
|
10
|
+
|
11
|
+
See the [DataMeta Project](https://github.com/eBayDataMeta)
|
12
|
+
|
13
|
+
## FEATURES/PROBLEMS:
|
14
|
+
|
15
|
+
* None so far
|
16
|
+
|
17
|
+
## SYNOPSIS:
|
18
|
+
|
19
|
+
* No command line runnables in this gem, it is a library only.
|
20
|
+
|
21
|
+
## REQUIREMENTS:
|
22
|
+
|
23
|
+
* Standard Ruby 1.9.3 or later.
|
24
|
+
|
25
|
+
## INSTALL:
|
26
|
+
|
27
|
+
gem install dataMetaXtra
|
28
|
+
|
29
|
+
## LICENSE:
|
30
|
+
|
31
|
+
[Apache v 2.0](https://github.com/eBayDataMeta/DataMeta/blob/master/LICENSE.md)
|
32
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
%w(yard rdoc/task rake/testtask fileutils ./lib/dataMetaXtra).each{ |r| require r}
|
2
|
+
|
3
|
+
Rake::TestTask.new do |t|
|
4
|
+
t.libs << 'test'
|
5
|
+
end
|
6
|
+
|
7
|
+
desc 'Regen RDocs'
|
8
|
+
task :default => :docs
|
9
|
+
|
10
|
+
YARD::Rake::YardocTask.new('docs') {|r|
|
11
|
+
r.stats_options = ['--list-undoc']
|
12
|
+
}
|
13
|
+
|
@@ -0,0 +1,335 @@
|
|
1
|
+
|
2
|
+
module DataMetaXtra
|
3
|
+
|
4
|
+
=begin rdoc
|
5
|
+
File System utilities.
|
6
|
+
=end
|
7
|
+
module FileSys
|
8
|
+
|
9
|
+
=begin rdoc
|
10
|
+
FileSystem Entry
|
11
|
+
=end
|
12
|
+
class FsEntry
|
13
|
+
=begin rdoc
|
14
|
+
Entyr type - file.
|
15
|
+
=end
|
16
|
+
FILE_TYPE = :f
|
17
|
+
=begin rdoc
|
18
|
+
Entyr type - directory.
|
19
|
+
=end
|
20
|
+
DIR_TYPE = :d
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
=begin rdoc
|
25
|
+
A set of permissions: any mix of read, write and execute, including all set to false.
|
26
|
+
@!attribute [rw] r
|
27
|
+
@return [Boolean] read access, true or false
|
28
|
+
@!attribute [rw] w
|
29
|
+
@return [Boolean] write access, true or false
|
30
|
+
@!attribute [rw] w
|
31
|
+
@return [Boolean] execute access, true or false
|
32
|
+
|
33
|
+
=end
|
34
|
+
class Perm
|
35
|
+
attr_accessor :r, :w, :x
|
36
|
+
|
37
|
+
# POSIX Read permission mask: binary 100
|
38
|
+
READ_MASK = 4
|
39
|
+
|
40
|
+
# POSIX Write permission mask: binary 010
|
41
|
+
WRITE_MASK = 2
|
42
|
+
|
43
|
+
# POSIX Execute permission mask: binary 1
|
44
|
+
EXEC_MASK = 1
|
45
|
+
=begin rdoc
|
46
|
+
Unix {http://en.wikipedia.org/wiki/Sticky_bit Sticky bit},
|
47
|
+
the +S_ISVTX+ mask (or +S_ISTXT+ in BSD) defined in
|
48
|
+
{http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_stat.h.html sys/stat.h}.
|
49
|
+
Use with caution because the semantics is fuzzy and, by some is considered obsolete.
|
50
|
+
=end
|
51
|
+
STICKY_MASK = 01000
|
52
|
+
|
53
|
+
=begin rdoc
|
54
|
+
Unix +S_ISUID+ flag defined in {http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_stat.h.html sys/stat.h}
|
55
|
+
which sets the owner's ID on executable regardless of who actually activates the executable.
|
56
|
+
See {http://en.wikipedia.org/wiki/Setuid this article for details.}
|
57
|
+
=end
|
58
|
+
USER_ID_EXE_MASK = 04000
|
59
|
+
|
60
|
+
=begin rdoc
|
61
|
+
Unix +S_ISGID+ flag defined in {http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_stat.h.html sys/stat.h}
|
62
|
+
which sets the owner's ID on executable regardless of who actually activates the executable.
|
63
|
+
See {http://en.wikipedia.org/wiki/Setuid this article for details.}
|
64
|
+
=end
|
65
|
+
GROUP_ID_EXE_MASK = 02000
|
66
|
+
|
67
|
+
def initialize(r, w, x)
|
68
|
+
@r, @w, @x = r, w, x
|
69
|
+
end
|
70
|
+
|
71
|
+
=begin rdoc
|
72
|
+
Standard Ruby object equality method for hashes and sets.
|
73
|
+
=end
|
74
|
+
def eql?(other)
|
75
|
+
self.r == other.r && self.w == other.w && self.x == other.x
|
76
|
+
end
|
77
|
+
|
78
|
+
=begin rdoc
|
79
|
+
Redefine equality operator for simple comparison, not delegated to {#eql?}, code simply repeated here
|
80
|
+
for speed
|
81
|
+
=end
|
82
|
+
def ==(other)
|
83
|
+
self.r == other.r && self.w == other.w && self.x == other.x
|
84
|
+
end
|
85
|
+
=begin rdoc
|
86
|
+
Creates an instance from textual specification, up to tree letters +r+, +w+, +x+ in any order,
|
87
|
+
'<tt>r</tt>' for 'read', '<tt>w</tt>' for 'write', '<tt>x</tt>' for 'execute.
|
88
|
+
Letter present turns the setting on, letter absent turns it off.
|
89
|
+
@param [String] specs String of letters as described or a Fixnum with usual Posix bitmask: 4 for read, 2 for write, 1 for exec.
|
90
|
+
@raise [ArgumentError] if the specs contain invalid character when specified as a String or if it does not fall into the range
|
91
|
+
between 0 and 7 inclusively if passed as a Fixnum
|
92
|
+
@return [Perm] instance per the specs
|
93
|
+
=end
|
94
|
+
def self.of(specs)
|
95
|
+
result = Perm.new(false, false, false)
|
96
|
+
case
|
97
|
+
when specs.kind_of?(String)
|
98
|
+
specs.each_char { |c|
|
99
|
+
case c
|
100
|
+
when 'r'
|
101
|
+
result.r = true
|
102
|
+
when 'w'
|
103
|
+
result.w = true
|
104
|
+
when 'x'
|
105
|
+
result.x = true
|
106
|
+
else
|
107
|
+
raise ArgumentError, %<Illegal perms letter "#{c}" in the string of "#{specs}">
|
108
|
+
end
|
109
|
+
}
|
110
|
+
when specs.kind_of?(Fixnum)
|
111
|
+
raise ArgumentError, %<Illegal perm mask value of #{specs}> if specs < 0 || specs > 7
|
112
|
+
result.r = true if specs & READ_MASK != 0
|
113
|
+
result.w = true if specs & WRITE_MASK != 0
|
114
|
+
result.x = true if specs & EXEC_MASK != 0
|
115
|
+
else
|
116
|
+
raise ArgumentError, %<Illegal specs: "#{specs.inspect}">
|
117
|
+
end
|
118
|
+
result
|
119
|
+
end
|
120
|
+
|
121
|
+
=begin rdoc
|
122
|
+
Turns the permission into the 'rwx' format for brevity and serialization
|
123
|
+
=end
|
124
|
+
def toRwx
|
125
|
+
result = ''
|
126
|
+
result << 'r' if r
|
127
|
+
result << 'w' if w
|
128
|
+
result << 'x' if x
|
129
|
+
result
|
130
|
+
end
|
131
|
+
|
132
|
+
=begin rdoc
|
133
|
+
Turns the permission into the bitmask format for brevity and serialization
|
134
|
+
=end
|
135
|
+
|
136
|
+
def to_i
|
137
|
+
result = 0
|
138
|
+
result |= READ_MASK if r
|
139
|
+
result |= WRITE_MASK if w
|
140
|
+
result |= EXEC_MASK if x
|
141
|
+
result
|
142
|
+
end
|
143
|
+
=begin rdoc
|
144
|
+
Convenient instance - all perms
|
145
|
+
=end
|
146
|
+
ALL = Perm.new(true, true, true)
|
147
|
+
|
148
|
+
=begin rdoc
|
149
|
+
Convenient instance - no perms
|
150
|
+
=end
|
151
|
+
NONE = Perm.new(false, false, false)
|
152
|
+
|
153
|
+
=begin rdoc
|
154
|
+
Convenient instance - read only
|
155
|
+
=end
|
156
|
+
R = Perm.new(true, false, false)
|
157
|
+
|
158
|
+
=begin rdoc
|
159
|
+
Convenient instance - write only
|
160
|
+
=end
|
161
|
+
W = Perm.new(false, true, false)
|
162
|
+
|
163
|
+
=begin rdoc
|
164
|
+
Convenient instance - read/write
|
165
|
+
=end
|
166
|
+
RW = Perm.new(true, true, false)
|
167
|
+
|
168
|
+
=begin rdoc
|
169
|
+
Convenient instance - read and exec
|
170
|
+
=end
|
171
|
+
RX = Perm.new(true, false, true)
|
172
|
+
# Not providing constants for just exec and write+exec, those are not very useful and hardly ever seen.
|
173
|
+
|
174
|
+
=begin rdoc
|
175
|
+
Creates an instance with 3 booleans: read, write, exec
|
176
|
+
=end
|
177
|
+
end
|
178
|
+
|
179
|
+
=begin rdoc
|
180
|
+
POSIX access perms - per system, user, group and world
|
181
|
+
|
182
|
+
@!attribute [rw] s
|
183
|
+
@return [Perm] Sticky flag
|
184
|
+
|
185
|
+
@!attribute [rw] u
|
186
|
+
@return [Perm] user perms
|
187
|
+
|
188
|
+
@!attribute [rw] g
|
189
|
+
@return [Perm] group perms
|
190
|
+
|
191
|
+
@!attribute [rw] a
|
192
|
+
@return [Perm] world perms (all)
|
193
|
+
=end
|
194
|
+
class PosixPerms
|
195
|
+
attr_accessor :s, :u, :g, :a
|
196
|
+
=begin rdoc
|
197
|
+
Parses the {Perm} instance from the given source.
|
198
|
+
|
199
|
+
@param [String] source either a String or a Fixnum a {Perm} or +nil+, see the method {Perm.of} for details.
|
200
|
+
@param [String] kind the kind of the permissions for diagnostics, like 'user', 'group', 'world' or 'system'
|
201
|
+
@return [Perm] instance according to the description
|
202
|
+
@raise [ArgumentError] if the specs contain invalid character in case of a String or if the source is neither
|
203
|
+
a String nor a {Perm} nor +nil+
|
204
|
+
=end
|
205
|
+
def self.from(source, kind)
|
206
|
+
case
|
207
|
+
when source.kind_of?(NilClass) || source.kind_of?(Perm)
|
208
|
+
source
|
209
|
+
when source.kind_of?(String) || source.kind_of?(Fixnum)
|
210
|
+
Perm.of(source)
|
211
|
+
else
|
212
|
+
raise ArgumentError, %<For #{kind} perms, invalid perm source: #{source.inspect} >
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
=begin rdoc
|
217
|
+
Creates an instance
|
218
|
+
@param [String] user user permissions, can be passed as {Perm} object or String or Fixnum, see the method {PosixPerms.from} for details.
|
219
|
+
@param [String] group group permissions, can be passed as {Perm} object or String or Fixnum, see the method {PosixPerms.from} for details.
|
220
|
+
@param [String] world world permissions, can be passed as {Perm} object or String or Fixnum, see the method {PosixPerms.from} for details.
|
221
|
+
@param [String] sticky flag, can be passed as {Perm} object or String or Fixnum, see the method {PosixPerms.from} for details.
|
222
|
+
=end
|
223
|
+
def initialize(user, group, world, sys = nil)
|
224
|
+
@u = PosixPerms.from(user, 'user')
|
225
|
+
@g = PosixPerms.from(group, 'group')
|
226
|
+
@a = PosixPerms.from(world, 'world')
|
227
|
+
@s = PosixPerms.from(sys, 'system')
|
228
|
+
end
|
229
|
+
|
230
|
+
=begin rdoc
|
231
|
+
Standard Ruby object equality method for hashes and sets.
|
232
|
+
=end
|
233
|
+
def eql?(other)
|
234
|
+
self.u == other.u && self.g == other.g && self.a == other.a && self.s == other.s
|
235
|
+
end
|
236
|
+
=begin rdoc
|
237
|
+
Redefine equality operator for simple comparison, not delegated to {#eql?}, code simply repeated here
|
238
|
+
for speed
|
239
|
+
=end
|
240
|
+
def ==(other)
|
241
|
+
self.u == other.u && self.g == other.g && self.a == other.a && self.s == other.s
|
242
|
+
end
|
243
|
+
|
244
|
+
=begin
|
245
|
+
Converts to integer POSIX specification, 3 bits per each of User, Group, All aka World aka Others
|
246
|
+
=end
|
247
|
+
def to_i; ('%d%d%d' % [@u, @g, @a]).to_i(8) end
|
248
|
+
|
249
|
+
end
|
250
|
+
|
251
|
+
=begin rdoc
|
252
|
+
Generic Id and Name pair, good for any such situation, but in this case used specifically for POSIX user/group ID+Name.
|
253
|
+
|
254
|
+
Regarding equality of these instances, it's better to use one of the components straight, although the both the {#eql?}
|
255
|
+
and <tt>==</tt> method override are provided.
|
256
|
+
|
257
|
+
@!attribute [rw] id
|
258
|
+
@return [Fixnum] numeric ID associated with the name.
|
259
|
+
|
260
|
+
@!attribute [rw] name
|
261
|
+
@return [String] the name associated with the ID
|
262
|
+
|
263
|
+
=end
|
264
|
+
class IdName
|
265
|
+
attr_accessor :id, :name
|
266
|
+
|
267
|
+
=begin rdoc
|
268
|
+
Name-only instance, id set to nil. Useful for cases when ID is irrelevant, such as transferring directory structure
|
269
|
+
between hosts.
|
270
|
+
@raise [ArgumentError] if the name string is empty or contains invalid characters
|
271
|
+
@param [String] name the {#name}
|
272
|
+
=end
|
273
|
+
def self.forName(name)
|
274
|
+
IdName.new(nil, name)
|
275
|
+
end
|
276
|
+
|
277
|
+
=begin rdoc
|
278
|
+
Convenience constructor
|
279
|
+
@raise [ArgumentError] if the name string is empty or contains invalid characters
|
280
|
+
=end
|
281
|
+
def initialize(id, name)
|
282
|
+
raise ArgumentError, %<Invalid POSIX name: "#{name}"> unless name =~ /^[a-z][\w\.-]*$/
|
283
|
+
@id, @name = id, name
|
284
|
+
end
|
285
|
+
|
286
|
+
=begin rdoc
|
287
|
+
Standard Ruby object equality method for hashes and sets.
|
288
|
+
=end
|
289
|
+
def eql?(other)
|
290
|
+
self.id == other.id && self.name == other.name
|
291
|
+
end
|
292
|
+
=begin rdoc
|
293
|
+
Redefine equality operator for simple comparison, not delegated to {#eql?}, code simply repeated here
|
294
|
+
for speed
|
295
|
+
=end
|
296
|
+
def ==(other)
|
297
|
+
self.id == other.id && self.name == other.name
|
298
|
+
end
|
299
|
+
end
|
300
|
+
|
301
|
+
=begin rdoc
|
302
|
+
POSIX ownership information - group and the user
|
303
|
+
=end
|
304
|
+
class PosixOwn
|
305
|
+
attr_accessor :g, :u
|
306
|
+
=begin rdoc
|
307
|
+
@param [String] source either a String or a {IdName} or +nil+, see the method {IdName.forName} for details.
|
308
|
+
@param [String] kind the kind of the ownership for diagnostics, user or group
|
309
|
+
@return [IdName] instance according to the description
|
310
|
+
@raise [ArgumentError] if the specs contain invalid character in case of a String or if the source is neither
|
311
|
+
a String nor a {Perm} nor +nil+
|
312
|
+
|
313
|
+
=end
|
314
|
+
def self.from(source, kind)
|
315
|
+
case
|
316
|
+
when source.kind_of?(NilClass) || source.kind_of?(IdName)
|
317
|
+
source
|
318
|
+
when source.kind_of?(String)
|
319
|
+
IdName.forName(source)
|
320
|
+
else
|
321
|
+
raise ArgumentError, %<For #{kind} ownership, invalid ownership source: #{source.inspect} >
|
322
|
+
end
|
323
|
+
end
|
324
|
+
=begin rdoc
|
325
|
+
Convenience constructor
|
326
|
+
@param [IdName] user either the IdName instance or a string, in case of a string, see {IdName.forName}
|
327
|
+
=end
|
328
|
+
def initialize(user, group = nil)
|
329
|
+
@u = PosixOwn.from(user, 'user')
|
330
|
+
@g = PosixOwn.from(group, 'group')
|
331
|
+
end
|
332
|
+
end
|
333
|
+
end
|
334
|
+
end
|
335
|
+
|
data/lib/dataMetaXtra.rb
ADDED
@@ -0,0 +1,212 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__)) unless
|
2
|
+
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
|
3
|
+
|
4
|
+
require 'logger'
|
5
|
+
|
6
|
+
#Various extensions to the Ruby SDK addressing whatever shortcomings we run into.
|
7
|
+
module DataMetaXtra
|
8
|
+
# Current version
|
9
|
+
VERSION = '1.0.0'
|
10
|
+
|
11
|
+
# Default Logger datetime format
|
12
|
+
LOGGER_DTTM_FMT = '%Y-%m-%d %H:%M:%S'
|
13
|
+
|
14
|
+
# Constants to deal with the operational system, operational environment
|
15
|
+
module Sys
|
16
|
+
# Platform constant - +true+ if running under Microsoft Windows.
|
17
|
+
WINDOWS = (/mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM) != nil
|
18
|
+
|
19
|
+
# Platform constant - +true+ if running under Cygwin.
|
20
|
+
CYGWIN = (/cygwin/ =~ RUBY_PLATFORM) != nil
|
21
|
+
|
22
|
+
# Platform constant - +true+ if running under MacOS X.
|
23
|
+
MAC_OS_X = (/darwin/ =~ RUBY_PLATFORM) != nil
|
24
|
+
|
25
|
+
# Platform constant - +true+ if running under Linux.
|
26
|
+
LINUX = (/linux|GNU/i =~ RUBY_PLATFORM) != nil
|
27
|
+
|
28
|
+
# Platform constant - +true+ if running under any Unix environment: Linux, MacOS X or Cygwin.
|
29
|
+
UNIX = LINUX || MAC_OS_X || CYGWIN
|
30
|
+
|
31
|
+
# Who's running this program - this won't change as long as the program is running.
|
32
|
+
OS_USER = ENV['USERNAME'] || ENV['USER']
|
33
|
+
|
34
|
+
# What's the current user's home path in the filesystem.
|
35
|
+
OS_USER_HOME= case
|
36
|
+
when WINDOWS
|
37
|
+
"#{ENV['HOMEDRIVE']}/#{ENV['HOMEPATH'].gsub(/\\/, '/')}"
|
38
|
+
when CYGWIN
|
39
|
+
"#{ENV['HOME']}" # changed in latest versions of CygWin, now you get /cygdrive/c/Users/mubergens/
|
40
|
+
#"/cygdrive/#{ENV['HOMEDRIVE'][0, 1].downcase}#{ENV['HOMEPATH'].gsub(/\\/, '/')}"
|
41
|
+
else # Linux, MacOS (verified)
|
42
|
+
"#{ENV['HOME']}"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
=begin rdoc
|
46
|
+
Builds a default logger for the given trollop opts and parser.
|
47
|
+
If the opts and parser passed, builds the logger according to the options,
|
48
|
+
with daily rollover and max size 10 M.
|
49
|
+
|
50
|
+
If no opts or no parser passed, returns the logger to STDOUT for the WARN level.
|
51
|
+
|
52
|
+
There is no point in creating a more generic method, the bare <tt>Logger.new</tt> call
|
53
|
+
creates a weekly logger with the 1M size, to STDOUT. Can call <tt>Logger.new('file.log')</tt>
|
54
|
+
|
55
|
+
The default level is DEBUG, therefore you may want change it
|
56
|
+
|
57
|
+
@param [Hash] opts standard Ruby options hash keyed by a sym, see individual options for details
|
58
|
+
@param [Trollop::Parser] parser optional Trollop parser to call "educate" on.
|
59
|
+
=end
|
60
|
+
def defaultLogger(opts=nil, parser=nil)
|
61
|
+
if opts && parser
|
62
|
+
#noinspection RubyArgCount
|
63
|
+
result = Logger.new(opts[:logFile] || 'dataMetaXtra.log', 'daily', 10*1024*1024)
|
64
|
+
result.level = case opts[:level] ? opts[:level].downcase[0] : 'i'
|
65
|
+
when 'd'
|
66
|
+
Logger::DEBUG
|
67
|
+
when 'i'
|
68
|
+
Logger::INFO
|
69
|
+
when 'w'
|
70
|
+
Logger::WARN
|
71
|
+
when 'e'
|
72
|
+
Logger::ERROR
|
73
|
+
else
|
74
|
+
parser.educate
|
75
|
+
raise "Invalid log level #{opts[:level]}"
|
76
|
+
end
|
77
|
+
result.datetime_format = '%Y-%m-%d %H:%M:%S'
|
78
|
+
result
|
79
|
+
else
|
80
|
+
result = Logger.new($stdout)
|
81
|
+
result.level = Logger::WARN
|
82
|
+
result
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
=begin rdoc
|
87
|
+
Hack for Windows that often the name of the executable into the first argument:
|
88
|
+
Discard the first argument if any if it has the same base file name as the current runnable
|
89
|
+
Pass the caller's <tt>__FILE__</tt>.
|
90
|
+
=end
|
91
|
+
def winArgHack(file)
|
92
|
+
ARGV.shift if !ARGV.empty? && ARGV[0] && File.exist?(ARGV[0]) && File.basename(ARGV[0]) == File.basename(file)
|
93
|
+
end
|
94
|
+
|
95
|
+
# Empty block factory
|
96
|
+
class ProcFactory
|
97
|
+
# Creates a new Proc, Proc requires a block, that's why have to place it in a class in a method
|
98
|
+
def create; Proc.new {} end
|
99
|
+
end
|
100
|
+
|
101
|
+
=begin rdoc
|
102
|
+
New empty binding for evaluation to avoid exposing class variables
|
103
|
+
|
104
|
+
Require anything that you may need here outside of the block, it bubbles into here.
|
105
|
+
=end
|
106
|
+
def nilBinding; ProcFactory.new.create.binding end
|
107
|
+
|
108
|
+
=begin rdoc
|
109
|
+
Adding some methods to the standard Ruby String class, useful to generate code.
|
110
|
+
|
111
|
+
For more useful String related methods, see {ActiveSupport's Inflections}[http://apidock.com/rails/ActiveSupport/Inflector/inflections]
|
112
|
+
|
113
|
+
=end
|
114
|
+
module Str
|
115
|
+
|
116
|
+
# Capitalize just first letter, leave everything else as it is.
|
117
|
+
# In contrast to the standard method capitalize which leaves the tail lowercased.
|
118
|
+
def capFirst(original)
|
119
|
+
original[0].chr.upcase + original[1..-1]
|
120
|
+
end
|
121
|
+
|
122
|
+
# turn the first letter lowercase, leave everything else as it is.
|
123
|
+
def downCaseFirst(original)
|
124
|
+
original[0].chr.downcase + original[1..-1]
|
125
|
+
end
|
126
|
+
|
127
|
+
=begin rdoc
|
128
|
+
Turns underscored into camelcase, with first letter of the string and each after underscore
|
129
|
+
turned uppercase and the rest lowercase. Useful for making class names.
|
130
|
+
|
131
|
+
Note that there is one good implementation in the {ActiveSupport gem}[http://apidock.com/rails/ActiveSupport/Inflector/inflections]
|
132
|
+
too.
|
133
|
+
|
134
|
+
Examples:
|
135
|
+
* +this_one_var+ => +ThisOneVar+
|
136
|
+
* +That_oThEr_vAR+ => +ThatOtherVar+
|
137
|
+
|
138
|
+
See also variablize.
|
139
|
+
=end
|
140
|
+
def camelize(original)
|
141
|
+
return original.downcase.capitalize if original =~ /[A-Z]+/ && original !~ /_/
|
142
|
+
return original.capitalize if original !~ /_/
|
143
|
+
original.split('_').map { |e| e.capitalize }.join
|
144
|
+
end
|
145
|
+
|
146
|
+
=begin rdoc
|
147
|
+
Same as camelize but makes sure that the first letter stays lowercase,
|
148
|
+
useful for making variable names.
|
149
|
+
|
150
|
+
Example:
|
151
|
+
* +That_oTHer_vAr+ => +thatOtherVar+
|
152
|
+
|
153
|
+
See also camelize.
|
154
|
+
=end
|
155
|
+
def variablize(original)
|
156
|
+
return original.downcase if original =~ /[A-Z]+/ && original !~ /_/
|
157
|
+
return original[0].downcase + original[1..-1] if original !~ /_/
|
158
|
+
camelized = original.split('_').map { |e| e.capitalize }.join
|
159
|
+
camelized[0].downcase + camelized[1..-1]
|
160
|
+
end
|
161
|
+
module_function :camelize, :variablize, :capFirst, :downCaseFirst
|
162
|
+
end
|
163
|
+
|
164
|
+
=begin rdoc
|
165
|
+
Returns a log name for the given filename, replacing the extension with "<tt>log</tt>".
|
166
|
+
|
167
|
+
Normally would pass <tt>__FILE__</tt> to this method.
|
168
|
+
|
169
|
+
To get a full path, can call <tt>File.extend_path</tt>
|
170
|
+
=end
|
171
|
+
def logName(fullPath); "#{fullPath.chomp(File.extname(fullPath))}.log" end
|
172
|
+
|
173
|
+
# Turns the given instance to milliseconds as integer.
|
174
|
+
def toMillis(time); (time.to_f * 1000).to_i end
|
175
|
+
|
176
|
+
# Turns the given instance to microseconds as integer.
|
177
|
+
def toMicros(time); (time.to_f * 1000000).to_i end
|
178
|
+
|
179
|
+
# likely to be lacking precision
|
180
|
+
# UTC millis of now.
|
181
|
+
# not delegated to {#toMillis} because method calls are still relatively expensive in Ruby, especially in
|
182
|
+
# older versions
|
183
|
+
def nowMillis; (Time.now.utc.to_f * 1000).to_i end
|
184
|
+
|
185
|
+
# UTC seconds of now.
|
186
|
+
def nowSeconds; Time.now.utc.to_i end
|
187
|
+
|
188
|
+
# UTC micros of now.
|
189
|
+
# not delegated to {#toMicros} because method calls are still relatively expensive in Ruby, especially in
|
190
|
+
# older versions
|
191
|
+
def nowMicros; (Time.now.utc.to_f * 1000000).to_i end
|
192
|
+
|
193
|
+
# Current-Directory-Basename - dash - seconds.
|
194
|
+
def nowWdSeconds; "#{File.basename(Dir.getwd)}-#{nowSeconds}" end
|
195
|
+
|
196
|
+
|
197
|
+
=begin rdoc
|
198
|
+
Collects several glob patterns to this array. This is so simple that can be inlined.
|
199
|
+
|
200
|
+
@param [Array] arr array to append the globs to
|
201
|
+
@param [Array] patterns array of glob patterns
|
202
|
+
|
203
|
+
@return [Array] flattenned source array with the filenames by the glob patterns appended to the end
|
204
|
+
=end
|
205
|
+
def appendGlobs(arr, patterns); patterns.each { |p| arr << Dir.glob(p) }; arr.flatten end
|
206
|
+
|
207
|
+
# Turns this array to a PATH list according to <tt>File::PATH_SEPARATOR</tt>.
|
208
|
+
def toPathList(arr); arr.join(File::PATH_SEPARATOR) end
|
209
|
+
|
210
|
+
module_function :winArgHack, :defaultLogger, :nilBinding, :appendGlobs, :toPathList,
|
211
|
+
:nowWdSeconds, :logName, :toMillis, :toMicros, :nowMillis, :nowSeconds, :nowMicros
|
212
|
+
end
|
metadata
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dataMetaXtra
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Michael Bergens
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-01-15 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: A few small enhancements to some standard Ruby classes in one place convenient
|
14
|
+
place.
|
15
|
+
email: michael.bergens@gmail.com
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- ".yardopts"
|
21
|
+
- History.md
|
22
|
+
- Manifest.txt
|
23
|
+
- PostInstall.txt
|
24
|
+
- README.md
|
25
|
+
- Rakefile
|
26
|
+
- lib/dataMetaXtra.rb
|
27
|
+
- lib/dataMetaXtra/fileSys.rb
|
28
|
+
homepage: https://github.com/eBayDataMeta
|
29
|
+
licenses:
|
30
|
+
- Apache-2.0
|
31
|
+
metadata: {}
|
32
|
+
post_install_message:
|
33
|
+
rdoc_options: []
|
34
|
+
require_paths:
|
35
|
+
- lib
|
36
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
42
|
+
requirements:
|
43
|
+
- - ">="
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
requirements: []
|
47
|
+
rubyforge_project:
|
48
|
+
rubygems_version: 2.5.1
|
49
|
+
signing_key:
|
50
|
+
specification_version: 4
|
51
|
+
summary: Small enhancements to a few Ruby standard classes.
|
52
|
+
test_files: []
|