Overlo...leCheck(3pm)

πŸ“¦
version 0.015 Β· 5 versions
, in ubuntu stonking

πŸ‘‘ Overload::FileCheck β€” the manual page, but make it cute

So bestie, quick lil orientation: this is the Overlo...leCheck(3pm) page from the User Contributed Perl Documentation. Yeah the name is literally truncated like that in the header, we don't make the rules πŸ’€. Anyway, let's get into it.


✨ NAME ✨

Overload::FileCheck β€” override/mock perl file check -X: -e, -f, -d, ...

🌸 VERSION 🌸

version 0.015

πŸ¦‹ SYNOPSIS πŸ¦‹

Okay so Overload::FileCheck gives you a way to mock one or more file checks. You can also mock the stat/lstat functions using mock_all_from_stat and let Overload::FileCheck do the mocking for you for any other -X checks.

And by using mock_all_file_checks you can set a hook function that replies to any -X check. Main character energy, honestly.

#!perl

use strict;
use warnings;

use Test::More;
use Overload::FileCheck q{:all};

my @exist     = qw{cherry banana apple};
my @not_there = qw{not-there missing-file};

mock_all_file_checks( \&my_custom_check );

sub my_custom_check {
    my ( $check, $f ) = @_;

    if ( $check eq 'e' || $check eq 'f' ) {
        return CHECK_IS_TRUE  if grep { $_ eq $f } @exist;
        return CHECK_IS_FALSE if grep { $_ eq $f } @not_there;
    }

    return CHECK_IS_FALSE if $check eq 'd' && grep { $_ eq $f } @exist;

    # fallback to the original Perl OP
    return FALLBACK_TO_REAL_OP;
}

foreach my $f (@exist) {
    ok( -e $f,  "-e $f is true" );
    ok( -f $f,  "-f $f is true" );
    ok( !-d $f, "-d $f is false" );
}

foreach my $f (@not_there) {
    ok( !-e $f, "-e $f is false" );
    ok( !-f $f, "-f $f is false" );
}

unmock_all_file_checks();

done_testing;

πŸ’– DESCRIPTION πŸ’–

Overload::FileCheck gives you a whole hook system to mock Perl filecheck OPs. πŸŽ€

With this module you can hand over your own pure perl code whenever a file check happens using one of the -X ops: -e, -f, -z, ...

<https://perldoc.perl.org/functions/-X.html>

Here's the full lore on what each -X means, straight up:

-r  File is readable by effective uid/gid.
-w  File is writable by effective uid/gid.
-x  File is executable by effective uid/gid.
-o  File is owned by effective uid.
-R  File is readable by real uid/gid.
-W  File is writable by real uid/gid.
-X  File is executable by real uid/gid.
-O  File is owned by real uid.
-e  File exists.
-z  File has zero size (is empty).
-s  File has nonzero size (returns size in bytes).
-f  File is a plain file.
-d  File is a directory.
-l  File is a symbolic link (false if symlinks aren't
    supported by the file system).
-p  File is a named pipe (FIFO), or Filehandle is a pipe.
-S  File is a socket.
-b  File is a block special file.
-c  File is a character special file.
-t  Filehandle is opened to a tty.
-u  File has setuid bit set.
-g  File has setgid bit set.
-k  File has sticky bit set.
-T  File is an ASCII or UTF-8 text file (heuristic guess).
-B  File is a "binary" file (opposite of -T).
-M  Script start time minus file modification time, in days.
-A  Same for access time.
-C  Same for inode change time (Unix, may differ for other
platforms)

Also go peek at pp_sys.c in the Perl source code, that's where the original OPs are defined. 🫢

Plus β€” and this is the slay part β€” you can also mock the Perl OP stat and lstat. Go read the "Mocking stat and lstat" section for the deets.

🌈 Usage and Examples 🌈

When you're using this module, you get to choose: mock those filecheck OPs at import time, or later at run time. Your call, babe.

πŸ’… Mocking filecheck at import time

You can mock multiple filechecks at import time. Just so you know: ':check' will import constants like CHECK_IS_TRUE, CHECK_IS_FALSE, FALLBACK_TO_REAL_OP β€” and those are the recommended return values to use inside your hook functions. iykyk.

#!perl

use strict;
use warnings;

use Overload::FileCheck '-e' => \&my_dash_e, -f => sub { 1 }, ':check';

# example of your own callback function to mock -e
# when returning
#  0: the test is false
#  1: the test is true
# -1: you want to use the answer from Perl itself :-)

sub dash_e {
    my ($file_or_handle) = @_;

    # return true on -e for this specific file
    return CHECK_IS_TRUE if $file_or_handle eq '/this/file/is/not/there/but/act/like/if/it/was';

    # claim that /tmp is not available even if it exists
    return CHECK_IS_FALSE if $file_or_handle eq '/tmp';

    # delegate the answer to the Perl CORE -e OP
    #   as we do not want to control these files
    return FALLBACK_TO_REAL_OP;
}

πŸŽ€ Mocking filecheck at run time

You can also get a basically identical vibe by declaring the overload later, at run time. No rush, it's fine. ⭐

#!perl

use strict;
use warnings;

use Overload::FileCheck q(:all);

mock_file_check( '-e' => \&my_dash_e );
mock_file_check( '-f' => sub { CHECK_IS_TRUE } );

sub dash_e {
    my ($file_or_fh) = @_;

    # return true on -e for this specific file
    return CHECK_IS_TRUE if $file_or_fh eq '/this/file/is/not/there/but/act/like/if/it/was';

    # claim that /tmp is not available even if it exists
    return CHECK_IS_FALSE if $file_or_fh eq '/tmp';

    # delegate the answer to the Perl CORE -e OP
    #   as we do not want to control these files
    return FALLBACK_TO_REAL_OP;
}

πŸ“ Check helpers to use in your callback function

Inside your callback function you should use the following helpers when you return. Pick your fighter:

  • CHECK_IS_FALSE: use this constant when the test is false
  • CHECK_IS_TRUE: use this one when the test is true
  • FALLBACK_TO_REAL_OP: you wanna delegate the answer to Perl itself :-)

And lowkey you can also just return a single integer. Checks like -s, -M, -C, -A can return any integers. ✨

Example:

use Overload::FileCheck q(:all);

mock_file_check( '-s' => \&my_dash_s );

sub my_dash_s {
    my ( $file_or_handle ) = @_;

    if ( $file_or_handle eq '/a/b/c' ) {
        return 42;
    }

    return FALLBACK_TO_REAL_OP;
}

πŸ”₯ Tracing all file checks usage

You can trace every single file check in your codebase without altering it. Obsessed.

#!perl

use strict;
use warnings;

use Carp;
use Overload::FileCheck q{:all};

mock_all_file_checks( \&my_custom_check );

sub my_custom_check {
    my ( $check, $f ) = @_;

    local $Carp::CarpLevel = 2;    # do not display Overload::FileCheck stack
    printf( "# %-10s called from %s", "-$check '$f'", Carp::longmess() );

    # fallback to the original Perl OP
    return FALLBACK_TO_REAL_OP;
}

-d '/root';
-l '/root';
-e '/';
-d '/';

unmock_all_file_checks();

__END__

# The output looks similar to

-d '/root' called from  at t/perldoc_mock-all-file-check-trace.t line 26.
-l '/root' called from  at t/perldoc_mock-all-file-check-trace.t line 27.
-e '/'     called from  at t/perldoc_mock-all-file-check-trace.t line 28.
-d '/'     called from  at t/perldoc_mock-all-file-check-trace.t line 29.

πŸ‘‘ Mock one or more file checks: -e, -f

You can mock a single file check type like '-e', '-f', ... one at a time, no biggie.

#!perl

use strict;
use warnings;

use Overload::FileCheck qw{mock_file_check unmock_file_check unmock_all_file_checks :check};
use Errno ();

# all -f checks will be true from now
mock_file_check( '-f' => sub { 1 } );

# mock all calls to -e and delegate to the function dash_e
mock_file_check( '-e' => \&dash_e );

# example of your own callback function to mock -e
# when returning
#  0: the test is false
#  1: the test is true
# -1: you want to use the answer from Perl itself :-)

sub dash_e {
    my ($file_or_fh) = @_;

    # return true on -e for this specific file
    return CHECK_IS_TRUE
      if $file_or_fh eq '/this/file/is/not/there/but/act/like/if/it/was';

    # claim that /tmp is not available even if it exists
    if ( $file_or_fh eq '/tmp' ) {

        # you can set Errno to any custom value
        #   or it would be set to Errno::ENOENT() by default
        $! = Errno::ENOENT();    # set errno to "No such file or directory"
        return CHECK_IS_FALSE;
    }

    # delegate the answer to the Perl CORE -e OP
    #   as we do not want to control these files
    return FALLBACK_TO_REAL_OP;
}

# unmock -e and -f
unmock_file_check('-e');
unmock_file_check('-f');
unmock_file_check(qw{-e -f});

# or unmock all existing filecheck
unmock_all_file_checks();

🧚 Mock check calls at import time

You can also mock the check functions at import time by handing over a check test plus a custom function. So extra of you, we love it. πŸ’œ

#!perl

use strict;
use warnings;

use Test::More;
use Overload::FileCheck '-e' => \&my_dash_e, q{:check};

# Mock one or more check
#use Overload::FileCheck '-e' => \&my_dash_e, '-f' => sub { 1 }, 'x' => sub { 0 }, ':check';

my @exist     = qw{cherry banana apple};
my @not_there = qw{chocolate and peanuts};

sub my_dash_e {
    my $f = shift;

    note "mocked -e called for", $f;

    return CHECK_IS_TRUE  if grep { $_ eq $f } @exist;
    return CHECK_IS_FALSE if grep { $_ eq $f } @not_there;

    # we have no idea about these files
    return FALLBACK_TO_REAL_OP;
}

foreach my $f (@exist) {
    ok( -e $f, "file '$f' exists" );
}

foreach my $f (@not_there) {
    ok( !-e $f, "file '$f' exists" );
}

# this is using the fallback logic '-1'
ok -e $0,  q[$0 is there];
ok -e $^X, q[$^X is there];

done_testing;

Bestie this was only part 1 of 3 β€” do not close the tab, more is coming πŸ’–

πŸ¦‹ Mocking stat and lstat πŸ’…

✨ How to mock stat? ✨

okay bestie so here's a lil sample of how you can mock stat and lstat, fr fr. It's an extract from the testsuite, and the Test2::* modules are just there to show you the vibe β€” you do not need to use them in your own code, no cap.

For the more extra samples, go browse the source code and peek at the test files in the t or examples directories. πŸ•΅οΈβ€β™€οΈ

#!perl

use strict;
use warnings;

use Test2::Bundle::Extended;
use Test2::Tools::Explain;
use Test2::Plugin::NoWarnings;

use Overload::FileCheck q(:all);

# our helper would be called for every stat & lstat calls
mock_stat( \&my_stat );

sub my_stat {
    my ( $opname, $file_or_handle ) = @_;

    # $opname can be 'stat' or 'lstat'
    # in this sample only mock stat, leave lstat alone
    return FALLBACK_TO_REAL_OP() if $opname eq 'lstat';

    my $f = $file_or_handle;    # alias for readability

    # return an array ref with 13 elements containing the stat output
    return [ 1 .. 13 ] if $f eq $0;

    my $fake_stat = [ (0) x 13 ];

    # you also have access to some constants
    # to set the stat values in the correct slot
    # this is using some fake values, without any specific meaning...
    $fake_stat->[ST_DEV]     = 1;
    $fake_stat->[ST_INO]     = 2;
    $fake_stat->[ST_MODE]    = 4;
    $fake_stat->[ST_NLINK]   = 8;
    $fake_stat->[ST_UID]     = 16;
    $fake_stat->[ST_GID]     = 32;
    $fake_stat->[ST_RDEV]    = 64;
    $fake_stat->[ST_SIZE]    = 128;
    $fake_stat->[ST_ATIME]   = 256;
    $fake_stat->[ST_MTIME]   = 512;
    $fake_stat->[ST_CTIME]   = 1024;
    $fake_stat->[ST_BLKSIZE] = 2048;
    $fake_stat->[ST_BLOCKS]  = 4096;

    return $fake_stat if $f eq 'fake.stat';

    # can also return stats as a hash ref
    return { st_dev => 1, st_atime => 987654321 } if $f eq 'hash.stat';

    return {
        st_dev     => 1,
        st_ino     => 2,
        st_mode    => 3,
        st_nlink   => 4,
        st_uid     => 5,
        st_gid     => 6,
        st_rdev    => 7,
        st_size    => 8,
        st_atime   => 9,
        st_mtime   => 10,
        st_ctime   => 11,
        st_blksize => 12,
        st_blocks  => 13,
    } if $f eq 'hash.stat.full';

    # return an empty array if you want to mark the file as not available
    return [] if $f eq 'file.is.not.there';

    # fallback to the regular OP
    return FALLBACK_TO_REAL_OP();
}

is [ stat($0) ], [ 1 .. 13 ], 'stat is mocked for $0';
is [ stat(_) ], [ 1 .. 13 ],
  '_ also works: your mocked function is not called';

is [ stat('fake.stat') ],
  [ 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096 ], 'fake.stat';

is [ stat('hash.stat.full') ], [ 1 .. 13 ], 'hash.stat.full';

unmock_stat();

done_testing;

🌸 Convenient constants available when mocking stat 🌸

When you're mocking the stat or lstat function, your callback function should return one of these, bestie:

  • either one ARRAY Ref containing 13 entries, exactly like stat describes them (same order, don't shuffle them πŸ’€)
  • or an empty ARRAY Ref, if the file does not exist
  • or one HASH ref using one or more of these keys: st_dev, st_ino, st_mode, st_nlink, st_uid, st_gid, st_rdev, st_size, st_atime, st_mtime, st_ctime, st_blksize, st_blocks
  • or return FALLBACK_TO_REAL_OP when you want to let Perl take back the control for that file 🫢

And to manipulate that ARRAY ref and insert/update one specific entry, there are some constants available to grab the correct index by 'name':

  • ST_DEV
  • ST_INO
  • ST_MODE
  • ST_NLINK
  • ST_UID
  • ST_GID
  • ST_RDEV
  • ST_SIZE
  • ST_ATIME
  • ST_MTIME
  • ST_CTIME
  • ST_BLKSIZE
  • ST_BLOCKS

πŸ‘‘ Mocking all file checks from a single stat function πŸ‘‘

A recommended option (highkey the move) is to only mock the stat and lstat functions and let Overload::FileCheck mock all the file checks for you: -e, -f, -s, -z, ...

By doing so, using _ or *_ (a.k.a. PL_defgv) in your filecheck would work without any extra effort. ✨

-d "/my/file" && -s _

Netherway, some limitations exist, ngl. The checks -B and -T are using some heuristics to figure out if the file is binary or text. That would need more than just a simple stat output. So in these cases you can mock -B and -T with your own functions:

mock_file_check( '-B' => sub { ... } );
mock_file_check( '-T' => sub { ... } );

πŸ’œ mock_all_from_stat

By using the mock_all_from_stat function, you'll only provide a 'fake' stat / lstat function and let Overload::FileCheck provide the hooks for all the common checks. Iconic behaviour honestly. πŸŽ€

#!perl

use strict;
use warnings;

# setup at import time
use Overload::FileCheck '-from-stat' => \&mock_stat_from_sys, qw{:check :stat};

# or set it later at run time
# mock_all_from_stat( \&my_stat );

sub mock_stat_from_sys {

    my ( $stat_or_lstat, $f ) = @_;

    # $stat_or_lstat would be set to 'stat' or 'lstat' depending
    #   if it's a 'stat' or 'lstat' call

    if ( defined $f && $f eq 'mocked.file' ) {    # "<<$f is mocked>>"
        return [                                  # return a fake stat output (regular file)
            64769,      69887159,   33188, 1, 0, 0, 0, 13,
            1539928982, 1539716940, 1539716940,
            4096,       8
        ];

        return stat_as_file();

        return [];                                # if the file is missing
    }

    # let Perl answer the stat question for us
    return FALLBACK_TO_REAL_OP;
}

# ...

# later in your code
if ( -e 'mocked.file' && -f _ && !-d _ ) {
    print "# This file looks real...\n";
}

# ...

# you can unmock the OPs at anytime
Overload::FileCheck::unmock_all_file_checks();

πŸ¦‹ Using stat_as_* helpers πŸ¦‹

When you're mocking the stat functions, you might want to consider using one of the stat_as_* helpers. The available functions are:

  • stat_as_directory
  • stat_as_file
  • stat_as_symlink
  • stat_as_socket
  • stat_as_chr
  • stat_as_block
  • stat_as_fifo

All of these functions take some optional arguments to set: uid, gid, perms, dev, ino, nlink, rdev, size, atime, mtime, ctime, blksize, blocks. Slay. πŸ’…

Example:

use Overload::FileCheck -from-stat => \&my_stat, q{:check};

sub my_stat {
    my ( $stat_or_lstat, $f_or_fh ) = @_;

    return stat_as_file() if $f_or_fh eq 'fake.file';

    return stat_as_directory( uid => 0, gid => 'root' ) if $f_or_fh eq 'fake.dir';

    return stat_as_file( mtime => time() ) if $f_or_fh eq 'touch.file';

    return stat_as_file( perms => 0755 ) if $f_or_fh eq 'touch.file.0755';

    return FALLBACK_TO_REAL_OP;
}

πŸ’– Available functions πŸ’–

okay bestie this is the part where we meet every single function Overload::FileCheck hands you. buckle up πŸŽ€


✨ mock_file_check( $check, CODE ) ✨

mock_file_check is the one that lets you mock one of the filecheck ops. like, one. singular. iconic behavior πŸ’…

the first argument is one of the file checks: '-f', '-e', ... and the dash is optional β€” it also happily takes 'e', 'f', ... 🌸

⚠️ if you try to mock a filecheck that's already mocked, this thing will die with an error looking like
-f is already mocked by Overload::FileCheck

and honestly?? that's a feature, not a bug. it guarantees you're not mocking the same filecheck twice in your codebase and creating the most cursed little shadow-mock situation 🫢

otherwise it returns 1 on success.

# this is probably a very bad idea to do this in your codebase
# but can be useful for some testing
# in that sample all '-e' checks will always return true...
mock_file_check( '-e' => sub { 1 } )

not me showing you a bad idea in a code sample but here we are 😭


✨ mock_file_check_guard( $check, CODE ) ✨

like mock_file_check, but instead of returning 1 it hands you back a guard object 🧚. the moment that guard goes out of scope (or gets destroyed some other way), the mock is automatically removed via unmock_file_check.

it's giving ✨test isolation✨ because cleanup is guaranteed even if your test straight-up dies πŸ’€

{
    my $guard = mock_file_check_guard( '-e' => sub { CHECK_IS_TRUE } );
    ok( -e "/fake/file", "mocked" );
}
# -e is automatically unmocked here

and if you wanna stop the auto-unmock from ever happening, just call $guard->cancel πŸ‘‘


✨ unmock_file_check( $check, [@extra_checks] ) ✨

disables the effect of one or more specific mocks. you can pass a list or a single scalar value, and yeah the leading dash is optional, she's flexible like that πŸ’œ

unmock_file_check( '-e' );
unmock_file_check( 'e' );            # also work without the dash
unmock_file_check( qw{-e -f -z} );
unmock_file_check( qw{e f} );        # also work without the dashes

✨ unmock_all_file_checks() ✨

one lil call to unmock_all_file_checks and you've disabled the effect of overriding the filecheck OPs. bestie note this well: the XS code is still plugged in, but it falls back to the original OP as soon as possible πŸ‘‘


✨ mock_stat( CODE ) ✨

mock_stat gives you one interface to set up a hook for all "stat" and "lstat" calls. it's slightly different from the other mock functions tho, because the first argument passed to your hook function is a string β€” 'stat' or 'lstat' πŸ¦‹

you can grab a more advanced hook sample from "Mocking stat".

use Overload::FileCheck q(:all);

# our helper would be called for every stat & lstat calls
mock_stat( \&my_stat );

sub my_stat {
    my ( $opname, $file_or_handle ) = @_;

    ...

    return FALLBACK_TO_REAL_OP;
}

✨ unmock_stat() ✨

call unmock_stat and boom, any previous hook set using mock_stat is disabled πŸ’…


✨ mock_all_from_stat( CODE ) ✨

give it a single hook for 'stat' and 'lstat', and OverLoad::FileCheck will take care of mocking all the other -X checks for you. so generous of her fr fr 🫢

read " Mocking all file checks from a single 'stat' function" for sample usage.


✨ stat_as_directory( %OPTS ) ✨

creates a stat array ref for a directory πŸ“. %OPTS is optional and can set one or more using arguments among:

  • uid
  • gid
  • perms
  • dev
  • ino
  • nlink
  • rdev
  • size
  • atime
  • mtime
  • ctime
  • blksize
  • blocks

read the section "Using stat_as_* helpers" for some sample usages ✨


✨ stat_as_file( %OPTS ) ✨

creates a stat array ref for a regular file πŸ“ view stat_as_directory and "Using stat_as_* helpers" for some sample usages


creates a stat array ref for a symlink πŸ”— view stat_as_directory and "Using stat_as_* helpers" for some sample usages


✨ stat_as_socket( %OPTS ) ✨

creates a stat array ref for a socket 🧦 view stat_as_directory and "Using stat_as_* helpers" for some sample usages


✨ stat_as_chr( %OPTS ) ✨

creates a stat array ref for an empty character device view stat_as_directory and "Using stat_as_* helpers" for some sample usages


✨ stat_as_block( %OPTS ) ✨

creates a stat array ref for an empty block device view stat_as_directory and "Using stat_as_* helpers" for some sample usages


✨ stat_as_fifo( %OPTS ) ✨

creates a stat array ref for a named pipe (FIFO) πŸŽ€ view stat_as_directory and "Using stat_as_* helpers" for some sample usages


🌈 Notice 🌈

this is a very early development stage and some behavior might change before the release of a more stable build. so like… don't come for her if things shift, she's growing 🌱


πŸ’€ Known Limitations πŸ’€

πŸŽ€ This is design for Unit Test purpose πŸŽ€

this code was mainly designed to be used during unit tests. it's far from being optimized at this time. no cap 😭

πŸŽ€ Mock as soon as possible πŸŽ€

code loaded or interpreted before you mock a file check would not take benefit of Overload::FileCheck. so you probably want to load and call the mock function of Overload::FileCheck as early as possible ⏰

πŸŽ€ -B and -T are using heuristics πŸŽ€

file check operators like -B and -T use heuristics to guess whether the file content is binary or text. and by using mock_all_from_stat or ('-from-stat' at import time), we cannot provide an accurate -B or -T check. you'd need to provide custom hooks for them, bestie 🫢


πŸ“œ LICENSE πŸ“œ

This software is copyright (c) 2018 by cPanel, Inc.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.


⚠️ DISCLAIMER OF WARRANTY ⚠️

BECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR, OR CORRECTION.

IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE SOFTWARE AS PERMITTED BY THE ABOVE LICENCE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.


πŸ‘‘ AUTHOR πŸ‘‘

Nicolas R <atoomic@cpan.org>


This software is copyright (c) 2026 by cPanel, L.L.C.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.


and that's the whole page bestie!! πŸŽ‰ you made it all the way through, main character energy fr πŸ’– this lovely lil doc comes from perl v5.42.3 and was dated 2026-08-19. go mock some filechecks and slay βœ¨πŸ¦‹πŸŒΈ

πŸ“¦ where this page comes from