mcpan instal perl deployment dependencies cpan

instal - perl mcpan



¿Cómo puedo determinar las dependencias de CPAN antes de implementar un proyecto de Perl? (8)

En el pasado, he usado Devel :: Modlist, que es bastante buena y te permite ir

perl -d:Modlist script.pl

Para obtener una lista de los módulos requeridos.

¿Alguien tiene alguna sugerencia para un buen enfoque para encontrar todas las dependencias de CPAN que puedan haber surgido en un proyecto de desarrollo a medida? Como suele ser el caso, su entorno de desarrollo local rara vez coincide con su entorno real y a medida que construye más y más proyectos, tiende a construir una biblioteca local de módulos instalados. Esto te lleva a no necesariamente notar que tu último proyecto tiene un requisito en un módulo no principal. Dado que generalmente es necesario empaquetar todo el proyecto para su implementación en otro grupo (en nuestro caso, nuestro equipo de operaciones), es importante saber qué módulos se deben incluir en el paquete.

¿Alguien tiene alguna idea sobre el problema?

Gracias

Peter


Puede usar el servicio web en línea en deps.cpantesters.org que le proporcionará muchos datos de dependencia útiles. Todos los módulos en CPAN ya tienen el enlace al sitio de dependencia (en el lado derecho de la página del módulo).


Tengo un sistema de compilación basado en Make para todas mis aplicaciones C / C ++ (tanto para PC como para varios proyectos integrados), y aunque me encanta poder hacer una compilación de alto nivel en una máquina nueva y verificar que todas las dependencias estén en lugar (verifico mis cadenas de herramientas en el control de revisión: D), me he sentido frustrado al no hacer lo mismo con los idiomas interpretados que actualmente no tienen archivo MAKE en mi sistema de compilación.

Estoy tentado de escribir un script que:

  • busca en mi repositorio de control de revisiones los archivos con la extensión .pl o .pm
  • ejecuta perl -d:Modlist en ellos (¡gracias Vagnerr!)
  • concatenándolo a la lista de módulos requeridos
  • y finalmente compararlo con la lista de módulos instalados.

Luego, ejecutaba ese script como parte de mi compilación de nivel superior, de modo que cualquier persona que construya algo sabrá si tiene todo lo que necesita para ejecutar cada script de Perl que obtuvo del control de revisión. Si hay alguna secuencia de comandos perl que nunca se ejecutan y no desean que CPAN instale lo que se requiere para ejecutarla, tendrían que eliminar la secuencia de comandos no deseada de su disco duro, por lo que el verificador de dependencias no puede encontrarlos. Sé cómo modificar un cliente forzado para que deje de lado ciertos subdirectorios cuando haces una ''sincronización'', tendré que resolverlo para la subversión ...

Sugeriría que el comprobador de dependencias sea una sola secuencia de comandos que busque archivos pl, en lugar de un archivo MAKE individual para verificar las dependencias de cada secuencia de comandos, o en base a una lista de nombres de secuencia de comandos codificados. Si elige un método que requiere acción del usuario para que se compruebe la existencia de una secuencia de comandos, las personas se olvidarán de realizar esa acción, ya que podrán ejecutar la secuencia de comandos incluso si no realizan la comprobación de dependencia.

Como dije, aún no implementé lo anterior, pero esta pregunta me ha impulsado a intentarlo. Publicaré mi experiencia una vez que haya terminado.


Aquí hay una función quickie bash (usando el excelente ack ):

# find-perl-module-use <directory> (lib/ by default) function find-perl-module-use() { dir=${1:-lib} ack ''^/s*use/s+.*;/s*$'' $dir | awk ''{ print $2 }'' | sed ''s/();/?$/|;$//'' | sort | uniq ack ''^/s*use/s+base/s+.*;/s*$'' $dir | awk ''{ print $3 }'' | sed ''s/();/?$/|;$//'' | sort | uniq }


La forma "obvia", dolorosa pero moderadamente efectiva, es instalar una nueva versión de la base Perl en un lugar apartado (no va a utilizar esto en producción), y luego intente instalar su módulo usando este versión ''virgen'' de Perl. Encontrarás todas las dependencias faltantes. La primera vez, esto podría ser doloroso. Después de la primera vez, ya tendrá la mayoría de las dependencias cubiertas, y será mucho menos doloroso.

Considere la posibilidad de ejecutar su propio repositorio local de módulos CPAN, para que no siempre tenga que descargar el código. También considere cómo limpia los módulos desactualizados.


use Acme::Magic::Pony;

Seriamente. Automatizará la instalación de los módulos de Perl si faltan. Vea la página Acme :: Magic :: Pony en CPAN.


Es una respuesta "caballo que está atornillado", pero tengo la costumbre de crear un archivo Bundle con todas mis dependencias. Por lo tanto, cuando voy a un nuevo entorno, simplemente lo copio e instalo.

Por ej. Tengo un Baz.pm

package Bundle::Baz; $VERSION = ''0.1''; 1; __END__ =head1 NAME Bundle::Baz =head1 SYNOPSIS perl -MCPAN -e ''install Bundle::Baz'' =head1 CONTENTS # Baz''s modules XML::Twig XML::Writer Perl6::Say Moose

Pon esto en ~ / .cpan / Bundle / (o donde sea que tu .cpan viva) y luego instala ''Bundle :: Baz'' como un módulo de CPAN normal. Esto luego instala todos los módulos listados bajo "= head1 CONTENTS".


He tenido este problema yo mismo. Devel :: Modlist (como lo sugiere esta respuesta ) adopta un enfoque dinámico. Informa los módulos que se cargaron realmente durante una ejecución particular de su secuencia de comandos. Esto capta los módulos que se cargan por cualquier medio, pero es posible que no capte los requisitos condicionales. Es decir, si tienes un código como este:

if ($some_condition) { require Some::Module }

y $some_condition es falsa, Devel::Modlist no incluirá Some::Module como requisito.

Decidí usar Module :: ExtractUse en su lugar. Hace un análisis estático, lo que significa que siempre captará Some::Module en el ejemplo anterior. Por otro lado, no puede hacer nada acerca del código como:

my $module = "Other::Module"; eval "use $module;";

Por supuesto, puede usar ambos enfoques y luego combinar las dos listas.

De todos modos, aquí está la solución que se me ocurrió:

#! /usr/bin/perl #--------------------------------------------------------------------- # Copyright 2008 Christopher J. Madsen <perl at cjmweb.net> # # This program is free software; you can redistribute it and/or modify # it under the same terms as Perl itself. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See either the # GNU General Public License or the Artistic License for more details. # # Recursively collect dependencies of Perl scripts #--------------------------------------------------------------------- use strict; use warnings; use File::Spec (); use Module::CoreList (); use Module::ExtractUse (); my %need; my $core = $Module::CoreList::version{''5.008''}; # These modules have lots of dependencies. I don''t need to see them now. my %noRecurse = map { $_ => 1 } qw( Log::Log4perl XML::Twig ); foreach my $file (@ARGV) { findDeps($file); } foreach my $module (sort keys %need) { print " $module/n"; } #--------------------------------------------------------------------- sub findDeps { my ($file) = @_; my $p = Module::ExtractUse->new; $p->extract_use($file); foreach my $module ($p->array) { next if exists $core->{$module}; next if $module =~ /^5[._/d]+/; # Ignore "use MIN-PERL-VERSION" next if $module =~ //$/; # Run-time specified module if (++$need{$module} == 1 and not $noRecurse{$module}) { my $path = findModule($module); if ($path) { findDeps($path) } else { warn "WARNING: Can''t find $module/n" } } # end if first use of $module } # end foreach $module used } # end findDeps #--------------------------------------------------------------------- sub findModule { my ($module) = @_; $module =~ s!::|/'!/!g; $module .= ''.pm''; foreach my $dir (@INC) { my $path = File::Spec->catfile($dir, $module); return $path if -f $path; } return; } # end findModule

Dirías esto como:

perl finddeps.pl scriptToCheck.pl otherScriptToCheck.pl

Imprime una lista de todos los módulos no esenciales necesarios para ejecutar los scripts enumerados. (A menos que hagan trucos con la carga del módulo que impiden que Module :: ExtractUse los vea).