fs 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.mdown CHANGED
@@ -55,7 +55,6 @@ Here is my mind … here is my mind …
55
55
  - remove! to force something
56
56
  - maybe makedir! to mkdir -p
57
57
  - use Find#find in FS#find ;)
58
- - some kind of #tree output
59
58
  - file type
60
59
  - exist?
61
60
  - list_dirs
data/lib/fs.rb CHANGED
@@ -2,6 +2,8 @@ $LOAD_PATH.unshift(File.dirname(__FILE__)) unless $LOAD_PATH.include?(File.dirna
2
2
 
3
3
  require 'fileutils'
4
4
  require 'etc'
5
+ require 'tmpdir'
6
+
5
7
  require 'fs/base'
6
8
  require 'fs/alias'
7
9
 
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(/^#{fulldir}\/?/, '')
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
@@ -1,3 +1,3 @@
1
1
  module FS
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
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.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'tmp', 'test'))
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.0
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-03-29 00:00:00 +02:00
13
+ date: 2011-04-09 00:00:00 +02:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency