Каждое приложение требует определенного уровня конфигурации. С помощью специальных языков можно создавать файлы, которые способны автоматизировать инициализацию системы. Эти файлы обычно читаются и интерпретируются только один раз. Наиболее распространенный пример — конфигурации INI Windows, которые обрабатываются с использованием API Microsoft.
Популярность конфигураций вроде INI с годами менялась. По мере развития приложений росла и сложность конфигурирования. Поэтому особенно важно правильно выбрать язык конфигураций, чтобы не усложнить жизнь себе и своему pet-проекту. Под катом рассказываем о пикулях и Pkl — новом решении от Apple.
Используйте навигацию, если не хотите читать текст полностью:
→ Зачем нужны языки конфигураций
→ Подробнее про Pkl
→ Начало работы с новым языком
→ На примерах: сравнение с другими форматами
→ Заключение
Зачем нужны языки конфигураций
Языки конфигураций обычно декларативные. Всего есть несколько решений — у каждого свои преимущества и недостатки. Например, XML, JSON, YAML и HCL в некоторой степени совместимы, но в зависимости от выбранного языка необходимы компромиссы. Или же можно использовать «языки общего назначения» (Kotlin, Ruby, JavaScript и им подобные), то есть описывать параметры системы в виде программного кода.
Последний вариант не всегда приемлем: появляются лишние зависимости, описанные конфигурации становятся «завязанными» на интерпретаторах и компиляторах. Например, если описать параметры приложения, описать их на Python и перенести в виртуальное окружение, в котором он не установлен, возникнет исключение. Даже если установить парселтанг, то появится вопрос совместимости конфигурации с «рутом», который должен еще считать.
При чем здесь пикули?
Для решения описанных проблем Apple разработала язык конфигураций Pkl (Pickle, «пикули»). Компания посчитала, что конфигурация лучше всего выражается как смесь статического языка и языка программирования.
Разработчики взяли лучшее из обоих миров — и создали язык, декларативный и простой для чтения и записи, но дополненный возможностями, заимствованными из языков общего назначения. Версия Pkl 0.25 запущена 1 февраля 2024 года и доступна в репозитории GitHub. Познакомимся с ней поближе.
Подробнее про Pkl
Pkl спроектирован на основе структуры «ключ-значение», аналогично JSON, а не на императивных инструкциях, как во многих других традиционных языках. Одним из ключевых преимуществ этого подхода является высокая совместимость с популярными форматами конфигураций, таких как JSON, XML и YAML.
Pkl использует некоторые идеи из трех других языков: Python, Kotlin и Lisp. Кроме того, может работать на любой платформе, поддерживающей эти ЯП, и беспрепятственно взаимодействовать с ними. Возможно, Pkl и означает Python-Kotlin-Lisp. А может и нет.
Pkl поддерживает как сложные типы (списки, карты, наборы и перечисления), так и примитивные (целые числа, строки, логические значения и «ноль»). Кроме того, пользователи могут выполнять проверку типов во время сборки и выполнения, а также создавать новые типы и схемы.
Pkl поддерживает песочницу, которая создает изолированное виртуальное окружения работы с кодом конфигурации. Вариант с наименьшими привилегиями, который предоставляет минимум разрешений, необходимых для задания конфигурации, также поддерживается языком.
Кроме того, с помощью Pkl можно настраивать сети, серверы, облачные службы, контейнеры и другие элементы инфраструктуры. Pkl спроектирован так, чтобы быть одновременно декларативным и простым для чтения и записи, но при этом включать в себя элементы, обычно встречающиеся в традиционных языках программирования: классы, функции, условные выражения и циклы. Это позволяет использовать разные уровни абстракции.
Также Pkl может создавать файлы статической конфигурации в распространенных форматах или встраиваться в виде библиотеки в другие среды выполнения приложений. Но это все слова, которые можно узнать и на официальном сайте. Давайте перейдем к практике.
Начало работы с новым языком
Для начала работы необходимо установить интерфейс командной строки (CLI) Pkl. Пользователи могут создавать, изменять, собирать, выполнять и тестировать файлы конфигурации Pkl с помощью интерфейса этой командной строки. Достаточно установить
На примерах: сравнение с другими форматами
Вероятно, самые популярные форматы хранения данных в удобочитаемом и машиночитаемом формате — JSON и YAML. Pkl хоть не такой известный язык, но он имеет минимальный и последовательный синтаксис, который также легко воспринимать и писать.
Плюсы
- Pkl более «выразительный», чем JSON и YAML.
- Язык поддерживает валидацию типов.
- Может работать в паре с другими языками.
Минусы
- Уступает JSON и YAML в плане поддержки — в силу своей новизны.
- Сложнее, чем JSON и YAML, потому что сочетает в себе приемы из ЯП.
Примеры
Вот несколько примеров файлов JSON, YAML и Pickle, которые определяют одни и те же данные конфигурации. Сравните, что для вас кажется более понятным, и напишите свое мнение в комментариях!
{
"name": "My application",
"port": 8080,
"database": {
"host": "localhost",
"user": "root",
"password": "password"
}
}
JSONname: My application
port: 8080
database:
host: localhost
user: root
password: password
YAMLmodule ApplicationConfig
name: String
port: UInt16
database: Database
class Database {
host: String
user: String
password: String(isBetween(8, 40))
}
applicationConfig {
name = "My application"
port = 8080
database {
host = "localhost"
user = "root"
password = "password"
}
}
PklВ примере выше определяется модуль с именем ApplicationConfig с конфигурацией верхнего уровня для приложения, включая имя и порт. Он также определяет класс базы данных, описывая параметры доступа: хост, пользователя и пароль.
Язык предоставляет экземпляр applicationConfig с фактическими значениями, соответствующими предоставленному примеру JSON. Этот подход использует возможности Pkl для определения структурированных, безопасных конфигураций. И может быть расширен за счет дополнительных проверок или функций.
Пример Pickle более «выразителен», чем JSON или YAML. Он также включает проверку, гарантирующую, что длина пароля составляет не менее восьми символов. Можно также использовать и операторы для валидации данных:
isEmpty (!isEmpty)
isBetween(a, b)
==, >, <, ≥, ≤
matches(Regex("….")
Некоторые из операторов Pkl. Больше информации — в документации.
Вот, как будет выглядеть дополнительная валидация в конфигурации:
module Person
name: String(!isEmpty)
age: Int(isBetween(0, 130))
zipCode: String(matches(Regex("\\d{5}")))
Pkl может взаимодействовать с другими языками двумя способами: «внедрением» и генерацией кода. Язык можно встроить в качестве библиотеки в Java, Kotlin, Swift, Go. Например, вот так можно загрузить файл Pkl и получить доступ к его значениям из Java и Golang:
import com.apple.pkl.Pkl;
import com.apple.pkl.PklConfig;
import com.apple.pkl.PklException;
// Загрузка Pkl-файла
PklConfig config = Pkl.load("config.pkl");
// Доступ к значению Pkl
String host = config.getString("host");
// Изменение значения Pkl
config.set("port", 8080);
// Сохранение Pkl-файла
Pkl.dump(config, "config.pkl");
import (
"context"
"github.com/apple/pkl-go"
)
// Загрузка Pkl-файла
config, err := pkl.LoadFromPath(context.Background(), "config.pkl")
if err != nil {
panic(err)
}
// Доступ к значению Pkl
host := config.GetString("host")
// Изменение значения Pkl
config.Set("port", 8080)
// Сохранение Pkl-файла
err = pkl.Dump(config, "config.pkl")
if err != nil {
panic(err)
}
Pkl поддерживает генерацию кода для Java, Kotlin, Swift и Go и может «формировать» классы, перечисления, константы и аннотации на основе значений конфигурации. Например, так можно создать класс Java из файла Pkl:
# Define a Pkl value
(def person
(dict
:name "Alice"
:age 25
:gender "female"
)
)
Generate a Java class
(pkl-codegen-java person "Person")
Сгенерированный класс Java будет выглядеть так:
public class Person {
public static final String name = "Alice";
public static final int age = 25;
public static final String gender = "female";
}
Заключение
Apple Pkl — это новый язык программирования для простой, выразительной и переносимой настройки. Его может быть полезно использовать в различных сценариях, где необходима настройка, например, приложения. Он также может взаимодействовать с другими языками путем встраивания или генерации кода. Это проект с открытым исходным кодом, который приветствует вклад каждого.
Что думаете насчет Pkl вы? Поделитесь своим мнением в комментариях!