# from Johan Vromans
# on Sunday 17 June 2007 02:36 am:

>Eric Wilhelm wrote:
>>For instance, process_foo_files() would be terribly
>> convenient if copy_if_modified() could hit a callback rather than
>> File::Copy::copy() *after* creating the basedir and before the
>> chmod.  
>
>Assume the file contains ABBC, and the copy hook turns that into AXXC.
>The file on disk is ABBC. Coy if modified will do nothing, since it's
>not modified?

(Actually, it would copy given explicit source and dest because 
up_to_date($src, $dest) would return false.)

But, that's not the "in lieu of File::Copy::copy()" of which I speak.  
I'm talking about changing the file *content* not the names.

Here's the processor without any copy_files() support.

Note the assumptions I'm making about a unix filesystem (the compilation 
via '-MInline=_INSTALL_' is a hack and of course assumes make, etc.  
But bear with me there.)

Also note that I have to loop over the two sets of files individually.

Also note that the @$pmfiles loop assumes existing directories (which 
just happens to be true *in this case* because the @$cfiles loop 
creates them.)

Also note that I have to open,read and open,write the file.

Also note that I forgot to chmod the .pm's.

I could add extra code to get the cross-platform bits right, but that's 
what I'm thinking should be addressed in M::B.  The proposed 
copy_files() and content-rewriting hooks would eliminate the need for 
that extra code.  They also keep allow authors to get it right without 
having to think about all of those issues and/or test their custom 
copy-with-modifications code.

  sub process_inline_files {
    my $self = shift;

    # find & copy ilib tree into blib/lib
    my $cfiles = $self->rscan_dir('ilib', qr{\.c(pp)?$});

    foreach my $file (@$cfiles) {
      (my $to = $file) =~ s#ilib#blib/lib#;
      $self->copy_if_modified(from => $file, to => $to);
    }

    # now the .pm files
    my $pmfiles = $self->rscan_dir('ilib', qr{\.pm$});
    foreach my $file (@$pmfiles) {
      (my $to = $file) =~ s#ilib#blib/lib#;
      next if($self->up_to_date($file, $to));

      my $code = do {open(my $fh, '<', $file) or die;
        local $/; <$fh>;};

      # look for a name
      my ($name) = ($code =~ m/^package ([\w:]+);/) or
        die "cannot find name";

      # turn the the version on
      my $count = ($code =~ s/^(\s*)#(\s*VERSION *=>)/$1$2/mg);
      $count or die "missing '#VERSION =>' entry";
      ($count == 1) or die "too many '#VERSION =>' entries?";

      # write
      open(my $fh, '>', $to) or die "cannot write '$to' $!";
      print $fh $code;
      close($fh) or die "$!";

      # then build it
      $self->do_system($^X, '-Iblib/lib', '-MInline=_INSTALL_',
        "-M$name", qw(-e1 0.1 blib/arch)
      );
    }
  } # end sub process_inline_files


So here's what happens when we support all of the filename munging in 
copy_files().  I'm still undecided on the particulars of "fixup".  (I 
also just realized that we would need some sort of "re-rooting" option 
and I'm totally undecided on that at this point.)

Anyway, this is now able to be completely cross-platform without the 
author having to worry about all of this details (and better yet, the 
author gets to be lazy.)  (You still have to ignore the inline hack -- 
that's a completely different problem than copy_files().)

  sub process_inline_files {
    my $self = shift;

    # find & copy ilib tree into blib/lib
    my $files = $self->rscan_dir('ilib', qr{\.(?:pm|c(pp)?)$});
    # remove the ilib root
    my @paths = map({s/ilib//; $_} @$files);

    my @inline_mods;
    $self->copy_files([EMAIL PROTECTED], 'blib/lib',
      fromdir => 'ilib',
      fixup => {
        where   => qr/\.pm$/,
        content => sub {
          # look for a name
          my ($name) = (m/^package ([\w:]+);/) or
            die "cannot find name";
          push(@inline_mods, $name);

          # turn the the version on
          my $count = (s/^(\s*)#(\s*VERSION *=>)/$1$2/mg);
          $count or die "missing '#VERSION =>' entry";
          ($count == 1) or die "too many '#VERSION =>' entries?";
        },
      },
    );

    # then build them
    foreach my $name (@inline_mods) {
      $self->do_system($^X, '-Iblib/lib', '-MInline=_INSTALL_',
        "-M$name", qw(-e1 0.1 blib/arch)
      );
    }
  } # end sub process_inline_files


--Eric
-- 
I arise in the morning torn between a desire to improve the world and a
desire to enjoy the world. This makes it hard to plan the day.
--E.B. White
---------------------------------------------------
    http://scratchcomputing.com
---------------------------------------------------

Reply via email to