obfusk-util 0.0.1.SNAPSHOT.20130724234552

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/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 :
@@ -0,0 +1,5 @@
1
+ # my namespace
2
+ module Obfusk; module Util
3
+ VERSION = '0.0.1.SNAPSHOT.20130724234552'
4
+ DATE = '2013-07-24'
5
+ end; end
@@ -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: