Having a single version number in all modules in a distro

Burak on 2008-10-16T19:45:10

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 :)


Perhaps Crosspost on Perlmonks

Limbic Region on 2008-10-17T14:41:05

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.

Re:Perhaps Crosspost on Perlmonks

Burak on 2008-10-21T21:12:36

Well, it looks like this was discussed at least once :)

http://www.nntp.perl.org/group/perl.module.build/2007/04/msg642.html

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...