如果我的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推广到生产,需要发生的唯一事情就是从BETA向prod位置发出cp
命令 - 文件名AND文件内容必须保持相同。
BETA版本的脚本必须调用其他BETA脚本和BETA库(如果存在)或生产库(如果BETA库不存在)
BETA和制作之间的代码路径必须相同,但基目录除外(/usr/code/
vs /usr/code/beta/
)
这些脚本必须全部位于相同的基本目录下,但它们可能位于任意深度级别的子目录中(这排除了<\ n1}中的经典use lib "$FindBin::Bin/../lib"
解决方案strong> 31.13。使用“Programming Perl”的 )
我将介绍我们如何解决问题作为这个问题的答案,但我想知道是否有更好的方法。
答案 0 :(得分:2)
我们自己的解决方案如下:
拥有一个库(我们称之为BetaOrProd.pm)
use BetaOrProd;
”加入
use
”编译指示之后每个脚本中的第一个use strict;
语句(如果我们使用它,则使用“使用警告”)。包括在任何BEGIN
块之前。BEGIN
块,其中包含大部分逻辑BEGIN
块检查程序的目录路径(基于$ 0并且应用了绝对路径)/usr/code/beta
开头,则认为该程序在BETA位置运行,否则在生产中运行/usr/local/lib/perl
都未移至@INC
列表/usr/code/beta/lib/perl
在此之后未被转移到@INC
列表的开头。每当脚本/库需要调用另一个脚本时,调用脚本的路径将根据从BetaOrProd.pm导出的$ isBETA变量的所述访问者计算
无论何时需要或使用Perl库,都不需要特殊的逻辑 - 由BetaOrProd.pm修改的@INC
负责了解模块的导入位置。如果该模块位于BETA位置,则BETA位置的库将由BETA脚本使用,否则来自prod位置的库。
这种方法的主要缺点是:
要求每个脚本必须具有“use BetaOrProd;
”作为“use
”pragma之后的每个脚本中的第一个use strict;
语句。< / p>
由于我们公司要求每个部署的代码都通过自动验证器,这可以检查此要求。
BETA无法通过/usr/code/beta/lib/perl
测试BetaOrProd.pm。 D'呃。
通过库的非常彻底的单元和集成测试来缓解
答案 1 :(得分:2)
我用FindBin解决了这个问题:
use FindBin;
use lib "$FindBin::Bin/../lib";
或者,如果污染模式处于活动状态:
use FindBin;
use lib ("$FindBin::Bin/../lib" =~ m[^(/.*)])[0];
由于这不依赖于任何已知路径或固定路径,因此只需创建项目目录的新副本,即可在单个机器上使用尽可能多的独立代码集。
我在项目的每个开发图像中都保留了所有项目模块的完整副本,但听起来你不这样做,而是依靠beta副本回到实时副本的模块;上面use lib /path/to/live/bin
之前的use lib
会处理该问题,或者您只需将/path/to/live/bin
链接到@INC
上的某个目录中,这样它就会立即可用
如果实时和测试版本将从不同的帐户运行,local::lib也可能值得一看,但这似乎并不是它的目的。
更新:如果脚本本身可能存在于给定目录的多个子目录中,则不起作用,但不起作用。
答案 2 :(得分:0)
我不得不使用类似的配置。该模块以项目名称命名,并且可以执行其他一些任务:加载一些特定于环境的配置变量(例如,数据的位置,dev / prod数据库的凭证),处理一些命令行参数以及设置一些其他变量对项目中的大多数脚本都有用(YYYYMMDD格式的当前日期,股票市场当前是否开放等)。