在部署Perl项目之前,如何确定CPAN依赖关系?
有人对找到定制开发项目中可能出现的所有CPAN依赖项的好方法有什么建议吗。通常情况下,您的本地开发环境很少与您的实时开发环境相匹配,并且随着您构建越来越多的项目,您倾向于构建本地已安装模块库。这样,您就不必注意到您的最新项目对非核心模块有需求。由于通常需要将整个项目打包以部署到另一个组(在我们的案例中是我们的操作团队),因此了解包中应该包含哪些模块非常重要 有人对这个问题有什么见解吗 谢谢 彼得在过去,我用过一种比较好的方法让你去在部署Perl项目之前,如何确定CPAN依赖关系?,perl,deployment,dependencies,cpan,Perl,Deployment,Dependencies,Cpan,有人对找到定制开发项目中可能出现的所有CPAN依赖项的好方法有什么建议吗。通常情况下,您的本地开发环境很少与您的实时开发环境相匹配,并且随着您构建越来越多的项目,您倾向于构建本地已安装模块库。这样,您就不必注意到您的最新项目对非核心模块有需求。由于通常需要将整个项目打包以部署到另一个组(在我们的案例中是我们的操作团队),因此了解包中应该包含哪些模块非常重要 有人对这个问题有什么见解吗 谢谢 彼得在过去,我用过一种比较好的方法让你去 perl -d:Modlist script.pl 获取所需模
perl -d:Modlist script.pl
获取所需模块的列表。您可以使用在线web服务,该服务将为您提供许多有用的依赖关系数据。CPAN上的所有模块都已经有了到依赖项站点的链接(在模块页面的右侧)。显而易见的方法是在一些偏僻的位置安装全新的基本Perl版本(您不会在生产中使用),然后尝试使用这个“virgin”版本的Perl安装您的模块。您将找到所有缺少的依赖项。第一次,这可能是痛苦的。在第一次之后,您将已经覆盖了大部分依赖项,并且这将大大减少痛苦
考虑运行您自己的CPAN模块本地存储库,这样您就不必总是下载代码。还考虑如何清理过时的模块。< P>我有一个基于构建的构建系统,用于所有的C/C++应用程序(基于PC和各种嵌入式项目),而我喜欢能够在一台新机器上做一个顶级的构建,并验证所有依赖性都已就位(我检查工具链到修订控制:D),对于目前在我的构建系统中没有makefile的解释语言,我一直很沮丧没有这样做 我很想写一个脚本:
- 在我的修订控制存储库中搜索扩展名为.pl或.pm的文件
- 在它们上运行
(感谢Vagnerr!)perl-d:Modlist
- 将其连接到所需模块列表
- 最后将其与已安装模块列表进行比较
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
把它放在~/.cpan/Bundle/(或者你的.cpan所在的任何地方),然后像普通的cpan模块一样安装“Bundle::Baz”。然后安装“=head1 CONTENTS”下列出的所有模块。我自己也遇到过这个问题。(如建议的)采用动态方法。它报告在特定脚本运行期间实际加载的模块。这会捕获通过任何方式加载的模块,但可能不会捕获条件需求。也就是说,如果您有这样的代码:
if ($some_condition) { require Some::Module }
而$some_条件
恰好为假,Devel::Modlist
不会将some::Module
列为需求
我决定改用。它进行静态分析,这意味着在上面的示例中,它将始终捕获Some::Module
。另一方面,它无法处理以下代码:
my $module = "Other::Module";
eval "use $module;";
当然,您可以使用这两种方法,然后将这两个列表组合起来
总之,我想出了一个解决方案:
#! /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
它打印运行列出的脚本所需的所有非核心模块的列表。(除非他们在加载模块时耍花招,阻止module::ExtractUse看到它们。)
真的。如果发现Perl模块丢失,它将自动安装这些模块。请参阅CPAN中的页面。这里有一个quickie bash函数(使用优秀的:
#查找perl模块的用法(默认为lib/)
函数find-perl-module-use(){
dir=${1:-lib}
ack'^\s*使用\s+.*\s*$'$dir | awk'{print$2}'| sed's/();\?$\\\\\\\;$/'| sort | uniq
ack'^\s*使用\s+base\s+.*\s*$'$dir | awk'{print$3}'| sed's/();\?$\\\\\\\\;$/'| sort | uniq
}
很有趣,但如果您尝试在实时商业环境中使用它,您的运营团队会对您感到有点不安,希望了解您是否了解稳定性和安全性的概念:-)
perl finddeps.pl scriptToCheck.pl otherScriptToCheck.pl
use Acme::Magic::Pony;
# 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
}