obfusk-util 0.0.1.SNAPSHOT.20130724234552
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +232 -0
- data/lib/obfusk/util/all.rb +29 -0
- data/lib/obfusk/util/cmd.rb +69 -0
- data/lib/obfusk/util/data.rb +53 -0
- data/lib/obfusk/util/die.rb +45 -0
- data/lib/obfusk/util/fs.rb +35 -0
- data/lib/obfusk/util/message.rb +73 -0
- data/lib/obfusk/util/misc.rb +19 -0
- data/lib/obfusk/util/module.rb +41 -0
- data/lib/obfusk/util/opt.rb +37 -0
- data/lib/obfusk/util/os.rb +36 -0
- data/lib/obfusk/util/process.rb +41 -0
- data/lib/obfusk/util/run.rb +124 -0
- data/lib/obfusk/util/spec.rb +55 -0
- data/lib/obfusk/util/struct.rb +83 -0
- data/lib/obfusk/util/term.rb +94 -0
- data/lib/obfusk/util/valid.rb +43 -0
- data/lib/obfusk/util/version.rb +5 -0
- data/obfusk-util.gemspec +27 -0
- metadata +90 -0
data/README.md
ADDED
@@ -0,0 +1,232 @@
|
|
1
|
+
[]: {{{1
|
2
|
+
|
3
|
+
File : README.md
|
4
|
+
Maintainer : Felix C. Stegerman <flx@obfusk.net>
|
5
|
+
Date : 2013-07-24
|
6
|
+
|
7
|
+
Copyright : Copyright (C) 2013 Felix C. Stegerman
|
8
|
+
Version : v0.0.1.SNAPSHOT
|
9
|
+
|
10
|
+
[]: }}}1
|
11
|
+
|
12
|
+
## Description
|
13
|
+
[]: {{{1
|
14
|
+
|
15
|
+
[rb-]obfusk-util - miscellaneous utility library for ruby
|
16
|
+
|
17
|
+
...
|
18
|
+
|
19
|
+
[]: }}}1
|
20
|
+
|
21
|
+
## Examples
|
22
|
+
[]: {{{1
|
23
|
+
|
24
|
+
[]: {{{2
|
25
|
+
|
26
|
+
```ruby
|
27
|
+
Obfusk::Util::Cmd.killsig 'SIGINT foo bar'
|
28
|
+
# => { command: 'foo bar', signal: 'SIGINT' }
|
29
|
+
|
30
|
+
Obfusk::Util::Cmd.killsig 'foo bar'
|
31
|
+
# => { command: 'foo bar', signal: 'SIGTERM' }
|
32
|
+
|
33
|
+
Obfusk::Util::Cmd.shell 'SHELL echo "$FOO: $BAR"'
|
34
|
+
# => { command: 'echo "$FOO: $BAR"', shell: 'bash' }
|
35
|
+
|
36
|
+
Obfusk::Util::Cmd.set_vars 'echo ${FOO} ... ${BAR} ...',
|
37
|
+
{ 'FOO' => 'foo', 'BAR' => 'bar' }
|
38
|
+
# => 'echo foo ... bar ...'
|
39
|
+
```
|
40
|
+
|
41
|
+
[]: }}}2
|
42
|
+
|
43
|
+
[]: {{{2
|
44
|
+
|
45
|
+
```ruby
|
46
|
+
x = { x: { y: 0 }, z: [1,2,3] }
|
47
|
+
Obfusk::Util.assoc(x, [:x,:y] => 1, [:z,1] => 99)
|
48
|
+
x[:x][:y] == 1 # => true
|
49
|
+
x[:z] == [1,99,3] # => true
|
50
|
+
|
51
|
+
y = Obfusk::Util.deepdup x
|
52
|
+
Obfusk::Util.empty_as_nil(ENV['FOO']) || default
|
53
|
+
```
|
54
|
+
|
55
|
+
[]: }}}2
|
56
|
+
|
57
|
+
[]: {{{2
|
58
|
+
|
59
|
+
```ruby
|
60
|
+
Obfusk::Util::FS.append 'file', *lines
|
61
|
+
Obfusk::Util::FS.exists? 'file-or-possibly-broken-symlink'
|
62
|
+
```
|
63
|
+
|
64
|
+
[]: }}}2
|
65
|
+
|
66
|
+
[]: {{{2
|
67
|
+
|
68
|
+
```ruby
|
69
|
+
Obfusk::Util.ohai *%w{ rackup -p 8888 }
|
70
|
+
# shows '==> rackup -p 8888' in colour
|
71
|
+
|
72
|
+
Obfusk::Util.onow 'Starting', 'foo', 'bar'
|
73
|
+
# shows '==> Starting: foo, bar' in colour
|
74
|
+
|
75
|
+
Obfusk::Util.onoe 'Something is wrong!' # error in colour
|
76
|
+
Obfusk::Util.opoo 'This looks funny!' # warning in colour
|
77
|
+
```
|
78
|
+
|
79
|
+
There are some o\* methods all over obfusk-util that combine some
|
80
|
+
operation with e.g. ohai.
|
81
|
+
|
82
|
+
[]: }}}2
|
83
|
+
|
84
|
+
[]: {{{2
|
85
|
+
|
86
|
+
```ruby
|
87
|
+
Obfusk::Util.require_all 'foo/bar'
|
88
|
+
# requires foo/bar/*
|
89
|
+
|
90
|
+
Obfusk::Util.submodules Foo
|
91
|
+
# => { 'bar' => Foo::Bar, 'baz' => Foo:Baz, ... }
|
92
|
+
```
|
93
|
+
|
94
|
+
[]: }}}2
|
95
|
+
|
96
|
+
[]: {{{2
|
97
|
+
|
98
|
+
Slightly improved OptionParser (w/o officious options):
|
99
|
+
|
100
|
+
```ruby
|
101
|
+
p = Obfusk::Util::Opt::Parser.new # ...
|
102
|
+
remaining_args = p.parse_r ARGV
|
103
|
+
```
|
104
|
+
|
105
|
+
[]: }}}2
|
106
|
+
|
107
|
+
[]: {{{2
|
108
|
+
|
109
|
+
```ruby
|
110
|
+
Obfusk::Util::OS.home # => current user's home
|
111
|
+
Obfusk::Util::OS.home 'user' # => user's home
|
112
|
+
Obfusk::Util::OS.user # => current user
|
113
|
+
Obfusk::Util::OS.now # => current time as '%F %T'
|
114
|
+
```
|
115
|
+
|
116
|
+
[]: }}}2
|
117
|
+
|
118
|
+
[]: {{{2
|
119
|
+
|
120
|
+
```ruby
|
121
|
+
Obfusk::Util::Process.age pid # => e.g. '01:06:19'
|
122
|
+
Obfusk::Util::Process.alive? pid # => false/true/:not_mine
|
123
|
+
```
|
124
|
+
|
125
|
+
[]: }}}2
|
126
|
+
|
127
|
+
[]: {{{2
|
128
|
+
|
129
|
+
spawn_w is spawn + wait (which is nicer than system). No shell is
|
130
|
+
ever used; env is an option instead of an optional first argument;
|
131
|
+
ENOENT becomes RunError. See also: exec, spawn, system, popen3.
|
132
|
+
|
133
|
+
```ruby
|
134
|
+
Obfusk::Util.spawn_w *%w{ some command }, env: { 'FOO' => 'bar' },
|
135
|
+
chdir: 'some/dir' #, ...
|
136
|
+
# => $?
|
137
|
+
|
138
|
+
# raise RunError if command returned non-zero
|
139
|
+
Obfusk::Util.chk_exit(%w{ some command }) do |a|
|
140
|
+
# spawn + wait + ohai
|
141
|
+
Obfusk::Util.ospawn_w *a
|
142
|
+
end
|
143
|
+
```
|
144
|
+
|
145
|
+
[]: }}}2
|
146
|
+
|
147
|
+
[]: {{{2
|
148
|
+
|
149
|
+
```ruby
|
150
|
+
Foo = Obfusk::Util.struct(*%w{ field1 field2 field3 }) do
|
151
|
+
def some_method; field1 + field2; end
|
152
|
+
end
|
153
|
+
|
154
|
+
foo = Foo.new field1: 37, field2: 5
|
155
|
+
foo.some_method # => 42
|
156
|
+
|
157
|
+
# build a Foo which is frozen when the block ends
|
158
|
+
bar = Foo.build(field1: 99) do |x|
|
159
|
+
c.field2 = 1
|
160
|
+
# ...
|
161
|
+
end
|
162
|
+
|
163
|
+
bar.field3 = 99 # => RuntimeError b/c frozen
|
164
|
+
bar.check! # => IncompleteError b/c there are empty fields
|
165
|
+
```
|
166
|
+
|
167
|
+
[]: }}}2
|
168
|
+
|
169
|
+
[]: {{{2
|
170
|
+
|
171
|
+
```ruby
|
172
|
+
Obfusk::Util::Term.colour :red
|
173
|
+
# => ansi escape code if $stdout is a tty, '' otherwise
|
174
|
+
|
175
|
+
Obfusk::Util::Term.columns # terminal columns
|
176
|
+
Obfusk::Util::Term.lines # terminal lines
|
177
|
+
Obfusk::Util::Term.tty? # is $stdout a tty?
|
178
|
+
Obfusk::Util::Term.tty? :err # is $stderr a tty?
|
179
|
+
|
180
|
+
Obfusk::Util::Term.prompt 'foo> ' # prompt for input
|
181
|
+
Obfusk::Util::Term.prompt 'foo> ', :hide # prompt for password
|
182
|
+
```
|
183
|
+
|
184
|
+
[]: }}}2
|
185
|
+
|
186
|
+
[]: {{{2
|
187
|
+
|
188
|
+
```ruby
|
189
|
+
def foo(*args_)
|
190
|
+
Obfusk::Util::Valid.args 'description', args_, 1, 3
|
191
|
+
# => ArgumentError if #args not in 1..3
|
192
|
+
end
|
193
|
+
```
|
194
|
+
|
195
|
+
[]: }}}2
|
196
|
+
|
197
|
+
[]: }}}1
|
198
|
+
|
199
|
+
## Specs & Docs
|
200
|
+
[]: {{{1
|
201
|
+
|
202
|
+
$ rake spec
|
203
|
+
$ rake docs
|
204
|
+
|
205
|
+
[]: }}}1
|
206
|
+
|
207
|
+
## TODO
|
208
|
+
[]: {{{1
|
209
|
+
|
210
|
+
* write more specs
|
211
|
+
* write more docs
|
212
|
+
* dual-license under EPLv1?
|
213
|
+
* ...
|
214
|
+
|
215
|
+
[]: }}}1
|
216
|
+
|
217
|
+
## License
|
218
|
+
[]: {{{1
|
219
|
+
|
220
|
+
GPLv2 [1].
|
221
|
+
|
222
|
+
[]: }}}1
|
223
|
+
|
224
|
+
## References
|
225
|
+
[]: {{{1
|
226
|
+
|
227
|
+
[1] GNU General Public License, version 2
|
228
|
+
--- http://www.opensource.org/licenses/GPL-2.0
|
229
|
+
|
230
|
+
[]: }}}1
|
231
|
+
|
232
|
+
[]: ! ( vim: set tw=70 sw=2 sts=2 et fdm=marker : )
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# -- ; {{{1
|
2
|
+
#
|
3
|
+
# File : obfusk/util/all.rb
|
4
|
+
# Maintainer : Felix C. Stegerman <flx@obfusk.net>
|
5
|
+
# Date : 2013-07-24
|
6
|
+
#
|
7
|
+
# Copyright : Copyright (C) 2013 Felix C. Stegerman
|
8
|
+
# Licence : GPLv2
|
9
|
+
#
|
10
|
+
# -- ; }}}1
|
11
|
+
|
12
|
+
require 'obfusk/util/cmd'
|
13
|
+
require 'obfusk/util/data'
|
14
|
+
require 'obfusk/util/die'
|
15
|
+
require 'obfusk/util/fs'
|
16
|
+
require 'obfusk/util/message'
|
17
|
+
require 'obfusk/util/misc'
|
18
|
+
require 'obfusk/util/module'
|
19
|
+
require 'obfusk/util/opt'
|
20
|
+
require 'obfusk/util/os'
|
21
|
+
require 'obfusk/util/process'
|
22
|
+
require 'obfusk/util/run'
|
23
|
+
require 'obfusk/util/spec'
|
24
|
+
require 'obfusk/util/struct'
|
25
|
+
require 'obfusk/util/term'
|
26
|
+
require 'obfusk/util/valid'
|
27
|
+
require 'obfusk/util/version'
|
28
|
+
|
29
|
+
# vim: set tw=70 sw=2 sts=2 et fdm=marker :
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# -- ; {{{1
|
2
|
+
#
|
3
|
+
# File : obfusk/util/cmd.rb
|
4
|
+
# Maintainer : Felix C. Stegerman <flx@obfusk.net>
|
5
|
+
# Date : 2013-07-24
|
6
|
+
#
|
7
|
+
# Copyright : Copyright (C) 2013 Felix C. Stegerman
|
8
|
+
# Licence : GPLv2
|
9
|
+
#
|
10
|
+
# -- ; }}}1
|
11
|
+
|
12
|
+
# my namespace
|
13
|
+
module Obfusk; module Util; module Cmd
|
14
|
+
|
15
|
+
SIG_RX = /^(SIG[A-Z0-9]+)\s+(.*)$/
|
16
|
+
SH_RX = /^SHELL(=(\S+))?\s+(.*)$/
|
17
|
+
VAR_RX = / \$ \{ ([A-Z_]+) \} /x
|
18
|
+
|
19
|
+
# --
|
20
|
+
|
21
|
+
# parses optional `SIG*` prefix in command string;
|
22
|
+
# (e.g. `'SIGINT foo bar ...'`);
|
23
|
+
# if there is no prefix, signal is default
|
24
|
+
# @return [Hash] `{ command: command, signal: signal }`
|
25
|
+
def self.killsig(cmd, default = 'SIGTERM') # {{{1
|
26
|
+
if m = cmd.match(SIG_RX)
|
27
|
+
{ command: m[2], signal: m[1] }
|
28
|
+
else
|
29
|
+
{ command: cmd, signal: default }
|
30
|
+
end
|
31
|
+
end # }}}1
|
32
|
+
|
33
|
+
# parses optional `SHELL[=...]` prefix in command string
|
34
|
+
# (e.g. `'SHELL=bash foo bar ...'`, `'SHELL foo bar ...'`);
|
35
|
+
# if there is no prefix, shell is nil;
|
36
|
+
# if there is no `=...`, shell is default
|
37
|
+
# @return [Hash] `{ command: command, shell: shell }`
|
38
|
+
def self.shell(cmd, default = 'bash') # {{{1
|
39
|
+
if m = cmd.match(SH_RX)
|
40
|
+
{ command: m[3], shell: (m[2] || default) }
|
41
|
+
else
|
42
|
+
{ command: cmd, shell: nil }
|
43
|
+
end
|
44
|
+
end # }}}1
|
45
|
+
|
46
|
+
# --
|
47
|
+
|
48
|
+
# prepend nohup to args
|
49
|
+
def self.nohup(*args)
|
50
|
+
['nohup'] + args
|
51
|
+
end
|
52
|
+
|
53
|
+
# replaces `${VAR}s` in command string using vars hash;
|
54
|
+
# missing values are replaced with empty strings
|
55
|
+
def self.set_vars(cmd, vars)
|
56
|
+
cmd.gsub(VAR_RX) { |m| vars[$1] }
|
57
|
+
end
|
58
|
+
|
59
|
+
# --
|
60
|
+
|
61
|
+
# env hash as array (w/o nil values)
|
62
|
+
# @return [<String>] `['k1="v1"', ...]`
|
63
|
+
def self.env_to_a(h)
|
64
|
+
h.reject { |k,v| v.nil? } .map { |k,v| "#{k}=#{v.inspect}" }
|
65
|
+
end
|
66
|
+
|
67
|
+
end; end; end
|
68
|
+
|
69
|
+
# vim: set tw=70 sw=2 sts=2 et fdm=marker :
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# -- ; {{{1
|
2
|
+
#
|
3
|
+
# File : obfusk/util/data.rb
|
4
|
+
# Maintainer : Felix C. Stegerman <flx@obfusk.net>
|
5
|
+
# Date : 2013-07-24
|
6
|
+
#
|
7
|
+
# Copyright : Copyright (C) 2013 Felix C. Stegerman
|
8
|
+
# Licence : GPLv2
|
9
|
+
#
|
10
|
+
# -- ; }}}1
|
11
|
+
|
12
|
+
# my namespace
|
13
|
+
module Obfusk; module Util
|
14
|
+
|
15
|
+
# assoc key(s) w/ value(s); array keys represent nested keys;
|
16
|
+
# will autovivivy missing (if false/nil) nested objects as hashes
|
17
|
+
#
|
18
|
+
# ```
|
19
|
+
# x = { x: { y: 0 } }; assoc(x, [:x,:y] => 1); x[:x][:y] == 1
|
20
|
+
# ```
|
21
|
+
def self.assoc(x, h = {}) # {{{1
|
22
|
+
h.each do |k,v|
|
23
|
+
if k.is_a? Array
|
24
|
+
case k.length
|
25
|
+
when 0; raise ArgumentError, 'empty array key'
|
26
|
+
when 1; x[k.first] = v
|
27
|
+
else h, *t = k; assoc (x[h] ||= {}), t => v
|
28
|
+
end
|
29
|
+
else
|
30
|
+
x[k] = v
|
31
|
+
end
|
32
|
+
end
|
33
|
+
x
|
34
|
+
end # }}}1
|
35
|
+
|
36
|
+
# deep copy using Marshal
|
37
|
+
def self.deepdup(obj)
|
38
|
+
Marshal.load Marshal.dump obj
|
39
|
+
end
|
40
|
+
|
41
|
+
# nil if x is `.empty?`, x otherwise
|
42
|
+
def self.empty_as_nil(x)
|
43
|
+
x && x.empty? ? nil : x
|
44
|
+
end
|
45
|
+
|
46
|
+
# hash to struct
|
47
|
+
def self.h_to_struct(h = {})
|
48
|
+
Struct.new(*h.keys).new(*h.values)
|
49
|
+
end
|
50
|
+
|
51
|
+
end; end
|
52
|
+
|
53
|
+
# vim: set tw=70 sw=2 sts=2 et fdm=marker :
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# -- ; {{{1
|
2
|
+
#
|
3
|
+
# File : obfusk/util/die.rb
|
4
|
+
# Maintainer : Felix C. Stegerman <flx@obfusk.net>
|
5
|
+
# Date : 2013-07-24
|
6
|
+
#
|
7
|
+
# Copyright : Copyright (C) 2013 Felix C. Stegerman
|
8
|
+
# Licence : GPLv2
|
9
|
+
#
|
10
|
+
# -- ; }}}1
|
11
|
+
|
12
|
+
# my namespace
|
13
|
+
module Obfusk; module Util
|
14
|
+
|
15
|
+
# print msgs to stderr and exit 1;
|
16
|
+
# pass `{ status: code }` as last argument to use other statuscode
|
17
|
+
def self.die!(*msgs)
|
18
|
+
code = _die_msgs msgs; exit code
|
19
|
+
end
|
20
|
+
|
21
|
+
# print msgs to stderr, show usage, exit
|
22
|
+
def self.udie!(usage, *msgs)
|
23
|
+
code = _die_msgs msgs; $stderr.puts "Usage: #{usage}"; exit code
|
24
|
+
end
|
25
|
+
|
26
|
+
# --
|
27
|
+
|
28
|
+
# onoe, exit; requires `obfusk/util/message`
|
29
|
+
def self.odie!(msg, opts = {})
|
30
|
+
o = opts.dup; c = o.delete(:status) || 1
|
31
|
+
::Obfusk::Util.onoe msg, o; exit c
|
32
|
+
end
|
33
|
+
|
34
|
+
# --
|
35
|
+
|
36
|
+
# helper; modifies msgs -> OK b/c comes from *msgs
|
37
|
+
def self._die_msgs(msgs)
|
38
|
+
code = (msgs.last.is_a?(Hash) && msgs.pop[:status]) || 1
|
39
|
+
msgs.each { |m| $stderr.puts "Error: #{m}" }
|
40
|
+
code
|
41
|
+
end
|
42
|
+
|
43
|
+
end; end
|
44
|
+
|
45
|
+
# vim: set tw=70 sw=2 sts=2 et fdm=marker :
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# -- ; {{{1
|
2
|
+
#
|
3
|
+
# File : obfusk/util/fs.rb
|
4
|
+
# Maintainer : Felix C. Stegerman <flx@obfusk.net>
|
5
|
+
# Date : 2013-07-24
|
6
|
+
#
|
7
|
+
# Copyright : Copyright (C) 2013 Felix C. Stegerman
|
8
|
+
# Licence : GPLv2
|
9
|
+
#
|
10
|
+
# -- ; }}}1
|
11
|
+
|
12
|
+
require 'fileutils'
|
13
|
+
|
14
|
+
# my namespace
|
15
|
+
module Obfusk; module Util; module FS
|
16
|
+
|
17
|
+
# append to file
|
18
|
+
def self.append(file, *lines)
|
19
|
+
File.open(file, 'a') { |f| f.puts lines }
|
20
|
+
end
|
21
|
+
|
22
|
+
# does file/dir or symlink exists?
|
23
|
+
def self.exists?(path)
|
24
|
+
File.exists?(path) || File.symlink?(path)
|
25
|
+
end
|
26
|
+
|
27
|
+
# ohai + mkdir_p; requires `obfusk/util/message`
|
28
|
+
def self.omkdir_p(*paths)
|
29
|
+
::Obfusk::Util.ohai "mkdir -p #{paths*' '}"
|
30
|
+
FileUtils.mkdir_p paths
|
31
|
+
end
|
32
|
+
|
33
|
+
end; end; end
|
34
|
+
|
35
|
+
# vim: set tw=70 sw=2 sts=2 et fdm=marker :
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# -- ; {{{1
|
2
|
+
#
|
3
|
+
# File : obfusk/util/message.rb
|
4
|
+
# Maintainer : Felix C. Stegerman <flx@obfusk.net>
|
5
|
+
# Date : 2013-07-24
|
6
|
+
#
|
7
|
+
# Copyright : Copyright (C) 2013 Felix C. Stegerman
|
8
|
+
# Licence : GPLv2
|
9
|
+
#
|
10
|
+
# -- ; }}}1
|
11
|
+
|
12
|
+
require 'obfusk/util/term'
|
13
|
+
|
14
|
+
# my namespace
|
15
|
+
module Obfusk; module Util
|
16
|
+
|
17
|
+
# info message w/ colours:
|
18
|
+
# ```
|
19
|
+
# "==> <msg>"
|
20
|
+
# ```
|
21
|
+
def self.ohai(msg)
|
22
|
+
puts _tcol(:lbl) + '==> ' + _tcol(:whi) + msg + _tcol(:non)
|
23
|
+
end
|
24
|
+
|
25
|
+
# info message w/ colours:
|
26
|
+
# ```
|
27
|
+
# "==> <msg>: <a>[, <b>, ...]"
|
28
|
+
# ```
|
29
|
+
def self.onow(msg, *what)
|
30
|
+
puts _tcol(:lgn) + '==> ' + _tcol(:whi) + msg + _tcol(:non) +
|
31
|
+
(what.empty? ? '' : _owhat(what))
|
32
|
+
end
|
33
|
+
|
34
|
+
# --
|
35
|
+
|
36
|
+
# error message w/ colours:
|
37
|
+
# ```
|
38
|
+
# "<label>: <msg>"
|
39
|
+
# ```
|
40
|
+
#
|
41
|
+
# `opts[:label]` defaults to 'Error';
|
42
|
+
# set `opts[:log]` to a lambda to pass message on to a logger
|
43
|
+
def self.onoe(msg, opts = {})
|
44
|
+
l = opts[:label] || 'Error'
|
45
|
+
$stderr.puts _tcole(:lrd) + l + _tcole(:non) + ': ' + msg
|
46
|
+
opts[:log]["#{l}: #{msg}"] if opts[:log]
|
47
|
+
end
|
48
|
+
|
49
|
+
# warning message (onoe w/ label 'Warning')
|
50
|
+
def self.opoo(msg, opts = {})
|
51
|
+
onoe msg, opts.merge(label: 'Warning')
|
52
|
+
end
|
53
|
+
|
54
|
+
# --
|
55
|
+
|
56
|
+
# (helper for onow)
|
57
|
+
def self._owhat(what)
|
58
|
+
': ' + what.map { |x| _tcol(:lgn) + x + _tcol(:non) } *', '
|
59
|
+
end
|
60
|
+
|
61
|
+
# Term.colour
|
62
|
+
def self._tcol(*a)
|
63
|
+
Term.colour *a
|
64
|
+
end
|
65
|
+
|
66
|
+
# Term.colour_e
|
67
|
+
def self._tcole(*a)
|
68
|
+
Term.colour_e *a
|
69
|
+
end
|
70
|
+
|
71
|
+
end; end
|
72
|
+
|
73
|
+
# vim: set tw=70 sw=2 sts=2 et fdm=marker :
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# -- ; {{{1
|
2
|
+
#
|
3
|
+
# File : obfusk/util/misc.rb
|
4
|
+
# Maintainer : Felix C. Stegerman <flx@obfusk.net>
|
5
|
+
# Date : 2013-07-17
|
6
|
+
#
|
7
|
+
# Copyright : Copyright (C) 2013 Felix C. Stegerman
|
8
|
+
# Licence : GPLv2
|
9
|
+
#
|
10
|
+
# -- ; }}}1
|
11
|
+
|
12
|
+
# my namespace
|
13
|
+
module Obfusk; module Util
|
14
|
+
|
15
|
+
# ...
|
16
|
+
|
17
|
+
end; end
|
18
|
+
|
19
|
+
# vim: set tw=70 sw=2 sts=2 et fdm=marker :
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# -- ; {{{1
|
2
|
+
#
|
3
|
+
# File : obfusk/util/module.rb
|
4
|
+
# Maintainer : Felix C. Stegerman <flx@obfusk.net>
|
5
|
+
# Date : 2013-07-24
|
6
|
+
#
|
7
|
+
# Copyright : Copyright (C) 2013 Felix C. Stegerman
|
8
|
+
# Licence : GPLv2
|
9
|
+
#
|
10
|
+
# -- ; }}}1
|
11
|
+
|
12
|
+
# my namespace
|
13
|
+
module Obfusk; module Util
|
14
|
+
|
15
|
+
# load `dir/*` (by searching for `dir/*.rb` in `$LOAD_PATH`)
|
16
|
+
#
|
17
|
+
# ```
|
18
|
+
# require_all('napp/types') ~> require 'napp/types/*'
|
19
|
+
# ```
|
20
|
+
#
|
21
|
+
# @return [Hash] `{ module => result-of-require }`
|
22
|
+
def self.require_all(dir)
|
23
|
+
Hash[ $LOAD_PATH.map { |x| Dir["#{x}/#{dir}/*.rb"] } .flatten \
|
24
|
+
.map { |x| "#{dir}/" + File.basename(x, '.rb') } .uniq \
|
25
|
+
.map { |x| y = require x; [x,y] } ]
|
26
|
+
end
|
27
|
+
|
28
|
+
# get submodules as hash
|
29
|
+
#
|
30
|
+
# ```
|
31
|
+
# submodules(Foo) -> { 'bar' => Foo::Bar, ... }
|
32
|
+
# ```
|
33
|
+
def self.submodules(mod)
|
34
|
+
Hash[ mod.constants \
|
35
|
+
.map { |x| [x.downcase.to_s, mod.const_get(x)] } \
|
36
|
+
.select { |k,v| v.class == Module } ]
|
37
|
+
end
|
38
|
+
|
39
|
+
end; end
|
40
|
+
|
41
|
+
# vim: set tw=70 sw=2 sts=2 et fdm=marker :
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# -- ; {{{1
|
2
|
+
#
|
3
|
+
# File : obfusk/util/opt.rb
|
4
|
+
# Maintainer : Felix C. Stegerman <flx@obfusk.net>
|
5
|
+
# Date : 2013-07-24
|
6
|
+
#
|
7
|
+
# Copyright : Copyright (C) 2013 Felix C. Stegerman
|
8
|
+
# Licence : GPLv2
|
9
|
+
#
|
10
|
+
# -- ; }}}1
|
11
|
+
|
12
|
+
require 'optparse'
|
13
|
+
|
14
|
+
# my namespace
|
15
|
+
module Obfusk; module Util; module Opt
|
16
|
+
|
17
|
+
# better OptionParser
|
18
|
+
class Parser < OptionParser
|
19
|
+
# do nothing!
|
20
|
+
def add_officious; end
|
21
|
+
|
22
|
+
# parse options, return remaining args
|
23
|
+
def parse_r(args)
|
24
|
+
as = args.dup; parse! as; as
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# --
|
29
|
+
|
30
|
+
# parse options, return remaining args
|
31
|
+
def self.parse(op, args)
|
32
|
+
as = args.dup; op.parse! as; as
|
33
|
+
end
|
34
|
+
|
35
|
+
end; end; end
|
36
|
+
|
37
|
+
# vim: set tw=70 sw=2 sts=2 et fdm=marker :
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# -- ; {{{1
|
2
|
+
#
|
3
|
+
# File : obfusk/util/os.rb
|
4
|
+
# Maintainer : Felix C. Stegerman <flx@obfusk.net>
|
5
|
+
# Date : 2013-07-24
|
6
|
+
#
|
7
|
+
# Copyright : Copyright (C) 2013 Felix C. Stegerman
|
8
|
+
# Licence : GPLv2
|
9
|
+
#
|
10
|
+
# -- ; }}}1
|
11
|
+
|
12
|
+
require 'etc'
|
13
|
+
|
14
|
+
# my namespace
|
15
|
+
module Obfusk; module Util; module OS
|
16
|
+
|
17
|
+
# home dir of (current) user
|
18
|
+
def self.home(user = nil)
|
19
|
+
user ? Etc.getpwnam(user).dir : Dir.home
|
20
|
+
end
|
21
|
+
|
22
|
+
# user name
|
23
|
+
def self.user
|
24
|
+
Etc.getlogin
|
25
|
+
end
|
26
|
+
|
27
|
+
# --
|
28
|
+
|
29
|
+
# current time ('%F %T')
|
30
|
+
def self.now(fmt = '%F %T')
|
31
|
+
Time.now.strftime fmt
|
32
|
+
end
|
33
|
+
|
34
|
+
end; end; end
|
35
|
+
|
36
|
+
# vim: set tw=70 sw=2 sts=2 et fdm=marker :
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# -- ; {{{1
|
2
|
+
#
|
3
|
+
# File : obfusk/util/process.rb
|
4
|
+
# Maintainer : Felix C. Stegerman <flx@obfusk.net>
|
5
|
+
# Date : 2013-07-24
|
6
|
+
#
|
7
|
+
# Copyright : Copyright (C) 2013 Felix C. Stegerman
|
8
|
+
# Licence : GPLv2
|
9
|
+
#
|
10
|
+
# -- ; }}}1
|
11
|
+
|
12
|
+
# my namespace
|
13
|
+
module Obfusk; module Util; module Process
|
14
|
+
|
15
|
+
GET_AGE = ->(pid) { "ps -p #{pid} -o etime=" }
|
16
|
+
|
17
|
+
# --
|
18
|
+
|
19
|
+
# get process age information from ps
|
20
|
+
def self.age(pid)
|
21
|
+
ispid! pid; %x[#{GET_AGE[pid]}].gsub(/\s/, '')
|
22
|
+
end
|
23
|
+
|
24
|
+
# process alive?
|
25
|
+
# @return [Boolean] false if not alive
|
26
|
+
# @return [Boolean] true if alive and mine
|
27
|
+
# @return [Symbol] :not_mine if alive and not mine
|
28
|
+
def self.alive?(pid)
|
29
|
+
::Process.kill 0, pid; true
|
30
|
+
rescue Errno::EPERM; :not_mine
|
31
|
+
rescue Errno::ESRCH; false
|
32
|
+
end
|
33
|
+
|
34
|
+
# @raise ArgumentError if pid is not an integer
|
35
|
+
def self.ispid!(pid)
|
36
|
+
pid.is_a? Integer or raise ArgumentError, 'invalid PID'
|
37
|
+
end
|
38
|
+
|
39
|
+
end; end; end
|
40
|
+
|
41
|
+
# vim: set tw=70 sw=2 sts=2 et fdm=marker :
|
@@ -0,0 +1,124 @@
|
|
1
|
+
# -- ; {{{1
|
2
|
+
#
|
3
|
+
# File : obfusk/util/run.rb
|
4
|
+
# Maintainer : Felix C. Stegerman <flx@obfusk.net>
|
5
|
+
# Date : 2013-07-24
|
6
|
+
#
|
7
|
+
# Copyright : Copyright (C) 2013 Felix C. Stegerman
|
8
|
+
# Licence : GPLv2
|
9
|
+
#
|
10
|
+
# -- ; }}}1
|
11
|
+
|
12
|
+
require 'open3'
|
13
|
+
|
14
|
+
# my namespace
|
15
|
+
module Obfusk; module Util
|
16
|
+
|
17
|
+
class RunError < RuntimeError; end
|
18
|
+
|
19
|
+
# --
|
20
|
+
|
21
|
+
# better Kernel.exec; should never return (if successful);
|
22
|
+
# see spawn, spawn_w, system
|
23
|
+
# @raise RunError on ENOENT
|
24
|
+
def self.exec(*args)
|
25
|
+
_enoent_to_run('exec', args) do |a|
|
26
|
+
Kernel.exec *_spawn_args(*a)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# better Kernel.spawn; options can be passed as last arg like w/
|
31
|
+
# Kernel.spawn, but instead of env as optional first arg, options
|
32
|
+
# takes an :env key as well; also, no shell is ever used;
|
33
|
+
# returns PID; see exec, spawn_w, system
|
34
|
+
# @raise RunError on ENOENT
|
35
|
+
def self.spawn(*args)
|
36
|
+
_enoent_to_run('spawn', args) do |a|
|
37
|
+
Kernel.spawn *_spawn_args(*a)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# better system: spawn + wait; returns $?; see exec, spawn, system
|
42
|
+
def self.spawn_w(*args)
|
43
|
+
pid = spawn(*args); ::Process.wait pid; $?
|
44
|
+
end
|
45
|
+
|
46
|
+
# better Kernel.system; returns true/false; see exec, spawn, spawn_w
|
47
|
+
# @raise RunError on failure (Kernel.system -> nil)
|
48
|
+
def self.system(*args)
|
49
|
+
r = Kernel.system *_spawn_args(*args)
|
50
|
+
raise RunError, "failed to run command #{args} (#$?)" if r.nil?
|
51
|
+
r
|
52
|
+
end
|
53
|
+
|
54
|
+
# --
|
55
|
+
|
56
|
+
# better Open3.popen3; see exec, spawn, spawn_w, system
|
57
|
+
# @raise RunError on ENOENT
|
58
|
+
def self.popen3(*args, &b)
|
59
|
+
_enoent_to_run('popen3', args) do |a|
|
60
|
+
Open3.popen3 *_spawn_args(*a), &b
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# --
|
65
|
+
|
66
|
+
# ohai + spawn; requires `obfusk/util/message`
|
67
|
+
def self.ospawn(*args)
|
68
|
+
::Obfusk::Util.ohai _spawn_rm_opts(args)*' '; spawn *args
|
69
|
+
end
|
70
|
+
|
71
|
+
# ohai + spawn_w; requires `obfusk/util/message`
|
72
|
+
def self.ospawn_w(*args)
|
73
|
+
::Obfusk::Util.ohai _spawn_rm_opts(args)*' '; spawn_w *args
|
74
|
+
end
|
75
|
+
|
76
|
+
# --
|
77
|
+
|
78
|
+
# run block w/ args, check `.exitstatus`
|
79
|
+
# @raise RunError if Process::Status's exitstatus is non-zero
|
80
|
+
def self.chk_exit(args, &b)
|
81
|
+
chk_exitstatus args, b[args].exitstatus
|
82
|
+
end
|
83
|
+
|
84
|
+
# @raise RunError if c != 0
|
85
|
+
def self.chk_exitstatus(args, c)
|
86
|
+
exit_non_zero! args, c if c != 0
|
87
|
+
end
|
88
|
+
|
89
|
+
# @raise RunError command returned non-zero
|
90
|
+
def self.exit_non_zero!(args, c)
|
91
|
+
raise RunError, "command returned non-zero: #{args} -> #{c}"
|
92
|
+
end
|
93
|
+
|
94
|
+
# --
|
95
|
+
|
96
|
+
# helper
|
97
|
+
def self._enoent_to_run(what, args, &b) # {{{1
|
98
|
+
begin
|
99
|
+
b[args]
|
100
|
+
rescue Errno::ENOENT => e
|
101
|
+
raise RunError,
|
102
|
+
"failed to #{what} command #{args}: #{e.message}"
|
103
|
+
end
|
104
|
+
end # }}}1
|
105
|
+
|
106
|
+
# helper
|
107
|
+
def self._spawn_args(cmd, *args) # {{{1
|
108
|
+
c = [cmd, cmd]
|
109
|
+
if args.last && (l = args.last.dup).is_a?(Hash) \
|
110
|
+
&& e = l.delete(:env)
|
111
|
+
[e, c] + args[0..-2] + [l]
|
112
|
+
else
|
113
|
+
[c] + args
|
114
|
+
end
|
115
|
+
end # }}}1
|
116
|
+
|
117
|
+
# helper
|
118
|
+
def self._spawn_rm_opts(args)
|
119
|
+
args.last.is_a?(Hash) ? args[0..-2] : args
|
120
|
+
end
|
121
|
+
|
122
|
+
end; end
|
123
|
+
|
124
|
+
# vim: set tw=70 sw=2 sts=2 et fdm=marker :
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# -- ; {{{1
|
2
|
+
#
|
3
|
+
# File : obfusk/util/spec.rb
|
4
|
+
# Maintainer : Felix C. Stegerman <flx@obfusk.net>
|
5
|
+
# Date : 2013-07-24
|
6
|
+
#
|
7
|
+
# Copyright : Copyright (C) 2013 Felix C. Stegerman
|
8
|
+
# Licence : GPLv2
|
9
|
+
#
|
10
|
+
# -- ; }}}1
|
11
|
+
|
12
|
+
require 'stringio'
|
13
|
+
|
14
|
+
# my namespace
|
15
|
+
module Obfusk; module Util
|
16
|
+
|
17
|
+
# use StringIO to provide $stdin to block
|
18
|
+
def self.provide_stdin(str, isatty = false, &b) # {{{1
|
19
|
+
old = $stdin
|
20
|
+
begin
|
21
|
+
StringIO.open(str, 'r') do |s|
|
22
|
+
def s.isatty; true; end if isatty; $stdin = s; b[]
|
23
|
+
end
|
24
|
+
ensure
|
25
|
+
$stdin = old
|
26
|
+
end
|
27
|
+
end # }}}1
|
28
|
+
|
29
|
+
# use StringIO to capture $stdout from block
|
30
|
+
def self.capture_stdout(isatty = false, &b) # {{{1
|
31
|
+
old = $stdout
|
32
|
+
begin
|
33
|
+
StringIO.open('', 'w') do |s|
|
34
|
+
def s.isatty; true; end if isatty; $stdout = s; b[]; s.string
|
35
|
+
end
|
36
|
+
ensure
|
37
|
+
$stdout = old
|
38
|
+
end
|
39
|
+
end # }}}1
|
40
|
+
|
41
|
+
# use StringIO to capture $stderr from block
|
42
|
+
def self.capture_stderr(isatty = false, &b) # {{{1
|
43
|
+
old = $stderr
|
44
|
+
begin
|
45
|
+
StringIO.open('', 'w') do |s|
|
46
|
+
def s.isatty; true; end if isatty; $stderr = s; b[]; s.string
|
47
|
+
end
|
48
|
+
ensure
|
49
|
+
$stderr = old
|
50
|
+
end
|
51
|
+
end # }}}1
|
52
|
+
|
53
|
+
end; end
|
54
|
+
|
55
|
+
# vim: set tw=70 sw=2 sts=2 et fdm=marker :
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# -- ; {{{1
|
2
|
+
#
|
3
|
+
# File : obfusk/util/struct.rb
|
4
|
+
# Maintainer : Felix C. Stegerman <flx@obfusk.net>
|
5
|
+
# Date : 2013-07-24
|
6
|
+
#
|
7
|
+
# Copyright : Copyright (C) 2013 Felix C. Stegerman
|
8
|
+
# Licence : GPLv2
|
9
|
+
#
|
10
|
+
# -- ; }}}1
|
11
|
+
|
12
|
+
# my namespace
|
13
|
+
module Obfusk; module Util
|
14
|
+
|
15
|
+
# better Struct; create using Obfusk::Util.struct
|
16
|
+
module BetterStruct # {{{1
|
17
|
+
|
18
|
+
class IncompleteError < RuntimeError; end
|
19
|
+
|
20
|
+
# --
|
21
|
+
|
22
|
+
# include class methods as well
|
23
|
+
def self.included(base)
|
24
|
+
base.extend ClassMethods
|
25
|
+
end
|
26
|
+
|
27
|
+
module ClassMethods # {{{2
|
28
|
+
|
29
|
+
# new, block, freeze, return
|
30
|
+
def build(h = {}, &b)
|
31
|
+
x = new h; b[x] if b; x.freeze
|
32
|
+
end
|
33
|
+
|
34
|
+
end # }}}2
|
35
|
+
|
36
|
+
# checks for missing fields, returns self
|
37
|
+
# @raise IncompleteError if any fields are nil
|
38
|
+
def check!
|
39
|
+
members.each do |f|
|
40
|
+
self[f].nil? and raise IncompleteError, "empty field: #{f}"
|
41
|
+
end; self
|
42
|
+
end
|
43
|
+
|
44
|
+
# def with(h = {}, &b)
|
45
|
+
# x = dup
|
46
|
+
# h.each {
|
47
|
+
# end
|
48
|
+
|
49
|
+
unless Struct.method_defined? :to_h
|
50
|
+
# convert to hash (ruby 2 has this already)
|
51
|
+
def to_h
|
52
|
+
Hash[each_pair.to_a]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# convert to hash w/ string keys
|
57
|
+
def to_str_h
|
58
|
+
Hash[to_h.map { |k,v| [k.to_s,v] }]
|
59
|
+
end
|
60
|
+
|
61
|
+
end # }}}1
|
62
|
+
|
63
|
+
# --
|
64
|
+
|
65
|
+
# better struct; see examples in README.md
|
66
|
+
def self.struct(*fields, &b) # {{{1
|
67
|
+
Class.new(Struct.new(*fields.map(&:to_sym))) do
|
68
|
+
|
69
|
+
include BetterStruct
|
70
|
+
|
71
|
+
# init w/ hash
|
72
|
+
def initialize(h = {})
|
73
|
+
h.each { |k,v| self[k] = v }
|
74
|
+
end
|
75
|
+
|
76
|
+
self.class_eval &b if b
|
77
|
+
|
78
|
+
end
|
79
|
+
end # }}}1
|
80
|
+
|
81
|
+
end; end
|
82
|
+
|
83
|
+
# vim: set tw=70 sw=2 sts=2 et fdm=marker :
|
@@ -0,0 +1,94 @@
|
|
1
|
+
# -- ; {{{1
|
2
|
+
#
|
3
|
+
# File : obfusk/util/term.rb
|
4
|
+
# Maintainer : Felix C. Stegerman <flx@obfusk.net>
|
5
|
+
# Date : 2013-07-24
|
6
|
+
#
|
7
|
+
# Copyright : Copyright (C) 2013 Felix C. Stegerman
|
8
|
+
# Licence : GPLv2
|
9
|
+
#
|
10
|
+
# -- ; }}}1
|
11
|
+
|
12
|
+
require 'io/console'
|
13
|
+
|
14
|
+
# my namespace
|
15
|
+
module Obfusk; module Util; module Term
|
16
|
+
|
17
|
+
# ansi colour codes
|
18
|
+
TERM_COLOUR_CODES = { # {{{1
|
19
|
+
black: '0;30', dark_gray: '1;30',
|
20
|
+
blue: '0;34', light_blue: '1;34',
|
21
|
+
green: '0;32', light_green: '1;32',
|
22
|
+
cyan: '0;36', light_cyan: '1;36',
|
23
|
+
red: '0;31', light_red: '1;31',
|
24
|
+
purple: '0;35', light_purple: '1;35',
|
25
|
+
brown: '0;33', yellow: '1;33',
|
26
|
+
light_gray: '0;37', white: '1;37',
|
27
|
+
none: '0'
|
28
|
+
} # }}}1
|
29
|
+
|
30
|
+
# some colour aliases
|
31
|
+
TERM_COLOUR_ALIASES = { # {{{1
|
32
|
+
bla: :black, dgr: :dark_gray,
|
33
|
+
blu: :blue, lbl: :light_blue,
|
34
|
+
grn: :green, lgn: :light_green,
|
35
|
+
cyn: :cyan, lcy: :light_cyan, lrd: :light_red,
|
36
|
+
pur: :purple, lpu: :light_purple,
|
37
|
+
bro: :brown, yel: :yellow,
|
38
|
+
lgr: :light_gray, whi: :white, non: :none,
|
39
|
+
} # }}}1
|
40
|
+
|
41
|
+
# ansi colour escapes
|
42
|
+
TERM_COLOUR_ESCAPES = (->(;a,b) {
|
43
|
+
a = Hash[TERM_COLOUR_CODES.map { |k,v| [k,"\e[#{v}m"] }]
|
44
|
+
b = Hash[TERM_COLOUR_ALIASES.map { |k,v| [k, a[v] ] }]
|
45
|
+
a.merge b
|
46
|
+
})[]
|
47
|
+
|
48
|
+
GET_COLS = 'TERM=${TERM:-dumb} tput cols'
|
49
|
+
GET_LINES = 'TERM=${TERM:-dumb} tput lines'
|
50
|
+
|
51
|
+
# --
|
52
|
+
|
53
|
+
# colour code (or '' if not tty)
|
54
|
+
def self.colour(x, what = :out)
|
55
|
+
c = TERM_COLOUR_ESCAPES[x] or raise ArgumentError,
|
56
|
+
"No such colour: #{x}"
|
57
|
+
tty?(what) ? c : ''
|
58
|
+
end
|
59
|
+
|
60
|
+
# colour code for $stderr
|
61
|
+
def self.colour_e(x)
|
62
|
+
colour x, :err
|
63
|
+
end
|
64
|
+
|
65
|
+
# --
|
66
|
+
|
67
|
+
# terminal columns
|
68
|
+
def self.columns
|
69
|
+
%x[#{GET_COLS}].to_i
|
70
|
+
end
|
71
|
+
|
72
|
+
# terminal lines
|
73
|
+
def self.lines
|
74
|
+
%x[#{GET_LINES}].to_i
|
75
|
+
end
|
76
|
+
|
77
|
+
# is $stdout (or $stderr) a tty?
|
78
|
+
def self.tty?(what = :out)
|
79
|
+
(what == :out ? $stdout : $stderr).isatty
|
80
|
+
end
|
81
|
+
|
82
|
+
# --
|
83
|
+
|
84
|
+
# prompt for line; optionally hide input
|
85
|
+
def self.prompt(prompt, hide = false)
|
86
|
+
print prompt; $stdout.flush
|
87
|
+
line = hide ? $stdin.noecho { |i| i.gets } .tap { puts } :
|
88
|
+
$stdin.gets
|
89
|
+
line && line.chomp
|
90
|
+
end
|
91
|
+
|
92
|
+
end; end; end
|
93
|
+
|
94
|
+
# vim: set tw=70 sw=2 sts=2 et fdm=marker :
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# -- ; {{{1
|
2
|
+
#
|
3
|
+
# File : obfusk/util/valid.rb
|
4
|
+
# Maintainer : Felix C. Stegerman <flx@obfusk.net>
|
5
|
+
# Date : 2013-07-24
|
6
|
+
#
|
7
|
+
# Copyright : Copyright (C) 2013 Felix C. Stegerman
|
8
|
+
# Licence : GPLv2
|
9
|
+
#
|
10
|
+
# -- ; }}}1
|
11
|
+
|
12
|
+
# my namespace
|
13
|
+
module Obfusk; module Util; module Valid
|
14
|
+
|
15
|
+
class ArgumentError < RuntimeError; end
|
16
|
+
class ValidationError < RuntimeError; end
|
17
|
+
|
18
|
+
# --
|
19
|
+
|
20
|
+
# validate #args in min..max (min.. if max is nil)
|
21
|
+
# @return [Array] args
|
22
|
+
# @raise ArgumentError on out of bounds
|
23
|
+
def self.args(what, args, min, max = min)
|
24
|
+
if (l = args.length) < min || (max && l > max)
|
25
|
+
raise ArgumentError,
|
26
|
+
"#{what} expected #{min}..#{max} arguments, got #{l}"
|
27
|
+
end; args
|
28
|
+
end
|
29
|
+
|
30
|
+
# @raise ValidationError
|
31
|
+
def self.invalid!(msg)
|
32
|
+
raise ValidationError, msg
|
33
|
+
end
|
34
|
+
|
35
|
+
# validate value against regex
|
36
|
+
# @raise ValidationError on no match
|
37
|
+
def self.validate!(x, rx, name)
|
38
|
+
x.to_s.match /^(#{rx})$/ or invalid! "invalid #{name}"
|
39
|
+
end
|
40
|
+
|
41
|
+
end; end; end
|
42
|
+
|
43
|
+
# vim: set tw=70 sw=2 sts=2 et fdm=marker :
|
data/obfusk-util.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require File.expand_path('../lib/obfusk/util/version', __FILE__)
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = 'obfusk-util'
|
5
|
+
s.homepage = 'https://github.com/obfusk/rb-obfusk-util'
|
6
|
+
s.summary = 'miscellaneous utility library for ruby'
|
7
|
+
|
8
|
+
s.description = <<-END.gsub(/^ {4}/, '')
|
9
|
+
...
|
10
|
+
END
|
11
|
+
|
12
|
+
s.version = Obfusk::Util::VERSION
|
13
|
+
s.date = Obfusk::Util::DATE
|
14
|
+
|
15
|
+
s.authors = [ 'Felix C. Stegerman' ]
|
16
|
+
s.email = %w{ flx@obfusk.net }
|
17
|
+
|
18
|
+
s.license = 'GPLv2'
|
19
|
+
|
20
|
+
s.files = %w{ README.md obfusk-util.gemspec }\
|
21
|
+
+ Dir['lib/**/*.rb']
|
22
|
+
|
23
|
+
s.add_development_dependency 'rake'
|
24
|
+
s.add_development_dependency 'rspec'
|
25
|
+
|
26
|
+
s.required_ruby_version = '>= 1.9.1'
|
27
|
+
end
|
metadata
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: obfusk-util
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1.SNAPSHOT.20130724234552
|
5
|
+
prerelease: 6
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Felix C. Stegerman
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-07-24 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rake
|
16
|
+
requirement: &15323640 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *15323640
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rspec
|
27
|
+
requirement: &15321480 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *15321480
|
36
|
+
description: ! '...
|
37
|
+
|
38
|
+
'
|
39
|
+
email:
|
40
|
+
- flx@obfusk.net
|
41
|
+
executables: []
|
42
|
+
extensions: []
|
43
|
+
extra_rdoc_files: []
|
44
|
+
files:
|
45
|
+
- README.md
|
46
|
+
- obfusk-util.gemspec
|
47
|
+
- lib/obfusk/util/message.rb
|
48
|
+
- lib/obfusk/util/struct.rb
|
49
|
+
- lib/obfusk/util/spec.rb
|
50
|
+
- lib/obfusk/util/os.rb
|
51
|
+
- lib/obfusk/util/version.rb
|
52
|
+
- lib/obfusk/util/process.rb
|
53
|
+
- lib/obfusk/util/run.rb
|
54
|
+
- lib/obfusk/util/data.rb
|
55
|
+
- lib/obfusk/util/opt.rb
|
56
|
+
- lib/obfusk/util/fs.rb
|
57
|
+
- lib/obfusk/util/term.rb
|
58
|
+
- lib/obfusk/util/misc.rb
|
59
|
+
- lib/obfusk/util/valid.rb
|
60
|
+
- lib/obfusk/util/all.rb
|
61
|
+
- lib/obfusk/util/die.rb
|
62
|
+
- lib/obfusk/util/module.rb
|
63
|
+
- lib/obfusk/util/cmd.rb
|
64
|
+
homepage: https://github.com/obfusk/rb-obfusk-util
|
65
|
+
licenses:
|
66
|
+
- GPLv2
|
67
|
+
post_install_message:
|
68
|
+
rdoc_options: []
|
69
|
+
require_paths:
|
70
|
+
- lib
|
71
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ! '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: 1.9.1
|
77
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
78
|
+
none: false
|
79
|
+
requirements:
|
80
|
+
- - ! '>'
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 1.3.1
|
83
|
+
requirements: []
|
84
|
+
rubyforge_project:
|
85
|
+
rubygems_version: 1.8.11
|
86
|
+
signing_key:
|
87
|
+
specification_version: 3
|
88
|
+
summary: miscellaneous utility library for ruby
|
89
|
+
test_files: []
|
90
|
+
has_rdoc:
|