Apple опубликовал Pkl, язык программирования для определения конфигурации

Новости мира unix. Хотите узнать секрет вечного счастья? Откройте страницу 246.
Ответить
acolyte
Аватара пользователя
Сообщения: 3252
Зарегистрирован: 20.08.2022

#

Apple опубликовал Pkl, язык программирования для определения конфигурации
Дата публикации:Sun, 04 Feb 2024 14:39:00 +0300




Компания Apple открыла реализацию языка программирования Pkl, предназначенного для определения конфигурации и продвигающего модель "конфигурация как код". Связанный с Pkl инструментарий написан на Kotlin и опубликован под лицензией Apache. Плагины для работы с кодом на языке Pkl подготовлены для сред разработки IntelliJ, Visual Studio Code и Neovim. В ближайшее время ожидается публикация обработчика LSP (Language Server Protocol).




Pkl сочетает свойства простого для восприятия декларативного языка c расширенными возможностями, свойственными для языков общего назначения. В языке поддерживаются аннотации типов, классы, функции, вычислительные выражения, условия и циклы. Pkl может применяться как для генерации статических конфигураций в разных форматах, таких как JSON, YAML и XML, так для формирования модулей для обработки заданных форматов конфигурации в приложениях на различных языках программирования.



Привязки для интеграции Pkl в приложения подготовлены для Java, Kotlin, Go и Swift. Отдельно предложен модуль для интеграции с фреймворком Spring. Привязки позволяют на основе конфигурации на языке Pkl сформировать готовые пакеты и модули с классами для работы с описанной конфигурацией в приложении. Пакеты с описанием конфигурации могут публиковаться в репозиториях и импортироваться в качестве зависимости, что допускает совместное использование кода Pkl между разными проектами.






Язык предоставляет гибкие средства для определения условий и проверок корректности значений, позволяющих выявлять ошибки в итоговой конфигурации на этапе до её применения в приложении. Например, можно определить допустимый диапазон значений ("port: Int(this > 1000)" или "age: Int(isBetween(0, 130))"), обязательность или необязательность заполнения и формат ("zipCode: String(matches(Regex("\\d{5}")))"). В случае присвоения значения, не соответствующего условию, валидатор выведет ошибку (например, при попытке присвоить значение 1001 параметру, определённому как "Int(this > 1000)").







Например, на языке Pkl можно написать модуль Application.pkl с шаблоном конфигурации подключения к СУБД:

module Application

hostname: String
port: UInt16
environment: Environment
database: Database

class Database {
username: String
password: String
host: String
port: UInt16
dbName: String
}
typealias Environment = "dev"|"qa"|"prod"




Далее можно создать непосредственно файл конфигурации, использующий данный модуль для проверки корректности значений:

amends "Application.pkl"
hostname = "localhost"
port = 3599
environment = "dev"
database {
host = "localhost"
port = 5786
username = "admin"
password = read("env:DATABASE_PASSWORD")
dbName = "myapp"
}



А также написать генератор для автоматизации изменения номера порта для четырёх разных СУБД:

import "Application.pkl"

hidden db: Application.Database = new {
host = "localhost"
username = "admin"
password = read("env:DATABASE_PASSWORD")
dbName = "myapp"
}

sidecars {
for (offset in List(0, 1, 2, 3)) {
(db) {
port = 6000 + offset
}
}
}




При желании можно экспортировать конфигурацию в другом формате, например, YAML:

sidecars:
- username: admin
password: hunter2
host: localhost
port: 6000
dbName: myapp
- username: admin
password: hunter2
host: localhost
port: 6001
dbName: myapp
- username: admin
password: hunter2
host: localhost
port: 6002
dbName: myapp
- username: admin
password: hunter2
host: localhost
port: 6003
dbName: myapp



Схема конфигурации на языке Pkl также может быть преобразована в классы или структуры для встраивания в код приложения. Например, можно сгенерировать привязку для Kotlin:

import kotlin.Int
import kotlin.Long
import kotlin.String

data class Application(
val hostname: String,
val port: Int,
val environment: Environment,
val database: Database
) {

data class Database(
val username: String,
val password: String,
val host: String,
val port: Int,
val dbName: String
)

enum class Environment(
val value: String
) {
DEV("dev"),
QA("qa"),
PROD("prod");
override fun toString() = value
}
}


Новость позаимствована с opennet.ru
Ссылка на оригинал: https://www.opennet.ru/opennews/art.shtml?num=60549

Жизнь за Нер'зула!

Ответить