epitools 0.4.37 → 0.4.38
Sign up to get free protection for your applications and to get access to all the features.
- 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
|