epitools 0.4.37 → 0.4.38
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/VERSION +1 -1
- data/epitools.gemspec +2 -2
- data/lib/epitools.rb +57 -0
- data/lib/epitools/autoloads.rb +2 -1
- data/lib/epitools/basetypes.rb +16 -1
- data/lib/epitools/browser.rb +1 -1
- data/lib/epitools/clitools.rb +2 -0
- data/lib/epitools/path.rb +95 -2
- data/lib/epitools/zopen.rb +4 -3
- data/spec/basetypes_spec.rb +2 -0
- data/spec/path_spec.rb +35 -2
- metadata +2 -2
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.4.
|
1
|
+
0.4.38
|
data/epitools.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{epitools}
|
8
|
-
s.version = "0.4.
|
8
|
+
s.version = "0.4.38"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["epitron"]
|
12
|
-
s.date = %q{2011-
|
12
|
+
s.date = %q{2011-06-07}
|
13
13
|
s.description = %q{Miscellaneous utility libraries to make my life easier.}
|
14
14
|
s.email = %q{chris@ill-logic.com}
|
15
15
|
s.extra_rdoc_files = [
|
data/lib/epitools.rb
CHANGED
@@ -2,6 +2,7 @@ require 'pp'
|
|
2
2
|
require 'set'
|
3
3
|
|
4
4
|
class Object
|
5
|
+
|
5
6
|
unless defined?(__DIR__)
|
6
7
|
#
|
7
8
|
# This method is convenience for the `File.expand_path(File.dirname(__FILE__))` idiom.
|
@@ -13,8 +14,64 @@ class Object
|
|
13
14
|
::File.expand_path(::File.join(dir, *args.map{|a| a.to_s}))
|
14
15
|
end
|
15
16
|
end
|
17
|
+
|
18
|
+
#
|
19
|
+
# 'autoreq' is a replacement for autoload that can load gems.
|
20
|
+
#
|
21
|
+
# Usage:
|
22
|
+
# autoreq :Constant, 'thing-to-require'
|
23
|
+
# autoreq :Constant, 'thing-to-require'
|
24
|
+
# autoreq :OtherConstant do
|
25
|
+
# gem 'somegem', '~> 1.2'
|
26
|
+
# require 'somegem'
|
27
|
+
# end
|
28
|
+
#
|
29
|
+
def autoreq(const, path=nil, &block)
|
30
|
+
raise "Error: autoreq must be supplied with a file to load, or a block." unless !!path ^ block_given?
|
31
|
+
|
32
|
+
if block_given?
|
33
|
+
Module.autoreqs[const] = block
|
34
|
+
else
|
35
|
+
Module.autoreqs[const] = path
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
#
|
42
|
+
# Patch 'Module#const_missing' to support 'autoreq'
|
43
|
+
#
|
44
|
+
class Module
|
45
|
+
|
46
|
+
@@autoreq_searching_for = nil
|
47
|
+
|
48
|
+
alias const_missing_without_autoreq const_missing
|
49
|
+
|
50
|
+
def const_missing(const)
|
51
|
+
return if const == @@autoreq_searching_for
|
52
|
+
|
53
|
+
if thing = autoreqs[const]
|
54
|
+
case thing
|
55
|
+
when String, Symbol
|
56
|
+
require thing
|
57
|
+
when Proc
|
58
|
+
Object.class_eval(&thing)
|
59
|
+
else
|
60
|
+
raise "Error: Don't know how to autoload a #{thing.class}: #{thing.inspect}"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
@@autoreq_searching_for = const
|
65
|
+
const_get(const) || const_missing_without_autoreq(const)
|
66
|
+
end
|
67
|
+
|
68
|
+
def autoreqs
|
69
|
+
@@autoreqs ||= {}
|
70
|
+
end
|
71
|
+
|
16
72
|
end
|
17
73
|
|
74
|
+
|
18
75
|
## Pretty error messages
|
19
76
|
require_wrapper = proc do |mod|
|
20
77
|
#p [:loading, mod]
|
data/lib/epitools/autoloads.rb
CHANGED
data/lib/epitools/basetypes.rb
CHANGED
@@ -483,7 +483,7 @@ module Enumerable
|
|
483
483
|
def foldl(methodname=nil, &block)
|
484
484
|
result = nil
|
485
485
|
|
486
|
-
raise "Error: pass a parameter OR a block, not both!"
|
486
|
+
raise "Error: pass a parameter OR a block, not both!" unless !!methodname ^ block_given?
|
487
487
|
|
488
488
|
if methodname
|
489
489
|
|
@@ -842,6 +842,19 @@ class Object
|
|
842
842
|
end
|
843
843
|
end
|
844
844
|
|
845
|
+
unless IO.respond_to? :copy_stream
|
846
|
+
|
847
|
+
class IO
|
848
|
+
|
849
|
+
def self.copy_stream(input, output)
|
850
|
+
while chunk = input.read(8192)
|
851
|
+
output.write(chunk)
|
852
|
+
end
|
853
|
+
end
|
854
|
+
|
855
|
+
end
|
856
|
+
|
857
|
+
end
|
845
858
|
|
846
859
|
#
|
847
860
|
# Emit a quick debug message (only if $DEBUG is true)
|
@@ -856,3 +869,5 @@ def dmsg(msg)
|
|
856
869
|
end
|
857
870
|
end
|
858
871
|
end
|
872
|
+
|
873
|
+
|
data/lib/epitools/browser.rb
CHANGED
@@ -133,7 +133,7 @@ class Browser
|
|
133
133
|
#end
|
134
134
|
|
135
135
|
# Determine the cache setting
|
136
|
-
use_cache = options[:
|
136
|
+
use_cache = (options[:cached] == false) ? false : @use_cache
|
137
137
|
|
138
138
|
cached_already = cache.include?(url)
|
139
139
|
|
data/lib/epitools/clitools.rb
CHANGED
data/lib/epitools/path.rb
CHANGED
@@ -22,6 +22,9 @@ class Path
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
+
#
|
26
|
+
# TODO: Remove the tempfile when the Path object is garbage collected or freed.
|
27
|
+
#
|
25
28
|
def self.tmpfile(prefix="tmp")
|
26
29
|
path = Path[ Tempfile.new(prefix).path ]
|
27
30
|
yield path if block_given?
|
@@ -111,7 +114,6 @@ class Path
|
|
111
114
|
end
|
112
115
|
end
|
113
116
|
|
114
|
-
|
115
117
|
## getters
|
116
118
|
|
117
119
|
# The directories in the path, split into an array. (eg: ['usr', 'src', 'linux'])
|
@@ -153,6 +155,11 @@ class Path
|
|
153
155
|
end
|
154
156
|
end
|
155
157
|
|
158
|
+
def exts
|
159
|
+
extensions = basename.split('.')[1..-1]
|
160
|
+
extensions += [@ext] if @ext
|
161
|
+
extensions
|
162
|
+
end
|
156
163
|
|
157
164
|
## fstat info
|
158
165
|
|
@@ -245,6 +252,8 @@ class Path
|
|
245
252
|
File.open(path, mode)
|
246
253
|
end
|
247
254
|
end
|
255
|
+
alias_method :io, :open
|
256
|
+
alias_method :stream, :open
|
248
257
|
|
249
258
|
def read(length=nil, offset=nil)
|
250
259
|
File.read(path, length, offset)
|
@@ -373,10 +382,63 @@ class Path
|
|
373
382
|
def md5
|
374
383
|
Digest::MD5.file(self).hexdigest
|
375
384
|
end
|
376
|
-
|
377
385
|
alias_method :md5sum, :md5
|
378
386
|
|
379
387
|
|
388
|
+
# http://ruby-doc.org/stdlib/libdoc/zlib/rdoc/index.html
|
389
|
+
|
390
|
+
def gzip
|
391
|
+
gz_filename = self.with(:filename=>filename+".gz")
|
392
|
+
|
393
|
+
raise "#{gz_filename} already exists" if gz_filename.exists?
|
394
|
+
|
395
|
+
open("rb") do |input|
|
396
|
+
Zlib::GzipWriter.open(gz_filename) do |gzip|
|
397
|
+
IO.copy_stream(input, gzip)
|
398
|
+
end
|
399
|
+
end
|
400
|
+
|
401
|
+
gz_filename
|
402
|
+
end
|
403
|
+
|
404
|
+
def gzip!
|
405
|
+
gzipped = self.gzip
|
406
|
+
self.rm
|
407
|
+
self.path = gzipped.path
|
408
|
+
end
|
409
|
+
|
410
|
+
def gunzip
|
411
|
+
raise "Not a .gz file" unless ext == "gz"
|
412
|
+
|
413
|
+
gunzipped = self.with(:ext=>nil)
|
414
|
+
|
415
|
+
gunzipped.open("wb") do |out|
|
416
|
+
Zlib::GzipReader.open(self) do |gunzip|
|
417
|
+
IO.copy_stream(gunzip, out)
|
418
|
+
end
|
419
|
+
end
|
420
|
+
|
421
|
+
gunzipped
|
422
|
+
end
|
423
|
+
|
424
|
+
def gunzip!
|
425
|
+
gunzipped = self.gunzip
|
426
|
+
self.rm
|
427
|
+
self.path = gunzipped.path
|
428
|
+
end
|
429
|
+
|
430
|
+
#
|
431
|
+
# Return the IO object for this file.
|
432
|
+
#
|
433
|
+
def io
|
434
|
+
open
|
435
|
+
end
|
436
|
+
alias_method :stream, :io
|
437
|
+
|
438
|
+
def =~(pattern)
|
439
|
+
path =~ pattern
|
440
|
+
end
|
441
|
+
|
380
442
|
## Class method versions of FileUtils-like things
|
381
443
|
|
382
444
|
%w[
|
@@ -394,9 +456,40 @@ class Path
|
|
394
456
|
end
|
395
457
|
}
|
396
458
|
end
|
459
|
+
|
460
|
+
|
461
|
+
# Mimetype finding and magic (requires 'mimemagic' gem)
|
462
|
+
|
463
|
+
#
|
464
|
+
# Find the file's mimetype (first from file extension, then by magic)
|
465
|
+
#
|
466
|
+
def mimetype
|
467
|
+
mimetype_from_ext || magic
|
468
|
+
end
|
469
|
+
alias_method :identify, :mimetype
|
470
|
+
|
471
|
+
#
|
472
|
+
# Find the file's mimetype (only using the file extension)
|
473
|
+
#
|
474
|
+
def mimetype_from_ext
|
475
|
+
MimeMagic.by_extension(ext)
|
476
|
+
end
|
477
|
+
|
478
|
+
#
|
479
|
+
# Find the file's mimetype (by magic)
|
480
|
+
#
|
481
|
+
def magic
|
482
|
+
open { |io| MimeMagic.by_magic(io) }
|
483
|
+
end
|
484
|
+
|
485
|
+
def ext_by_magic
|
486
|
+
# TODO: return the extension for the mime type.
|
487
|
+
raise NotImplementedError
|
488
|
+
end
|
397
489
|
|
398
490
|
end
|
399
491
|
|
492
|
+
|
400
493
|
#
|
401
494
|
# A wrapper for URL objects
|
402
495
|
#
|
data/lib/epitools/zopen.rb
CHANGED
@@ -14,11 +14,12 @@ require 'epitools'
|
|
14
14
|
# zopen("otherfile.gz", "w") #=> #<Zlib::GzipWriter:0x7fe30448>>
|
15
15
|
# zopen("test.txt.gz") { |f| f.read } # read the contents of the .gz file, then close the file handle automatically.
|
16
16
|
#
|
17
|
-
def zopen(
|
17
|
+
def zopen(path, mode="r")
|
18
18
|
|
19
|
-
|
19
|
+
path = Path[path] unless path.is_a? Path
|
20
|
+
file = path.open(mode)
|
20
21
|
|
21
|
-
if
|
22
|
+
if path.ext == "gz"
|
22
23
|
case mode
|
23
24
|
when "r", "rb"
|
24
25
|
file = Zlib::GzipReader.new(file)
|
data/spec/basetypes_spec.rb
CHANGED
data/spec/path_spec.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
|
-
require 'epitools
|
2
|
-
require 'epitools/path'
|
1
|
+
require 'epitools'
|
3
2
|
|
4
3
|
describe Path do
|
5
4
|
|
@@ -216,4 +215,38 @@ describe Path do
|
|
216
215
|
path.sha1.should == Path.sha1(path)
|
217
216
|
end
|
218
217
|
|
218
|
+
it "gzips and gunzips" do
|
219
|
+
path = Path.tmpfile
|
220
|
+
500.times { path << "whee" }
|
221
|
+
|
222
|
+
path.ext.should_not == "gz"
|
223
|
+
gzipped = path.gzip
|
224
|
+
|
225
|
+
before = path.size
|
226
|
+
after = gzipped.size
|
227
|
+
before.should > after
|
228
|
+
gzipped.ext.should == "gz"
|
229
|
+
|
230
|
+
gunzipped = gzipped.gunzip
|
231
|
+
gunzipped.size.should == before
|
232
|
+
gunzipped.should == path
|
233
|
+
end
|
234
|
+
|
235
|
+
it "exts" do
|
236
|
+
path = Path["file.tar.gz"]
|
237
|
+
path.ext.should == "gz"
|
238
|
+
path.exts.should == ["tar", "gz"]
|
239
|
+
end
|
240
|
+
|
241
|
+
it "ios and streams" do
|
242
|
+
path = Path.tmpfile
|
243
|
+
f = open(path)
|
244
|
+
f.inspect.should == path.io.inspect
|
245
|
+
f.inspect.should == path.stream.inspect
|
246
|
+
end
|
247
|
+
|
248
|
+
it "mimes" do
|
249
|
+
Path[__FILE__].mimetype == "application/x-ruby"
|
250
|
+
end
|
251
|
+
|
219
252
|
end
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: epitools
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.4.
|
5
|
+
version: 0.4.38
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- epitron
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-
|
13
|
+
date: 2011-06-07 00:00:00 -04:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|