fs 0.1.0 → 0.1.1
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.mdown +0 -1
- data/lib/fs.rb +2 -0
- data/lib/fs/alias.rb +3 -0
- data/lib/fs/base.rb +145 -1
- data/lib/fs/version.rb +1 -1
- data/spec/base_spec.rb +249 -0
- data/spec/support/test_dir_support.rb +1 -2
- metadata +2 -2
data/README.mdown
CHANGED
data/lib/fs.rb
CHANGED
data/lib/fs/alias.rb
CHANGED
@@ -7,11 +7,14 @@ module FS
|
|
7
7
|
:rmdir => :removedir,
|
8
8
|
:rm_r => :removedirs,
|
9
9
|
:cd => :changedir,
|
10
|
+
:pwd => :currentdir,
|
10
11
|
:mv => :move,
|
11
12
|
:cp => :copy,
|
12
13
|
:rm => :remove,
|
13
14
|
:cat => :read,
|
14
15
|
:ln => :link,
|
16
|
+
:dir? => :directory?,
|
17
|
+
:expand => :expand_path,
|
15
18
|
}
|
16
19
|
|
17
20
|
def self.included(base)
|
data/lib/fs/base.rb
CHANGED
@@ -111,6 +111,112 @@ module FS
|
|
111
111
|
def currentdir
|
112
112
|
Dir.pwd
|
113
113
|
end
|
114
|
+
|
115
|
+
# tmpdir / Dir.tmpdir
|
116
|
+
def tempdir
|
117
|
+
Dir.tmpdir
|
118
|
+
end
|
119
|
+
|
120
|
+
# TODO: use separate options for prefix, suffix and target_dir
|
121
|
+
# tmpdir / Dir.mktmpdir
|
122
|
+
def maketempdir(prefix_suffix=nil, parent_dir=nil)
|
123
|
+
Dir.mktmpdir(prefix_suffix, parent_dir)
|
124
|
+
end
|
125
|
+
|
126
|
+
# uses the methods of the tmpdir library to touch a new file in tempdir
|
127
|
+
def maketempfile(prefix_suffix=nil, parent_dir=nil)
|
128
|
+
Dir::Tmpname.create(prefix_suffix || "f", parent_dir || Dir.tmpdir) {|n| FileUtils.touch(n)}
|
129
|
+
end
|
130
|
+
|
131
|
+
# same as the `tree` shell command
|
132
|
+
def tree(dir='.')
|
133
|
+
output = []
|
134
|
+
visit_tree(output, '.', '', '', '', dir)
|
135
|
+
output.join("\n")
|
136
|
+
end
|
137
|
+
|
138
|
+
# File.exist?
|
139
|
+
def exist?(path)
|
140
|
+
File.exist?(path)
|
141
|
+
end
|
142
|
+
|
143
|
+
# File.directory?
|
144
|
+
def directory?(path)
|
145
|
+
File.directory?(path)
|
146
|
+
end
|
147
|
+
|
148
|
+
# File.file?
|
149
|
+
def file?(path)
|
150
|
+
File.file?(path)
|
151
|
+
end
|
152
|
+
|
153
|
+
# uses File.size and Dir.entries
|
154
|
+
# for files it returns `nil` if file does not exist, `true` if it's empty
|
155
|
+
def empty?(path)
|
156
|
+
if !File.exist?(path)
|
157
|
+
nil
|
158
|
+
elsif File.directory?(path)
|
159
|
+
Dir.entries(path) == ['.', '..']
|
160
|
+
else
|
161
|
+
File.size(path) == 0
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
# File.join
|
166
|
+
def join(*args)
|
167
|
+
File.join(*args)
|
168
|
+
end
|
169
|
+
|
170
|
+
# File.expand_path
|
171
|
+
def expand_path(path)
|
172
|
+
File.expand_path(path)
|
173
|
+
end
|
174
|
+
|
175
|
+
# checks for a slash at the beginning
|
176
|
+
def absolute?(path)
|
177
|
+
%r{\A/} =~ path ? true : false
|
178
|
+
end
|
179
|
+
|
180
|
+
# File.dirname
|
181
|
+
# "tmp/foo/bar.todo" => "tmp/foo"
|
182
|
+
def dirname(path)
|
183
|
+
File.dirname(path)
|
184
|
+
end
|
185
|
+
|
186
|
+
# File.basename
|
187
|
+
# "tmp/foo/bar.todo" => "bar.todo"
|
188
|
+
def basename(path)
|
189
|
+
File.basename(path)
|
190
|
+
end
|
191
|
+
|
192
|
+
# File.extname
|
193
|
+
# "tmp/foo/bar.todo" => ".todo"
|
194
|
+
def extname(path)
|
195
|
+
File.extname(path)
|
196
|
+
end
|
197
|
+
|
198
|
+
# "tmp/foo/bar.todo" => "bar"
|
199
|
+
def filename(path)
|
200
|
+
return '' if path == '/' || path == '.'
|
201
|
+
base = File.basename(path)
|
202
|
+
ext = File.extname(path)
|
203
|
+
ext.empty? ? base :base[0...-ext.size]
|
204
|
+
end
|
205
|
+
|
206
|
+
# "tmp/foo/bar.todo" => ["tmp/foo", "bar", ".todo"]
|
207
|
+
def splitname(path)
|
208
|
+
[dirname(path), filename(path), extname(path)]
|
209
|
+
end
|
210
|
+
|
211
|
+
# __FILE__ of the caller
|
212
|
+
def this_file
|
213
|
+
caller_file(caller)
|
214
|
+
end
|
215
|
+
|
216
|
+
# File.dirname(__FILE__) of the caller
|
217
|
+
def this_dir
|
218
|
+
File.dirname(caller_file(caller))
|
219
|
+
end
|
114
220
|
|
115
221
|
private
|
116
222
|
|
@@ -120,8 +226,46 @@ module FS
|
|
120
226
|
|
121
227
|
def glob(dir, *patterns)
|
122
228
|
fulldir = File.expand_path(dir)
|
229
|
+
regexp = /^#{Regexp.escape(fulldir)}\/?/
|
123
230
|
Dir.glob(File.join(fulldir, patterns)).map do |path|
|
124
|
-
path.gsub(
|
231
|
+
path.gsub(regexp, '')
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
def visit_tree(output, parent_path, indent, arm, tie, node)
|
236
|
+
output << "#{indent}#{arm}#{tie}#{node}"
|
237
|
+
|
238
|
+
node_path = File.expand_path(node, parent_path)
|
239
|
+
return unless File.directory?(node_path) && File.readable?(node_path)
|
240
|
+
|
241
|
+
subnodes = FS.list(node_path)
|
242
|
+
return if subnodes.empty?
|
243
|
+
|
244
|
+
arms = Array.new(subnodes.length - 1, '|') << '`'
|
245
|
+
arm_to_indent = {
|
246
|
+
'' => '',
|
247
|
+
'|' => '| ',
|
248
|
+
'`' => ' '
|
249
|
+
}
|
250
|
+
subnodes.each_with_index do |subnode, index|
|
251
|
+
visit_tree(output, node_path, indent + arm_to_indent[arm], arms[index], '-- ', subnode)
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
def caller_file(trace)
|
256
|
+
if arr = parse_caller(trace.first)
|
257
|
+
arr.first
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
# http://grosser.it/2009/07/01/getting-the-caller-method-in-ruby/
|
262
|
+
# Stolen from ActionMailer, where this was used but was not made reusable
|
263
|
+
def parse_caller(at)
|
264
|
+
if /^(.+?):(\d+)(?::in `(.*)')?/ =~ at
|
265
|
+
file = Regexp.last_match[1]
|
266
|
+
line = Regexp.last_match[2].to_i
|
267
|
+
method = Regexp.last_match[3]
|
268
|
+
[file, line, method]
|
125
269
|
end
|
126
270
|
end
|
127
271
|
|
data/lib/fs/version.rb
CHANGED
data/spec/base_spec.rb
CHANGED
@@ -322,4 +322,253 @@ describe FS::Base do
|
|
322
322
|
end
|
323
323
|
end
|
324
324
|
|
325
|
+
describe 'tree' do
|
326
|
+
before(:each) do
|
327
|
+
FS.touch('a.file')
|
328
|
+
FS.makedir('baz')
|
329
|
+
FS.touch('baz/b.file')
|
330
|
+
FS.mkdir('baz/bar')
|
331
|
+
FS.touch('baz/bar/c.file')
|
332
|
+
FS.touch('baz/d.file')
|
333
|
+
FS.makedir('foo')
|
334
|
+
FS.touch('foo/e.file')
|
335
|
+
end
|
336
|
+
|
337
|
+
it 'returns the tree of the current dir' do
|
338
|
+
tree = <<-TXT
|
339
|
+
.
|
340
|
+
|-- a.file
|
341
|
+
|-- baz
|
342
|
+
| |-- b.file
|
343
|
+
| |-- bar
|
344
|
+
| | `-- c.file
|
345
|
+
| `-- d.file
|
346
|
+
`-- foo
|
347
|
+
`-- e.file
|
348
|
+
TXT
|
349
|
+
FS.tree.should eql(tree.strip)
|
350
|
+
end
|
351
|
+
|
352
|
+
it 'returns the tree of a dir' do
|
353
|
+
tree = <<-TXT
|
354
|
+
baz
|
355
|
+
|-- b.file
|
356
|
+
|-- bar
|
357
|
+
| `-- c.file
|
358
|
+
`-- d.file
|
359
|
+
TXT
|
360
|
+
FS.tree('baz').should eql(tree.strip)
|
361
|
+
end
|
362
|
+
|
363
|
+
end
|
364
|
+
|
365
|
+
describe 'exist?' do
|
366
|
+
it 'returns if a path exist' do
|
367
|
+
FS.makedir('foo')
|
368
|
+
FS.touch('bar')
|
369
|
+
FS.exist?('foo').should be_true
|
370
|
+
FS.exist?('bar').should be_true
|
371
|
+
FS.exist?('baz').should be_false
|
372
|
+
end
|
373
|
+
end
|
374
|
+
|
375
|
+
describe 'directory?' do
|
376
|
+
it 'checks for a directory' do
|
377
|
+
FS.makedir('foo')
|
378
|
+
FS.touch('bar')
|
379
|
+
FS.directory?('foo').should be_true
|
380
|
+
FS.directory?('bar').should be_false
|
381
|
+
FS.directory?('baz').should be_false
|
382
|
+
end
|
383
|
+
end
|
384
|
+
|
385
|
+
describe 'file?' do
|
386
|
+
it 'checks for a file' do
|
387
|
+
FS.makedir('foo')
|
388
|
+
FS.touch('bar')
|
389
|
+
FS.file?('foo').should be_false
|
390
|
+
FS.file?('bar').should be_true
|
391
|
+
FS.file?('baz').should be_false
|
392
|
+
end
|
393
|
+
end
|
394
|
+
|
395
|
+
describe 'empty?' do
|
396
|
+
it 'returns nil if the path does not exist' do
|
397
|
+
FS.exist?('foobar').should be_false
|
398
|
+
FS.empty?('foobar').should be_nil
|
399
|
+
end
|
400
|
+
|
401
|
+
it 'returns if a file is empty' do
|
402
|
+
FS.touch('empty.file')
|
403
|
+
FS.write('content.file', 'something')
|
404
|
+
FS.empty?('empty.file').should be_true
|
405
|
+
FS.empty?('content.file').should be_false
|
406
|
+
end
|
407
|
+
|
408
|
+
it 'returns if a dir is empty' do
|
409
|
+
FS.mkdir('empty.dir')
|
410
|
+
FS.mkdir('content.dir')
|
411
|
+
FS.touch('content.dir/some.file')
|
412
|
+
FS.empty?('empty.dir').should be_true
|
413
|
+
FS.empty?('content.dir').should be_false
|
414
|
+
end
|
415
|
+
end
|
416
|
+
|
417
|
+
describe 'join' do
|
418
|
+
it 'joins pathes' do
|
419
|
+
FS.join('foo', 'bar').should eql('foo/bar')
|
420
|
+
FS.join('foo', '/bar').should eql('foo/bar')
|
421
|
+
FS.join('foo/', 'bar').should eql('foo/bar')
|
422
|
+
end
|
423
|
+
end
|
424
|
+
|
425
|
+
describe 'expand_path' do
|
426
|
+
it 'expands pathes' do
|
427
|
+
here = File.expand_path('.')
|
428
|
+
FS.expand_path('.').should eql(here)
|
429
|
+
FS.expand_path('foo').should eql(File.join(here, 'foo'))
|
430
|
+
FS.expand_path('foo/bar').should eql(File.join(here, 'foo', 'bar'))
|
431
|
+
end
|
432
|
+
end
|
433
|
+
|
434
|
+
describe 'absolute?' do
|
435
|
+
it 'checks for an absolute path' do
|
436
|
+
FS.absolute?('/').should be_true
|
437
|
+
FS.absolute?('/foo').should be_true
|
438
|
+
FS.absolute?('.').should be_false
|
439
|
+
FS.absolute?('foo').should be_false
|
440
|
+
end
|
441
|
+
end
|
442
|
+
|
443
|
+
describe 'dirname' do
|
444
|
+
it 'extracts the dir of a path' do
|
445
|
+
FS.dirname('tmp/foo/bar.todo').should eql('tmp/foo')
|
446
|
+
FS.dirname('tmp/foo').should eql('tmp')
|
447
|
+
FS.dirname('tmp/foo/').should eql('tmp')
|
448
|
+
FS.dirname('/tmp').should eql('/')
|
449
|
+
FS.dirname('/').should eql('/')
|
450
|
+
FS.dirname('.').should eql('.')
|
451
|
+
end
|
452
|
+
end
|
453
|
+
|
454
|
+
describe 'basename' do
|
455
|
+
it 'extracts the base of a path' do
|
456
|
+
FS.basename('tmp/foo/bar.todo').should eql('bar.todo')
|
457
|
+
FS.basename('tmp/foo').should eql('foo')
|
458
|
+
FS.basename('tmp/foo/').should eql('foo')
|
459
|
+
FS.basename('/tmp').should eql('tmp')
|
460
|
+
FS.basename('/').should eql('/')
|
461
|
+
FS.basename('.').should eql('.')
|
462
|
+
end
|
463
|
+
end
|
464
|
+
|
465
|
+
describe 'filename' do
|
466
|
+
it 'extracts the filename of a path' do
|
467
|
+
FS.filename('tmp/foo/bar.todo').should eql('bar')
|
468
|
+
FS.filename('tmp/foo').should eql('foo')
|
469
|
+
FS.filename('tmp/foo/').should eql('foo')
|
470
|
+
FS.filename('/tmp').should eql('tmp')
|
471
|
+
FS.filename('/').should eql('') # this is not like FS.basename
|
472
|
+
FS.filename('.').should eql('') # this is not like FS.basename
|
473
|
+
FS.filename('foo.bar.txt').should eql('foo.bar')
|
474
|
+
end
|
475
|
+
end
|
476
|
+
|
477
|
+
describe 'extname' do
|
478
|
+
it 'extracts the extension of a path' do
|
479
|
+
FS.extname('tmp/foo/bar.todo').should eql('.todo')
|
480
|
+
FS.extname('tmp/foo').should eql('')
|
481
|
+
FS.extname('tmp/foo/').should eql('')
|
482
|
+
FS.extname('/tmp').should eql('')
|
483
|
+
FS.extname('/').should eql('')
|
484
|
+
FS.extname('.').should eql('')
|
485
|
+
FS.extname('foo.bar.txt').should eql('.txt')
|
486
|
+
end
|
487
|
+
end
|
488
|
+
|
489
|
+
describe 'splitname' do
|
490
|
+
it 'splits the parts of a path' do
|
491
|
+
FS.splitname('tmp/foo/bar.todo').should eql(["tmp/foo", "bar", ".todo"])
|
492
|
+
FS.splitname('tmp/foo').should eql(['tmp', 'foo', ''])
|
493
|
+
FS.splitname('tmp/foo/').should eql(['tmp', 'foo', ''])
|
494
|
+
FS.splitname('/tmp').should eql(['/', 'tmp', ''])
|
495
|
+
FS.splitname('/').should eql(['/', '', ''])
|
496
|
+
FS.splitname('.').should eql(['.', '', ''])
|
497
|
+
end
|
498
|
+
end
|
499
|
+
|
500
|
+
describe 'this_file' do
|
501
|
+
it 'returns this file' do
|
502
|
+
FS.this_file.should eql(__FILE__)
|
503
|
+
end
|
504
|
+
end
|
505
|
+
|
506
|
+
describe 'this_dir' do
|
507
|
+
it 'returns the dir of this file' do
|
508
|
+
FS.this_dir.should eql(File.dirname(__FILE__))
|
509
|
+
end
|
510
|
+
end
|
511
|
+
|
512
|
+
describe 'tempdir' do
|
513
|
+
it 'returns the current temp dir' do
|
514
|
+
FS.tempdir.should eql(Dir.tmpdir)
|
515
|
+
end
|
516
|
+
end
|
517
|
+
|
518
|
+
describe 'maketempdir' do
|
519
|
+
it 'creates a new dir in the default temp dir' do
|
520
|
+
dir = FS.maketempdir
|
521
|
+
File.exist?(dir).should be_true
|
522
|
+
File.directory?(dir).should be_true
|
523
|
+
Dir.entries(dir).should eql([".", ".."])
|
524
|
+
Dir.entries(Dir.tmpdir).should include(File.basename(dir))
|
525
|
+
end
|
526
|
+
|
527
|
+
it 'creates a new temp dir with the given prefix' do
|
528
|
+
dir = FS.maketempdir('my_dir')
|
529
|
+
dir.should match(/\/my_dir/)
|
530
|
+
File.exist?(dir).should be_true
|
531
|
+
File.directory?(dir).should be_true
|
532
|
+
Dir.entries(dir).should eql([".", ".."])
|
533
|
+
Dir.entries(Dir.tmpdir).should include(File.basename(dir))
|
534
|
+
end
|
535
|
+
|
536
|
+
it 'creates a new temp dir inside of the given dir' do
|
537
|
+
parent_dir = FS.maketempdir('parent_dir')
|
538
|
+
dir = FS.maketempdir(nil, parent_dir)
|
539
|
+
File.exist?(dir).should be_true
|
540
|
+
File.directory?(dir).should be_true
|
541
|
+
Dir.entries(dir).should eql([".", ".."])
|
542
|
+
Dir.entries(parent_dir).should include(File.basename(dir))
|
543
|
+
end
|
544
|
+
end
|
545
|
+
|
546
|
+
describe 'maketempfile' do
|
547
|
+
it 'creates a new file in the default temp dir' do
|
548
|
+
file = FS.maketempfile
|
549
|
+
FS.exist?(file).should be_true
|
550
|
+
FS.file?(file).should be_true
|
551
|
+
FS.empty?(file).should be_true
|
552
|
+
FS.list(Dir.tmpdir).should include(File.basename(file))
|
553
|
+
end
|
554
|
+
|
555
|
+
it 'creates a new temp file with the given prefix' do
|
556
|
+
file = FS.maketempfile('my_file')
|
557
|
+
file.should match(/\/my_file/)
|
558
|
+
FS.exist?(file).should be_true
|
559
|
+
FS.file?(file).should be_true
|
560
|
+
FS.empty?(file).should be_true
|
561
|
+
FS.list(Dir.tmpdir).should include(File.basename(file))
|
562
|
+
end
|
563
|
+
|
564
|
+
it 'creates a new temp file inside of the given dir' do
|
565
|
+
parent_dir = FS.maketempdir('parent_dir')
|
566
|
+
file = FS.maketempfile(nil, parent_dir)
|
567
|
+
FS.exist?(file).should be_true
|
568
|
+
FS.file?(file).should be_true
|
569
|
+
FS.empty?(file).should be_true
|
570
|
+
FS.list(parent_dir).should include(File.basename(file))
|
571
|
+
end
|
572
|
+
end
|
573
|
+
|
325
574
|
end
|
@@ -12,8 +12,7 @@ module FS
|
|
12
12
|
def use_helper(describe_block)
|
13
13
|
describe_block.before :each do
|
14
14
|
unless @test_dir
|
15
|
-
@test_dir = File.
|
16
|
-
FileUtils.mkdir_p(@test_dir)
|
15
|
+
@test_dir = File.realpath(Dir.mktmpdir('test_'))
|
17
16
|
Dir.chdir(@test_dir)
|
18
17
|
end
|
19
18
|
end
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: fs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.1.
|
5
|
+
version: 0.1.1
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- "Bernd J\xC3\xBCnger"
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-
|
13
|
+
date: 2011-04-09 00:00:00 +02:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|