win32-file 0.5.6 → 0.6.0

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