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