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