NAME

Perl::Version::Bumper - Update use VERSION on any Perl code

SYNOPSIS

use Perl::Version::Bumper;

my $perv = Perl::Version::Bumper->new( version => 'v5.36' );

# bump a PPI::Document
my $bumped_ppi = $perv->bump_ppi($ppi_doc);

# bump source code
my $bumped_code = $perv->bump($code);

# bump the source of a file
$perv->bump_file($filename);

# safe versions (check the result compiles)

my $bumped_ppi  = $perv->bump_ppi_safely($ppi_doc);
my $bumped_code = $perv->bump_safely($code);
$perv->bump_file_safely( $filename, $version_limit );

DESCRIPTION

Perl::Version::Bumper can update Perl code to make it declare it uses a more recent version of the Perl language by way of use VERSION.

It takes care of removing unnecessary loading of feature and experimental warnings, and adds the use VERSION line at the top of the file (thus encouraging "line 1 semantics").

It also manages the removal of "compatibility" modules when the feature they provide a compatibility layer with is fully supported in the target Perl version.

If the code already declares a Perl version, it can only be bumped to a higher version.

The module exports a few helper functions. These are mostly used by support tools for this distribution, and are not meant for general use.

CONSTRUCTOR

new

my $perv = Perl::Version::Bumper->new( %attributes );
my $perv = Perl::Version::Bumper->new( \%attributes );

Return a new Perl::Version::Bumper object.

ATTRIBUTES

version

The target version to bump to.

Defaults to the stable version less than or equal to the version of the currenly running perl.

The constructor accepts both forms of Perl versions, regular (e.g. v5.36) and floating-point (e.g. 5.036), and will turn it into a string suitable for use VERSION.

To protect against simple mistakes (e.g. passing 5.36 instead of v5.36), the constructor does some sanity checking, and checks that the given version:

  • is greater than or equal to v5.10,

  • is lower than the version of the Perl currently running,

  • is a stable Perl version.

The constructor will also drops any sub-version information (so v5.36.2 will be turned into v5.36).

CLASS METHODS

feature_version

Return the version (in numeric format) of the feature set recognized by this module. It is not possible to bump code over that version.

The current value of feature_version is: 5.040.

METHODS

version_num

Return the "version" attribute as a number.

bump_ppi

my $bumped_ppi_doc = $perv->bump_ppi($ppi_doc);

Take a PPI::Document as input, and return a new PPI::Document with its declared version bumped to "version".

bump

my $bumped_code = $perv->bump($code);

Take a string containing Perl code as input, bump the declared Perl version in the source code to "version", and return the new source code as a string.

bump_file

$perv->bump_file($filename);

Bump the code of the file argument in-place.

Return a boolean indicating if the file content was modified or not.

SAFE METHODS

The "bump_ppi", "bump" and "bump_file" methods previously described modify the source code they're given, but give no garanties that the updated code will even compile.

To address this issue, "bump_ppi_safely", "bump_safely" and "bump_file_safely" methods work as the regular methods, but will only produce code that actually compiles.

If all attempts fail, the return value is identical to the input value.

Example of a safe bump

The following code uses multidimensional array emulation:

my %h; $h{ 1, 2 } = 3;    # same as $foo{"1\x{1c}2"} = 3;

"bump" will produce the following when trying to update it to v5.40:

use v5.40;
my %h; $h{ 1, 2 } = 3;    # same as $foo{"1\x{1c}2"} = 3;

Which fails to compile with the following error:

Multidimensional hash lookup is disabled

It's not possible to just bump this code up to v5.40 and expect it to work, because it uses multidimensional array emulation, and the feature that represents this (multidimensional) was disabled in v5.36. The actual cause for the error is that Perl v5.36 doesn't support multidimensional array emulation. This code will in fact fail to compile with all versions greater or equal to v5.36.

A safe way to try to bump this code to v5.40 is to try with v5.40, detect it fails to compile, try again with v5.38 and v5.36, which also fail, until we hit v5.34 which compiles just fine (because the multidimensional feature is still enabled in that bundle). Leaving us with the following code:

use v5.34;
my %h; $h{ 1, 2 } = 3;    # same as $foo{"1\x{1c}2"} = 3;

The code needs to be updated to not use multidimensional array emulation before it can safely be bumped past version v5.34.

Process of a safe bump

The process for a safe bump is to take some input, and try to compile it. If the compilation fails, return immediately.

Otherwise, continue with the process: bump the content, and try to compile the result. Return as soon as compilation succeeds.

If compilation fails, decrease the target Perl version number, bump the content to that version, and try to compile the result again. Keep decreasing the target version, all the way back to the currently declared version in the document, or version_limit, whichever is more recent. Give up after the last compilation failure.

Options for a safe bump

All the methods below take one input argument (a PPI::Document, a string of code or a filename) and one optional hash reference for options.

The possible options are:

version_limit

The version at which to stop decreasing the target version. Defaults to v5.10.

env

A hash reference of key/value pairs for environment variables to be set when trying to compile the bumped code.

bump_ppi_safely

my $bumped_ppi = $perv->bump_ppi_safely( $ppi_doc, \%options );

Safely bump the source code in the given PPI::Document.

The return value is a new PPI::Document containing the result of the "safe bump" (its content might be the same as the original if there's no safe way to bump the code).

bump_safely

my $bumped_code = $perv->bump_safely( $code, \%options );
my ( $bumped_code, $new_version ) = $perv->bump_safely($code);

Safely bump the source code given as a string.

The return value is a string containing the new source code.

bump_file_safely

$perv->bump_file_safely( $filename, \%options );

Safely bump the code in the file argument in-place. The file will not be modified if the code can't be bumped safely.

The return value is undef if the original didn't compile, false if all attempts to bump the file failed, and the actual (numerical) version number the file was bumped to in case of success.

EXPORTS

The following functions can be optionally exported. Be aware that they are mostly meant for internal use of the module and helper scripts.

version_fmt

my $v = version_fmt( $version );

Return the given version (in string, v-string or float format) as a number.

This function will die if the given version is not a plausible Perl version number, i.e. is strictly lower than 5.010.

Note that all the following functions start by normalizing their argument by calling "version_fmt", meaning they will die in the same circumstances.

version_use

my $v = version_use( $version );

Return the given version (in string, v-string or float format) as a string suitable for a use VERSION line.

stable_version

my $s = stable_version( $version );

Return the closest stable version lower or equal to the given version, as a number.

stable_version_inc

my $n = stable_version_inc( $version );

Return the stable version following the given version, as a number.

stable_version_dec

my $p = stable_version_dec( $version );

Return the stable version preceding the given version, as a number.

ACKNOWLEDGMENT

This software was originally developed at Booking.com. With approval from Booking.com, this software was released as open source, for which the authors would like to express their gratitude.

AUTHOR

Philippe Bruhat (BooK) <book@cpan.org>

COPYRIGHT

Copyright 2024 Philippe Bruhat (BooK), all rights reserved.

LICENSE

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