dataMetaXtra 1.0.0
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.
- 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: []
|