JSON, YAML, TOML, HCL - за последние годы человечество успело изобрести десяток языков для конфигурации.
Каждый обещал быть "простым", "удобным" и "читаемым человеком".
Но по факту - все они страдают от одних и тех же проблем: шумный синтаксис, хрупкие отступы, бесконечные кавычки и отсутствие элементарных возможностей вроде модульности и слияния конфигов.
Пора перестать с этим мириться и сделать конфигурации наконец человеческими.
🛑 Перестаньте
-
утомлять глаза, пытаясь разобраться в тонне бесполезных кавычек
-
утомлять глаза, пытаясь распознать в каком месте есть проблема с отступом
-
писать велосипед, когда в очередной раз нужно мержить конфиги для разных окружений
-
писать велосипед, когда нужно парсить env переменные в структуру конфига
-
забивать , пытаясь разобраться в огромной конфигурации из-за отсутствия модульности
⁉️ Как перестать?
Использовать адекватный язык для конфигурации ATMC
ATMC - минималистичный, но мощный язык конфигурации, созданный для удобного описания системных настроек.
Он сочетает простоту синтаксиса, поддержку импортов, переопределений, гибкого слияния конфигов и переменные окружения.
💎 Почему ATMC?
-
топовый синтаксис
-
супер минималистичный
-
интуитивно понятный и простой
-
не перегружен конструкциями
-
не зависит от отступов, переносов, кавычек, запятых и прочей чепухи
-
очень простой и в то же время достаточно мощный
-
-
модульность
-
можно импортировать разные кусочки (модули) конфига
-
очень минималистичный синтаксис импорта
-
можно обращаться к вложенным полям импортированного конфига
-
-
слияние конфигов (киллер фича)
-
супер легко мерджить несколько конфигов (например, common + stg или prod)
-
есть возможность переопределять поля
-
умное слияние - рекурсивное - не перетирает поле полностью
-
-
встраивание
-
можно встраивать объекты и массивы с помощью spread (...) оператора
-
с помощью него же и происходит слияние
-
-
доступ к env переменным
-
$YOUR_ENV_VARIABLE
-
-
поддержка всех необходимых типов
-
int
-
float
-
string
-
bool
-
object
-
array
-
-
компиляция в структуру и мапу из коробки
-
поддержка комментариев
-
расширяемость:
-
можно получить итоговый AST со всеми резовленными значениями
-
можно сделать на этой основе компилятор во что угодно
-
в перспективе можно поддержать LSP
-
💡 Примеры использования
Простой пример
📄File: config.atmc
{
logging: {
level: ["warn", "error"]
}
database: {
clickhouse: {
username: "username"
password: "password"
port: 9000
}
}
}
Пример с импортом
📄File: config.atmc
db ./database.atmc // Супер минималистичный импорт
{
logging: {
level: ["warn", "error"]
}
database: db // Тут появится объект из импортированного файла
}
📄File: database.atmc
{
clickhouse: {
username: "username"
password: "password"
port: 9000
}
}
Пример с spread + env
📄File: config.atmc
db ./database.atmc
{
logging: {
level: ["warn", "error"]
}
database: {
postgres: {
username: $POSTGRES_USERNAME // Будет подставленно значение из env
password: $POSTGRES_PASSWORD
}
db... // Сюда встроится импортированный конфиг
}
}
📄File: database.atmc
{
clickhouse: {
username: "username"
password: "password"
port: 9000
}
}
Пример с доступом к вложенному полю
📄File: config.atmc
db ./database.atmc
{
logging: {
level: ["warn", "error"]
}
database: {
postgres: {
username: $POSTGRES_USERNAME // Будет подставленно значение из env
password: $POSTGRES_PASSWORD
}
clickhouse: db.clickhouse // Сюда будет встроен вложенный в db объект
}
}
📄File: database.atmc
{
clickhouse: {
username: "username"
password: "password"
port: 9000
}
}
Пример со слиянием
📄File: common.atmc
{
logging: {
level: ["error"]
}
database: {
postgres: {
username: $POSTGRES_USERNAME
password: $POSTGRES_PASSWORD
host: "localhost"
port: 5432
}
}
}
📄File: prod.atmc - конфиг для prod окружения
common ./common.atmc
{
common... // Встраивается общий конфиг
// Далее добавляются новые параметры и переопределяются параметры из общего конфига
logging: {
level: ["warn", "error"] // Переопределяется
enable_tracing: true // Добавляется новое поле
}
database: {
postgres: {
port: 6432 // Переопределяется только порт, остальные поля не будут затронуты
}
}
}
📄File: stage.atmc - конфиг для stage окружения
common ./common.atmc
{
common... // Встраивается общий конфиг
// Далее добавляются новые параметры и переопределяются параметры из общего конфига
logging: {
// Переопределяется - можно без запятых
level: [
"info"
"warn"
"error"
]
}
}
⚙️ Что под капотом?
Язык конфигурации работает благодаря множеству компонентов:
-
lexer
-
преобразует код в токены
-
-
parser
-
преобразует токены в AST
-
-
analyzer
-
проверяет семантику в рамках одного AST
-
проверяет наличие неиспользованных переменных
-
проверяет использование неопределенных переменных
-
-
linker
-
резолвит значения переменных из всех связанных AST
-
резолвит значения переменных среды
-
выдает один итоговый AST
-
-
processor
-
получает на вход путь до файла с конфигом
-
запускает все необходимые компоненты для обработки всех связанных файлов
-
отдает полученный итоговый AST после линковки
-
-
compiler
-
компилирует итоговый AST
-
компиляторы могут быть разными (в map, в struct и т.д.)
-
🧩 Поддержка и интеграция
Язык написан пока только на Go, соответственно работает только для этого языка программирования.
В дальнейшем планируется поддержка других платформ
🔮 В планах
-
компиляция в самого себя
-
будет удобно смотреть итоговый конфиг
-
можно будет выводить итоговый конфиг, как это делает, например,
nginx -T
-
-
кодогенерация структур на базе конфига
-
тогда описывать конфиг придется только в одном месте - в atmc файле
-
-
автоматическая загрузка env переменных из .env файла
-
сейчас такого нет - нужно будет самим загружать, чтобы они стали доступны в os.Getenv
-
но будет удобно, если добавить
-
-
подсветка синтаксиса
-
имплементация LSP
-
умная подсветка синтаксиса
-
подсказки
-
поиск определений и помощь в импортах
-
P.S. Знаю, что уже есть похожие языки, но у всех есть свои недостатки. Где-то приятный синтаксис, но нет модульности; где-то есть модульность, но нет слияния; а где-то есть всё, но язык излишне усложнён. В ATMC есть всё нужное - и ничего лишнего.
Моя цель - сделать конфигурации такими же простыми, как Go-код: предсказуемыми, читаемыми и расширяемыми.
👉 Репозиторий и примеры: https://github.com/atmxlab/atmc
Автор: supermetrolog
