Как использовать бета-модули Perl из бета-скриптов Perl?
Если мой Perl-код имеет местоположение производственного кода и местоположение "бета-кода" (например, производственный код Perl, мы /usr/code/scripts
, Бета-код Perl находится в /usr/code/beta/scripts
; библиотеки Perl производства находятся в /usr/code/lib/perl
и бета-версии этих библиотек находятся в /usr/code/beta/lib/perl
Есть ли простой способ для меня, чтобы добиться такой настройки?
Точные требования:
Код должен быть таким же в производстве и в бета-версии.
Чтобы прояснить, продвигать любой код (библиотеку или скрипт) из бета-версии в производство, ЕДИНСТВЕННАЯ вещь, которая должна произойти, это буквально выпуск
cp
команда от BETA до местоположения prod - и имя файла, и содержимое файла должны оставаться идентичными.BETA-версии сценариев должны вызывать другие BETA-сценарии и библиотеки BETA (если существуют) или производственные библиотеки (если библиотеки BETA не существуют)
Пути кода должны быть одинаковыми между BETA и производством, за исключением базового каталога (
/usr/code/
против/usr/code/beta/
)Все сценарии должны находиться в одном базовом каталоге, но они могут находиться в его подкаталогах на произвольном уровне глубины (это исключает классический
use lib "$FindBin::Bin/../lib"
решение из раздела 31.13. используйте lib "Programming Perl")
Я представлю, как мы решили проблему, как ответ на этот вопрос, но я хотел бы знать, есть ли лучший способ.
3 ответа
Наше собственное решение было следующим:
Есть библиотека (назовем это BetaOrProd.pm)
- Библиотека ДОЛЖНА быть включена через "
use BetaOrProd;
"в каждом сценарии - Библиотека ДОЛЖНА быть самой первой
use
утверждение в каждом сценарии после "use strict;
"Прагма (и" использовать предупреждения ", если мы используем это). Включая перед любымBEGIN
блоки. - В библиотеке есть
BEGIN
блок, который содержит большую часть логики - Тот
BEGIN
Блок в библиотеке проверяет путь к каталогу программы (от $0 с применением абсолютного пути) - Если путь к каталогу начинается с
/usr/code/beta
программа считается запущенной в бета-версии, а еще в производстве - В любом случае,
/usr/local/lib/perl
не сдвинут в начало@INC
список - Если бета-местоположение,
/usr/code/beta/lib/perl
не сдвинут в начало@INC
список после этого. - Если BETA location, специальная переменная $isBETA (доступная методом доступа, экспортированным из BetaOrProd.pm) устанавливается в "BETA".
- Библиотека ДОЛЖНА быть включена через "
Каждый раз, когда скрипту / библиотеке нужно вызвать другой скрипт, путь к вызываемому скрипту рассчитывается на основе указанного метода доступа к переменной $ isBETA, экспортированной из BetaOrProd.pm.
В любое время, когда требуется или используется библиотека Perl, никакой специальной логики не требуется -
@INC
измененный BetaOrProd.pm заботится о том, чтобы знать, откуда следует импортировать модули. Если модуль присутствует в папке BETA, то библиотека из местоположения BETA будет использоваться скриптом BETA, в противном случае библиотека из местоположения продукта.
Основными недостатками этого подхода являются:
Требование, что каждый скрипт должен иметь
use BetaOrProd;
"как самый первыйuse
утверждение в каждом сценарии после "use strict;
"Прагма.Смягчается тем фактом, что наша компания требует, чтобы каждый развернутый фрагмент кода проходил автоматический валидатор, который может проверить это требование.
Не могу BETA протестировать BetaOrProd.pm через
/usr/code/beta/lib/perl
, D'эм.Смягчается очень тщательным модулем и интеграционным тестом библиотеки
Я обращаюсь к этому с помощью FindBin:
use FindBin;
use lib "$FindBin::Bin/../lib";
Или, если активен режим taint:
use FindBin;
use lib ("$FindBin::Bin/../lib" =~ m[^(/.*)])[0];
Поскольку это не зависит от каких-либо известных или фиксированных путей, оно позволяет создавать столько независимых наборов кода на одном компьютере, сколько мне нравится, просто создавая новую копию каталога проекта.
Я сохраняю полные копии всех модулей проекта в каждом образе разработки проекта, но похоже, что вы этого не делаете, и вместо этого полагаются на то, что бета-копия возвращается к модулям живой копии; use lib /path/to/live/bin
до use lib
s выше справится с этим, или вы можете просто связать /path/to/live/bin
в один из каталогов на @INC
так что он всегда будет доступен сразу.
Если живая и бета-версия будут запускаться с разных учетных записей, возможно, стоит посмотреть и на local:: lib, но на самом деле это не то, для чего он предназначен.
ОБНОВЛЕНИЕ: Это не работает, если сами сценарии могут находиться в нескольких подкаталогах данного каталога, но работает иначе.
Мне пришлось использовать аналогичную конфигурацию. Однако модуль был назван в честь имени проекта и мог выполнять некоторые другие обязанности: загружать некоторые переменные конфигурации, относящиеся к среде (например, расположение данных, учетные данные для баз данных dev/prod), обрабатывать некоторые аргументы командной строки и устанавливать некоторые другие переменные, которые были полезны для большинства сценариев в проекте (текущая дата в формате ГГГГММДД, открыт ли в настоящее время фондовый рынок и т. д.)