filepath 0.3.1 → 0.4
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/.yardopts +1 -0
- data/Rakefile +1 -1
- data/lib/filepath.rb +4 -608
- data/lib/filepath/core_ext/array.rb +46 -0
- data/lib/filepath/core_ext/string.rb +22 -0
- data/lib/filepath/filepath.rb +802 -0
- data/lib/{filepathlist.rb → filepath/filepathlist.rb} +31 -31
- data/spec/filepath_spec.rb +63 -4
- data/spec/filepathlist_spec.rb +45 -12
- data/spec/spec_helper.rb +0 -1
- metadata +10 -7
@@ -1,6 +1,7 @@
|
|
1
1
|
# This is free and unencumbered software released into the public domain.
|
2
2
|
# See the `UNLICENSE` file or <http://unlicense.org/> for more details.
|
3
3
|
|
4
|
+
|
4
5
|
class FilePathList
|
5
6
|
include Enumerable
|
6
7
|
|
@@ -36,16 +37,29 @@ class FilePathList
|
|
36
37
|
return FilePathList.new(@entries + extra_entries.to_a)
|
37
38
|
end
|
38
39
|
|
39
|
-
def -(others)
|
40
|
-
|
41
|
-
|
40
|
+
def -(others)
|
41
|
+
remaining_entries = @entries - others.as_path_list.to_a
|
42
|
+
|
43
|
+
return FilePathList.new(remaining_entries)
|
44
|
+
end
|
45
|
+
|
46
|
+
def exclude(pattern = nil, &block)
|
47
|
+
if block_given?
|
48
|
+
select { |e| !block.call(e) }
|
42
49
|
else
|
43
|
-
|
50
|
+
select { |e| !(e =~ pattern) }
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def select(pattern = nil, &block)
|
55
|
+
if !block_given?
|
56
|
+
block = proc { |e| e =~ pattern }
|
44
57
|
end
|
45
58
|
|
59
|
+
remaining_entries = @entries.select { |e| block.call(e) }
|
60
|
+
|
46
61
|
return FilePathList.new(remaining_entries)
|
47
62
|
end
|
48
|
-
alias :exclude :-
|
49
63
|
|
50
64
|
def <<(extra_path)
|
51
65
|
return FilePathList.new(@entries + [extra_path.as_path])
|
@@ -60,16 +74,16 @@ class FilePathList
|
|
60
74
|
return FilePathList.new(paths)
|
61
75
|
end
|
62
76
|
|
63
|
-
def
|
64
|
-
|
65
|
-
max_length =
|
77
|
+
def remove_common_segments
|
78
|
+
all_segs = @entries.map(&:segments)
|
79
|
+
max_length = all_segs.map(&:length).min
|
66
80
|
|
67
81
|
idx_different = nil
|
68
82
|
|
69
83
|
(0..max_length).each do |i|
|
70
|
-
|
84
|
+
segment = all_segs.first[i]
|
71
85
|
|
72
|
-
different =
|
86
|
+
different = all_segs.any? { |segs| segs[i] != segment }
|
73
87
|
if different
|
74
88
|
idx_different = i
|
75
89
|
break
|
@@ -78,9 +92,9 @@ class FilePathList
|
|
78
92
|
|
79
93
|
idx_different ||= max_length
|
80
94
|
|
81
|
-
|
95
|
+
remaining_segs = all_segs.map { |segs| segs[idx_different..-1] }
|
82
96
|
|
83
|
-
return FilePathList.new(
|
97
|
+
return FilePathList.new(remaining_segs)
|
84
98
|
end
|
85
99
|
|
86
100
|
# @return [FilePathList] the path list itself
|
@@ -97,6 +111,8 @@ class FilePathList
|
|
97
111
|
@to_s ||= @entries.map(&:to_str).join(SEPARATOR)
|
98
112
|
end
|
99
113
|
|
114
|
+
|
115
|
+
# @private
|
100
116
|
def inspect
|
101
117
|
@entries.inspect
|
102
118
|
end
|
@@ -106,6 +122,7 @@ class FilePathList
|
|
106
122
|
end
|
107
123
|
|
108
124
|
module ArrayMethods
|
125
|
+
# @private
|
109
126
|
def self.define_array_method(name)
|
110
127
|
define_method(name) do |*args, &block|
|
111
128
|
return @entries.send(name, *args, &block)
|
@@ -121,26 +138,9 @@ class FilePathList
|
|
121
138
|
define_array_method :each
|
122
139
|
|
123
140
|
define_array_method :map
|
141
|
+
|
142
|
+
define_array_method :size
|
124
143
|
end
|
125
144
|
|
126
145
|
include ArrayMethods
|
127
146
|
end
|
128
|
-
|
129
|
-
class Array
|
130
|
-
# Generates a path list from an array of paths.
|
131
|
-
#
|
132
|
-
# The elements of the array must respond to `#as_path`.
|
133
|
-
#
|
134
|
-
# `ary.as_path` is equivalent to `FilePathList.new(ary)`.
|
135
|
-
#
|
136
|
-
# @return [FilePathList] a new path list containing the elements of
|
137
|
-
# the array as FilePaths
|
138
|
-
#
|
139
|
-
# @see String#as_path
|
140
|
-
# @see Array#as_path
|
141
|
-
# @see FilePath#as_path
|
142
|
-
|
143
|
-
def as_path_list
|
144
|
-
FilePathList.new(self)
|
145
|
-
end
|
146
|
-
end
|
data/spec/filepath_spec.rb
CHANGED
@@ -264,6 +264,24 @@ describe FilePath do
|
|
264
264
|
end
|
265
265
|
end
|
266
266
|
|
267
|
+
describe "#root?" do
|
268
|
+
it "says that </> points to the root directory" do
|
269
|
+
FilePath.new('/').should be_root
|
270
|
+
end
|
271
|
+
|
272
|
+
it "says that </..> points to the root directory" do
|
273
|
+
FilePath.new('/..').should be_root
|
274
|
+
end
|
275
|
+
|
276
|
+
it "says that <a/b> does not point to the root directory" do
|
277
|
+
FilePath.new('a/b').should_not be_root
|
278
|
+
end
|
279
|
+
|
280
|
+
it "says that </foo> does not point to the root directory" do
|
281
|
+
FilePath.new('/foo/bar').should_not be_root
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
267
285
|
describe "#absolute?" do
|
268
286
|
it "says that `/foo/bar` is absolute" do
|
269
287
|
FilePath.new('/foo/bar').should be_absolute
|
@@ -295,7 +313,7 @@ describe FilePath do
|
|
295
313
|
end
|
296
314
|
|
297
315
|
describe "#ascend" do
|
298
|
-
it "goes through all the
|
316
|
+
it "goes through all the segments of an absolute path" do
|
299
317
|
steps = []
|
300
318
|
FilePath.new("/a/b/c").ascend do |p|
|
301
319
|
steps << p
|
@@ -308,7 +326,7 @@ describe FilePath do
|
|
308
326
|
steps[3].should eq("/")
|
309
327
|
end
|
310
328
|
|
311
|
-
it "goes through all the
|
329
|
+
it "goes through all the segments of a relative path" do
|
312
330
|
steps = []
|
313
331
|
FilePath.new("a/b/c").ascend do |p|
|
314
332
|
steps << p
|
@@ -319,10 +337,15 @@ describe FilePath do
|
|
319
337
|
steps[1].should eq("a/b")
|
320
338
|
steps[2].should eq("a")
|
321
339
|
end
|
340
|
+
|
341
|
+
it "returns the path itself" do
|
342
|
+
path = FilePath.new("/a/b/c/")
|
343
|
+
path.ascend { }.should be(path)
|
344
|
+
end
|
322
345
|
end
|
323
346
|
|
324
347
|
describe "#descend" do
|
325
|
-
it "goes through all the
|
348
|
+
it "goes through all the segments of an absolute path" do
|
326
349
|
steps = []
|
327
350
|
FilePath.new("/a/b/c").descend do |p|
|
328
351
|
steps << p
|
@@ -335,7 +358,7 @@ describe FilePath do
|
|
335
358
|
steps[3].should eq("/a/b/c")
|
336
359
|
end
|
337
360
|
|
338
|
-
it "goes through all the
|
361
|
+
it "goes through all the segments of a relative path" do
|
339
362
|
steps = []
|
340
363
|
FilePath.new("a/b/c").descend do |p|
|
341
364
|
steps << p
|
@@ -346,6 +369,11 @@ describe FilePath do
|
|
346
369
|
steps[1].should eq("a/b")
|
347
370
|
steps[2].should eq("a/b/c")
|
348
371
|
end
|
372
|
+
|
373
|
+
it "returns the path itself" do
|
374
|
+
path = FilePath.new("/a/b/c/")
|
375
|
+
path.descend { }.should be(path)
|
376
|
+
end
|
349
377
|
end
|
350
378
|
|
351
379
|
describe "#to_s" do
|
@@ -580,11 +608,38 @@ describe FilePath do
|
|
580
608
|
end
|
581
609
|
end
|
582
610
|
|
611
|
+
describe "#find" do
|
612
|
+
it "finds all paths matching a glob string" do
|
613
|
+
list = @root.find('*1')
|
614
|
+
|
615
|
+
list.should have(6).items
|
616
|
+
list.each { |path| path.should =~ /1/ }
|
617
|
+
end
|
618
|
+
|
619
|
+
it "finds all paths matching a Regex" do
|
620
|
+
list = @root.find(/2/)
|
621
|
+
|
622
|
+
list.should have(5).items
|
623
|
+
list.each { |path| path.should =~ /2/ }
|
624
|
+
end
|
625
|
+
|
626
|
+
it "finds all paths for which the block returns true" do
|
627
|
+
list = @root.find { |path| path.directory? }
|
628
|
+
|
629
|
+
list.should have(9).items
|
630
|
+
list.each { |path| path.filename.should =~ /^d/ }
|
631
|
+
end
|
632
|
+
end
|
633
|
+
|
583
634
|
describe "#files" do
|
584
635
|
it "finds 1 file in the root directory" do
|
585
636
|
@root.files.should have(1).item
|
586
637
|
end
|
587
638
|
|
639
|
+
it "finds 3 files in the root directory and its sub directories" do
|
640
|
+
@root.files(true).should have(3).item
|
641
|
+
end
|
642
|
+
|
588
643
|
it "finds 2 files in directory <d1>" do
|
589
644
|
(@root / 'd1').files.should have(2).items
|
590
645
|
end
|
@@ -599,6 +654,10 @@ describe FilePath do
|
|
599
654
|
@root.directories.should have(4).items
|
600
655
|
end
|
601
656
|
|
657
|
+
it "finds 9 directories in the root directory and its sub directories" do
|
658
|
+
@root.directories(true).should have(9).item
|
659
|
+
end
|
660
|
+
|
602
661
|
it "finds 2 directories in directory <d2>" do
|
603
662
|
(@root / 'd2').directories.should have(2).items
|
604
663
|
end
|
data/spec/filepathlist_spec.rb
CHANGED
@@ -36,12 +36,6 @@ describe FilePathList do
|
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
|
-
describe "#exclude" do
|
40
|
-
list = FilePathList.new(%w{a.foo b.bar c.foo d.foo b.bar})
|
41
|
-
refined = list.exclude(/bar$/)
|
42
|
-
refined.each { |path| path.extension.should == 'foo' }
|
43
|
-
end
|
44
|
-
|
45
39
|
describe "#/" do
|
46
40
|
it "adds the same string to all the paths" do
|
47
41
|
list = FilePathList.new(%w{foo faa}) / 'bar'
|
@@ -75,6 +69,45 @@ describe FilePathList do
|
|
75
69
|
end
|
76
70
|
end
|
77
71
|
|
72
|
+
describe "#exclude" do
|
73
|
+
let(:list) { FilePathList.new(%w{a.foo b.bar c.foo d.foo b.bar}) }
|
74
|
+
|
75
|
+
it "excludes paths matching a Regex" do
|
76
|
+
remaining = list.exclude(/bar$/)
|
77
|
+
|
78
|
+
remaining.should be_a FilePathList
|
79
|
+
remaining.should have(3).items
|
80
|
+
remaining.each { |path| path.extension.should == 'foo' }
|
81
|
+
end
|
82
|
+
|
83
|
+
it "excludes all the paths for which the block returns true" do
|
84
|
+
remaining = list.exclude { |path| path.extension?('bar') }
|
85
|
+
|
86
|
+
remaining.should be_a FilePathList
|
87
|
+
remaining.should have(3).items
|
88
|
+
remaining.each { |path| path.extension.should == 'foo' }
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe "#select" do
|
93
|
+
let(:list) { FilePathList.new(%w{a.foo b.bar c.foo d.foo b.bar}) }
|
94
|
+
|
95
|
+
it "keeps paths matching a Regex" do
|
96
|
+
remaining = list.select(/bar$/)
|
97
|
+
|
98
|
+
remaining.should be_a FilePathList
|
99
|
+
remaining.should have(2).items
|
100
|
+
remaining.each { |path| path.extension.should == 'bar' }
|
101
|
+
end
|
102
|
+
|
103
|
+
it "keeps all the paths for which the block returns true" do
|
104
|
+
remaining = list.select { |ph| ph.extension?('bar') }
|
105
|
+
|
106
|
+
remaining.should have(2).items
|
107
|
+
remaining.each { |ph| ph.extension.should == 'bar' }
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
78
111
|
describe "#<<" do
|
79
112
|
it "adds a new to path to a existing FilePathList" do
|
80
113
|
list1 = FilePathList.new(%w{a/b /c/d})
|
@@ -133,10 +166,10 @@ describe FilePathList do
|
|
133
166
|
end
|
134
167
|
end
|
135
168
|
|
136
|
-
describe "#
|
169
|
+
describe "#remove_common_segments" do
|
137
170
|
it "works on lists of files from the same dir" do
|
138
171
|
paths = %w{a/b/x1 a/b/x2 a/b/x3}
|
139
|
-
list = FilePathList.new(paths).
|
172
|
+
list = FilePathList.new(paths).remove_common_segments
|
140
173
|
|
141
174
|
list.should have(3).items
|
142
175
|
list.should include(*%w{x1 x2 x3})
|
@@ -144,16 +177,16 @@ describe FilePathList do
|
|
144
177
|
|
145
178
|
it "works on lists of files from different dirs" do
|
146
179
|
list1 = FilePathList.new(%w{a/b/x1 a/b/c/x2 a/b/d/e/x3})
|
147
|
-
list2 = list1.
|
180
|
+
list2 = list1.remove_common_segments
|
148
181
|
|
149
182
|
list2.should have(3).items
|
150
183
|
list2.should include(*%w{x1 c/x2 d/e/x3})
|
151
184
|
end
|
152
185
|
|
153
|
-
it "works on lists of files with no common
|
186
|
+
it "works on lists of files with no common segments" do
|
154
187
|
paths = %w{a/b a/d g/f}
|
155
188
|
list1 = FilePathList.new(paths)
|
156
|
-
list2 = list1.
|
189
|
+
list2 = list1.remove_common_segments
|
157
190
|
|
158
191
|
list1.should == list2
|
159
192
|
end
|
@@ -161,7 +194,7 @@ describe FilePathList do
|
|
161
194
|
it "works on lists that contain duplicates only" do
|
162
195
|
paths = %w{a/b a/b a/b}
|
163
196
|
list1 = FilePathList.new(paths)
|
164
|
-
list2 = list1.
|
197
|
+
list2 = list1.remove_common_segments
|
165
198
|
|
166
199
|
list2.should == FilePathList.new(['.', '.', '.'])
|
167
200
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: filepath
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: '0.4'
|
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: 2012-01-
|
12
|
+
date: 2012-01-25 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bones-rspec
|
16
|
-
requirement: &
|
16
|
+
requirement: &19274420 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: 2.0.1
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *19274420
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: bones
|
27
|
-
requirement: &
|
27
|
+
requirement: &19273040 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,7 +32,7 @@ dependencies:
|
|
32
32
|
version: 3.7.3
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *19273040
|
36
36
|
description: ! 'filepath is a small library that helps dealing with files, directories
|
37
37
|
and
|
38
38
|
|
@@ -48,7 +48,10 @@ files:
|
|
48
48
|
- Rakefile
|
49
49
|
- UNLICENSE
|
50
50
|
- lib/filepath.rb
|
51
|
-
- lib/
|
51
|
+
- lib/filepath/core_ext/array.rb
|
52
|
+
- lib/filepath/core_ext/string.rb
|
53
|
+
- lib/filepath/filepath.rb
|
54
|
+
- lib/filepath/filepathlist.rb
|
52
55
|
- spec/filepath_spec.rb
|
53
56
|
- spec/filepathlist_spec.rb
|
54
57
|
- spec/spec_helper.rb
|