Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@eregon
Copy link
Member

@eregon eregon commented Aug 23, 2025

Includes the fixes from ruby/ruby#14303, although some of them are done slightly differently to match the semantics from pathname.c closer.

See #60 (comment) for the summary of what this PR does.

@eregon eregon requested a review from hsbt August 23, 2025 12:18
@eregon
Copy link
Member Author

eregon commented Aug 23, 2025

I also compared methods before and after #57:

diff methods_old.txt methods_new.txt 
50d49
< lutime
60a60
> path

path is expected new and is protected.
lutime is missing and the test was wrongly testing utime instead, will fix.

@eregon
Copy link
Member Author

eregon commented Aug 23, 2025

Ah and there is another bug in test/pathname/test_pathname.rb, its has_symlink? returns false, at least on Linux.

eregon added 9 commits August 26, 2025 09:37
* Provides extra testing and coverage.
* Found by ruby/spec, and confirmed pathname.c did the same.
* Found by ruby/spec, and confirmed pathname.c did the same.
* This has no test in test_pathname.rb, that is why it was missed.
* Found by ruby/spec, and confirmed pathname.c did the same.
* This reverts commit a9ef32e.
* It is already added in Ruby code.
* There is no point to call IO.sysopen and that's the last IO method,
  with Pathname we know it's always a file path.
@eregon
Copy link
Member Author

eregon commented Aug 26, 2025

I rebased this on top of #61, there were many conflicts.
I copied the original PR to #62 for clarity as some commits became less clear due to the rebase.
Anyway I made sure the end result is similar, so the diff between this and #62 is:

diff --git a/lib/pathname.rb b/lib/pathname.rb
index 1c4ec6e..a0db812 100644
--- a/lib/pathname.rb
+++ b/lib/pathname.rb
@@ -210,6 +210,7 @@ require 'pathname.so' if RUBY_ENGINE == 'ruby'
 #
 class Pathname
 
+  # The version string.
   VERSION = "0.4.0"
 
   # :stopdoc:
@@ -338,14 +339,42 @@ class Pathname
   end
 
   if File.dirname('A:') == 'A:.' # DOSish drive letter
-    ABSOLUTE_PATH = /\A(?:[A-Za-z]:|#{SEPARATOR_PAT})/o
+    ABSOLUTE_PATH = /\A(?:[A-Za-z]:|#{SEPARATOR_PAT})/
   else
-    ABSOLUTE_PATH = /\A#{SEPARATOR_PAT}/o
+    ABSOLUTE_PATH = /\A#{SEPARATOR_PAT}/
   end
   private_constant :ABSOLUTE_PATH
 
   # :startdoc:
 
+  # Creates a full path, including any intermediate directories that don't yet
+  # exist.
+  #
+  # See FileUtils.mkpath and FileUtils.mkdir_p
+  def mkpath(mode: nil)
+    path = @path == '/' ? @path : @path.chomp('/')
+
+    stack = []
+    until File.directory?(path) || File.dirname(path) == path
+      stack.push path
+      path = File.dirname(path)
+    end
+
+    stack.reverse_each do |dir|
+      dir = dir == '/' ? dir : dir.chomp('/')
+      if mode
+        Dir.mkdir dir, mode
+        File.chmod mode, dir
+      else
+        Dir.mkdir dir
+      end
+    rescue SystemCallError
+      raise unless File.directory?(dir)
+    end
+
+    self
+  end
+
   # chop_basename(path) -> [pre-basename, basename] or nil
   def chop_basename(path) # :nodoc:
     base = File.basename(path)
@@ -1167,16 +1196,6 @@ end
 
 
 class Pathname    # * FileUtils *
-  # Creates a full path, including any intermediate directories that don't yet
-  # exist.
-  #
-  # See FileUtils.mkpath and FileUtils.mkdir_p
-  def mkpath(mode: nil)
-    require 'fileutils'
-    FileUtils.mkpath(@path, mode: mode)
-    self
-  end
-
   # Recursively deletes a directory, including all directories beneath it.
   #
   # See FileUtils.rm_rf

Which is expected changes upstreamed from ruby/ruby.

@byroot
Copy link
Member

byroot commented Aug 26, 2025

👍

@eregon
Copy link
Member Author

eregon commented Aug 26, 2025

I'll merge this, it fixes 3 major issues with testing in ruby/pathname:

  • ruby/spec pathname specs were not run, but revealed issues in ruby/ruby in Migrate pathname.c to pathname_builtin.rb ruby#14303, now they are run here too.
  • has_symlink? was always false which meant 8 tests did not run at all (!)
  • the lutime test was skipped due to that has_symlink? bug, and was testing utime instead of lutime

@eregon eregon merged commit b0bb1ec into ruby:master Aug 26, 2025
21 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants