filepath 0.4 → 0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/.yardoc/checksums +5 -0
- data/.yardoc/object_types +0 -0
- data/.yardoc/objects/root.dat +0 -0
- data/.yardoc/proxy_types +0 -0
- data/Rakefile +1 -1
- data/lib/filepath/filepath.rb +241 -61
- data/lib/filepath/filepathlist.rb +31 -19
- data/spec/filepath_spec.rb +416 -61
- data/spec/filepathlist_spec.rb +74 -39
- data/spec/fixtures/d1/f11 +0 -0
- data/spec/fixtures/d1/f12 +0 -0
- data/spec/fixtures/f1 +0 -0
- data/spec/tasks.rb +12 -0
- metadata +73 -42
- data/.gitignore +0 -6
data/.yardoc/checksums
ADDED
@@ -0,0 +1,5 @@
|
|
1
|
+
lib/filepath/filepathlist.rb 335c103f2ff2f3f0ac8002e6572efec06bc6a39f
|
2
|
+
lib/filepath.rb b4eb1e60d85d4eec7fcc37bb64429918d7750887
|
3
|
+
lib/filepath/filepath.rb 0c95f278feab4f64cd5535d1c994338b5c2c2638
|
4
|
+
lib/filepath/core_ext/array.rb b774c4cbf988b1cd154222454dbc36730d4f5fe7
|
5
|
+
lib/filepath/core_ext/string.rb 75d10671a6f439286f1c7d4f81d03eb84c3796f6
|
Binary file
|
Binary file
|
data/.yardoc/proxy_types
ADDED
Binary file
|
data/Rakefile
CHANGED
data/lib/filepath/filepath.rb
CHANGED
@@ -68,8 +68,6 @@ class FilePath
|
|
68
68
|
return FilePath.join(self, *extra_paths)
|
69
69
|
end
|
70
70
|
|
71
|
-
alias :append :join
|
72
|
-
|
73
71
|
|
74
72
|
# An alias for {FilePath#/}.
|
75
73
|
#
|
@@ -165,8 +163,8 @@ class FilePath
|
|
165
163
|
#
|
166
164
|
# tmp_dir.relative_to_file(rc_file) #=> <../../tmp>
|
167
165
|
#
|
168
|
-
# @param [FilePath, String]
|
169
|
-
#
|
166
|
+
# @param [FilePath, String] base_file the file to use as base for the
|
167
|
+
# relative path
|
170
168
|
#
|
171
169
|
# @return [FilePath] the relative path
|
172
170
|
#
|
@@ -185,11 +183,13 @@ class FilePath
|
|
185
183
|
# @return [FilePath] the filename
|
186
184
|
|
187
185
|
def filename
|
188
|
-
|
186
|
+
segs = self.normalized_segments
|
187
|
+
|
188
|
+
if self.root? || segs.empty?
|
189
189
|
return ''.as_path
|
190
190
|
end
|
191
191
|
|
192
|
-
filename =
|
192
|
+
filename = segs.last
|
193
193
|
return filename.as_path
|
194
194
|
end
|
195
195
|
|
@@ -210,7 +210,7 @@ class FilePath
|
|
210
210
|
# @example
|
211
211
|
#
|
212
212
|
# post = "posts/2012-02-16-hello-world/index.md".as_path
|
213
|
-
# style = post.
|
213
|
+
# style = post.with_filename("style.css")
|
214
214
|
# style.to_s #=> "posts/2012-02-16-hello-world/style.css"
|
215
215
|
#
|
216
216
|
# @param [FilePath, String] new_path the path to be put in place of
|
@@ -220,14 +220,16 @@ class FilePath
|
|
220
220
|
# current filename
|
221
221
|
#
|
222
222
|
# @see #filename
|
223
|
-
# @see #
|
223
|
+
# @see #with_extension
|
224
224
|
|
225
|
-
def
|
225
|
+
def with_filename(new_path)
|
226
226
|
dir = self.parent_dir
|
227
227
|
return dir / new_path
|
228
228
|
end
|
229
229
|
|
230
|
-
alias :
|
230
|
+
alias :with_basename :with_filename
|
231
|
+
alias :replace_filename :with_filename
|
232
|
+
alias :replace_basename :with_filename
|
231
233
|
|
232
234
|
|
233
235
|
# The extension of the file.
|
@@ -289,44 +291,44 @@ class FilePath
|
|
289
291
|
#
|
290
292
|
# @see #extension
|
291
293
|
# @see #extension?
|
292
|
-
# @see #
|
293
|
-
# @see #
|
294
|
+
# @see #without_extension
|
295
|
+
# @see #with_filename
|
294
296
|
#
|
295
|
-
# @overload
|
297
|
+
# @overload with_extension(new_ext)
|
296
298
|
# Replaces the file extension with the supplied one. If the file
|
297
299
|
# has no extension it is added to the file name together with a dot.
|
298
300
|
#
|
299
301
|
# @example Extension replacement
|
300
302
|
#
|
301
303
|
# src_path = "pages/about.markdown".as_path
|
302
|
-
# html_path = src_path.
|
304
|
+
# html_path = src_path.with_extension("html")
|
303
305
|
# html_path.to_s #=> "pages/about.html"
|
304
306
|
#
|
305
307
|
# @example Extension addition
|
306
308
|
#
|
307
309
|
# base = "style/main-style".as_path
|
308
|
-
# sass_style = base.
|
310
|
+
# sass_style = base.with_extension("sass")
|
309
311
|
# sass_style.to_s #=> "style/main-style.sass"
|
310
312
|
#
|
311
313
|
# @param [String] new_ext the new extension
|
312
314
|
#
|
313
315
|
# @return [FilePath] a new path with the replaced extension
|
314
316
|
#
|
315
|
-
# @overload
|
317
|
+
# @overload with_extension
|
316
318
|
# Removes the file extension if present.
|
317
319
|
#
|
318
|
-
# The {#
|
320
|
+
# The {#without_extension} method provides the same functionality
|
319
321
|
# but has a more meaningful name.
|
320
322
|
#
|
321
323
|
# @example
|
322
324
|
#
|
323
325
|
# post_file = "post/welcome.html"
|
324
|
-
# post_url = post_file.
|
326
|
+
# post_url = post_file.with_extension(nil)
|
325
327
|
# post_url.to_s #=> "post/welcome"
|
326
328
|
#
|
327
329
|
# @return [FilePath] a new path without the extension
|
328
330
|
|
329
|
-
def
|
331
|
+
def with_extension(new_ext) # FIXME: accept block
|
330
332
|
orig_filename = filename.to_s
|
331
333
|
|
332
334
|
if !self.extension?
|
@@ -351,8 +353,9 @@ class FilePath
|
|
351
353
|
return FilePath.new(segs)
|
352
354
|
end
|
353
355
|
|
354
|
-
alias :
|
355
|
-
alias :
|
356
|
+
alias :replace_extension :with_extension
|
357
|
+
alias :replace_ext :with_extension
|
358
|
+
alias :sub_ext :with_extension
|
356
359
|
|
357
360
|
|
358
361
|
# Removes the file extension if present.
|
@@ -360,18 +363,19 @@ class FilePath
|
|
360
363
|
# @example
|
361
364
|
#
|
362
365
|
# post_file = "post/welcome.html"
|
363
|
-
# post_url = post_file.
|
366
|
+
# post_url = post_file.without_extension
|
364
367
|
# post_url.to_s #=> "post/welcome"
|
365
368
|
#
|
366
369
|
# @return [FilePath] a new path without the extension
|
367
370
|
#
|
368
|
-
# @see #
|
371
|
+
# @see #with_extension
|
369
372
|
|
370
|
-
def
|
371
|
-
return
|
373
|
+
def without_extension
|
374
|
+
return with_extension(nil)
|
372
375
|
end
|
373
376
|
|
374
|
-
alias :remove_ext :
|
377
|
+
alias :remove_ext :without_extension
|
378
|
+
alias :remove_extension :without_extension
|
375
379
|
|
376
380
|
|
377
381
|
# Matches a pattern against this path.
|
@@ -460,6 +464,36 @@ class FilePath
|
|
460
464
|
|
461
465
|
alias :normalised :normalized
|
462
466
|
|
467
|
+
# Iterates over all the path segments, from the leftmost to the
|
468
|
+
# rightmost.
|
469
|
+
#
|
470
|
+
# @example
|
471
|
+
#
|
472
|
+
# web_dir = "/srv/example.org/web/html".as_path
|
473
|
+
# web_dir.each_segment do |seg|
|
474
|
+
# puts seg
|
475
|
+
# end
|
476
|
+
#
|
477
|
+
# # produces
|
478
|
+
# #
|
479
|
+
# # /
|
480
|
+
# # srv
|
481
|
+
# # example.org
|
482
|
+
# # web
|
483
|
+
# # html
|
484
|
+
#
|
485
|
+
# @yield [path] TODO
|
486
|
+
#
|
487
|
+
# @return [FilePath] the path itself.
|
488
|
+
#
|
489
|
+
# @see #ascend
|
490
|
+
# @see #descend
|
491
|
+
|
492
|
+
def each_segment(&block)
|
493
|
+
@segments.each(&block)
|
494
|
+
return self
|
495
|
+
end
|
496
|
+
|
463
497
|
|
464
498
|
# Iterates over all the path directories, from the current path to
|
465
499
|
# the root.
|
@@ -488,6 +522,7 @@ class FilePath
|
|
488
522
|
#
|
489
523
|
# @return [FilePath] the path itself.
|
490
524
|
#
|
525
|
+
# @see #each_segment
|
491
526
|
# @see #descend
|
492
527
|
|
493
528
|
def ascend(max_depth = nil, &block)
|
@@ -521,6 +556,7 @@ class FilePath
|
|
521
556
|
#
|
522
557
|
# @return [FilePath] the path itself.
|
523
558
|
#
|
559
|
+
# @see #each_segment
|
524
560
|
# @see #ascend
|
525
561
|
|
526
562
|
def descend(max_depth = nil, &block)
|
@@ -626,6 +662,11 @@ class FilePath
|
|
626
662
|
return @segments == other.segments
|
627
663
|
end
|
628
664
|
|
665
|
+
# @private
|
666
|
+
def <=>(other)
|
667
|
+
return self.normalized_segments <=> other.normalized_segments
|
668
|
+
end
|
669
|
+
|
629
670
|
# @private
|
630
671
|
def hash
|
631
672
|
return @segments.hash
|
@@ -655,9 +696,6 @@ class FilePath
|
|
655
696
|
def normalized_relative_segs(orig_segs)
|
656
697
|
segs = orig_segs.dup
|
657
698
|
|
658
|
-
# remove "current dir" markers
|
659
|
-
segs.delete('.')
|
660
|
-
|
661
699
|
i = 0
|
662
700
|
while (i < segs.length)
|
663
701
|
if segs[i] == '..' && segs[i-1] == SEPARATOR
|
@@ -669,6 +707,10 @@ class FilePath
|
|
669
707
|
segs.delete_at(i)
|
670
708
|
segs.delete_at(i-1)
|
671
709
|
i -= 2
|
710
|
+
elsif segs[i] == '.'
|
711
|
+
# remove "current dir" markers
|
712
|
+
segs.delete_at(i)
|
713
|
+
i -= 1
|
672
714
|
end
|
673
715
|
i += 1
|
674
716
|
end
|
@@ -683,36 +725,69 @@ class FilePath
|
|
683
725
|
return segs.join(SEPARATOR).sub(%r{^//}, SEPARATOR).sub(/\A\Z/, '.')
|
684
726
|
end
|
685
727
|
|
686
|
-
module
|
687
|
-
|
688
|
-
|
689
|
-
|
728
|
+
module MethodDelegation
|
729
|
+
# @private
|
730
|
+
def define_io_method(filepath_method, io_method = nil)
|
731
|
+
io_method ||= filepath_method
|
732
|
+
define_method(filepath_method) do |*args, &block|
|
733
|
+
return File.send(io_method, self, *args, &block)
|
690
734
|
end
|
691
|
-
|
692
|
-
return base_dir.as_path / self
|
693
|
-
end
|
694
|
-
|
695
|
-
def real_path(base_dir = Dir.pwd)
|
696
|
-
path = absolute_path(base_dir)
|
697
|
-
|
698
|
-
return path.resolve_link
|
699
735
|
end
|
700
736
|
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
737
|
+
# @private
|
738
|
+
def define_file_method(filepath_method, file_method = nil)
|
739
|
+
file_method ||= filepath_method
|
740
|
+
define_method(filepath_method) do |*args|
|
741
|
+
all_args = args + [self]
|
742
|
+
return File.send(file_method, *all_args)
|
743
|
+
end
|
705
744
|
end
|
706
|
-
end
|
707
745
|
|
708
|
-
module FileInfo
|
709
746
|
# @private
|
710
|
-
def
|
747
|
+
def define_filetest_method(filepath_method, filetest_method = nil)
|
711
748
|
filetest_method ||= filepath_method
|
712
749
|
define_method(filepath_method) do
|
713
750
|
return FileTest.send(filetest_method, self)
|
714
751
|
end
|
715
752
|
end
|
753
|
+
end
|
754
|
+
|
755
|
+
module MetadataInfo
|
756
|
+
extend MethodDelegation
|
757
|
+
|
758
|
+
define_file_method :stat
|
759
|
+
|
760
|
+
define_file_method :lstat
|
761
|
+
|
762
|
+
define_file_method :atime
|
763
|
+
|
764
|
+
define_file_method :ctime
|
765
|
+
|
766
|
+
define_file_method :mtime
|
767
|
+
end
|
768
|
+
|
769
|
+
module MetadataChanges
|
770
|
+
extend MethodDelegation
|
771
|
+
|
772
|
+
# utime(atime, mtime)
|
773
|
+
define_file_method :utime
|
774
|
+
alias :chtime :utime
|
775
|
+
|
776
|
+
# chmod(mode)
|
777
|
+
define_file_method :chmod
|
778
|
+
|
779
|
+
# lchmod(mode)
|
780
|
+
define_file_method :lchmod
|
781
|
+
|
782
|
+
# chown(owner_id, group_id)
|
783
|
+
define_file_method :chown
|
784
|
+
|
785
|
+
# lchown(owner_id, group_id)
|
786
|
+
define_file_method :lchown
|
787
|
+
end
|
788
|
+
|
789
|
+
module MetadataTests
|
790
|
+
extend MethodDelegation
|
716
791
|
|
717
792
|
define_filetest_method :file?
|
718
793
|
|
@@ -721,6 +796,14 @@ class FilePath
|
|
721
796
|
|
722
797
|
define_filetest_method :directory?
|
723
798
|
|
799
|
+
define_filetest_method :pipe?
|
800
|
+
|
801
|
+
define_filetest_method :socket?
|
802
|
+
|
803
|
+
define_filetest_method :blockdev?
|
804
|
+
|
805
|
+
define_filetest_method :chardev?
|
806
|
+
|
724
807
|
define_filetest_method :exists?
|
725
808
|
alias :exist? :exists?
|
726
809
|
|
@@ -734,26 +817,108 @@ class FilePath
|
|
734
817
|
|
735
818
|
define_filetest_method :setuid?
|
736
819
|
|
737
|
-
define_filetest_method :
|
738
|
-
alias :zero? :empty?
|
820
|
+
define_filetest_method :sticky?
|
739
821
|
|
740
822
|
def hidden?
|
741
823
|
@segments.last.start_with?('.') # FIXME: windows, mac
|
742
824
|
end
|
743
825
|
end
|
744
826
|
|
745
|
-
module
|
746
|
-
def
|
747
|
-
|
827
|
+
module FilesystemInfo
|
828
|
+
def absolute_path(base_dir = Dir.pwd) # FIXME: rename to `#absolute`?
|
829
|
+
if self.absolute?
|
830
|
+
return self
|
831
|
+
end
|
832
|
+
|
833
|
+
return base_dir.as_path / self
|
834
|
+
end
|
835
|
+
|
836
|
+
def real_path(base_dir = Dir.pwd)
|
837
|
+
path = absolute_path(base_dir)
|
838
|
+
|
839
|
+
return path.resolve_link
|
748
840
|
end
|
749
841
|
|
842
|
+
alias :realpath :real_path
|
843
|
+
|
844
|
+
def resolve_link
|
845
|
+
return File.readlink(self).as_path
|
846
|
+
end
|
847
|
+
end
|
848
|
+
|
849
|
+
module FilesystemChanges
|
750
850
|
def touch
|
751
851
|
self.open('a') do ; end
|
752
852
|
File.utime(File.atime(self), Time.now, self)
|
753
853
|
end
|
754
854
|
end
|
755
855
|
|
756
|
-
module
|
856
|
+
module FilesystemTests
|
857
|
+
def mountpoint?
|
858
|
+
if !directory? || !exists?
|
859
|
+
return false
|
860
|
+
end
|
861
|
+
|
862
|
+
if root?
|
863
|
+
return true
|
864
|
+
end
|
865
|
+
|
866
|
+
return self.lstat.dev != parent_dir.lstat.dev
|
867
|
+
end
|
868
|
+
end
|
869
|
+
|
870
|
+
module ContentInfo
|
871
|
+
extend MethodDelegation
|
872
|
+
|
873
|
+
define_io_method :read
|
874
|
+
|
875
|
+
if IO.respond_to? :binread
|
876
|
+
define_io_method :binread
|
877
|
+
else
|
878
|
+
alias :binread :read
|
879
|
+
end
|
880
|
+
|
881
|
+
define_io_method :readlines
|
882
|
+
|
883
|
+
define_io_method :size
|
884
|
+
end
|
885
|
+
|
886
|
+
module ContentChanges
|
887
|
+
extend MethodDelegation
|
888
|
+
|
889
|
+
define_io_method :open
|
890
|
+
|
891
|
+
def write(content)
|
892
|
+
open('w') do |file|
|
893
|
+
file.write(content)
|
894
|
+
end
|
895
|
+
end
|
896
|
+
|
897
|
+
def append(content)
|
898
|
+
open('a') do |file|
|
899
|
+
file.write(content)
|
900
|
+
end
|
901
|
+
end
|
902
|
+
|
903
|
+
define_io_method :file_truncate, :truncate
|
904
|
+
|
905
|
+
def truncate(*args)
|
906
|
+
if args.empty?
|
907
|
+
args << 0
|
908
|
+
end
|
909
|
+
|
910
|
+
file_truncate(*args)
|
911
|
+
end
|
912
|
+
end
|
913
|
+
|
914
|
+
module ContentTests
|
915
|
+
extend MethodDelegation
|
916
|
+
|
917
|
+
define_file_method :empty?, :zero?
|
918
|
+
alias :zero? :empty?
|
919
|
+
end
|
920
|
+
|
921
|
+
module SearchMethods
|
757
922
|
def entries(pattern = '*', recursive = false)
|
758
923
|
if !self.directory?
|
759
924
|
raise Errno::ENOTDIR.new(self)
|
@@ -770,9 +935,9 @@ class FilePath
|
|
770
935
|
end
|
771
936
|
alias :glob :entries
|
772
937
|
|
773
|
-
def find(pattern = nil, &block)
|
774
|
-
if pattern.respond_to?
|
775
|
-
return entries(pattern,
|
938
|
+
def find(pattern = nil, recursive = true, &block)
|
939
|
+
if !pattern.nil? && pattern.respond_to?(:to_str)
|
940
|
+
return entries(pattern, recursive)
|
776
941
|
end
|
777
942
|
|
778
943
|
if !block_given?
|
@@ -795,8 +960,23 @@ class FilePath
|
|
795
960
|
end
|
796
961
|
end
|
797
962
|
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
963
|
+
module EnvironmentInfo
|
964
|
+
def FilePath.getwd
|
965
|
+
return Dir.getwd.as_path
|
966
|
+
end
|
967
|
+
end
|
968
|
+
|
969
|
+
include MetadataInfo
|
970
|
+
include MetadataChanges
|
971
|
+
include MetadataTests
|
972
|
+
|
973
|
+
include FilesystemInfo
|
974
|
+
include FilesystemChanges
|
975
|
+
include FilesystemTests
|
976
|
+
|
977
|
+
include ContentInfo
|
978
|
+
include ContentChanges
|
979
|
+
include ContentTests
|
980
|
+
|
981
|
+
include SearchMethods
|
802
982
|
end
|