kenahoo / Path-Class

Cross-platform path specification manipulation
http://search.cpan.org/dist/Path-Class/
15 stars 28 forks source link

Build tests fail under perl 5.36 on Windows 10 #55

Open blues1875 opened 2 years ago

blues1875 commented 2 years ago

The module fails on build tests under perl 5.36 on Windows 10. The test

ok dir()->absolute->resolve, dir(Cwd::cwd())->resolve;

from file 01-basic.t fails with the error

Can't call method "relative" on an undefined value at ...blib\lib/Path/Class/Entity.pm line 71.
blues1875 commented 2 years ago

As suggested over on a Strawberry Perl issues forum, I removed the $^O override in 01-basic.t and tested again. This time, there is no fatal error, but the test fails 30 of the 78 subtests with lots of complaints about backslashes like this:

# Test 6 got: "dir\\bar.txt" (t/01-basic.t at line 20)
#   Expected: "dir/bar.txt"
sisyphus commented 2 years ago

The test fails because $^O is set to 'Unix'. This used to work ok on Windows up to and including perl-5.32.1 but since then, it fails in the way already indicated.

If I comment out the offending BEGIN{} block at the very start of t/01-basic.t and hard code the assignment of 'Unix' to $module in File/Spec.pm then all files pass. So it's not the assigning of 'Unix' path formatting that's the problem. The problem is that $^O has been overwritten.

I doubt that File::Spec intended for $^O to be bludgeoned just so 'Unix' path formatting could be obtained on Windows. If File::Spec wants to allow for the option to have 'Unix' path formatting on Windows, then they should have allowed for this to be achieved in a way that doesn't invalidate $^O.

So I think the thing to do is to have t/01-basic.t written so that it can run its tests without overwriting $^O. That could involve having File::Spec amended to provide alteration of the path formatting in a sane way - ie a way that leaves $^O as it is .

There's some discussion of other weirdnesses related to the overriding of $^O at https://www.perlmonks.org/?node_id=11145885 .

Cheers, Rob

kenahoo commented 2 years ago

Yeah, File::Spec provides no official way to work with paths using the semantics of a specified (as opposed to the native) OS. That was one of the motivations for creating Path::Class in the first place - for example, "I'm on a Windows machine and I'm calling processes on a Unix machine that require specifying paths", or the opposite, or whatever.

If File::Spec could provide such a capability, it would be welcome and provide an easy fix here. A very simple version of it would be to simply have File::Spec use some intermediate package-local variable that's initialized to $^O but allowed to be assigned to other values.

A short-term fix that's basically equivalent to the current testing situation would be to have t/01-basic.t just explicitly use Unix mode (Path::Class::File->new_foreign('Unix', ...) etc.) for all its tests. I'd like to understand better what change in perl or File::Spec led to the failure surfacing now, though.

Leont commented 2 years ago

Can't call method "relative" on an undefined value at ...blib\lib/Path/Class/Entity.pm line 71.

That suggests that $self->new(...) can return undef, which feels wrong. Apparently that happens if the argument to a Path::Class::Dir is undefined. I guess that means that Cwd::realpath chokes on whatever $self->stringify returns.

Leont commented 2 years ago

Yeah, File::Spec provides no official way to work with paths using the semantics of a specified (as opposed to the native) OS. That

You can just use File::Spec::Unix instead?

sisyphus commented 2 years ago

You can just use File::Spec::Unix instead?

That would seem to be possible:

C:\>perl -MFile::Spec -e "print File::Spec->catfile('a', 'b', 'c');"
a\b\c

C:\>perl -MFile::Spec::Unix -e "print File::Spec::Unix->catfile('a', 'b', 'c');"
a/b/c