Как использовать бета-модули 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, будь то фондовый рынок в настоящее время открыт и т.д.)