win32-file 0.5.6 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGES CHANGED
@@ -1,3 +1,14 @@
1
+ == 0.6.0 - 14-Nov-2008
2
+ * Converted methods to use wide character handling.
3
+ * Added working implementations for the File.readlink, File.symlink and
4
+ File.symlink? singleton methods. These require Windows Vista or later to
5
+ work properly. Otherwise, they follow current MRI behavior.
6
+ * To work properly in conjunction with win32-file-stat, a custom version
7
+ of the File.directory? method was implemented.
8
+ * Changed VERSION to WIN32_FILE_VERSION to be more consistent with other
9
+ Win32Utils libraries, and to avoid any potential conflicts with Ruby itself.
10
+ * Prerequisite updates.
11
+
1
12
  == 0.5.6 - 30-Sep-2008
2
13
  * The File.long_path and File.short_path methods now return the full path
3
14
  instead of just the basename of the path. I really have no idea why I was
data/lib/win32/file.rb CHANGED
@@ -16,9 +16,10 @@ class File
16
16
  extend Windows::Security
17
17
  extend Windows::MSVCRT::Buffer
18
18
  extend Windows::Limits
19
+ extend Windows::Handle
19
20
 
20
21
  # The version of the win32-file library
21
- VERSION = '0.5.6'
22
+ WIN32_FILE_VERSION = '0.6.0'
22
23
 
23
24
  # Abbreviated attribute constants for convenience
24
25
 
@@ -58,11 +59,15 @@ class File
58
59
  alias basename_orig basename
59
60
  alias blockdev_orig blockdev?
60
61
  alias chardev_orig chardev?
62
+ alias directory_orig? directory?
61
63
  alias dirname_orig dirname
62
64
  alias lstat_orig lstat
65
+ alias readlink_orig readlink
63
66
  alias size_orig size
64
67
  alias split_orig split
65
68
  alias stat_orig stat
69
+ alias symlink_orig symlink
70
+ alias symlink_orig? symlink?
66
71
 
67
72
  ## Security
68
73
 
@@ -104,8 +109,11 @@ class File
104
109
  # * GENERIC_ALL
105
110
  #
106
111
  def set_permissions(file, perms)
112
+ raise TypeError unless file.is_a?(String)
107
113
  raise TypeError unless perms.kind_of?(Hash)
108
114
 
115
+ file = multi_to_wide(file)
116
+
109
117
  account_rights = 0
110
118
  sec_desc = 0.chr * SECURITY_DESCRIPTOR_MIN_LENGTH
111
119
 
@@ -211,7 +219,7 @@ class File
211
219
  raise ArgumentError, get_last_error
212
220
  end
213
221
 
214
- unless SetFileSecurity(file, DACL_SECURITY_INFORMATION, sec_desc)
222
+ unless SetFileSecurityW(file, DACL_SECURITY_INFORMATION, sec_desc)
215
223
  raise ArgumentError, get_last_error
216
224
  end
217
225
 
@@ -253,8 +261,8 @@ class File
253
261
  sec_buf = ''
254
262
 
255
263
  loop do
256
- bool = GetFileSecurity(
257
- file,
264
+ bool = GetFileSecurityW(
265
+ multi_to_wide(file),
258
266
  DACL_SECURITY_INFORMATION,
259
267
  sec_buf,
260
268
  sec_buf.length,
@@ -366,7 +374,7 @@ class File
366
374
  # Windows 2000 or later only.
367
375
  #
368
376
  def encrypt(file)
369
- unless EncryptFile(file)
377
+ unless EncryptFileW(multi_to_wide(file))
370
378
  raise ArgumentError, get_last_error
371
379
  end
372
380
  self
@@ -385,7 +393,7 @@ class File
385
393
  # Windows 2000 or later only.
386
394
  #
387
395
  def decrypt(file)
388
- unless DecryptFile(file, 0)
396
+ unless DecryptFileW(multi_to_wide(file), 0)
389
397
  raise ArgumentError, get_last_error
390
398
  end
391
399
  self
@@ -401,6 +409,9 @@ class File
401
409
  # paths properly, i.e. it should not return anything less than the root.
402
410
  # In all other respects it is identical to the current implementation.
403
411
  #
412
+ # Unlike MRI, this version will convert all forward slashes to
413
+ # backslashes automatically.
414
+ #
404
415
  # Examples:
405
416
  #
406
417
  # File.basename("C:\\foo\\bar.txt") -> "bar.txt"
@@ -408,49 +419,45 @@ class File
408
419
  # File.basename("\\\\foo\\bar") -> "\\\\foo\\bar"
409
420
  #
410
421
  def basename(file, suffix = nil)
411
- fpath = false
412
- file = file.dup # Don't modify original string
413
-
414
- # We have to convert forward slashes to backslashes for the Windows
415
- # functions to work properly.
416
- if file.include?('/')
417
- file.tr!('/', '\\')
418
- fpath = true
419
- end
422
+ raise TypeError unless file.is_a?(String)
423
+ raise TypeError unless suffix.is_a?(String) if suffix
424
+
425
+ return file if file.empty? # Return an empty path as-is.
426
+ file = multi_to_wide(file)
427
+
428
+ # Required for Windows API functions to work properly.
429
+ file.tr!(File::SEPARATOR, File::ALT_SEPARATOR)
430
+
431
+ # Return a root path as-is.
432
+ return wide_to_multi(file) if PathIsRootW(file)
420
433
 
421
- # Return an empty or root path as-is.
422
- if file.empty? || PathIsRoot(file)
423
- file.tr!("\\", '/') if fpath
424
- return file
425
- end
426
-
427
- PathStripPath(file) # Gives us the basename
434
+ PathStripPathW(file) # Gives us the basename
428
435
 
429
436
  if suffix
430
437
  if suffix == '.*'
431
- PathRemoveExtension(file)
438
+ PathRemoveExtensionW(file)
432
439
  else
433
- if PathFindExtension(file) == suffix
434
- PathRemoveExtension(file)
440
+ if PathFindExtensionA(wide_to_multi(file)) == suffix
441
+ PathRemoveExtensionW(file)
435
442
  end
436
443
  end
437
444
  end
438
-
439
- file = file.split(0.chr).first
440
-
441
- # Trim trailing slashes
442
- while file[-1].chr == "\\"
443
- file.chop!
444
- end
445
-
446
- # Return forward slashes if that's how the path was passed in.
447
- if fpath
448
- file.tr!("\\", '/')
449
- end
450
-
445
+
446
+ file = wide_to_multi(file)
447
+ file.chop! while file[-1].chr == "\\" # Trim trailing slashes
448
+
451
449
  file
452
450
  end
453
451
 
452
+ # Returns true if +file+ is a directory, false otherwise.
453
+ #--
454
+ # This method was redefined to handle wide character strings.
455
+ #
456
+ def directory?(file)
457
+ file = multi_to_wide(file)
458
+ GetFileAttributesW(file) & FILE_ATTRIBUTE_DIRECTORY > 0
459
+ end
460
+
454
461
  # Returns all components of the filename given in +filename+ except the
455
462
  # last one.
456
463
  #
@@ -458,36 +465,33 @@ class File
458
465
  # paths properly, i.e. it should not return anything less than the root.
459
466
  # In all other respects it is identical to the current implementation.
460
467
  #
468
+ # Also, this method will convert all forward slashes to backslashes.
469
+ #
461
470
  # Examples:
462
471
  #
463
472
  # File.dirname("C:\\foo\\bar\\baz.txt") -> "C:\\foo\\bar"
464
473
  # File.dirname("\\\\foo\\bar") -> "\\\\foo\\bar"
465
474
  #
466
- def dirname(file)
467
- fpath = false
468
- file = file.dup
469
-
470
- if file.include?('/')
471
- file.tr!('/', "\\")
472
- fpath = true
473
- end
475
+ def dirname(file)
476
+ raise TypeError unless file.is_a?(String)
477
+ file = multi_to_wide(file)
478
+
479
+ # Convert slashes to backslashes for the Windows API functions
480
+ file.tr!(File::SEPARATOR, File::ALT_SEPARATOR)
474
481
 
475
- if PathIsRoot(file)
476
- file.tr!("\\", '/') if fpath
477
- return file
478
- end
482
+ # Return a root path as-is.
483
+ return wide_to_multi(file) if PathIsRootW(file)
479
484
 
480
- PathRemoveFileSpec(file)
481
- file = file.split(0.chr).first
485
+ # Remove trailing file name and backslash, if present
486
+ PathRemoveFileSpecW(file)
487
+
488
+ file = wide_to_multi(file)
482
489
 
483
490
  # Empty paths, short relative paths
484
491
  if file.nil? || (file && file.empty?)
485
492
  return '.'
486
493
  end
487
494
 
488
- PathRemoveBackslash(file)
489
-
490
- file.tr!("\\", '/') if fpath
491
495
  file
492
496
  end
493
497
 
@@ -501,10 +505,48 @@ class File
501
505
  #
502
506
  def long_path(path)
503
507
  buf = 0.chr * MAXPATH
504
- if GetLongPathName(path, buf, buf.size) == 0
508
+ if GetLongPathNameW(multi_to_wide(path), buf, buf.size) == 0
505
509
  raise ArgumentError, get_last_error
506
510
  end
507
- buf.split(0.chr).first
511
+ wide_to_multi(buf)
512
+ end
513
+
514
+ # Returns the path of the of the symbolic link referred to by +file+.
515
+ #
516
+ # Requires Windows Vista or later. On older versions of Windows it
517
+ # will raise a NotImplementedError, as per MRI.
518
+ #
519
+ def readlink(file)
520
+ if defined? GetFinalPathNameByHandle
521
+ file = multi_to_wide(file)
522
+
523
+ begin
524
+ handle = CreateFileW(
525
+ file,
526
+ GENERIC_READ,
527
+ FILE_SHARE_READ,
528
+ nil,
529
+ OPEN_EXISTING,
530
+ FILE_ATTRIBUTE_NORMAL,
531
+ nil
532
+ )
533
+
534
+ if handle == INVALID_HANDLE_VALUE
535
+ raise ArgumentError, get_last_error
536
+ end
537
+
538
+ path = 0.chr * MAXPATH
539
+
540
+ GetFinalPathNameByHandleW(handle, path, path.size, 0)
541
+ ensure
542
+ CloseHandle(handle)
543
+ end
544
+
545
+ wide_to_multi(path).strip[4..-1] # get rid of prepending "\\?\"
546
+ else
547
+ msg = "readlink() function is unimplemented on this machine"
548
+ raise NotImplementedError, msg
549
+ end
508
550
  end
509
551
 
510
552
  # Returns +path+ in 8.3 format. For example, 'c:\documentation.doc'
@@ -512,10 +554,10 @@ class File
512
554
  #
513
555
  def short_path(path)
514
556
  buf = 0.chr * MAXPATH
515
- if GetShortPathName(path, buf, buf.size) == 0
557
+ if GetShortPathNameW(multi_to_wide(path), buf, buf.size) == 0
516
558
  raise ArgumentError, get_last_error
517
559
  end
518
- buf.split(0.chr).first
560
+ wide_to_multi(buf)
519
561
  end
520
562
 
521
563
  # Splits the given string into a directory and a file component and
@@ -525,7 +567,7 @@ class File
525
567
  def split(file)
526
568
  array = []
527
569
 
528
- if file.empty? || PathIsRoot(file)
570
+ if file.empty? || PathIsRootW(multi_to_wide(file))
529
571
  array.push(file, '')
530
572
  else
531
573
  array.push(File.dirname(file), File.basename(file))
@@ -533,6 +575,57 @@ class File
533
575
  array
534
576
  end
535
577
 
578
+ # Creates a symbolic link called +new_name+ for the file or directory
579
+ # +old_name+.
580
+ #
581
+ # This method requires Windows Vista or later to work. Otherwise, it
582
+ # returns nil as per MRI.
583
+ #
584
+ def symlink(old_name, new_name)
585
+ if defined? CreateSymbolicLink
586
+ old_name = multi_to_wide(old_name)
587
+ new_name = multi_to_wide(new_name)
588
+ flags = File.directory?(wide_to_multi(old_name)) ? 1 : 0
589
+
590
+ unless CreateSymbolicLinkW(new_name, old_name, flags)
591
+ raise ArgumentError, get_last_error
592
+ end
593
+ else
594
+ nil
595
+ end
596
+ end
597
+
598
+ # Return true if the named file is a symbolic link, false otherwise.
599
+ #
600
+ # This method requires Windows Vista or later to work. Otherwise, it
601
+ # always returns false as per MRI.
602
+ #
603
+ def symlink?(file)
604
+ bool = false
605
+ file = multi_to_wide(file)
606
+ attr = GetFileAttributesW(file)
607
+
608
+ # Differentiate between a symlink and other kinds of reparse points
609
+ if attr & FILE_ATTRIBUTE_REPARSE_POINT > 0
610
+ begin
611
+ buffer = 0.chr * 278 # WIN32_FIND_DATA
612
+ handle = FindFirstFileW(file, buffer)
613
+
614
+ if handle == INVALID_HANDLE_VALUE
615
+ raise ArgumentError, get_last_error
616
+ end
617
+
618
+ if buffer[36,4].unpack('L')[0] == IO_REPARSE_TAG_SYMLINK
619
+ bool = true
620
+ end
621
+ ensure
622
+ CloseHandle(handle)
623
+ end
624
+ end
625
+
626
+ bool
627
+ end
628
+
536
629
  ## Stat methods
537
630
 
538
631
  # Returns a File::Stat object, as defined in the win32-file-stat package.
@@ -578,8 +671,9 @@ class File
578
671
 
579
672
  # We no longer need the aliases, so remove them
580
673
  remove_method(:basename_orig, :blockdev_orig, :chardev_orig)
581
- remove_method(:dirname_orig, :lstat_orig, :size_orig)
582
- remove_method(:split_orig, :stat_orig)
674
+ remove_method(:dirname_orig, :lstat_orig, :size_orig, :split_orig)
675
+ remove_method(:stat_orig, :symlink_orig, :symlink_orig?, :readlink_orig)
676
+ remove_method(:directory_orig?)
583
677
  end # class << self
584
678
 
585
679
  ## Attribute methods
@@ -646,8 +740,6 @@ class File
646
740
  def self.readonly?(file)
647
741
  File::Stat.new(file).readonly?
648
742
  end
649
-
650
-
651
743
 
652
744
  # Returns true if the file or directory has an associated reparse point. A
653
745
  # reparse point is a collection of user defined data associated with a file
@@ -703,7 +795,8 @@ class File
703
795
  # temporary
704
796
  #
705
797
  def self.attributes(file)
706
- attributes = GetFileAttributes(file)
798
+ file = multi_to_wide(file)
799
+ attributes = GetFileAttributesW(file)
707
800
  arr = []
708
801
 
709
802
  if attributes == INVALID_FILE_ATTRIBUTES
@@ -731,7 +824,8 @@ class File
731
824
  # not remove existing attributes, it merely adds to them.
732
825
  #
733
826
  def self.set_attributes(file, flags)
734
- attributes = GetFileAttributes(file)
827
+ file = multi_to_wide(file)
828
+ attributes = GetFileAttributesW(file)
735
829
 
736
830
  if attributes == INVALID_FILE_ATTRIBUTES
737
831
  raise ArgumentError, get_last_error
@@ -739,7 +833,7 @@ class File
739
833
 
740
834
  attributes |= flags
741
835
 
742
- if SetFileAttributes(file, attributes) == 0
836
+ if SetFileAttributesW(file, attributes) == 0
743
837
  raise ArgumentError, get_last_error
744
838
  end
745
839
 
@@ -749,7 +843,8 @@ class File
749
843
  # Removes the file attributes based on the given (numeric) +flags+.
750
844
  #
751
845
  def self.remove_attributes(file, flags)
752
- attributes = GetFileAttributes(file)
846
+ file = multi_to_wide(file)
847
+ attributes = GetFileAttributesW(file)
753
848
 
754
849
  if attributes == INVALID_FILE_ATTRIBUTES
755
850
  raise ArgumentError, get_last_error
@@ -757,7 +852,7 @@ class File
757
852
 
758
853
  attributes &= ~flags
759
854
 
760
- if SetFileAttributes(file, attributes) == 0
855
+ if SetFileAttributesW(file, attributes) == 0
761
856
  raise ArgumentError, get_last_error
762
857
  end
763
858
 
@@ -773,7 +868,8 @@ class File
773
868
  # Sets whether or not the file is an archive file.
774
869
  #
775
870
  def archive=(bool)
776
- attributes = GetFileAttributes(self.path)
871
+ wide_path = multi_to_wide(self.path)
872
+ attributes = GetFileAttributesW(wide_path)
777
873
 
778
874
  if attributes == INVALID_FILE_ATTRIBUTES
779
875
  raise ArgumentError, get_last_error
@@ -785,7 +881,7 @@ class File
785
881
  attributes &= ~FILE_ATTRIBUTE_ARCHIVE;
786
882
  end
787
883
 
788
- if SetFileAttributes(self.path, attributes) == 0
884
+ if SetFileAttributesW(wide_path, attributes) == 0
789
885
  raise ArgumentError, get_last_error
790
886
  end
791
887
 
@@ -800,8 +896,8 @@ class File
800
896
  bytes = [0].pack('L')
801
897
 
802
898
  # We can't use get_osfhandle here because we need specific attributes
803
- handle = CreateFile(
804
- self.path,
899
+ handle = CreateFileW(
900
+ multi_to_wide(self.path),
805
901
  FILE_READ_DATA | FILE_WRITE_DATA,
806
902
  FILE_SHARE_READ | FILE_SHARE_WRITE,
807
903
  0,
@@ -840,7 +936,8 @@ class File
840
936
  # true means that the file is not included in an ordinary directory listing.
841
937
  #
842
938
  def hidden=(bool)
843
- attributes = GetFileAttributes(self.path)
939
+ wide_path = multi_to_wide(self.path)
940
+ attributes = GetFileAttributesW(wide_path)
844
941
 
845
942
  if attributes == INVALID_FILE_ATTRIBUTES
846
943
  raise ArgumentError, get_last_error
@@ -852,9 +949,10 @@ class File
852
949
  attributes &= ~FILE_ATTRIBUTE_HIDDEN;
853
950
  end
854
951
 
855
- if SetFileAttributes(self.path, attributes) == 0
952
+ if SetFileAttributesW(wide_path, attributes) == 0
856
953
  raise ArgumentError, get_last_error
857
954
  end
955
+
858
956
  self
859
957
  end
860
958
 
@@ -863,7 +961,8 @@ class File
863
961
  # service.
864
962
  #
865
963
  def indexed=(bool)
866
- attributes = GetFileAttributes(self.path)
964
+ wide_path = multi_to_wide(self.path)
965
+ attributes = GetFileAttributesW(wide_path)
867
966
 
868
967
  if attributes == INVALID_FILE_ATTRIBUTES
869
968
  raise ArgumentError, get_last_error
@@ -875,7 +974,7 @@ class File
875
974
  attributes |= FILE_ATTRIBUTE_NOT_CONTENT_INDEXED;
876
975
  end
877
976
 
878
- if SetFileAttributes(self.path, attributes) == 0
977
+ if SetFileAttributes(wide_path, attributes) == 0
879
978
  raise ArgumentError, get_last_error
880
979
  end
881
980
 
@@ -884,7 +983,7 @@ class File
884
983
 
885
984
  alias :content_indexed= :indexed=
886
985
 
887
- # Sets the normal attribute. Note that only 'true' is a valid argument,
986
+ # Sets the normal attribute. Note that only 'true' is a valid argument,
888
987
  # which has the effect of removing most other attributes. Attempting to
889
988
  # pass any value except true will raise an ArgumentError.
890
989
  #
@@ -893,7 +992,7 @@ class File
893
992
  raise ArgumentError, "only 'true' may be passed as an argument"
894
993
  end
895
994
 
896
- if SetFileAttributes(self.path, FILE_ATTRIBUTE_NORMAL) == 0
995
+ if SetFileAttributesW(multi_to_wide(self.path),FILE_ATTRIBUTE_NORMAL) == 0
897
996
  raise ArgumentError, get_last_error
898
997
  end
899
998
 
@@ -909,7 +1008,8 @@ class File
909
1008
  # Applications should not arbitrarily change this attribute.
910
1009
  #
911
1010
  def offline=(bool)
912
- attributes = GetFileAttributes(self.path)
1011
+ wide_path = multi_to_wide(self.path)
1012
+ attributes = GetFileAttributesW(wide_path)
913
1013
 
914
1014
  if attributes == INVALID_FILE_ATTRIBUTES
915
1015
  raise ArgumentError, get_last_error
@@ -921,7 +1021,7 @@ class File
921
1021
  attributes &= ~FILE_ATTRIBUTE_OFFLINE;
922
1022
  end
923
1023
 
924
- if SetFileAttributes(self.path, attributes) == 0
1024
+ if SetFileAttributesW(wide_path, attributes) == 0
925
1025
  raise ArgumentError, get_last_error
926
1026
  end
927
1027
 
@@ -933,7 +1033,8 @@ class File
933
1033
  # it. In the case of a directory, applications cannot delete it.
934
1034
  #
935
1035
  def readonly=(bool)
936
- attributes = GetFileAttributes(self.path)
1036
+ wide_path = multi_to_wide(self.path)
1037
+ attributes = GetFileAttributesW(wide_path)
937
1038
 
938
1039
  if attributes == INVALID_FILE_ATTRIBUTES
939
1040
  raise ArgumentError, get_last_error
@@ -945,7 +1046,7 @@ class File
945
1046
  attributes &= ~FILE_ATTRIBUTE_READONLY;
946
1047
  end
947
1048
 
948
- if SetFileAttributes(self.path, attributes) == 0
1049
+ if SetFileAttributesW(wide_path, attributes) == 0
949
1050
  raise ArgumentError, get_last_error
950
1051
  end
951
1052
 
@@ -963,8 +1064,8 @@ class File
963
1064
 
964
1065
  bytes = [0].pack('L')
965
1066
 
966
- handle = CreateFile(
967
- self.path,
1067
+ handle = CreateFileW(
1068
+ multi_to_wide(self.path),
968
1069
  FILE_READ_DATA | FILE_WRITE_DATA,
969
1070
  FILE_SHARE_READ | FILE_SHARE_WRITE,
970
1071
  0,
@@ -1003,7 +1104,8 @@ class File
1003
1104
  # that is part of the operating system or is used exclusively by it.
1004
1105
  #
1005
1106
  def system=(bool)
1006
- attributes = GetFileAttributes(self.path)
1107
+ wide_path = multi_to_wide(self.path)
1108
+ attributes = GetFileAttributesW(wide_path)
1007
1109
 
1008
1110
  if attributes == INVALID_FILE_ATTRIBUTES
1009
1111
  raise ArgumentError, get_last_error
@@ -1015,7 +1117,7 @@ class File
1015
1117
  attributes &= ~FILE_ATTRIBUTE_SYSTEM;
1016
1118
  end
1017
1119
 
1018
- if SetFileAttributes(self.path, attributes) == 0
1120
+ if SetFileAttributesW(wide_path, attributes) == 0
1019
1121
  raise ArgumentError, get_last_error
1020
1122
  end
1021
1123
 
@@ -1031,7 +1133,8 @@ class File
1031
1133
  # after the handle is closed.
1032
1134
  #
1033
1135
  def temporary=(bool)
1034
- attributes = GetFileAttributes(self.path)
1136
+ wide_path = multi_to_wide(self.path)
1137
+ attributes = GetFileAttributesW(wide_path)
1035
1138
 
1036
1139
  if attributes == INVALID_FILE_ATTRIBUTES
1037
1140
  raise ArgumentError, get_last_error
@@ -1043,7 +1146,7 @@ class File
1043
1146
  attributes &= ~FILE_ATTRIBUTE_TEMPORARY;
1044
1147
  end
1045
1148
 
1046
- if SetFileAttributes(self.path, attributes) == 0
1149
+ if SetFileAttributesW(wide_path, attributes) == 0
1047
1150
  raise ArgumentError, get_last_error
1048
1151
  end
1049
1152
 
@@ -26,7 +26,7 @@ class TC_Win32_File_Attributes < Test::Unit::TestCase
26
26
  end
27
27
 
28
28
  def test_version
29
- assert_equal('0.5.6', File::VERSION)
29
+ assert_equal('0.6.0', File::WIN32_FILE_VERSION)
30
30
  end
31
31
 
32
32
  def test_temporary
@@ -268,7 +268,7 @@ class TC_Win32_File_Attributes < Test::Unit::TestCase
268
268
  end
269
269
 
270
270
  def teardown
271
- SetFileAttributes(@@file, @attr)
271
+ SetFileAttributesA(@@file, @attr)
272
272
  @fh.close
273
273
  end
274
274
 
@@ -12,7 +12,7 @@ require 'win32/file'
12
12
 
13
13
  class TC_Win32_File_Path < Test::Unit::TestCase
14
14
  def self.startup
15
- Dir.chdir('test') unless File.basename(Dir.pwd) == 'test'
15
+ Dir.chdir('test') rescue nil #unless File.basename(Dir.pwd) == 'test'
16
16
  @@file = File.join(Dir.pwd, 'path_test.txt')
17
17
  File.open(@@file, 'w'){ |fh| fh.puts "This is a path test." }
18
18
  end
@@ -52,16 +52,16 @@ class TC_Win32_File_Path < Test::Unit::TestCase
52
52
  assert_equal("bar", File.basename("/bar"))
53
53
  assert_equal("bar", File.basename("/bar/"))
54
54
  assert_equal("baz", File.basename("//foo/bar/baz"))
55
- assert_equal("//foo", File.basename("//foo"))
56
- assert_equal("//foo/bar", File.basename("//foo/bar"))
55
+ assert_equal("\\\\foo", File.basename("//foo"))
56
+ assert_equal("\\\\foo\\bar", File.basename("//foo/bar"))
57
57
  end
58
58
 
59
59
  def test_basename_with_forward_slashes
60
60
  assert_equal("bar", File.basename("C:/foo/bar"))
61
61
  assert_equal("bar", File.basename("C:/foo/bar/"))
62
62
  assert_equal("foo", File.basename("C:/foo"))
63
- assert_equal("C:/", File.basename("C:/"))
64
- assert_equal("bar", File.basename("C:/foo/bar\\\\"))
63
+ assert_equal("C:\\", File.basename("C:/"))
64
+ assert_equal("bar", File.basename("C:/foo/bar//"))
65
65
  end
66
66
 
67
67
  def test_basename_edge_cases
@@ -109,16 +109,16 @@ class TC_Win32_File_Path < Test::Unit::TestCase
109
109
  end
110
110
 
111
111
  def test_dirname_forward_slashes
112
- assert_equal("C:/foo", File.dirname("C:/foo/bar.txt"))
113
- assert_equal("C:/foo", File.dirname("C:/foo/bar"))
114
- assert_equal("C:/", File.dirname("C:/foo"))
115
- assert_equal("C:/", File.dirname("C:/"))
116
- assert_equal("//foo/bar", File.dirname("//foo/bar/baz"))
117
- assert_equal("//foo/bar", File.dirname("//foo/bar"))
118
- assert_equal("//foo", File.dirname("//foo"))
119
- assert_equal("//", File.dirname("//"))
112
+ assert_equal("C:\\foo", File.dirname("C:/foo/bar.txt"))
113
+ assert_equal("C:\\foo", File.dirname("C:/foo/bar"))
114
+ assert_equal("C:\\", File.dirname("C:/foo"))
115
+ assert_equal("C:\\", File.dirname("C:/"))
116
+ assert_equal("\\\\foo\\bar", File.dirname("//foo/bar/baz"))
117
+ assert_equal("\\\\foo\\bar", File.dirname("//foo/bar"))
118
+ assert_equal("\\\\foo", File.dirname("//foo"))
119
+ assert_equal("\\\\", File.dirname("//"))
120
120
  assert_equal(".", File.dirname("./foo"))
121
- assert_equal("./foo", File.dirname("./foo/bar"))
121
+ assert_equal(".\\foo", File.dirname("./foo/bar"))
122
122
  end
123
123
 
124
124
  def test_dirname_edge_cases
@@ -147,13 +147,13 @@ class TC_Win32_File_Path < Test::Unit::TestCase
147
147
  end
148
148
 
149
149
  def test_split_forward_slashes
150
- assert_equal(["C:/foo", "bar"], File.split("C:/foo/bar"))
150
+ assert_equal(["C:\\foo", "bar"], File.split("C:/foo/bar"))
151
151
  assert_equal([".", "foo"], File.split("foo"))
152
152
  end
153
153
 
154
154
  def test_split_unix_paths
155
- assert_equal(["/foo","bar"], File.split("/foo/bar"))
156
- assert_equal(["/", "foo"], File.split("/foo"))
155
+ assert_equal(["\\foo","bar"], File.split("/foo/bar"))
156
+ assert_equal(["\\", "foo"], File.split("/foo"))
157
157
  assert_equal([".", "foo"], File.split("foo"))
158
158
  end
159
159
 
@@ -55,7 +55,7 @@ class TC_Win32_File_Stat < Test::Unit::TestCase
55
55
  assert_nothing_raised{ File.blockdev?("C:\\") }
56
56
  assert_equal(false, File.blockdev?("NUL"))
57
57
 
58
- omit_unless(File.exists?("D:\\"), "No media in device - skipping")
58
+ omit_unless(File.exists?(@@block_dev), "No media in device - skipping")
59
59
  assert_equal(true, File.blockdev?(@@block_dev))
60
60
  end
61
61
 
data/win32-file.gemspec CHANGED
@@ -2,7 +2,7 @@ require "rubygems"
2
2
 
3
3
  spec = Gem::Specification.new do |gem|
4
4
  gem.name = "win32-file"
5
- gem.version = "0.5.6"
5
+ gem.version = "0.6.0"
6
6
  gem.authors = ["Daniel J. Berger", "Park Heesob"]
7
7
  gem.email = "djberg96@gmail.com"
8
8
  gem.homepage = "http://www.rubyforge.org/projects/win32utils"
@@ -15,12 +15,14 @@ spec = Gem::Specification.new do |gem|
15
15
  gem.files.reject! { |fn| fn.include? "CVS" }
16
16
  gem.require_path = "lib"
17
17
  gem.extra_rdoc_files = ["README", "CHANGES"]
18
- gem.add_dependency("win32-file-stat", ">= 1.2.0")
18
+ gem.add_dependency("win32-api", ">= 1.2.1")
19
+ gem.add_dependency("win32-file-stat", ">= 1.3.2")
19
20
  gem.add_dependency("test-unit", ">= 2.0.0")
21
+ gem.add_dependency("windows-pr", ">= 0.9.6")
20
22
  gem.rubyforge_project = "win32utils"
21
23
  end
22
24
 
23
25
  if $0 == __FILE__
24
- Gem.manage_gems
26
+ Gem.manage_gems if Gem::RubyGemsVersion.to_f < 1.3
25
27
  Gem::Builder.new(spec).build
26
28
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: win32-file
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.6
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel J. Berger
@@ -10,9 +10,19 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2008-09-30 00:00:00 -06:00
13
+ date: 2008-11-14 00:00:00 -07:00
14
14
  default_executable:
15
15
  dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: win32-api
18
+ type: :runtime
19
+ version_requirement:
20
+ version_requirements: !ruby/object:Gem::Requirement
21
+ requirements:
22
+ - - ">="
23
+ - !ruby/object:Gem::Version
24
+ version: 1.2.1
25
+ version:
16
26
  - !ruby/object:Gem::Dependency
17
27
  name: win32-file-stat
18
28
  type: :runtime
@@ -21,7 +31,7 @@ dependencies:
21
31
  requirements:
22
32
  - - ">="
23
33
  - !ruby/object:Gem::Version
24
- version: 1.2.0
34
+ version: 1.3.2
25
35
  version:
26
36
  - !ruby/object:Gem::Dependency
27
37
  name: test-unit
@@ -33,6 +43,16 @@ dependencies:
33
43
  - !ruby/object:Gem::Version
34
44
  version: 2.0.0
35
45
  version:
46
+ - !ruby/object:Gem::Dependency
47
+ name: windows-pr
48
+ type: :runtime
49
+ version_requirement:
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: 0.9.6
55
+ version:
36
56
  description: Extra or redefined methods for the File class on Windows.
37
57
  email: djberg96@gmail.com
38
58
  executables: []
@@ -79,7 +99,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
79
99
  requirements: []
80
100
 
81
101
  rubyforge_project: win32utils
82
- rubygems_version: 1.3.0
102
+ rubygems_version: 1.3.1
83
103
  signing_key:
84
104
  specification_version: 2
85
105
  summary: Extra or redefined methods for the File class on Windows.