如何找到Perl脚本的模块依赖关系?

如何找到Perl脚本的模块依赖关系?,perl,dependencies,module,cpan,Perl,Dependencies,Module,Cpan,我希望另一个开发人员运行我编写的Perl脚本。该脚本使用许多CPAN模块,在脚本运行之前必须安装这些模块。是否可以让脚本(或perlbinary)转储所有缺失模块的列表?当我试图运行脚本时,Perl会打印出缺少的模块的名称,但这是冗长的,不会一次列出所有缺少的模块。我想做一些类似的事情: $ cpan -i `said-script --list-deps` 甚至: $ list-deps said-script > required-modules # on my machine $

我希望另一个开发人员运行我编写的Perl脚本。该脚本使用许多CPAN模块,在脚本运行之前必须安装这些模块。是否可以让脚本(或
perl
binary)转储所有缺失模块的列表?当我试图运行脚本时,Perl会打印出缺少的模块的名称,但这是冗长的,不会一次列出所有缺少的模块。我想做一些类似的事情:

$ cpan -i `said-script --list-deps`
甚至:

$ list-deps said-script > required-modules # on my machine
$ cpan -i `cat required-modules` # on his machine
有简单的方法吗?这不是一个阻碍,但我想让其他开发者的生活更轻松。(所需的模块分散在几个文件中,因此我不容易手工制作列表而不遗漏任何内容。我知道,但对于我想要的内容来说,这似乎有点太复杂了。)


更新:谢谢,曼尼,就这样吧。我不知道
%INC
,我只知道
@INC
。我决定这样做:

print join("\n", map { s|/|::|g; s|\.pm$||; $_ } keys %INC);
打印出:

Moose::Meta::TypeConstraint::Registry
Moose::Meta::Role::Application::ToClass
Class::C3
List::Util
Imager::Color
…

看起来这会起作用。

您可以在脚本末尾转储
%INC
。它将包含所有已使用和必需的模块。当然,这只有在您不需要有条件地使用模块(如果$bar就需要Foo)的情况下才有帮助。

请检查并查看随附的“scandeps.pl”实用程序。编译或运行程序后,它可以对代码进行静态(和递归)分析,以确定依赖项以及%INC转储

请注意,静态源扫描总是在包含太多依赖项方面出错。(它是PAR使用的依赖扫描器,目的是在最终用户上最简单)。 最后,您可以选择将脚本作为CPAN分发版分发。这听起来比实际情况复杂得多。您可以使用类似的方法来设置暂定应用程序的基本框架::YourScript发行版。将脚本放在bin/子目录中,编辑Makefile.PL以引用所有直接依赖项。然后,对于分发,您需要执行以下操作:

  • perl Makefile.PL
  • 制造
  • 制造距离
  • 最后一步生成一个很好的App-YourScript-VERSION.tar.gz 现在,当客户机想要安装所有依赖项时,他会执行以下操作:

  • 正确设置CPAN客户端。只需运行它并回答问题。但你已经要求了
  • “tar-xz App-YourScript-VERSION.tar.gz&&cd App-YourScript-VERSION”
  • 运行“cpan”
  • CPAN客户端现在将自动安装所有直接依赖项以及这些发行版的依赖项。根据您的设置方式,它将自动递归地遵循先决条件,或者每次都以y/n提示


    例如,您可以在CPAN上查看一些App::*发行版。我认为App::Ack就是一个很好的例子。可能是以下应用之一::*来自我的CPAN目录(SMUELLER)的发行版。

    对于快速、不频繁的使用,
    %INC
    是最好的选择。如果您必须通过持续集成测试或其他更健壮的工具来实现这一点,那么还有其他一些工具可以提供帮助

    Steffen已经提到模块::ScanDeps

    中的代码可以做到这一点,但它有一个额外的层,确保Makefile.PL或Build.PL将它们作为依赖项列出。如果你做了修改,那就很容易检查新的依赖关系;只需再次运行测试套件

    除此之外,您还可以使用诸如之类的工具来解析静态代码,以查找use和require语句(尽管它在string evals中找不到它们)。这就得到了您告诉脚本要加载的模块。 此外,一旦知道加载了哪些模块,就可以将其与David Cantrell的工具结合起来,该工具已经为大多数CPAN模块创建了依赖关系树

    请注意,您还必须考虑可选功能。在本例中,您的代码没有它们,但有时您在需要模块之前不会加载模块:

    sub foo { require Bar; # don't load until we need to use it .... } sub-foo { require Bar;#在我们需要使用它之前不要加载 .... } 如果您在试运行或测试中不使用该特性,您将不会看到您需要该特性的Bar。当一个模块在不同的环境(比如mod_perl或Windows等)中加载一组不同的依赖模块时,也会出现类似的问题


    没有一种好的、自动化的方法来测试这样的可选特性,这样您就可以获得它们的依赖关系。然而,我认为这应该在我的待办事项清单上,因为这听起来像是一个有趣的问题。

    今天,我开发我的Perl应用程序,使用它可以通过插件处理依赖关系。这方面另一个有趣的代码是。

    这方面的另一个工具是Dist::Zilla及其AutoprererEqs插件使用的。它安装了一个
    scan perl prereqs
    程序,该程序将使用PPI和一些插件来搜索大多数类型的prereq声明,使用您定义的最低版本。一般来说,我建议过度扫描
    %INC
    ,这会带来虚假的需求并忽略版本。

    不,静态源代码扫描并不总是错误的,因为它包含了太多的依赖项。它也可能会错过一些东西,比如
    eval“require$module”
    ,其中
    $module
    是在运行时根据一些标准计算出来的。这比
    scandeps
    更适合我的工作流程。它只给了我故意包含的名字。(子依赖项通常不感兴趣,因为现代安装程序会为您处理它们。)