Skip to content

RFC-015: Дизайн системы конфигурации YaoXiang

Дата принятия: 2026-02-15

Предшествующий RFC: RFC-014: Дизайн системы управления пакетами

Аннотация

Разработка унифицированной системы конфигурации для языка YaoXiang с двумя уровнями: пользовательским и проектным, обеспечивающей общую инфраструктуру конфигурации для менеджера пакетов, компилятора, REPL, LSP и других компонентов.

Мотивация

Зачем нужна эта возможность/изменение?

Инструментарий YaoXiang включает несколько компонентов:

  • Менеджер пакетов (читает зависимости)
  • Интерфейсный компилятор (читает i18n конфигурацию)
  • REPL (читает интерактивную конфигурацию)
  • LSP (читает fmt/lint/test конфигурацию)
  • Система сборки (читает конфигурацию сборки)

Каждому компоненту необходима унифицированная инфраструктура конфигурации.

Текущие проблемы

  • Конфигурации компонентов разрозненны, отсутствует единый стандарт
  • Пользователи не могут централизованно управлять настройками
  • Отсутствует чёткое разграничение между проектной и пользовательской конфигурацией

Предложение

Основной дизайн

Многоуровневая архитектура:

Приоритет конфигурации (высший → низший):
┌─────────────────────────────────────────────┐
│ 1. Проектный yaoxiang.toml                   │ ← Управление командой проекта
├─────────────────────────────────────────────┤
│ 2. Пользовательский ~/.config/yaoxiang/config.toml │ ← Пользовательские предпочтения
├─────────────────────────────────────────────┤
│ 3. Значения по умолчанию компилятора         │ ← Разумные начальные значения
└─────────────────────────────────────────────┘

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

Ограничения уровней конфигурации

Секция конфигурацииПользовательскийПроектныйПотребитель
[package].*Менеджер пакетов
[yaoxiang]Компилятор
[dependencies]Менеджер пакетов
[dev-dependencies]Менеджер пакетов
[bin]Менеджер пакетов
[lib]Менеджер пакетов
[build]Система сборки
[profile.*]Система сборки
[install]Менеджер пакетов
[i18n]Компилятор
[repl]REPL
[fmt]LSP
[lint]LSP
[test]LSP
[tasks]CLI

Примеры

Проектная конфигурация:

toml
# yaoxiang.toml
[package]
name = "my-package"
version = "0.1.0"

[yaoxiang]
version = ">=0.1.0, <1.0.0"

[dependencies]
foo = "^1.0.0"

[build]
output = "dist/"

[tasks]
build = "yaoxiang build"
test = "yaoxiang test"

Пользовательская конфигурация:

toml
# ~/.config/yaoxiang/config.toml
[install]
dir = "~/.local/share/yaoxiang"

[i18n]
lang = "zh"
fallback = "en"

[repl]
history-size = 1000
prompt = "yx> "
colors = true

[fmt]
line-width = 120
indent-width = 4

[lint]
rules = ["recommended"]

Детальный дизайн

Конфигурация только для проекта

toml
[package]
name = "my-package"
version = "0.1.0"
description = "A short description"
authors = ["Alice <alice@example.com>"]
license = "MIT"
repository = "https://github.com/alice/my-project"

[yaoxiang]
version = ">=0.1.0, <1.0.0"

[dependencies]
foo = "^1.0.0"

[dev-dependencies]
test-utils = "0.1.0"

[lib]
path = "src/lib.yx"

[[bin]]
name = "my-cli"
path = "src/cli.yx"

[exports]
"." = "src/lib.yx"
"./foo" = "src/foo.yx"

[build]
script = "build.yx"
output = "dist/"

[profile.release]
optimize = true
lto = true

[run]
main = "src/main.yx"
args = ["--quiet"]

[tasks]
build = "yaoxiang build"
test = "yaoxiang test"
lint = "yaoxiang fmt && yaoxiang check"

Конфигурация только для пользователя

toml
[install]
dir = "~/.local/share/yaoxiang"

Конфигурация для обоих уровней

ПолеТипПо умолчаниюОписание
[i18n].langString"en"Язык
[i18n].fallbackString"en"Резервный язык
[repl].history-sizeNumber1000Размер истории
[repl].history-filePath~Файл истории
[repl].promptString"yx> "Приглашение
[repl].colorsBooleantrueПодсветка синтаксиса
[repl].auto-imports[String][]Автоимпорт
[fmt].line-widthNumber120Ширина строки
[fmt].indent-widthNumber4Отступ
[fmt].use-tabsBooleanfalseТабуляция
[fmt].single-quoteBooleanfalseОдинарные кавычки
[lint].rules[String]["recommended"]Набор правил
[lint].strictBooleanfalseСтрогий режим
[test].reportString"console"Отчёт о тестах
[build].outputString"dist/"Выходной каталог

Переопределение через командную строку и переменные окружения

bash
# Переопределение через командную строку
yaoxiang run main.yx --lang zh
yaoxiang fmt --config-indent-width=2

# Переменные окружения
export YAOXIANG_LANG=zh
export YAOXIANG_FMT_INDENT_WIDTH=2

Приоритет: Командная строка > Переменные окружения > Файл конфигурации

Команда yaoxiang config

CLI-команды для управления конфигурацией:

bash
# Инициализировать пользовательскую конфигурацию (по умолчанию)
yaoxiang config init

# Редактировать пользовательскую конфигурацию (открыть редактор)
yaoxiang config edit

# Показать текущую конфигурацию (объединённую)
yaoxiang config show

# Показать источники конфигурации
yaoxiang config show --source

# Сбросить к конфигурации по умолчанию
yaoxiang config reset

Первый запуск: При первом запуске любой команды yaoxiang автоматически проверяется наличие пользовательской конфигурации. Если она отсутствует, конфигурация генерируется автоматически с параметрами по умолчанию.

Расположение файлов конфигурации:

  • Проектная: ./yaoxiang.toml (в корне проекта)
  • Пользовательская: ~/.config/yaoxiang/config.toml

Семантика слияния конфигурации

Конфигурации разных уровней сливаются по следующим правилам:

ТипСтратегияОписание
Скаляр (String/Number/Boolean)ЗаменаПроектный уровень переопределяет
Массив (Array)ЗаменаПроектный полностью заменяет
Объект (Object)Глубокое слияниеПоля объединяются, отсутствующие наследуются

Пример — глубокое слияние объектов:

toml
# Пользовательская
[lint]
rules = ["recommended"]
severity = "warn"

# Проектная
[lint]
strict = true

# Результат слияния
[lint]
rules = ["recommended"]    # Из пользовательской
severity = "warn"          # Из пользовательской
strict = true             # Из проектной

Обратная совместимость

  • ✅ Существующий режим без файла конфигурации сохраняется (все компоненты используют встроенные значения по умолчанию)
  • ✅ Новые параметры конфигурации имеют разумные значения по умолчанию
  • ✅ При первом запуске команды конфигурация генерируется автоматически с параметрами по умолчанию
  • ✅ При ошибке парсинга конфигурации отображается понятное сообщение с указанием конкретной строки и причины ошибки

Компромиссы

Преимущества

  • Унифицированная инфраструктура конфигурации, сокращение дублирования кода
  • Пользовательские предпочтения единообразны между проектами
  • LSP/REPL/компилятор используют единый набор конфигурации
  • Постепенная настройка, объявление по мере необходимости

Недостатки

  • Большое количество параметров конфигурации, несколько увеличивается кривая обучения
  • Требуется унифицированный парсер конфигурации

Альтернативные решения

РешениеПричина отклонения
Независимая конфигурация каждого компонентаДублирование кода, фрагментированный UX
Только аргументы командной строкиНевозможность сохранения пользовательских предпочтений
Только переменные окруженияКонфигурация проекта сложно версионируется

Стратегия реализации

Фазы

ФазаСодержание
Phase 1Базовый парсер конфигурации, поддержка toml, проектная конфигурация, yaoxiang config init
Phase 2Пользовательская конфигурация, логика слияния, yaoxiang config edit/show
Phase 3Переопределение через командную строку/переменные окружения, ограничения platform, расширение [tool.*]

Зависимости

  • Зависит от RFC-014 системы управления пакетами

Риски

РискМеры снижения
Слишком много параметровРазумные значения по умолчанию, прозрачно для пользователя
Сложный парсерИспользование существующей toml-библиотеки

Открытые вопросы

  • [x] Синтаксис features для условной компиляции? → Вынесен в отдельный RFC, зависит от RFC-011 системы generics
  • [x] Дизайн workspace рабочих пространств? → Вынесен в отдельный RFC, высокая сложность, требует отдельного дизайна

Принятые функции (третья фаза)

platform Ограничения платформы

Внимание: следующий синтаксис используется в файле конфигурации yaoxiang.toml, не в исходном коде YaoXiang (файлы .yx). Пользователям не нужно писать cfg(...) в коде.

Поддержка конфигурации, зависящей от целевой операционной системы/архитектуры:

toml
# yaoxiang.toml (файл конфигурации)

[target.'cfg(windows)'.build]
output = "dist/win32"

[target.'cfg(unix)'.build]
output = "dist/unix"

[target.'cfg(target_arch = "x86_64")'.build]
rustflags = ["-C target-cpu=native"]

Синтаксис: [target.'<условие>'.<секция_конфига>]

Описание:

  • Этот синтаксис появляется только в файле конфигурации yaoxiang.toml
  • При сборке выбирается соответствующая конфигурация на основе параметра --target
  • Пользователям не нужно и не следует писать синтаксис cfg(...) в исходном коде .yx

Поддерживаемые условия:

  • cfg(os = "windows") — Система Windows
  • cfg(os = "linux") — Система Linux
  • cfg(os = "macos") — Система macOS
  • cfg(target_arch = "x86_64") — 64-битная архитектура x86
  • cfg(target_arch = "aarch64") — 64-битная архитектура ARM

[tool.*] Расширение конфигурации сторонних инструментов

Разрешено сторонним инструментам хранить конфигурацию в секции [tool.<название>]:

toml
[tool.eslint]
extension = ["yx", "yxp"]
ignore = ["node_modules/", "dist/"]

[tool.prettier]
semi = false
singleQuote = true

Поведение:

  • YaoXiang игнорирует неизвестные секции [tool.*], но сохраняет их в файле конфигурации
  • Сторонние инструменты могут интегрироваться через yaoxiang tool run <название> или напрямую обращаться к конфигурации
  • Конфигурация, специфичная для инструментов, не валидируется

Ссылки