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 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
Binary file
data/Rakefile CHANGED
@@ -13,7 +13,7 @@ Bones {
13
13
  email 'gioele@svario.it'
14
14
  url 'http://github.com/gioele/filepath'
15
15
 
16
- version '0.4'
16
+ version '0.5'
17
17
 
18
18
  ignore_file '.gitignore'
19
19
 
@@ -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] base the file to use as base for the
169
- # relative path
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
- if self.root?
186
+ segs = self.normalized_segments
187
+
188
+ if self.root? || segs.empty?
189
189
  return ''.as_path
190
190
  end
191
191
 
192
- filename = self.normalized_segments.last
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.replace_filename("style.css")
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 #replace_extension
223
+ # @see #with_extension
224
224
 
225
- def replace_filename(new_path)
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 :replace_basename :replace_filename
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 #remove_extension
293
- # @see #replace_filename
294
+ # @see #without_extension
295
+ # @see #with_filename
294
296
  #
295
- # @overload replace_extension(new_ext)
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.replace_extension("html")
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.replace_extension("sass")
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 replace_extension
317
+ # @overload with_extension
316
318
  # Removes the file extension if present.
317
319
  #
318
- # The {#remove_extension} method provides the same functionality
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.replace_extension(nil)
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 replace_extension(new_ext) # FIXME: accept block
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 :replace_ext :replace_extension
355
- alias :sub_ext :replace_extension
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.remove_extension
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 #replace_extension
371
+ # @see #with_extension
369
372
 
370
- def remove_extension
371
- return replace_ext(nil)
373
+ def without_extension
374
+ return with_extension(nil)
372
375
  end
373
376
 
374
- alias :remove_ext :remove_extension
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 PathResolution
687
- def absolute_path(base_dir = Dir.pwd) # FIXME: rename to `#absolute`?
688
- if self.absolute?
689
- return self
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
- alias :realpath :real_path
702
-
703
- def resolve_link
704
- return File.readlink(self).as_path
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 self.define_filetest_method(filepath_method, filetest_method = nil)
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 :empty?, :zero?
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 FileManipulationMethods
746
- def open(*args, &block)
747
- File.open(self, *args, &block)
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 DirectoryMethods
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? :to_str
775
- return entries(pattern, true)
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
- include PathResolution
799
- include FileInfo
800
- include FileManipulationMethods
801
- include DirectoryMethods
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