Easy Dune (OCaml): Запуск сценария

В dune, системе сборки OCaml, есть много интересного. Вероятно, она может делать то, что вы хотите, но документация — хотя и подробная — никогда не утруждает себя объяснением того, как выполнять общие задачи так, чтобы это было полезно занятому разработчику.

Это «как» запустить скрипт с помощью dune. В конце вы сможете инициировать выполнение произвольной программы с помощью dune для выполнения полезной задачи для вашей базы кода. Подумайте о "scripts" в package.json, или о цели .PHONY в Makefile. Например, вы можете запустить CLI для генерации кода, например tailwindcss, или отправить артефакты сборки в S3 с помощью aws CLI-вызова. Мы будем называть такие вещи «скриптами», как и в проекте node/JavaScript.

Предположения

  • Вы знаете, как работать с терминалом и основными командами оболочки POSIX
  • У вас есть рабочая установка dune версии 3:
$ dune --version
3.4.1
Вход в полноэкранный режим Выход из полноэкранного режима

С нуля

Если у вас уже есть проект dune, найдите файл dune, в котором вы хотите определить команду, измените директорию на эту папку и перейдите к дальнейшим действиям.

Создание файла dune

Сценарии определяются в файле с именем dune в корне вашего проекта (или библиотеки, или исполняемого файла). В Dune есть набор команд init, помогающих создать этот файл, но они создают много лишнего шума, поэтому давайте сделаем минимальную настройку вручную:

$ mkdir run_task && cd run_task
$ touch dune
$ echo "(lang dune 3.3)" > dune-project
Войти в полноэкранный режим Выйдите из полноэкранного режима

На этом этапе вы должны быть в состоянии запустить:

$ dune build
Войти в полноэкранный режим Выйти из полноэкранного режима

При этом не возникнет ошибки, а появится новая папка _build, что подтверждает, что мы готовы к работе:

.
├── _build
│   ├── default
│   └── log
├── dune
└── dune-project
Войти в полноэкранный режим Выход из полноэкранного режима

Настройка Dune с помощью S-Expressions

Давайте быстро рассмотрим одну из приведенных выше команд:

$ echo "(lang dune 3.3)" > dune-project
Войти в полноэкранный режим Выход из полноэкранного режима

Возможно, вам интересно, что означает lang dune 3.3 и почему оно заключено в круглые скобки. Это называется S-выражением, и, подобно JSON, YAML или TOML, является языком, который можно использовать, помимо прочего, для файлов конфигурации. В отличие от последних форматов, S-выражения не часто встречаются за пределами OCaml, но они являются обычным способом сериализации данных в OCaml, подобно тому, как JSON является обычным способом сериализации данных в JavaScript.

Возможно, вы сочтете это странным выбором для инструмента программирования и языка, который надеется привлечь новых пользователей (я считаю именно так). Но независимо от этого, именно так мы будем «программировать» dune, чтобы она делала то, что мы хотим.

К счастью, вам не нужно много знать о s-выражениях, чтобы сделать то, что нам нужно. Пока что вы можете думать о них как об именованных вложенных массивах:

(key value value (subkey value))
Вход в полноэкранный режим Выйти из полноэкранного режима

Вот воображаемый пример:

(package (name my-package)(version 1.0))
(dependencies lib-1 lib-2 lib-3 (testing-only tool-a tool-b)(development-only lib-a))
Вход в полноэкранный режим Выход из полноэкранного режима

Хитрость заключается в том, чтобы знать, какие key являются значимыми для dune, и как dune реагирует на различные значения этих ключей, подобно тому, как в проекте npm вам нужно знать, что ключ package.json "files" требует массив шаблонов файлов в качестве значения.

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

(package 
  (name my-package)
  (version 1.0))

(dependencies 
    lib-1 
    lib-2
    lib-3 
    (testing-only tool-a tool-b)
    (development-only lib-a))
Войти в полноэкранный режим Выйти из полноэкранного режима

Добавление сценария: Правила

Вы определяете сценарий в проекте дюны как правило.

Простое правило

Пока что скопируйте это базовое правило «hello world» в свой файл dune и сохраните его:

(rule
  (alias helloworld)
  (deps (universe))
  (action (run echo "Hello World!")))
Войти в полноэкранный режим Выйти из полноэкранного режима

Если у вас уже есть записи в файле dune, добавьте это правило ниже всех остальных, без вложенности.

Теперь вы должны иметь возможность запускать:

$ dune build @helloworld
Hello World!
Войти в полноэкранный режим Выйти из полноэкранного режима

Потрясающе! Мы прошли 90% пути для вызова простых скриптов.

Понимание простых правил

Псевдонимы

У каждого правила может быть псевдоним, который вы вызываете командой build, добавляя к нему префикс @.

Обратите внимание, что в dune можно назначать псевдонимы многим вещам, например, набору зависимостей. Будьте осторожны, когда ссылаетесь на документацию!

Действие

Действие — это команда, которую dune выполняет для удовлетворения правила. Основной синтаксис показан выше, но существует внутренний язык, который может быть довольно сложным. И вы всегда можете использовать простой синтаксис для вызова небольшой программы для выполнения любой более сложной задачи сборки! Например, если вам очень нравятся S-выражения, вы можете написать несколько сумасшедших shell-скриптов с помощью библиотеки shexp.

Другие распространенные действия:

Зависимости

В отличие от скриптов в экосистеме npm, rules в dune имеют зависимости, которые отслеживаются dune, чтобы избежать лишней работы.

Чтобы проиллюстрировать это, удалите эту строку из примера «hello world», приведенного выше:

 (rule
   (alias helloworld)
-  (deps (universe))
   (action (run echo "Hello World!")))
Войти в полноэкранный режим Выйти из полноэкранного режима

И попробуйте запустить dune build @helloworld дважды. Вы заметите, что она работает так, как вы ожидаете, один раз, а затем перестает работать:

$ dune build @helloworld
Hello World!
$ dune build @helloworld
$ # Huh? No echo?
Войти в полноэкранный режим Выход из полноэкранного режима

Это потому, что без определения deps как universe, dune знает, что с момента последнего запуска команды @helloworld build… ничего не изменилось! И поэтому dune не делает то, что считает ненужной работой, и не запускает команду, которую мы определили во второй раз.

Это особенно эффективно для таких задач, как генерация кода, где, если ни один из входных файлов не изменился, мы можем не тратить время на создание артефактов сборки.

Вы можете ознакомиться с полной спецификацией определения зависимостей, чтобы поэкспериментировать, но пока знайте, что (deps (universe)) будет действовать аналогично скрипту npm или цели .PHONY и выполняться каждый раз, когда его вызывают.

Слон в комнате: Цели

Мы еще не рассмотрели одну важную концепцию: (target ...) настройки правила. Цели — это любые файлы, которые вы создаете с помощью правила, и они позволяют вам делать более сложные вещи с dune. Хорошей новостью является то, что если вы не хотите или не нуждаетесь в более продвинутых возможностях dune, вы можете игнорировать эту часть конфигурации.

Например, приведенная выше команда — это всего лишь эфемерный побочный эффект, поэтому в ней нет смысла. Однако обратите внимание, что dune на самом деле определяет ваши цели для определенных действий, поэтому последствия настройки цели могут проявиться, даже если вы не зададите ее в явном виде. В большинстве случаев все будет «просто работать». Но если вы углубитесь в создание собственных правил и увидите странное поведение или ошибки при упоминании целей, я бы рекомендовал прочитать о них.


Резюме

  • Запуск произвольных задач в ваших проектах («скриптов»), называется dune «правилом».
  • Правила записываются в файл dune в виде S-выражений.
  • Правила имеют имена, называемые «псевдонимами».
  • Правила имеют зависимости (и не будут выполняться, если зависимости не изменились с момента последнего вызова правила).
  • Правила имеют действия, которые определяют команду, выполняемую для выполнения правила.
  • Правила можно вызвать, выполнив команду dune build @ с последующим псевдонимом, например dune build @tailwind.

Оцените статью
devanswers.ru
Добавить комментарий