Как использовать сценарий оболочки для Raku CLI

Мне интересно, какие шаги (например, строки shebang и сценарии оболочки) рекомендуются при создании приложения CLI в Raku. Меня интересует информация как о скриптах, которые будут установлены вместе с Zef, так и о тех, которые будут распространяться отдельно.

В документации приведен пример программы:

      # inside "frobnicate.raku" 
sub MAIN(Str $file where *.IO.f, Int  :$length = 24, Bool :$verbose) { #`(body omitted)}

с которым я мог работать raku frobnicate.raku - прекрасное решение для скриптов, но не очень хорошее для реальной программы.

Если я хочу, чтобы это была немного более стандартная программа, я мог бы создать такой файл:

      #!/usr/bin/env raku
sub MAIN(Str $file where *.IO.f, Int  :$length = 24, Bool :$verbose) { #`(body omitted)}

Я могу сделать этот файл исполняемым с помощью chmod +x и переместите его в каталог в моем $PATH; тогда я могу заморозить команду. Пока все это имеет смысл и ничем не отличается от любого другого языка сценариев.

Однако ничто из этого не использует компиляцию Раку. В результате приложения CLI, которые выполняют больше обработки в MAIN может немного замедлиться (даже для генерации --helpвыход). Итак, следующий шаг - разрешить предварительное заполнение приложения, но я не совсем уверен, как это сделать.

С Зефом

Когда я смотрю на сценарии, которые я выполняю после установки программы Raku с Zef, почти все они имеют вид:

      #!/usr/bin/env perl6
sub MAIN(:$name, :$auth, :$ver, *@, *%) {
    CompUnit::RepositoryRegistry.run-script("frobnicate", :$name, :$auth, :$ver);
}

И, когда я проверяю исходный код пакета, это CompUnit::RepositoryRegistry.run-scriptлинии нет. Полагаю, Зеф добавляет это? Если да, нужно ли мне что-нибудь сделать при написании сценария, чтобы убедиться, что Zef будет использовать эту оболочку и что она будет работать?

(Этот комментарий был полезен для понимания происходящего, хотя я все еще не уверен, что понимаю его на 100%).

Без Зеф

Я хотел бы написать сценарии, которые пользователи могут запускать без необходимости устанавливать их через Zef (хотя это был бы мой рекомендуемый метод установки). Есть ли способ использовать run-scriptпоказанный выше метод без Zef? Или я должен сделать что-то вроде следующего, что я тоже видел:

      #!/usr/bin/env raku
use Frobnicate::CLI

(А затем переместите фактическую функциональность в файл).

Если я пойду по этому пути, мне нужно будет проинструктировать пользователей загрузить как сценарий оболочки, указанный выше, так и файл, верно? (То есть нет возможности сделать это в одном файле, не так ли?)

Предполагая, что мне действительно нужно, чтобы мои пользователи загрузили два файла, где я могу их установить? нужно зайти в их каталог, но как насчет Frobnicate/CLI.rakumod? Нужно ли его копировать в их путь поиска модуля Raku (и если да, то какая команда покажет им, что это за путь)? Или я могу изменить frobnicate оболочка каким-то образом (возможно, изменив raku к raku -Ilib или что-то в этом роде?) таким образом, чтобы они могли установить оба в каталог на своих PATH?

После того, как я напечатал все это, мне кажется, возможно, что я сильно над этим задумываюсь. Если да, то дайте мне знать! В любом случае, я был бы рад добавить еще несколько деталей в соответствующий раздел документации, если я немного лучше пойму это.

2 ответа

Полагаю, Зеф добавляет это?

CompUnit::Repository:: Установка добавляет его

Почему это там? Одна из причин заключается в том, что некоторая оболочка должна управлять сценариями bin с одинаковыми именами, которые в противном случае конфликтуют, если бы они находились в одном каталоге.

Есть ли способ использовать метод запуска сценария, показанный выше, без Zef?

run-script предназначен только для CompUnit::Repository::Installation - если вы не устанавливаете модуль, тогда run-script не будет интересно

Предполагая, что мне действительно нужно, чтобы мои пользователи загрузили два файла, где я могу их установить?

Что ж, рекомендуемый / идиоматический способ - использовать базовую функциональность raku для установки вещей (т.е. использовать zef). В противном случае, где вы должны поместить какой-либо код, либо а) не будет иметь значения, либо б) будет в основном зависеть от вашей среды, что является идиоматическим для вашей ОС и т. Д.

Нужно ли его копировать в их путь поиска модуля Raku (и, если да, то какая команда покажет им, что это за путь)

echo $RAKULIBдолжно хватить для отображения пути поиска модуля в большинстве случаев, особенно если их не интересует, где находятся пути установки. Таким образом, вы можете дать пользователям указание установить, например, RAKULIB=$FROB_LIB_DIR чтобы указать, где бы вы ни находились, если вы хотите, чтобы они могли запускать ваш скрипт, не указывая его вручную через raku -I../ frobnicate(поэтому они не копируют код в специальном месте, они просто указывают туда, где они, например, клонируют ваше репо). То же и для работы с.

Или я могу каким-то образом изменить оболочку frobnicate (возможно, изменив raku на raku -Ilib или что-то в этом роде?) Таким образом, чтобы они могли установить оба в каталог на их PATH?

Я бы посоветовал не устанавливать вещи, основанные на некоторой стоимости. Поручите пользователям установить, не устанавливайте ничего $PATH.

Технически вы могли бы добавить use lib '../' в ваш сценарий, но используя use lib в сценарии, который вы также хотите, чтобы пользователи установили, обычно не идеален, поскольку он добавляет неиспользуемый, потенциально поддающийся захвату путь поиска модуля при запуске из такой установки.

Если вы хотите, чтобы ваш код был предварительно скомпилирован, я предлагаю поместить его в модуль и проинструктировать ваших пользователей, что, если они не собираются его устанавливать, вызывать его через raku -I../ ./frobnicate на основе использования или что-то вроде export RAKULIB="$FROB_LIB_DIR,$RAKULIB" с последующим ./frobnicateдля чего-то более постоянного. В качестве альтернативы, если кто-то даже реализует предварительную компиляцию скриптов, вы можете просто использовать подход одного файла.

Некоторые комментарии по этой теме.

а) Я думаю, что это оптимально для использования, потому что также будут загружаться зависимости. Уже сейчас необычно иметь возможность писать программу на Raku без использования других модулей, и я ожидал бы, что это станет еще более необычным по мере разработки большего количества модулей Raku.

б) Я забываю, какие модули я установил в своей системе и включил в программу. Указав все в, а затем запустив zef test ., шанс убедиться, что кто-то еще может загрузить модуль, повышается. На самом деле, я нашел лучший способ убедиться в этом - создать файл докера и попытаться установить новый модуль в образ / контейнер докера, но это уже другая тема.

c) Я обнаружил (для Linux, и я не могу комментировать Windows), что если я:

  • напишите исполняемый файл в Raku (см. ниже), позвольте ему называть,
  • поместите это в <distribution>/bin папка,
  • дать ему разрешение (а) + x, и
  • укажите его в корневом файле дистрибутива
  • (опубликовать раздачу)

затем при установке дистрибутива будет работать в командной строке (при условии, что zef сам работает в командной строке, подразумевая, что PATH содержит каталог для zef).

c) Оптимальный (для меня) способ вызова программы, предназначенной для использования в командной строке или запускаемой с рабочего стола, следующий:

  • поместите в файл следующее (расширение не требуется)
      use v6.d;
use MyWonderLife;
  • поместите всю функциональность в
  • убедитесь, что есть хотя бы один sub MAIN в MyWonderLife.rakumod
  • уточнить MyWonderLife в файле (что дает большую гибкость в выборе каталога, в который вы можете поместить фактический MyWonderLife.rakummodфайл под; это не должно быть lib/)
  • создать простой тест t/basic.rakutest для раздачи, только с тестом use-ok 'MyWonderLife;

Этот рецепт означает, что все функциональные возможности предварительно скомпилированы zef, поэтому, когда исполняемый файл вызывается пользователем, ответ происходит гораздо быстрее. Самая медленная часть при использовании Raku - это компиляция программы. При установке с помощью zef это делается один раз во время установки. Программы на всех языках устанавливаются медленно, поэтому программа Raku не заставляет пользователя задаваться вопросом, что происходит в момент ее использования.

Во-вторых, можно использовать несколько multi sub MAINдля обработки различных ситуаций вызова и использования диапазона параметров командной строки, которые теперь можно обрабатывать. Хотя это, очевидно, возможно в любом сценарии, поместив их все в .rakumod файл кажется (мне) более естественным.

Я обнаружил, что при установке модулей сложно наблюдать за обширными тестами, поэтому я начал переносить большую часть тестирования разработки и обслуживания на xt/ и только простые тесты установки в t/.

Наконец, с помощью этого рецепта (и при условии, что вы дали дистрибутиву имя MyWonderLife в META6.json файл, инструкция по установке для MyWonder, предполагая, что можно вызвать программу без аргументов, просто:

Используйте zef для установки MyWonderLife, например,

      zef install MyWonderLife

и используйте его в командной строке следующим образом:

      MyWonder
Другие вопросы по тегам