Skip to content

Replace or complete bundled File::Path option handling #1131

Description

@fglock

Summary

PerlOnJava's bundled File::Path identifies itself as version 2.18 but implements only a simplified subset of that release. In particular, rmtree($path, { keep_root => 1 }) treats the options hash as the legacy boolean verbose argument, discards keep_root, and removes the root directory.

This causes the otherwise-passing Path-Extended-Tiny 0.08 suite to fail. Replacing the simplified bundled module with the full CPAN File::Path implementation is a viable option and may be preferable to incrementally reproducing its public behavior.

Minimal reproducer

use strict;
use warnings;
use File::Path qw(rmtree mkpath);
use File::Temp qw(tempdir);
my$temporary = tempdir(CLEANUP=> 0);
my$root = "$temporary/root";
my$child = "$root/child";
mkpath($child);
rmtree($root, { keep_root=> 1 });
print"root=", (-d$root ? 1 : 0),
" child=", (-d$child ? 1 : 0), "\n";
rmtree($temporary);

System Perl with File::Path 2.18:

root=1 child=0

Both PerlOnJava backends with the bundled module:

rmdir .../root/child
rmdir .../root
root=0 child=0

The unexpected rmdir output is additional evidence that the hash reference was interpreted as a true verbose flag.

Diagnosis

The bundled implementation in src/main/perl/lib/File/Path.pm delegates rmtree to a legacy wrapper equivalent to:

my$paths = shift;
my$verbose = shift || 0;
my$safe = shift || 0;

Passing { keep_root => 1 } therefore sets $verbose to the hash reference. The wrapper then constructs a new options hash containing only verbose and safe. The recursive removal routine always calls rmdir on the root and has no keep_root handling.

The full File::Path 2.18 implementation distinguishes old-style arguments from a trailing options hash and supports the documented options including:

  • keep_root
  • error
  • result
  • safe
  • verbose

CPAN integration evidence

Archived run: 20260825-173145-22349

Distribution: ISHIGAKI/Path-Extended-Tiny-0.08.tar.gz

Requested module: Path::Extended::Tiny

PerlOnJava result:

Files=22, Tests=79
Result: FAIL
Failed 1/22 test programs. 1/79 subtests failed.

The sole failure is t/30_directory/rmdir.t:

not ok - root dir exists after rmdir with keep_root

Path-Extended-Tiny is pure Perl, and all prerequisites installed successfully.

System Perl baseline

Using the same distribution source and test dependencies:

Files=22, Tests=79
All tests successful.
Result: PASS

Implementation options

Replace the bundled module with full CPAN File::Path

Import a compatible complete CPAN release, preserving its license and version metadata, then run its upstream suite on both PerlOnJava backends. This is likely the safer option because the current copy advertises version 2.18 while omitting more than this single documented option.

Review any platform-sensitive code—especially Windows path handling, permission recovery, symlink handling, current-working-directory protection, and VMS branches—against PerlOnJava's supported filesystem behavior. Keep any existing PerlOnJava-specific fixes as explicit, minimal adaptations rather than retaining a separate simplified implementation.

Complete the simplified implementation

At minimum, implement modern trailing-option-hash dispatch and keep_root. This has a greater risk of leaving other advertised File::Path 2.18 behavior incomplete, so the supported subset and version claim would need careful review.

Acceptance criteria

  • Add a permanent project-owned regression test for rmtree and remove_tree with { keep_root => 1 }, validated first under system Perl.
  • Preserve the root while removing its descendants on both JVM and interpreter backends.
  • Do not enable verbose output merely because an options hash was supplied.
  • Preserve legacy positional rmtree($paths, $verbose, $safe) compatibility.
  • Exercise the documented modern options, including error, result, safe, and verbose.
  • If replacing the module, run the imported File::Path upstream test suite on both backends and document intentional platform exclusions.
  • Rerun Path-Extended-Tiny 0.08 and pass all 22 programs/79 tests.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions