在部署Perl项目之前,如何确定CPAN依赖关系? [英] How can I determine CPAN dependencies before I deploy a Perl project?

查看:146
本文介绍了在部署Perl项目之前,如何确定CPAN依赖关系?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有人有任何建议,以寻找一个很好的方法来查找可能在定制开发项目中出现的所有CPAN依赖关系。由于您的本地开发环境很少与您的现场开发环境相匹配,并且随着您构建越来越多的项目,您倾向于构建已安装模块的本地库。这些导致您不一定注意到您的最新项目对非核心模块有要求。由于通常需要将整个项目整合到部署到另一个组(在我们的情况下是我们的运营团队),因此重要的是要知道包中应该包含哪些模块。



有没有人对此问题有任何见解。



谢谢



Peter

解决方案

我自己遇到了这个问题。 Devel :: Modlist (由这个答案)采取动态的方法。它报告在脚本的特定运行期间实际加载的模块。这样可以捕获通过任何方式加载的模块,但它可能无法满足条件要求。也就是说,如果你有这样的代码:

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

$ some_condition 恰好是假, Devel :: Modlist 不会列出 Some :: Module 作为要求。



我决定使用 Module :: ExtractUse 。它执行静态分析,这意味着它将在上面的例子中总是捕获 Some :: Module 。另一方面,它不能对代码做任何事情:

 我的$ module =Other :: Module; 
evaluse $ module;;

当然,您可以使用这两种方法,然后组合两个列表。



无论如何,这里是我想出的解决方案:

 #! / usr / bin / perl 
#--------------------------------------- ------------------------------
#版权所有2008 Christopher J. Madsen< perl at cjmweb.net>

#这个程序是免费的软件;您可以按照与Perl本身相同的条款重新分发和/或修改
#。

#这个程序是分发的,希望它是有用的,
#但没有任何保证;甚至没有隐含的保证
#适销性或适用于特定用途。有关详细信息,请参阅
#GNU通用公共许可证或艺术许可证。

#递归收集Perl脚本的依赖项
#----------------------------- ----------------------------------------

使用strict ;
使用警告;
使用File :: Spec();
使用Module :: CoreList();
使用Module :: ExtractUse();

我的%需要;
我的$ core = $ Module :: CoreList :: version {'5.008'};

#这些模块有很多依赖关系。我现在不需要看。
我的%noRecurse = map {$ _ => 1} qw(
Log :: Log4perl
XML :: Twig
);

foreach我的$文件(@ARGV){
findDeps($ file);
}

foreach我的$模块(排序键%需要){
打印$ module\\\
;
}

#------------------------------------ ---------------------------------
sub findDeps
{
my( $ file)= @_;

我的$ p = Module :: ExtractUse-> new;

$ p-> extract_use($ file);

foreach我的$模块($ p->数组){
next if exists $ core-> {$ module};
next如果$ module =〜/^5[._\d]+/; #忽略使用MIN-PERL-VERSION
如果$ module =〜/ \ $ /; #运行时指定的模块

if(++ $ need {$ module} == 1而不是$ noRecurse {$ module}){
my $ path = findModule($ module) ;
if($ path){findDeps($ path)}
else {warn警告:找不到$ module\\\
}
}#end如果首先使用$ module
}#end foreach $ module used
}#end findDeps

#---------------------- -----------------------------------------------
sub findModule
{
我的($ module)= @_;

$ module =〜s!:: | \'!/!g;
$ module。='.pm';

foreach我的$ dir(@INC){
我的$ path = File :: Spec-> catfile($ dir,$ module);
return $ path if -f $ path;
}

return;
}#end findModule

你可以这样运行:

  perl finddeps.pl scriptToCheck.pl otherScriptToCheck.pl 

它打印运行所列脚本所需的所有非核心模块的列表。 (除非他们使用模块加载,阻止Module :: ExtractUse看到它们的花哨的技巧。)


Does anyone have any suggestions for a good approach to finding all the CPAN dependencies that might have arisen in a bespoke development project. As tends to be the case your local development environment rarely matches your live one and as you build more and more projects you tend to build up a local library of installed modules. These then lead to you not necessarily noticing that your latest project has a requirement on a non-core module. As there is generally a requirement to package the entire project up for deployment to another group (in our case our operations team), it is important to know what modules should be included in the package.

Does anyone have any insights into the problem.

Thanks

Peter

解决方案

I've had this problem myself. Devel::Modlist (as suggested by this answer) takes a dynamic approach. It reports the modules that were actually loaded during a particular run of your script. This catches modules that are loaded by any means, but it may not catch conditional requirements. That is, if you have code like this:

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

and $some_condition happens to be false, Devel::Modlist will not list Some::Module as a requirement.

I decided to use Module::ExtractUse instead. It does a static analysis, which means that it will always catch Some::Module in the above example. On the other hand, it can't do anything about code like:

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

Of course, you could use both approaches and then combine the two lists.

Anyway, here's the solution I came up with:

#! /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

You'd run this like:

perl finddeps.pl scriptToCheck.pl otherScriptToCheck.pl

It prints a list of all non-core modules necessary to run the scripts listed. (Unless they do fancy tricks with module loading that prevent Module::ExtractUse from seeing them.)

这篇关于在部署Perl项目之前,如何确定CPAN依赖关系?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆