epitools 0.5.103 → 0.5.105

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/README.rdoc +1 -1
  3. data/Rakefile +2 -2
  4. data/TODO +1 -1
  5. data/VERSION +1 -1
  6. data/lib/epitools.rb +1 -1
  7. data/lib/epitools/colored.rb +25 -25
  8. data/lib/epitools/core_ext/enumerable.rb +1 -1
  9. data/lib/epitools/core_ext/file.rb +6 -2
  10. data/lib/epitools/core_ext/hash.rb +43 -29
  11. data/lib/epitools/core_ext/misc.rb +21 -1
  12. data/lib/epitools/core_ext/object.rb +19 -19
  13. data/lib/epitools/core_ext/truthiness.rb +5 -5
  14. data/lib/epitools/daemonize.rb +1 -1
  15. data/lib/epitools/hexdump.rb +1 -1
  16. data/lib/epitools/iter.rb +26 -26
  17. data/lib/epitools/lcs.rb +3 -3
  18. data/lib/epitools/mimemagic.rb +7 -7
  19. data/lib/epitools/niceprint.rb +18 -18
  20. data/lib/epitools/numwords.rb +34 -34
  21. data/lib/epitools/path.rb +7 -0
  22. data/lib/epitools/permutations.rb +9 -9
  23. data/lib/epitools/pretty_backtrace.rb +11 -11
  24. data/lib/epitools/progressbar.rb +7 -7
  25. data/lib/epitools/rails.rb +2 -2
  26. data/lib/epitools/rash.rb +16 -16
  27. data/lib/epitools/ratio.rb +1 -1
  28. data/lib/epitools/sys.rb +47 -47
  29. data/lib/epitools/trie.rb +4 -4
  30. data/lib/epitools/typed_struct.rb +5 -5
  31. data/lib/epitools/wm.rb +6 -6
  32. data/lib/epitools/zopen.rb +2 -2
  33. data/spec/autoreq_spec.rb +5 -5
  34. data/spec/browser_spec.rb +1 -1
  35. data/spec/colored_spec.rb +5 -5
  36. data/spec/core_ext_spec.rb +1 -1
  37. data/spec/histogram_spec.rb +3 -3
  38. data/spec/iter_spec.rb +16 -16
  39. data/spec/lcs_spec.rb +5 -5
  40. data/spec/numwords_spec.rb +8 -8
  41. data/spec/permutations_spec.rb +9 -9
  42. data/spec/rash_spec.rb +7 -7
  43. data/spec/ratio_spec.rb +5 -5
  44. data/spec/sys_spec.rb +6 -6
  45. data/spec/term_spec.rb +7 -7
  46. data/spec/typed_struct_spec.rb +5 -5
  47. data/spec/wm_spec.rb +4 -4
  48. data/spec/zopen_spec.rb +11 -11
  49. metadata +2 -2
@@ -8,9 +8,9 @@
8
8
  # greeting["Mrs. Steve Austin"] #=> "Evening, madame."
9
9
  #
10
10
  class Rash
11
-
11
+
12
12
  attr_accessor :optimize_every
13
-
13
+
14
14
  def initialize(initial={})
15
15
  @hash = {}
16
16
  @regexes = []
@@ -18,7 +18,7 @@ class Rash
18
18
  @regex_counts = Hash.new(0)
19
19
  @optimize_every = 500
20
20
  @lookups = 0
21
-
21
+
22
22
  update(initial)
23
23
  end
24
24
 
@@ -28,7 +28,7 @@ class Rash
28
28
  end
29
29
  self
30
30
  end
31
-
31
+
32
32
  def []=(key, value)
33
33
  case key
34
34
  when Regexp
@@ -39,20 +39,20 @@ class Rash
39
39
  end
40
40
  @hash[key] = value
41
41
  end
42
-
42
+
43
43
  #
44
44
  # Return the first thing that matches the key.
45
45
  #
46
46
  def [](key)
47
47
  all(key).first
48
48
  end
49
-
49
+
50
50
  #
51
51
  # Return everything that matches the query.
52
52
  #
53
53
  def all(query)
54
- return to_enum(:all, query) unless block_given?
55
-
54
+ return to_enum(:all, query) unless block_given?
55
+
56
56
  if @hash.include? query
57
57
  yield @hash[query]
58
58
  return
@@ -72,22 +72,22 @@ class Rash
72
72
  end
73
73
  end
74
74
  end
75
-
75
+
76
76
  when Integer
77
- @ranges.each do |range|
77
+ @ranges.each do |range|
78
78
  yield @hash[range] if range.include? query
79
79
  end
80
-
80
+
81
81
  when Regexp
82
82
  # TODO: this doesn't seem very useful. should I ditch it? let me know!
83
83
  @hash.each do |key,val|
84
- yield val if key.is_a? String and query =~ key
84
+ yield val if key.is_a? String and query =~ key
85
85
  end
86
-
86
+
87
87
  end
88
-
88
+
89
89
  end
90
-
90
+
91
91
  def method_missing(*args, &block)
92
92
  @hash.send(*args, &block)
93
93
  end
@@ -95,7 +95,7 @@ class Rash
95
95
  private
96
96
 
97
97
  def optimize_if_necessary!
98
- if (@lookups += 1) >= @optimize_every
98
+ if (@lookups += 1) >= @optimize_every
99
99
  @regexes = @regex_counts.sort_by { |regex,count| -count }.map { |regex,count| regex }
100
100
  @lookups = 0
101
101
  end
@@ -1,7 +1,7 @@
1
1
  #
2
2
  # The ratio between two numbers (eg: 2:1, 3:4)
3
3
  #
4
- # Can be compared, added, "percent"ed, "to_f"ed, and displayed.
4
+ # Can be compared, added, "percent"ed, "to_f"ed, and displayed.
5
5
  #
6
6
  class Ratio
7
7
 
@@ -5,11 +5,11 @@ require 'epitools/minimal'
5
5
  # Includes: process listing, platform detection, etc.
6
6
  #
7
7
  module Sys
8
-
8
+
9
9
  #-----------------------------------------------------------------------------
10
10
 
11
11
  #
12
- # Return the current operating system: Darwin, Linux, or Windows.
12
+ # Return the current operating system: Darwin, Linux, or Windows.
13
13
  #
14
14
  def self.os
15
15
  return @os if @os
@@ -20,7 +20,7 @@ module Sys
20
20
  else
21
21
  host_os = Config::CONFIG['host_os']
22
22
  end
23
-
23
+
24
24
  case host_os
25
25
  when /darwin/
26
26
  @os = "Darwin"
@@ -36,7 +36,7 @@ module Sys
36
36
 
37
37
  @os
38
38
  end
39
-
39
+
40
40
  #
41
41
  # Is this Linux?
42
42
  #
@@ -85,10 +85,10 @@ module Sys
85
85
  [:minflt, :to_i],
86
86
  [:command,:to_s],
87
87
  ]
88
-
88
+
89
89
  PS_FIELDS = PS_FIELD_TABLE.map { |name, func| name }
90
90
  PS_FIELD_TRANSFORMS = Hash[ *PS_FIELD_TABLE.flatten ]
91
-
91
+
92
92
  class ProcessNotFound < Exception; end
93
93
 
94
94
  #
@@ -124,7 +124,7 @@ module Sys
124
124
  "U"=>:wait,
125
125
  "Z"=>:zombie,
126
126
  "W"=>:swapped,
127
-
127
+
128
128
  "s"=>:session_leader,
129
129
  "X"=>:debugging,
130
130
  "E"=>:exiting,
@@ -133,7 +133,7 @@ module Sys
133
133
  "+"=>:foreground,
134
134
  "L"=>:locked_pages,
135
135
  }
136
-
136
+
137
137
  LINUX_STATES = {
138
138
  "R"=>:running,
139
139
  "S"=>:sleeping,
@@ -150,7 +150,7 @@ module Sys
150
150
  "L"=>:locked_pages,
151
151
  "l"=>:multithreaded,
152
152
  }
153
-
153
+
154
154
  def initialize(*args)
155
155
  @dead = false
156
156
  args << stat_to_state(args[PS_FIELDS.index(:stat)])
@@ -168,11 +168,11 @@ module Sys
168
168
 
169
169
  #
170
170
  # Convert all the process information to a hash.
171
- #
171
+ #
172
172
  def to_hash
173
173
  Hash[ *members.zip(values).flatten(1) ]
174
174
  end
175
-
175
+
176
176
  #
177
177
  # Send the TERM signal to this process.
178
178
  #
@@ -181,61 +181,61 @@ module Sys
181
181
  Process.kill(signal, pid)
182
182
  # TODO: handle exception Errno::ESRCH (no such process)
183
183
  end
184
-
184
+
185
185
  #
186
186
  # Has this process been killed?
187
187
  #
188
188
  def dead?
189
189
  @dead ||= Sys.pid(pid).empty?
190
190
  end
191
-
191
+
192
192
  #
193
193
  # Refresh this process' statistics.
194
194
  #
195
195
  def refresh
196
196
  processes = Sys.ps(pid)
197
-
197
+
198
198
  if processes.empty?
199
199
  @dead = true
200
200
  raise ProcessNotFound
201
201
  end
202
-
202
+
203
203
  updated_process = processes.first
204
204
  members.each { |member| self[member] = updated_process[member] }
205
205
  self
206
206
  end
207
-
207
+
208
208
  alias_method :name, :command
209
209
 
210
- # Linux-specific methods
210
+ # Linux-specific methods
211
211
  if Sys.linux?
212
-
212
+
213
213
  def exename
214
214
  @exename ||= File.readlink("/proc/#{pid}/exe") rescue :unknown
215
215
  @exename == :unknown ? nil : @exename
216
216
  end
217
-
217
+
218
218
  def fds
219
219
  Dir["/proc/#{pid}/fd/*"].map { |fd| File.readlink(fd) rescue nil }
220
220
  end
221
-
221
+
222
222
  end
223
-
224
- private
225
-
223
+
224
+ private
225
+
226
226
  def stat_to_state(str)
227
227
  states = case Sys.os
228
228
  when "Linux" then LINUX_STATES
229
229
  when "Darwin" then DARWIN_STATES
230
230
  else raise "Unsupported platform: #{Sys.os}"
231
231
  end
232
-
232
+
233
233
  str.scan(/./).map { |char| states[char] }.compact
234
234
  end
235
235
  end
236
236
 
237
237
  #-----------------------------------------------------------------------------
238
-
238
+
239
239
  def self.tree
240
240
  tree = Sys.ps.group_by(&:ppid)
241
241
  Hash[tree.map do |ppid, children|
@@ -246,35 +246,35 @@ module Sys
246
246
 
247
247
  #
248
248
  # List all (or specified) processes, and return ProcessInfo objects.
249
- # (Takes an optional list of pids as arguments.)
249
+ # (Takes an optional list of pids as arguments.)
250
250
  #
251
251
  def self.ps(*pids)
252
252
  #return @@cache if @@cache
253
253
 
254
254
  options = PS_FIELDS.join(',')
255
-
255
+
256
256
  pids = pids.map(&:to_i)
257
-
257
+
258
258
  if pids.any?
259
259
  command = "ps -p #{pids.join(',')} -o #{options}"
260
260
  else
261
261
  command = "ps awx -o #{options}"
262
262
  end
263
263
 
264
- lines = `#{command}`.lines.to_a
264
+ lines = `#{command}`.lines.to_a
265
265
 
266
266
  lines[1..-1].map do |line|
267
267
  fields = line.split
268
268
  if fields.size > PS_FIELDS.size
269
- fields = fields[0..PS_FIELDS.size-2] + [fields[PS_FIELDS.size-1..-1].join(" ")]
269
+ fields = fields[0..PS_FIELDS.size-2] + [fields[PS_FIELDS.size-1..-1].join(" ")]
270
270
  end
271
-
271
+
272
272
  fields = PS_FIELDS.zip(fields).map { |name, value| value.send(PS_FIELD_TRANSFORMS[name]) }
273
-
273
+
274
274
  ProcessInfo.new(*fields)
275
275
  end
276
276
  end
277
-
277
+
278
278
  #-----------------------------------------------------------------------------
279
279
 
280
280
  def self.refresh
@@ -288,7 +288,7 @@ module Sys
288
288
  # (Execute Signal.list to see what's available.)
289
289
  #
290
290
  # No paramters defaults to all signals except VTALRM, CHLD, CLD, and EXIT.
291
- #
291
+ #
292
292
  def self.trap(*args, &block)
293
293
  options = if args.last.is_a?(Hash) then args.pop else Hash.new end
294
294
  args = [args].flatten
@@ -304,14 +304,14 @@ module Sys
304
304
  Signal.trap(signal) { yield signal }
305
305
  end
306
306
  end
307
-
307
+
308
308
  #-----------------------------------------------------------------------------
309
309
 
310
310
  #
311
311
  # A metaprogramming helper that allows you to write platform-specific methods
312
312
  # which the user can call with one name. Here's how to use it:
313
313
  #
314
- # Define these methods:
314
+ # Define these methods:
315
315
  # reboot_linux, reboot_darwin, reboot_windows
316
316
  #
317
317
  # Call the magic method:
@@ -321,7 +321,7 @@ module Sys
321
321
  #
322
322
  # (Note: If you didn't create a method for a specific platform, then you'll get
323
323
  # NoMethodError exception when the "reboot" method is called on that platform.)
324
- #
324
+ #
325
325
  def self.cross_platform_method(name)
326
326
  platform_method_name = "#{name}_#{os.downcase}"
327
327
  metaclass.instance_eval do
@@ -342,11 +342,11 @@ module Sys
342
342
  def self.hostname_linux
343
343
  `uname -n`.strip
344
344
  end
345
-
345
+
346
346
  def self.hostname_mac
347
347
  `uname -n`.strip.gsub(/\.local$/, '')
348
348
  end
349
-
349
+
350
350
  def self.hostname_windows
351
351
  raise NotImplementedError
352
352
  end
@@ -394,7 +394,7 @@ module Sys
394
394
 
395
395
  device_ips
396
396
  end
397
-
397
+
398
398
  #
399
399
  # Windows: Return a hash of (device name, IP address) pairs.
400
400
  #
@@ -411,7 +411,7 @@ module Sys
411
411
  end
412
412
  result
413
413
  end
414
-
414
+
415
415
  #-----------------------------------------------------------------------------
416
416
 
417
417
  cross_platform_method :browser_open
@@ -440,11 +440,11 @@ module Sys
440
440
  #Mem: 4124380 3388548 735832 0 561888 968004
441
441
  #-/+ buffers/cache: 1858656 2265724
442
442
  #Swap: 2104504 166724 1937780
443
-
443
+
444
444
  #$ vmstat
445
- raise "Not implemented"
445
+ raise "Not implemented"
446
446
  end
447
-
447
+
448
448
  def self.memstat_darwin
449
449
  #$ vm_stat
450
450
  #Mach Virtual Memory Statistics: (page size of 4096 bytes)
@@ -462,7 +462,7 @@ module Sys
462
462
  #Object cache: 16 hits of 255782 lookups (0% hit rate)
463
463
 
464
464
  #$ iostat
465
- raise "Not implemented"
465
+ raise "Not implemented"
466
466
  end
467
467
 
468
468
  #-----------------------------------------------------------------------------
@@ -477,10 +477,10 @@ module Sys
477
477
  #SMC DRIVE BAY 1: 41 C
478
478
  #SMC NORTHBRIDGE POS 1: 46 C
479
479
  #SMC WLAN CARD: 45 C
480
- raise "Not implemented"
480
+ raise "Not implemented"
481
481
  end
482
482
 
483
- end
483
+ end
484
484
 
485
485
  if $0 == __FILE__
486
486
  require 'pp'
@@ -80,11 +80,11 @@
80
80
  # ''
81
81
  # /
82
82
  # r
83
- # / \
83
+ # / \
84
84
  # o u
85
- # / \
85
+ # / \
86
86
  # w b
87
- # \
87
+ # \
88
88
  # y
89
89
  #
90
90
  # are actually stored as
@@ -92,7 +92,7 @@
92
92
  # ''
93
93
  # /
94
94
  # r
95
- # / \
95
+ # / \
96
96
  # ow uby
97
97
  #
98
98
  # Because of this implementation (and to allow Trie.find to be called on
@@ -21,11 +21,11 @@
21
21
  # ["bigdecimal"] => BigDecimal
22
22
  # ["hex"] => Integer
23
23
  # ["date", "time", "datetime"] => DateTime (using DateTime.parse)
24
- # ["timestamp", "unixtime"] => Time (using Time.at)
24
+ # ["timestamp", "unixtime"] => Time (using Time.at)
25
25
  # ["bool", "boolean"] => Boolean, using the following rules:
26
- # false when: false, nil, 0, "0", "off", "no",
26
+ # false when: false, nil, 0, "0", "off", "no",
27
27
  # "false", "disabled", "disable"
28
- # true when: true, 1, "1", "on", "yes",
28
+ # true when: true, 1, "1", "on", "yes",
29
29
  # "true", "enabled", "enable"
30
30
  #
31
31
  class TypedStruct < Struct
@@ -48,7 +48,7 @@ class TypedStruct < Struct
48
48
  ["hex"] => proc { |me| me.to_i(16) },
49
49
  ["date", "time", "datetime"] => proc { |me| DateTime.parse me },
50
50
  ["timestamp", "unixtime"] => proc { |me| Time.at me },
51
- ["bool", "boolean"] => proc do |me|
51
+ ["bool", "boolean"] => proc do |me|
52
52
  case me
53
53
  when false, nil, 0, /^(0|off|no|false|disabled?)$/
54
54
  false
@@ -93,7 +93,7 @@ class TypedStruct < Struct
93
93
  struct = new(*pairs.transpose.first)
94
94
 
95
95
  # overload setter methods to call the proc
96
- pairs.each do |field, converter|
96
+ pairs.each do |field, converter|
97
97
  next if converter == :passthru
98
98
  struct.send(:define_method, "#{field}=") do |val|
99
99
  self[field] = ( val and converter.call val )