File : README.md
Maintainer : Felix C. Stegerman <[email protected]>
Date : 2014-03-03
Copyright : Copyright (C) 2014 Felix C. Stegerman
Version : v0.5.1
Description
[rb-]obfusk-util - miscellaneous utility library for ruby
Examples
require 'obfusk/util/all'
require 'obfusk/util/cmd'
Obfusk::Util::Cmd.killsig 'SIGINT foo bar'
# => { command: 'foo bar', signal: 'SIGINT' }
Obfusk::Util::Cmd.killsig 'foo bar'
# => { command: 'foo bar', signal: 'SIGTERM' }
Obfusk::Util::Cmd.shell 'SHELL echo "$FOO: $BAR"'
# => { command: 'echo "$FOO: $BAR"', shell: 'bash' }
Obfusk::Util::Cmd.set_vars 'echo ${FOO} ... ${BAR} ...',
{ 'FOO' => 'foo', 'BAR' => 'bar' }
# => 'echo foo ... bar ...'
require 'obfusk/util/data'
x = { x: { y: 0 }, z: [1,2,3] }
Obfusk::Util.assoc(x, [:x,:y] => 1, [:z,1] => 99)
x[:x][:y] # => 1
x[:z] # => [1,99,3]
Obfusk::Util.get_in({ x: { y: 1 } }, :x, :y)
# => 1
Obfusk::Util.symbolize_keys({ 'x' => 1, 'y' => 99 })
# => { x: 1, y: 99 }
Obfusk::Util.deep_stringify_keys({ x: { 2 => 99 } })
# => { 'x' => { '2' => 99 } }
h1 = { x: { y: 42 }, z: 11 }
h2 = { x: { y: 1, q: 1 }, z: 1 }
Obfusk::Util.deep_merge(h1, h2) { |k,o,n| o + n }
# => { x: { y: 43, q: 1 }, z: 12 }
y = Obfusk::Util.deepdup x
Obfusk::Util.empty_as_nil(ENV['FOO']) || default
require 'obfusk/util/fs'
Obfusk::Util::FS.append('file', *lines)
Obfusk::Util::FS.exists? 'file-or-possibly-broken-symlink'
require 'obfusk/util/message'
Obfusk::Util.ohai(*%w{ rackup -p 8888 })
# shows '==> rackup -p 8888' in colour
Obfusk::Util.onow 'Starting', 'foo', 'bar'
# shows '==> Starting: foo, bar' in colour
Obfusk::Util.onoe 'Something is wrong!' # error in colour
Obfusk::Util.opoo 'This looks funny!' # warning in colour
There are some o*
methods all over obfusk-util
that combine some
operation with e.g. ohai
.
require 'obfusk/util/module'
module Foo; def self.foo; 42; end; end
module Bar
# alias Foo.foo as Bar.foo and Bar.bar
Obfusk::Util.link_mod_method Foo, :foo, self
Obfusk::Util.link_mod_method Foo, :foo, self, :bar
end
Obfusk::Util.require_all 'foo/bar'
# requires foo/bar/*
Obfusk::Util.submodules Foo
# => { 'bar' => Foo::Bar, 'baz' => Foo:Baz, ... }
Slightly improved OptionParser
(w/o officious options):
require 'obfusk/util/opt'
p = Obfusk::Util::Opt::Parser.new # ...
remaining_args = p.parse_r ARGV
require 'obfusk/util/os'
Obfusk::Util::OS.home # => current user's home
Obfusk::Util::OS.home 'user' # => user's home
Obfusk::Util::OS.user # => current user
Obfusk::Util::OS.now # => current time as '%F %T'
require 'obfusk/util/process'
Obfusk::Util::Process.age pid # => e.g. '01:06:19'
Obfusk::Util::Process.alive? pid # => false/true/:not_mine
spawn_w
is spawn
+ wait
(which is nicer than system
). No
shell is ever used; env
is an option instead of an optional first
argument; ENOENT
becomes RunError
. See also: exec
, spawn
,
system
, capture{2,2e,3}
, pipeline{,_r,_rw,_start,_w}
,
popen{2,2e,3}
.
require 'obfusk/util/run'
Obfusk::Util.spawn_w(*%w{ some command }, env: { 'FOO' => 'bar' },
chdir: 'some/dir') #, ...
# => $?
# raise RunError if command returned non-zero
Obfusk::Util.chk_exit(%w{ some command }) do |a|
# spawn + wait + ohai
Obfusk::Util.ospawn_w(*a)
end
require 'obfusk/util/sh'
Obfusk::Util::sh 'echo "$0" ">>$1<<" ">>$FOO<<"', '"one"', 'FOO' => 'foo'
# stdout: bash >>"one"<< >>foo<<
Obfusk::Util::sh? 'false'
# => false
Obfusk::Util::sh! 'echo FOO; false'
# stdout: FOO
# => RunError
Obfusk::Util::shc('echo "$0" ">>$1<<" ">>$FOO<<"',
'"one"', 'FOO' => 'foo').stdout
# => %Q{bash >>"one"<< >>foo<<}
Obfusk::Util::shc('echo step1; false; echo step3',
print: true, exit: true, merge: true).stdout
# => "+ echo step1\nstep1\n+ false\n"
Obfusk::Util::shc? 'false'
# => false
Obfusk::Util::shc! 'false'
# => RunError
require 'obfusk/util/spec'
Obfusk::Util.provide_stdin(input) do
# do something with $stdin
end
output = Obfusk::Util.capture_stdout do
# do something with $stdout
end
output = Obfusk::Util.capture_stderr(:tty) do
# do something with $stderr; $stderr.isatty => true
end
require 'obfusk/util/struct'
Foo = Obfusk::Util.struct(*%w{ field1 field2 field3 }) do
def some_method; field1 + field2; end
end
foo = Foo.new field1: 37, field2: 5
foo.some_method # => 42
# build a Foo which is frozen when the block ends
= Foo.build(field1: 99) do |x|
c.field2 = 1
# ...
end
.field3 = 99 # => RuntimeError b/c frozen
.check! # => IncompleteError b/c there are empty fields
require 'obfusk/util/term'
Obfusk::Util::Term.colour :red
# => ansi escape code if $stdout is a tty, '' otherwise
Obfusk::Util::Term.columns # terminal columns
Obfusk::Util::Term.lines # terminal lines
Obfusk::Util::Term.tty? # is $stdout a tty?
Obfusk::Util::Term.tty? :err # is $stderr a tty?
Obfusk::Util::Term.prompt 'foo> ' # prompt for input
Obfusk::Util::Term.prompt 'foo> ', :hide # prompt for password
require 'obfusk/util/valid'
def foo(*args_)
Obfusk::Util::Valid.args 'description', args_, 1, 3
# => ArgumentError if #args not in 1..3
end
Specs & Docs
$ rake spec
$ rake docs
TODO
- improve sh w/ fp (pipe, lines, json, blocks)?
- more specs/docs?
- split into several gems?
- ...
License
LGPLv3+ [1].
References
[1] GNU Lesser General Public License, version 3 --- http://www.gnu.org/licenses/lgpl-3.0.html