filepath 0.4 → 0.5

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/.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