Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

Yanick (3196)

Yanick
  (email not shown publicly)
http://babyl.dyndns.org/techblog

Journal of Yanick (3196)

Wednesday March 19, 2008
09:13 PM

per(l)version

[ #35940 ]

Updating the version number is all the files of a module distribution is a pain in the behind. It's repetitive, boring and ridiculously prone to errors -- in short, a task fit for a script, not for humans. So I decided to hack myself a little something, for the time being called perversion, to take care of it.

The idea is pretty straight-forward. In the root directory of my distribution, I have a config file named perversionrc that contains Perl code that return an hash of all files where the the module version is given, and regular expressions to capture the said version. For example, here's the perversionrc of WWW::Ohloh::API:

use File::Find::Rule;

my %file;

$file{README} = qr/WWW-Ohloh-API version (\S+)/;

for my $m ( File::Find::Rule->file->name( '*.pm' )->in( 'lib' ) ) {
   $file{$m} = [ qr/\$VERSION\s*=\s*'(.*?)';/,
                 qr/This document describes \S+ version (\S*)/ ];
}

%file;

Once that file is present, perversion is ready to rock. You want to verify that the version number is consistent in all given files?

$ perversion
distribution version is set to 0.0.9
lib/WWW/Ohloh/API/Enlistment.pm:12: 0.0.6
!!! does not match distribution version (0.0.9) !!!
lib/WWW/Ohloh/API/Repository.pm:10: 0.0.6
!!! does not match distribution version (0.0.9) !!!
lib/WWW/Ohloh/API/ContributorLanguageFact.pm:10: 0.0.6
!!! does not match distribution version (0.0.9) !!!
lib/WWW/Ohloh/API/ContributorFact.pm:10: 0.0.6
!!! does not match distribution version (0.0.9) !!!
lib/WWW/Ohloh/API/ContributorFact.pm:241: 0.0.6
!!! does not match distribution version (0.0.9) !!!

Want to set the version to a specific value?

$ perversion -set 1.2.3
changing all versions to 1.2.3..
        updating lib/WWW/Ohloh/API.pm..
        updating lib/WWW/Ohloh/API/Language.pm..
        updating lib/WWW/Ohloh/API/ActivityFacts.pm..
        updating lib/WWW/Ohloh/API/Account.pm..
        updating lib/WWW/Ohloh/API/Kudos.pm..
        updating lib/WWW/Ohloh/API/Project.pm..
        updating lib/WWW/Ohloh/API/Enlistment.pm..
        updating lib/WWW/Ohloh/API/KudoScore.pm..
        updating lib/WWW/Ohloh/API/Factoid.pm..
        updating lib/WWW/Ohloh/API/Repository.pm..
        updating lib/WWW/Ohloh/API/Projects.pm..
        updating lib/WWW/Ohloh/API/ContributorLanguageFact.pm..
        updating lib/WWW/Ohloh/API/Languages.pm..
        updating lib/WWW/Ohloh/API/ActivityFact.pm..
        updating lib/WWW/Ohloh/API/ContributorFact.pm..
        updating lib/WWW/Ohloh/API/Analysis.pm..
        updating lib/WWW/Ohloh/API/Kudo.pm..
        updating README..
done

Don't want to go through the mental challenge of computing the next version yourself? No problem!

$ perversion -inc revision
distribution version is set to 1.2.3
new distribution version is 1.2.4

$ perversion -inc minor
distribution version is set to 1.2.4
new distribution version is 1.3.0

$ perversion -inc major
distribution version is set to 1.3.0
new distribution version is 2.0.0

$ perversion -inc alpha
distribution version is set to 2.0.0
new distribution version is 2.0_1

The script is still raw and in need of polishing, but for those interested, it's available from its very own git repository.

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.
  • http://search.cpan.org/src/ADAMK/PPI-PowerToys-0.10/lib/PPI/App/Version.pm [cpan.org]

    I really should chuck some proper docs on this and release it properly, instead of just relying on word of mouth :(
    • Shouldn't that be in the PPIx namespace?

      Or was this written earlier than that?
    • At first, I also thought of tackling the problem with PPI, but it has the disadvantage of not being able to much with the pod (I think) and, of course, non-Perl files like the README and friends. And those are the harder half of the problem, because in the code one could do

          use My::Module::Version; our $VERSION = $My::Module::Version::VERSION;

      and get away with only changing the $VERSION in My::Module. Or, at least, I think one could do that. I've didn't dare to put that theory to the test

  • The one place I regularly forget to update is the META.yml. However, version strings in a META.yml get a little tricky as you need to change them in context of the distribution and modules versions and nothing else. Been thinking I need to automated that somehow ... when I have time ;)

    • But then, META.yml is dealt with by './Build dist' or 'make dist', so one shouldn't have to dabble with it, no?

      And this being said, based on a five second pre-morning coffee perusal of the way META.yml presents its stuff (i.e., I'm probably wrong but still too sleepy for it to stop me :-) ), I think that something looking like the following added to the perversionrc hash should do the trick:

      $h{META.yml} = [
          qr/ ^ name:    \s \S+   $
                vers

      • But then, META.yml is dealt with by './Build dist' or 'make dist', so one shouldn't have to dabble with it, no?

        I don't use M::B and EU::MM doesn't build a fully documented META.yml. As such I write all my META.yml files by hand, as that way I can be guaranteed to include all the details I want.

        Also the ordering is not guaranteed, so your regex may work in some cases but not all. That's why I said it was tricky ;) A good headstart mind :)

        • Something that could be done would be to pervert perversion a little bit more still. Instead of giving a regular expression as a value in the config hash, one could also pass references to a sub that would then be able to do whatever it wants with the file content... Including parsing its YAML, updating versions at the right places, and then spitting back the result. It shouldn't be much more than a few lines more. I might hack that in later on today, just for fun. :-)

        • And here we go. I've updated the code such that you can now hook a subroutine ref in the perversionrc hash. E.g.:

          use YAML qw/ Load Dump /;

          sub do_meta {
              my ( $text, $version ) = @_;

              my $yaml = Load( $text );

              my @old;

              push @old, $yaml->{version};
              $yaml->{version} = $version;

              for ( values %{ $yaml->{provides} } ) {
                  push @old, $_->{version};
                  $_->{version} = $