2009-05-07 19 views
1

J'utilise Module :: Build pour effectuer des actions de build, test, testpod, html, & sur mon module Perl que je suis en train de développer. Les fichiers HTML générés sont corrects, mais je serais beaucoup plus heureux si je pouvais configurer Module :: Build pour utiliser l'utilitaire de formatage perltidy -html au lieu de son propre formateur HTML. Quelqu'un sait-il comment je peux remplacer le formateur HTML fourni avec Module :: Build avec le formateur HTML plus élégant?Puis-je utiliser le formateur HTML de perltidy dans ma compilation Perl automatisée?

Addendum: Quand je dis "Replace" ci-dessus, qui était probablement induire en erreur. Je ne veux pas vraiment écrire du code pour remplacer le formateur html fourni avec Module :: Build. Je veux vraiment savoir si Module :: Build a autres options de formatage HTML. Le HTML qu'il génère est tellement simple et générique. C'est tellement ennuyant. J'aime beaucoup la sortie de perltidy.

Voici comment je l'ai eu à travailler en ce moment dans un script de compilation que je l'ai écrit, mais il est tout à fait un hack ... tomber à la ligne de commande de script perltidy:

use strict; 
use warnings; 

# get list of files in directory 
my $libLocation = "lib/EDF"; 
opendir(DIR, $libLocation); 
my @filenameArray = readdir(DIR); 

# iterate over all files to find *.pm set 
for my $file (@filenameArray) { 
    if ($file =~ m/  # matching regex 
         \. # literal period character 
         pm # the pm file extenstion 
        /x  # end of regex 
     ) 
    { 

     my $return = `perl D:/Perl/site/bin/perltidy -q --indent-columns=4 --maximum-line-length=80 -html -opath blib/libhtml2 -toc $libLocation/$file`; 

     if ($return eq "") { 
      print "HTMLized " . $file . "\n"; 
     } 
     else { 
      print "Error: " . $return . "\n"; 
     } 

    } 

} 

Mais j'espérais vraiment il y avait un moyen d'utiliser Module :: Build et juste le dire avec un drapeau ou un argument ou quoi que ce soit pour lui dire d'utiliser un formateur HTML différent. Je suppose que c'est un rêve de pipe, cependant:

use strict; 
use warnings; 
use Module::Build; 

my $build = Module::Build->resume (
    properties => { 
    config_dir => '_build', 
    }, 
); 

$build->dispatch('build'); 
$build->dispatch('html', engine => 'perltidy'); 

ou peut-être:

$build->dispatch('htmltidy'); 

Répondre

1

Eh bien, l'action est mis en œuvre dans

htmlify_pods 

dans Module::Build::Base.

Il devrait être possible de remplacer cette méthode.

Beaucoup plus tard ...

Voici ma tentative (testé une seule fois):

package My::Builder; 

use strict; 
use warnings; 

use base 'Module::Build'; 

sub htmlify_pods { 
    my $self = shift; 
    my $type = shift; 
    my $htmldir = shift || File::Spec->catdir($self->blib, "${type}html"); 

    require Module::Build::Base; 
    require Module::Build::PodParser; 
    require Perl::Tidy; 

    $self->add_to_cleanup('pod2htm*'); 

    my $pods = $self->_find_pods( 
     $self->{properties}{"${type}doc_dirs"}, 
     exclude => [ Module::Build::Base::file_qr('\.(?:bat|com|html)$') ]); 
    return unless %$pods; # nothing to do 

    unless (-d $htmldir) { 
    File::Path::mkpath($htmldir, 0, oct(755)) 
     or die "Couldn't mkdir $htmldir: $!"; 
    } 

    my @rootdirs = ($type eq 'bin') ? qw(bin) : 
     $self->installdirs eq 'core' ? qw(lib) : qw(site lib); 

    my $podpath = join ':', 
       map $_->[1], 
       grep -e $_->[0], 
       map [File::Spec->catdir($self->blib, $_), $_], 
       qw(script lib); 

    foreach my $pod (keys %$pods) { 

    my ($name, $path) = File::Basename::fileparse($pods->{$pod}, 
     Module::Build::Base::file_qr('\.(?:pm|plx?|pod)$')); 
    my @dirs = File::Spec->splitdir(File::Spec->canonpath($path)); 
    pop(@dirs) if $dirs[-1] eq File::Spec->curdir; 

    my $fulldir = File::Spec->catfile($htmldir, @rootdirs, @dirs); 
    my $outfile = File::Spec->catfile($fulldir, "${name}.html"); 
    my $infile = File::Spec->abs2rel($pod); 

    next if $self->up_to_date($infile, $outfile); 

    unless (-d $fulldir){ 
     File::Path::mkpath($fulldir, 0, oct(755)) 
     or die "Couldn't mkdir $fulldir: $!"; 
    } 

    my $path2root = join('/', ('..') x (@[email protected])); 
    my $htmlroot = join('/', 
      ($path2root, 
       $self->installdirs eq 'core' ?() : qw(site))); 

    my $fh = IO::File->new($infile) or die "Can't read $infile: $!"; 
    my $abstract = Module::Build::PodParser->new(fh => $fh)->get_abstract(); 

    my $title = join('::', (@dirs, $name)); 
    $title .= " - $abstract" if $abstract; 

    my %opts = (
     argv => join(" ", 
      qw(-html --podflush), 
      "--title=$title", 
      '--podroot='.$self->blib, 
      "--htmlroot=$htmlroot", 
      "--podpath=$podpath", 
     ), 
     source => $infile, 
     destination => $outfile, 
    ); 

    if (eval{Pod::Html->VERSION(1.03)}) { 
     $opts{argv} .= ' --podheader'; 
     $opts{argv} .= ' --backlink=Back to Top'; 
     if ($self->html_css) { 
      $opts{argv} .= " --css=$path2root/" . $self->html_css; 
     } 
    } 

    $self->log_info("HTMLifying $infile -> $outfile\n"); 
    $self->log_verbose("perltidy %opts\n"); 
    Perl::Tidy::perltidy(%opts); # or warn "pod2html @opts failed: $!"; 
    } 
} 
1; 

** Pour l'utiliser .. **

#!/usr/bin/perl 

use strict; 
use warnings; 

use My::Builder; 

my $builder = My::Builder->new(
    module_name => 'My::Test', 
    license  => 'perl', 
); 

$builder->create_build_script; 
+0

Cela ressemble travail que je ne suis pas confortable à prendre. J'espérais qu'il y avait juste un drapeau que je pourrais mettre ou quelque chose. :-) –

+0

Ce n'est probablement pas si difficile. Je vais jeter un coup d'oeil plus tard. –

+0

Ceci est intéressant. Je suppose que vous venez de changer la dernière ligne de ce qu'elle était avant cet appel perltidy.Mon souci ici est que ceci est pour un projet de travail, et que je copierais un sous-programme CPAN existant et que je le gèlerais pour toujours et que je n'obtiendrais jamais les futures améliorations de Module :: Build pour cette routine particulière. Pas vraiment une bonne proactice de génie logiciel. Peut-être pas un gros problème pour ce petit cas, cependant. Je vais le considérer. Merci de me montrer comment le faire. –

1

Il est très il est facile de définir de nouvelles actions Module :: Build que vous pouvez appeler avec dispatch, et il existe de nombreux exemples dans la documentation Module :: Build. Définir une action pour gérer votre nouvelle étape:

 
sub ACTION_htmltidy 
    { 
    my($self) = @_; 

    $self->depends_on(...other targets...); 

    require Perl::Tidy; 

    ...do your damage... 
    } 

Si vous voulez une autre action à utiliser le vôtre, vous pouvez l'étendre afin que vous puissiez faire la dépendance:

 
sub ACTION_install 
    { 
    my($self) = @_; 

    $self->depends_on('htmltidy'); 

    $self->SUPER::install; 
    } 
+0

Merci pour le montrer. Définitivement élégant. –

+0

Donc dans la section "faites vos dégâts", je mettrais mon code qui lit mon répertoire de bibliothèque et analyse la liste des fichiers PM, puis traite chaque fichier PM en utilisant plus de code que j'écris? Est-ce que je ne fais pas beaucoup de travail dans la section "faites vos dégâts" que Module :: Build sait déjà faire? Cela ne semble pas être la bonne chose à faire pour moi. –

+0

@Kurt: vous utiliseriez l'API Module :: Build, donc vous réutiliserez ce que Module :: Build sait déjà faire. –