5

如果我的 Perl 代码有一个生产代码位置和“beta”代码位置(例如生产 Perl 代码我们在/usr/code/scripts,BETA Perl 代码在/usr/code/beta/scripts;生产 Perl 库在/usr/code/lib/perl并且这些库的 BETA 版本在/usr/code/beta/lib/perl,对我来说有一个简单的方法吗?实现这样的设置?

确切的要求是:

  • 该代码在生产和 BETA 位置中必须相同。

    澄清一下,要将任何代码(库或脚本)从 BETA 升级到生产,唯一需要发生的事情就是cp从 BETA 向 prod 位置发出命令——文件名和文件内容都必须保持相同

  • BETA 版本的脚本必须调用其他 BETA 脚本和 BETA 库(如果存在)或生产库(如果 BETA 库不存在)

  • BETA 和生产环境之间的代码路径必须相同,但基目录 ( /usr/code/vs /usr/code/beta/) 除外

  • 脚本必须全部位于同一个基目录下,但它们可能位于任意深度级别的子目录中(这排除了use lib "$FindBin::Bin/../lib"第 31.13 节中的经典解决方案。使用"Programming Perl"lib

我将介绍我们如何解决这个问题作为这个问题的答案,但我想知道是否有更好的方法。

4

3 回答 3

2

我用FindBin解决这个问题:

use FindBin;
use lib "$FindBin::Bin/../lib";

或者,如果污点模式处于活动状态:

use FindBin;
use lib ("$FindBin::Bin/../lib" =~ m[^(/.*)])[0];

由于这不依赖于任何已知的或固定的路径,它允许在一台机器上尽可能多的独立代码集,只需创建项目目录的新副本即可。

我在项目的每个开发映像中维护所有项目模块的完整副本,但听起来你没有,而是依靠测试版副本回退到实时副本的模块;use lib /path/to/live/bin上面 s之前的ause lib将处理该问题,或者您可以链接/path/to/live/bin到其中一个目录,@INC以便它始终可以立即使用。

如果 live 和 beta 版本将从不同的帐户运行,local::lib可能也值得一看,但这似乎并不是它的意图。

更新:如果脚本本身可能存在于给定目录的多个子目录中,这将不起作用,但在其他情况下起作用。

于 2010-03-19T10:59:08.377 回答
2

我们自己的解决方案如下:

  • 拥有一个库(我们称之为 BetaOrProd.pm)

    • 该库必须通过“ use BetaOrProd;”包含在每个脚本中
    • 该库必须是use每个脚本中“” pragma 之后的第一个语句use strict;(如果我们使用它,则“使用警告”)。包括在任何BEGIN块之前。
    • 该库有一个BEGIN包含大部分逻辑的块
    • 库中的那个BEGIN块检查程序的目录路径(基于 $0 应用绝对路径)
    • 如果目录路径以 开头/usr/code/beta,则程序被视为在 BETA 位置运行,否则在生产环境中运行
    • 在任何一种情况下,/usr/local/lib/perl都不会移动到@INC列表的开头
    • 如果 BETA 位置,/usr/code/beta/lib/perl则在此之后未移动到@INC列表的开头。
    • 如果是 BETA 位置,则将一个特殊变量 $isBETA(可通过从 BetaOrProd.pm 导出的访问器方法访问)设置为“BETA”。
  • 每当脚本/库需要调用另一个脚本时,被调用脚本的路径是根据从 BetaOrProd.pm 导出的 $isBETA 变量的所述访问器计算的

  • 任何时候需要或使用 Perl 库,都不需要特殊的逻辑 -@INC由 BetaOrProd.pm 修改的内容负责知道从哪里导入模块。如果模块存在于 BETA 位置,则来自 BETA 位置的库将由 BETA 脚本使用,否则来自 prod 位置的库。

这种方法的主要缺点是:

  1. 要求每个脚本必须将“ use BetaOrProd;”作为每个脚本中“ ”编译指示之后的第一个use语句。use strict;

    由于我们公司要求每段部署的代码都通过自动验证器,该验证器可以检查此要求,这一事实有所缓解。

  2. 无法通过 BETA 测试 BetaOrProd.pm /usr/code/beta/lib/perl。呃。

    通过对库进行非常彻底的单元和集成测试来缓解

于 2010-03-19T02:26:46.453 回答
0

我不得不使用类似的配置。但是,该模块以项目名称命名,并且可以执行一些其他任务:加载一些特定于环境的配置变量(例如数据位置、开发/生产数据库的凭据)、处理一些命令行参数和设置对项目中的大多数脚本有用的其他一些变量(YYYYMMDD 格式的当前日期,股票市场当前是否开放等)

于 2010-03-19T04:56:56.077 回答