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 ]

Burak (3156)

Burak
  (email not shown publicly)
http://www.burakgursoy.com/

Journal of Burak (3156)

Thursday October 16, 2008
02:45 PM

Having a single version number in all modules in a distro

[ #37679 ]
I was trying to figure out a mechanism to somehow format all modules in a distro (Text::Template::Simple) automatically to have a single version number instead of varying versions among files. I'm not so sure if this is the best way, but I chose to manually modify the files to update the versions in them. First, I had to subclass Module::Build to alter the `Build dist` action. However, M::B has an awkward interface for subclassing. One needs to pass the sublass code as a string into the subclass() method. Weirdo :p But since I didn't like this interface for subclassing and I wanted to use the syntax checking/coloring of my Komodo Edit, I've decided to load the content from an external file:

my $class = Module::Build->subclass(
                                class => 'MBSubclass',
                                code => raw_subclass(),
                        );

sub raw_subclass {
        my $file = File::Spec->catfile( 'tools', 'Build.pm' );
        my $FH = IO::File->new;
        $FH->open( $file, 'r' ) or die "Can not open($file): $!";
        my $rv = do { local $/; <$FH> };
        close $FH;
        return $rv;
}

And here is the subclass (note that there is no package declaration since M::B adds this part automatically afterwards):

use strict;
use vars qw( $VERSION );
use warnings;
use File::Find;
use constant RE_VERSION_LINE => qr{
      \A \$VERSION \s+ = \s+ ["'] (.+?) ['"] ; (.+?) \z
}xms;
use constant VTEMP => q{$VERSION = '%s';};

$VERSION = '0.10';

sub ACTION_dist {
      my $self = shift;
      warn sprintf(
                        "RUNNING 'dist' Action from subclass %s v%s\n",
                        ref($self),
                        $VERSION
                  );
      my @modules;
      find {
            wanted => sub {
                  my $file = $_;
                  return if $file !~ m{ \. pm \z }xms;
                  push @modules, $file;
                  warn "FOUND Module: $file\n";
            },
            no_chdir => 1,
      }, "lib";
      $self->_change_versions( \@modules );
      $self->SUPER::ACTION_dist( @_ );
}

sub _change_versions {
      my $self = shift;
      my $files = shift;
      my $dver = $self->dist_version;

      warn "DISTRO Version: $dver\n";

      foreach my $mod ( @{ $files } ) {
            warn "PROCESSING $mod\n";
            my $new = $mod . '.new';
            open my $RO_FH, '<:raw', $mod or die "Can not open file($mod): $!";
            open my $W_FH , '>:raw', $new or die "Can not open file($new): $!";
            my $changed;
            while ( my $line = readline $RO_FH ) {
                  if ( ! $changed && ( $line =~ RE_VERSION_LINE ) ) {
                          my $oldv = $1;
                          my $remainder = $2;
                          warn "CHANGED Version from $oldv to $dver\n";
                          printf $W_FH VTEMP . $remainder, $dver;
                          $changed++;
                          next;
                  }
                  print $W_FH $line;
            }

            close $RO_FH or die "Can not close file($mod): $!";
            close $W_FH or die "Can not close file($new): $!";

            unlink($mod) || die "Can not remove original module($mod): $!";
            rename( $new, $mod ) || die "Can not rename( $new, $mod ): $!";
            warn "RENAME Successful!\n";
      }

      return;
}

It's really straightforward. Find the *.pm and them create a modified copy that has the distro's version and replace the original with the new one and resume `dist` process :)
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.
  • I am not sure it makes sense unless the module can't stand on its own to share the version from the main application but I would love to hear what others have to say.

    • Well, it looks like this was discussed at least once :) http://www.nntp.perl.org/group/perl.module.build/2007/04/msg642.html [perl.org] Anyway, I bet (since this is not something new) there is already some stuff related to this on PerlMonks, but I'm too lazy to search right now :) As for my decision, Text::Template::Simple and all it's sub modules are actually a single monolithic thing splitted into separate files to ease managing :) And it was really a single .pm some time back...