fs 0.1.2 → 0.2.0

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/.travis.yml ADDED
@@ -0,0 +1,2 @@
1
+ rvm:
2
+ - 1.9.2
data/README.mdown CHANGED
@@ -37,33 +37,34 @@ using the good old standard library, but providing simple methods in a single pl
37
37
  Although verbose method names are good, there are some aliases for unix shell
38
38
  commands (unsorted).
39
39
 
40
- - ls => list
41
- - mkdir => makedir
42
- - mkdir_p => makedirs
43
- - cd => changedir
44
- - mv => move
45
- - cp => copy
46
- - rm => remove
47
- - ln => link
48
- - cat => read (no concatenate)
40
+ - ls => :list
41
+ - mkdir => :makedir
42
+ - mkdir_p => :makedirs
43
+ - rmdir => :removedir
44
+ - rm_r => :removedirs
45
+ - cd => :changedir
46
+ - pwd => :currentdir
47
+ - mv => :move
48
+ - cp => :copy
49
+ - rm => :remove
50
+ - cat => :read
51
+ - ln => :link
52
+ - dir? => :directory?
53
+ - expand => :expand_path
54
+ - [] => :join
49
55
 
50
56
  ## Todo
51
57
 
52
- Here is my mind … here is my mind …
58
+ Here is my mind …
53
59
 
54
60
  - maybe use underscores (remove_dir)
55
61
  - remove! to force something
56
62
  - maybe makedir! to mkdir -p
63
+ - maybe touch! to mkdir -p && touch
57
64
  - use Find#find in FS#find ;)
58
- - file type
59
- - exist?
65
+ - file type / ftype
60
66
  - list_dirs
61
67
  - list_files
62
68
  - find_dirs
63
69
  - find_files
64
70
  - FS.link('a.txt' => 'b.txt') with a hash
65
-
66
- ## BTW
67
-
68
- If you need a replacement for the shell in pure ruby, than have a look at
69
- [Rush](http://rush.heroku.com/).
data/lib/fs.rb CHANGED
@@ -3,12 +3,15 @@ $LOAD_PATH.unshift(File.dirname(__FILE__)) unless $LOAD_PATH.include?(File.dirna
3
3
  require 'fileutils'
4
4
  require 'etc'
5
5
  require 'tmpdir'
6
+ require 'find'
6
7
 
7
8
  require 'fs/base'
9
+ require 'fs/find'
8
10
  require 'fs/alias'
9
11
 
10
12
  module FS
11
13
  include FS::Base
14
+ include FS::Find
12
15
  include FS::Alias
13
16
  extend self
14
17
  end
data/lib/fs/alias.rb CHANGED
@@ -15,6 +15,7 @@ module FS
15
15
  :ln => :link,
16
16
  :dir? => :directory?,
17
17
  :expand => :expand_path,
18
+ :chop => :chop_path,
18
19
  :[] => :join,
19
20
  }
20
21
 
data/lib/fs/base.rb CHANGED
@@ -31,13 +31,15 @@ module FS
31
31
 
32
32
  # Dir#glob
33
33
  def list(dir='.', pattern='*')
34
- glob(dir, pattern)
34
+ glob(dir, pattern, nil)
35
35
  end
36
36
 
37
- # Dir#glob
38
- # TODO: use Find#find
39
- def find(dir='.', pattern='*')
40
- glob(dir, '**', pattern)
37
+ def list_dirs(dir='.', pattern='*')
38
+ glob(dir, pattern, ->(path){FS.directory?(path)})
39
+ end
40
+
41
+ def list_files(dir='.', pattern='*')
42
+ glob(dir, pattern, ->(path){FS.file?(path)})
41
43
  end
42
44
 
43
45
  # TODO: find time to make this cool, not work only
@@ -93,8 +95,9 @@ module FS
93
95
  end
94
96
 
95
97
  # Dir#home
98
+ # the path is always expanded
96
99
  def home(user=nil)
97
- Dir.home(user)
100
+ File.expand_path(Dir.home(user))
98
101
  end
99
102
 
100
103
  # always returns '/'
@@ -168,8 +171,22 @@ module FS
168
171
  end
169
172
 
170
173
  # File.expand_path
171
- def expand_path(path)
172
- File.expand_path(path)
174
+ def expand_path(path, base=nil)
175
+ File.expand_path(path, base)
176
+ end
177
+
178
+ # chop base from the path
179
+ # if it's not a subdir the absolute path will be returned
180
+ def chop_path(path, base='.')
181
+ full_base = File.expand_path(base)
182
+ full_path = File.expand_path(path)
183
+ if full_path == full_base
184
+ '.'
185
+ elsif full_path.start_with?(full_base)
186
+ full_path[full_base.size+1..-1]
187
+ else
188
+ full_path
189
+ end
173
190
  end
174
191
 
175
192
  # checks for a slash at the beginning
@@ -209,13 +226,15 @@ module FS
209
226
  end
210
227
 
211
228
  # __FILE__ of the caller
229
+ # the path is always expanded
212
230
  def this_file
213
- caller_file(caller)
231
+ File.expand_path(caller_file(caller))
214
232
  end
215
233
 
216
234
  # File.dirname(__FILE__) of the caller
235
+ # the path is always expanded
217
236
  def this_dir
218
- File.dirname(caller_file(caller))
237
+ File.expand_path(File.dirname(caller_file(caller)))
219
238
  end
220
239
 
221
240
  private
@@ -224,12 +243,14 @@ module FS
224
243
  raise "not a directory: #{path}" unless File.directory?(path)
225
244
  end
226
245
 
227
- def glob(dir, *patterns)
246
+ def glob(dir, *patterns, condition)
228
247
  fulldir = File.expand_path(dir)
229
248
  regexp = /^#{Regexp.escape(fulldir)}\/?/
230
- Dir.glob(File.join(fulldir, patterns)).map do |path|
231
- path.gsub(regexp, '')
232
- end
249
+ Dir.
250
+ glob(File.join(fulldir, patterns)).
251
+ select {|path| condition.nil? || condition[path] }.
252
+ map {|path| path.gsub(regexp, '') }.
253
+ sort
233
254
  end
234
255
 
235
256
  def visit_tree(output, parent_path, indent, arm, tie, node)
@@ -259,7 +280,7 @@ module FS
259
280
  end
260
281
 
261
282
  # 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
283
+ # Stolen from ActionMailer, where it wasn't reusable
263
284
  def parse_caller(at)
264
285
  if /^(.+?):(\d+)(?::in `(.*)')?/ =~ at
265
286
  file = Regexp.last_match[1]
data/lib/fs/find.rb ADDED
@@ -0,0 +1,42 @@
1
+ module FS
2
+ module Find
3
+
4
+ # Find::find
5
+ def find(dir, options={}, &block)
6
+ defaults = {
7
+ :current => false,
8
+ :absolute => false,
9
+ :condition => nil
10
+ }
11
+ options = defaults.merge(options)
12
+
13
+ result = []
14
+
15
+ full_dir = File.expand_path(dir)
16
+ ::Find.find(dir) do |full_path|
17
+ next if !options[:current] && full_path == full_dir
18
+ path = options[:absolute] ? full_path : FS.chop(full_path, full_dir)
19
+ next if options[:condition] && !options[:condition][path]
20
+
21
+ if block
22
+ block[path]
23
+ else
24
+ result << path
25
+ end
26
+ end
27
+
28
+ block ? nil : result
29
+ end
30
+
31
+ def find_dirs(dir, options={}, &block)
32
+ condition = ->(path){FileTest.directory?(path)}
33
+ find(dir, options.merge(:condition => condition), &block)
34
+ end
35
+
36
+ def find_files(dir, options={}, &block)
37
+ condition = ->(path){!FileTest.directory?(path)}
38
+ find(dir, options.merge(:condition => condition), &block)
39
+ end
40
+
41
+ end
42
+ end
data/lib/fs/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module FS
2
- VERSION = "0.1.2"
2
+ VERSION = "0.2.0"
3
3
  end
data/spec/base_spec.rb CHANGED
@@ -137,18 +137,12 @@ describe FS::Base do
137
137
  FS.makedir('foo/dir.rb')
138
138
  FS.list('foo', '*.txt').should eql(['dir.txt', 'file.txt'])
139
139
  end
140
- end
141
-
142
- describe '::find' do
143
- it 'returns an empty list if there are no files' do
144
- FS.find('.').should be_empty
145
- end
146
140
 
147
- it 'finds files in all subdirs' do
141
+ it 'lists files in all subdirs' do
148
142
  FS.makedirs('one/two/three')
149
143
  FS.touch('one/file.one')
150
144
  FS.touch('one/two/three/file.three')
151
- FS.find.should eql([
145
+ FS.list('.', '**/*').should eql([
152
146
  'one',
153
147
  'one/file.one',
154
148
  'one/two',
@@ -161,13 +155,39 @@ describe FS::Base do
161
155
  FS.makedirs('one/two/three')
162
156
  FS.touch('one/file.one')
163
157
  FS.touch('one/two/three/file.three')
164
- FS.find('.', 'file.*').should eql([
158
+ FS.list('.', '**/file.*').should eql([
165
159
  'one/file.one',
166
160
  'one/two/three/file.three'
167
161
  ])
168
162
  end
169
163
  end
170
164
 
165
+ describe '::list_dirs' do
166
+ it 'lists dirs only' do
167
+ FS.touch('bar.file')
168
+ FS.makedir('bar.dir')
169
+ FS.touch('foo.file')
170
+ FS.makedir('foo.dir')
171
+ FS.list_dirs.should eql([
172
+ 'bar.dir',
173
+ 'foo.dir'
174
+ ])
175
+ end
176
+ end
177
+
178
+ describe '::list_files' do
179
+ it 'lists files only' do
180
+ FS.touch('bar.file')
181
+ FS.makedir('bar.dir')
182
+ FS.touch('foo.file')
183
+ FS.makedir('foo.dir')
184
+ FS.list_files.should eql([
185
+ 'bar.file',
186
+ 'foo.file'
187
+ ])
188
+ end
189
+ end
190
+
171
191
  describe '::move' do
172
192
  it 'renames a file' do
173
193
  FS.touch('foo.txt')
@@ -327,7 +347,7 @@ describe FS::Base do
327
347
  FS.touch('a.file')
328
348
  FS.makedir('baz')
329
349
  FS.touch('baz/b.file')
330
- FS.mkdir('baz/bar')
350
+ FS.makedir('baz/bar')
331
351
  FS.touch('baz/bar/c.file')
332
352
  FS.touch('baz/d.file')
333
353
  FS.makedir('foo')
@@ -406,8 +426,8 @@ TXT
406
426
  end
407
427
 
408
428
  it 'returns if a dir is empty' do
409
- FS.mkdir('empty.dir')
410
- FS.mkdir('content.dir')
429
+ FS.makedir('empty.dir')
430
+ FS.makedir('content.dir')
411
431
  FS.touch('content.dir/some.file')
412
432
  FS.empty?('empty.dir').should be_true
413
433
  FS.empty?('content.dir').should be_false
@@ -429,6 +449,46 @@ TXT
429
449
  FS.expand_path('foo').should eql(File.join(here, 'foo'))
430
450
  FS.expand_path('foo/bar').should eql(File.join(here, 'foo', 'bar'))
431
451
  end
452
+
453
+ it 'uses a base dir to expand the path' do
454
+ here = File.expand_path('.')
455
+ FS.expand_path('foo', nil).should eql(File.join(here, 'foo'))
456
+ FS.expand_path('foo', here).should eql(File.join(here, 'foo'))
457
+ FS.expand_path('foo', '/').should eql('/foo')
458
+ FS.expand_path('foo', '/bar').should eql('/bar/foo')
459
+ FS.expand_path('foo', '/bar/').should eql('/bar/foo')
460
+ end
461
+ end
462
+
463
+ describe '::chop_path' do
464
+ it 'does nothing for relative paths' do
465
+ FS.chop_path('.').should eql('.')
466
+ FS.chop_path('./foo').should eql('foo')
467
+ FS.chop_path('foo').should eql('foo')
468
+ FS.chop_path('foo/bar').should eql('foo/bar')
469
+ end
470
+
471
+ it 'does not chop for non subdirs' do
472
+ FS.chop_path('/').should eql('/')
473
+ FS.chop_path('..').should eql(File.expand_path('..'))
474
+ FS.chop_path('/foo', '/foo/bar').should eql('/foo')
475
+ end
476
+
477
+ it 'chop absolute the path' do
478
+ here = File.expand_path('.')
479
+ FS.chop_path(here).should eql('.')
480
+ FS.chop_path(File.join(here, '.')).should eql('.')
481
+ FS.chop_path(File.join(here, 'foo')).should eql('foo')
482
+ FS.chop_path(File.join(here, 'foo/bar')).should eql('foo/bar')
483
+ FS.chop_path('/foo/bar').should eql('/foo/bar')
484
+ end
485
+
486
+ it 'uses a base dir to chop the path' do
487
+ FS.chop_path('.', '.').should eql('.')
488
+ FS.chop_path('/', '/').should eql('.')
489
+ FS.chop_path('/foo', '/foo').should eql('.')
490
+ FS.chop_path('/foo/bar', '/foo').should eql('bar')
491
+ end
432
492
  end
433
493
 
434
494
  describe '::absolute?' do
@@ -520,7 +580,7 @@ TXT
520
580
  dir = FS.maketempdir
521
581
  File.exist?(dir).should be_true
522
582
  File.directory?(dir).should be_true
523
- Dir.entries(dir).should eql([".", ".."])
583
+ Dir.entries(dir).should =~ ['.', '..']
524
584
  Dir.entries(Dir.tmpdir).should include(File.basename(dir))
525
585
  end
526
586
 
@@ -529,7 +589,7 @@ TXT
529
589
  dir.should match(/\/my_dir/)
530
590
  File.exist?(dir).should be_true
531
591
  File.directory?(dir).should be_true
532
- Dir.entries(dir).should eql([".", ".."])
592
+ Dir.entries(dir).should =~ ['.', '..']
533
593
  Dir.entries(Dir.tmpdir).should include(File.basename(dir))
534
594
  end
535
595
 
@@ -538,7 +598,7 @@ TXT
538
598
  dir = FS.maketempdir(nil, parent_dir)
539
599
  File.exist?(dir).should be_true
540
600
  File.directory?(dir).should be_true
541
- Dir.entries(dir).should eql([".", ".."])
601
+ Dir.entries(dir).should =~ ['.', '..']
542
602
  Dir.entries(parent_dir).should include(File.basename(dir))
543
603
  end
544
604
  end
data/spec/find_spec.rb ADDED
@@ -0,0 +1,135 @@
1
+ require 'spec_helper'
2
+
3
+ describe FS::Find do
4
+ before do
5
+ FS.touch 'a.txt'
6
+ FS.touch 'b.txt'
7
+ FS.makedirs 'bar'
8
+ FS.touch 'bar/c.txt'
9
+ FS.makedirs 'bar/foo'
10
+ FS.touch 'bar/foo/d.txt'
11
+ FS.makedirs 'baz'
12
+ FS.makedirs 'baz/lala'
13
+ FS.touch 'e.txt'
14
+ end
15
+
16
+ describe '::find' do
17
+ it 'returns the subdirs and files' do
18
+ FS.find(@test_dir).should == %w(
19
+ a.txt
20
+ b.txt
21
+ bar
22
+ bar/c.txt
23
+ bar/foo
24
+ bar/foo/d.txt
25
+ baz
26
+ baz/lala
27
+ e.txt
28
+ )
29
+ end
30
+
31
+ it 'returns current dir, subdirs and files' do
32
+ FS.find(@test_dir, :current => true).should == %w(
33
+ .
34
+ a.txt
35
+ b.txt
36
+ bar
37
+ bar/c.txt
38
+ bar/foo
39
+ bar/foo/d.txt
40
+ baz
41
+ baz/lala
42
+ e.txt
43
+ )
44
+ end
45
+
46
+ it 'returns the full path' do
47
+ FS.find(@test_dir, :absolute => true).should == [
48
+ FS[@test_dir, 'a.txt'],
49
+ FS[@test_dir, 'b.txt'],
50
+ FS[@test_dir, 'bar'],
51
+ FS[@test_dir, 'bar/c.txt'],
52
+ FS[@test_dir, 'bar/foo'],
53
+ FS[@test_dir, 'bar/foo/d.txt'],
54
+ FS[@test_dir, 'baz'],
55
+ FS[@test_dir, 'baz/lala'],
56
+ FS[@test_dir, 'e.txt']
57
+ ]
58
+ end
59
+
60
+ it 'yields the result' do
61
+ result = []
62
+
63
+ FS.find(@test_dir) do |path|
64
+ result << path
65
+ end
66
+
67
+ result.should == %w(
68
+ a.txt
69
+ b.txt
70
+ bar
71
+ bar/c.txt
72
+ bar/foo
73
+ bar/foo/d.txt
74
+ baz
75
+ baz/lala
76
+ e.txt
77
+ )
78
+ end
79
+ end
80
+
81
+ describe '::find_dirs' do
82
+ it 'returns dirs only' do
83
+ FS.find_dirs(@test_dir).should == %w(
84
+ bar
85
+ bar/foo
86
+ baz
87
+ baz/lala
88
+ )
89
+ end
90
+
91
+ it 'yields dirs only' do
92
+ result = []
93
+
94
+ FS.find_dirs(@test_dir) do |path|
95
+ result << path
96
+ end
97
+
98
+ result.should == %w(
99
+ bar
100
+ bar/foo
101
+ baz
102
+ baz/lala
103
+ )
104
+ end
105
+ end
106
+
107
+ describe '::find_files' do
108
+ it 'returns files only' do
109
+ FS.find_files(@test_dir).should == %w(
110
+ a.txt
111
+ b.txt
112
+ bar/c.txt
113
+ bar/foo/d.txt
114
+ e.txt
115
+ )
116
+ end
117
+
118
+ it 'yields files only' do
119
+ result = []
120
+
121
+ FS.find_files(@test_dir) do |path|
122
+ result << path
123
+ end
124
+
125
+ result.should == %w(
126
+ a.txt
127
+ b.txt
128
+ bar/c.txt
129
+ bar/foo/d.txt
130
+ e.txt
131
+ )
132
+ end
133
+ end
134
+
135
+ end
@@ -15,7 +15,7 @@ describe FS do
15
15
  end
16
16
 
17
17
  it 'is empty' do
18
- Dir.entries(@test_dir).should eql([".", ".."])
18
+ Dir.entries(@test_dir).should =~ ['.', '..']
19
19
  end
20
20
 
21
21
  it 'is the current dir' do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fs
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-11-04 00:00:00.000000000Z
12
+ date: 2011-11-10 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
16
- requirement: &2157319500 !ruby/object:Gem::Requirement
16
+ requirement: &2158694320 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - =
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 0.9.2.2
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *2157319500
24
+ version_requirements: *2158694320
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rspec
27
- requirement: &2157319020 !ruby/object:Gem::Requirement
27
+ requirement: &2158693840 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - =
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: 2.7.0
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *2157319020
35
+ version_requirements: *2158693840
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: yard
38
- requirement: &2157318560 !ruby/object:Gem::Requirement
38
+ requirement: &2158693380 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - =
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: 0.7.2
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *2157318560
46
+ version_requirements: *2158693380
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: bluecloth
49
- requirement: &2157318100 !ruby/object:Gem::Requirement
49
+ requirement: &2158692920 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - =
@@ -54,7 +54,7 @@ dependencies:
54
54
  version: 2.2.0
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *2157318100
57
+ version_requirements: *2158692920
58
58
  description: FS gathers the cluttered methods for working with files and dirs. Internally
59
59
  using the good old standard library, but providing simple methods in a single place.
60
60
  email:
@@ -65,6 +65,7 @@ extra_rdoc_files: []
65
65
  files:
66
66
  - .gitignore
67
67
  - .rspec
68
+ - .travis.yml
68
69
  - Gemfile
69
70
  - README.mdown
70
71
  - Rakefile
@@ -72,9 +73,11 @@ files:
72
73
  - lib/fs.rb
73
74
  - lib/fs/alias.rb
74
75
  - lib/fs/base.rb
76
+ - lib/fs/find.rb
75
77
  - lib/fs/version.rb
76
78
  - spec/alias_spec.rb
77
79
  - spec/base_spec.rb
80
+ - spec/find_spec.rb
78
81
  - spec/spec_helper.rb
79
82
  - spec/support/test_dir_support.rb
80
83
  - spec/test_dir_spec.rb
@@ -92,7 +95,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
92
95
  version: '0'
93
96
  segments:
94
97
  - 0
95
- hash: 612170262386871478
98
+ hash: 2428767844622882813
96
99
  required_rubygems_version: !ruby/object:Gem::Requirement
97
100
  none: false
98
101
  requirements:
@@ -101,7 +104,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
101
104
  version: '0'
102
105
  segments:
103
106
  - 0
104
- hash: 612170262386871478
107
+ hash: 2428767844622882813
105
108
  requirements: []
106
109
  rubyforge_project:
107
110
  rubygems_version: 1.8.10
@@ -111,6 +114,7 @@ summary: Work with your filesystem!
111
114
  test_files:
112
115
  - spec/alias_spec.rb
113
116
  - spec/base_spec.rb
117
+ - spec/find_spec.rb
114
118
  - spec/spec_helper.rb
115
119
  - spec/support/test_dir_support.rb
116
120
  - spec/test_dir_spec.rb