30

我希望另一个开发人员运行我编写的 Perl 脚本。该脚本使用许多 CPAN 模块,必须先安装这些模块才能运行该脚本。是否可以让脚本(或perl二进制文件)转储所有缺失模块的列表?当我尝试运行脚本时,Perl 会打印出丢失模块的名称,但这很冗长,并且不会一次列出所有丢失的模块。我想做类似的事情:

$ cpan -i `said-script --list-deps`

甚至:

$ list-deps said-script > required-modules # on my machine
$ cpan -i `cat required-modules` # on his machine

有没有简单的方法来做到这一点?这不是一个表演障碍,但我想让其他开发人员的生活更轻松。(所需的模块分散在几个文件中,因此我很难手动列出列表而不会遗漏任何内容。我知道PAR,但对于我想要的来说似乎有点太复杂了。)


更新:谢谢,曼尼,这样就可以了。我不知道%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
…

看起来这会奏效。

4

5 回答 5

27

查看Module::ScanDeps和它附带的“scandeps.pl”实用程序。它可以在编译或运行程序后对您的代码进行依赖关系以及 %INC 转储的静态(和递归)分析。

请注意,静态源扫描总是在包含太多依赖项的情况下出错。(它是 PAR 使用的依赖扫描器,旨在使最终用户最容易使用。)

最后,您可以选择将脚本作为 CPAN 分发版分发。这听起来比实际上要复杂得多。您可以使用Module::Starter之类的东西来设置暂定 App::YourScript 分发的基本框架。将您的脚本放在 bin/ 子目录中并编辑 Makefile.PL 以引用您的所有直接依赖项。然后,对于分发,您执行以下操作:

  1. perl 生成文件.PL
  2. 制作
  3. 使分布

最后一步生成一个不错的 App-YourScript-VERSION.tar.gz 现在,当客户端想要安装所有依赖项时,他执行以下操作:

  1. 正确设置 CPAN 客户端。只需运行它并回答问题。但无论如何,你已经需要了。
  2. “tar -xz App-YourScript-VERSION.tar.gz && cd App-YourScript-VERSION”
  3. 运行“cpan”。

CPAN 客户端现在将自动安装所有直接依赖项和这些发行版的依赖项。根据您的设置方式,它会自动递归地遵循先决条件,或者每次都使用 ay/n 提示。

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

于 2008-12-11T15:19:55.027 回答
21

%INC您可以在脚本末尾转储。它将包含所有使用和必需的模块。但是,当然,这只有在您没有条件地需要模块时才有用(如果 $bar 则需要 Foo)。

于 2008-12-11T10:43:10.653 回答
14

对于又快又脏、不经常使用的情况,这%INC是最好的方法。如果您必须通过持续集成测试或更健壮的东西来做到这一点,那么还有一些其他工具可以提供帮助。

Steffen 已经提到了 Module::ScanDeps。

Test::Prereq中的代码执行此操作,但它有一个附加层,可确保您的 Makefile.PL 或 Build.PL 将它们列为依赖项。如果你让你的脚本看起来像一个普通的 Perl 发行版,那么检查新的依赖关系就变得相当容易;再次运行测试套件。

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

请注意,您还必须考虑可选功能。在这种情况下,您的代码我没有它们,但有时您在需要时才加载模块:

子富
    {
    需要酒吧;# 在我们需要使用之前不要加载
    ……
    }

如果您在试运行或测试中不使用该功能,您将不会看到该功能需要 Bar。当一个模块在不同的环境(例如,mod_perl 或 Windows 等)中加载一组不同的依赖模块时,也会出现类似的问题。

没有一种很好的自动化方式来测试这样的可选功能,以便您可以获取它们的依赖关系。但是,我认为这应该在我的待办事项列表中,因为这听起来是一个有趣的问题。

于 2008-12-11T18:44:01.477 回答
7

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

于 2011-05-05T14:11:16.270 回答
2

今天,我使用Dist::Zilla将我的 Perl 应用程序开发为类似 CPAN 的发行版,它可以通过AutoPrereq插件处理依赖关系。这个领域另一个有趣的代码是carton

于 2010-05-16T11:57:38.843 回答