Skip to content

Latest commit

 

History

History
171 lines (128 loc) · 8.64 KB

File metadata and controls

171 lines (128 loc) · 8.64 KB

Вклад в Ktav

Languages: English · Русский · 简体中文

Основные правила

1. Каждый bug-fix сопровождается регрессионным тестом

Когда вы нашли баг, перед тем как чинить, напишите тест, который его воспроизводит — тест должен падать на main и проходить после фикса. Включите оба изменения в один PR.

Тест должен жить рядом со связанными тестами (например, в tests/edge_cases/<topic>.rs или tests/ser/<topic>.rs). Короткий комментарий к тесту объясняет характер падения, чтобы читатель через десять месяцев понимал, почему этот случай важен.

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

2. Чувствительные к производительности изменения сопровождаются числами before/after

Если PR трогает что-либо из:

  • src/parser/ / src/thin/parser.rs — горячий путь парсинга
  • src/ser/text_serializer.rs / src/render/ — горячий путь сериализации
  • src/thin/deserializer.rs / src/de/ — горячий путь десериализации
  • src/value/ — динамический тип значения

… в описании PR должен быть блок с before/after числами criterion по затронутым бенчам:

parse_to_struct/100_upstreams_typed
  before: 275 µs
  after:  198 µs
  change: -28%

Цель — не быть самым быстрым любой ценой, а сделать изменения подотчётными. Регрессия 5 % допустима, если она покупает ясность или корректность, но должна быть видна и обоснована.

Используйте удобный скрипт:

./bench.sh                # quick run (warmup 1s, measurement 2s, 20 samples)
./bench.sh full           # criterion defaults — longer, more accurate
./bench.sh parse          # filter: only parse benches
./bench.sh render         # filter: only render benches
./bench.sh "parse|render" # any criterion regex

Criterion хранит числа прошлого прогона в target/criterion/ и автоматически сравнивает их при следующем прогоне, так что в выводе будет change: +/- X %.

3. Изменения публичного API отмечают совместимость

Если вы трогаете что-либо под pub в lib.rs, в описании PR укажите — это:

  • semver-совместимо (добавления, ослабленные bounds, правки документации); или
  • ломает semver (переименования / удаления, изменённые сигнатуры, ужесточённые bounds) — в этом случае bump версии идёт в следующий MINOR, пока мы pre-1.0.

Обновите CHANGELOG.md в том же PR под ## [Unreleased].

4. Одна концепция — один коммит

Коммиты должны быть атомарными: bug-fix и его тест вместе, новая фича и её тесты вместе. Переименование — отдельный коммит. Рефакторинг, который попутно чинит баг, — вероятно, должен быть двумя коммитами.

git log --oneline должен читаться как changelog. Пишите именно так.

Получение кода

Набор тестов соответствия спецификации находится в git-субмодуле spec/ (ktav-lang/spec). Клонируйте вместе с субмодулем, чтобы cargo test мог его запустить:

git clone --recurse-submodules https://github.com/ktav-lang/rust

Если репозиторий уже склонирован без --recurse-submodules:

git submodule update --init

Запуск тестов

cargo test                         # все тесты (включая conformance)
cargo test --test spec_conformance # только языково-нейтральный набор
cargo test --test edge_cases       # одна категория
cargo test multiline               # по фильтру имени
cargo test --doc                   # doc-тесты

Категории тестов:

  • src/**/tests.rs — приватные unit-тесты на модуль.
  • tests/de/* — десериализация по фичам.
  • tests/ser/* — сериализация по фичам.
  • tests/roundtrip/* — round-trip (T → text → T).
  • tests/edge_cases/* — комбинаторные edge case-ы (литералы со скобками, ключевые слова в map-ах, глубокая вложенность, особые строки…).
  • tests/fixtures.rs — end-to-end по реальным .conf файлам.
  • tests/spec_conformance.rs — языково-нейтральный набор из ktav-lang/spec (valid-фикстуры совпадают с JSON-оракулом; invalid-фикстуры отклоняются; valid-фикстуры переживают round-trip).

Benchmarks

Источник: benches/parse.rs (criterion). Сценарии охватывают:

  • parse_to_value — сырой parse в Value (владеющее, публичное дерево).
  • parse_to_struct — parse по thin-пути в типизированную структуру.
  • render — сериализация типизированной структуры в текст.
  • roundtrip — parse + render.
  • multiline_dedent — разбор многострочных строк при разном количестве строк.

Руководство по раскладке кода

Правило декомпозиции: один экспортируемый элемент на файл. Приватные хелперы живут рядом с типом, который ими пользуется. Папки группируют тесно связанные элементы (весь src/thin/ — это zero-copy путь десериализации).

src/
├── lib.rs                         public entry points
├── value/                         owned Value enum (public)
├── parser/                        Value-building parser
├── render/                        Value  text
├── thin/                          zero-copy de path (ThinValue  T)
├── ser/                           T  Value (public) + T  text (direct)
├── de/                            Value  T (via ValueDeserializer)
└── error/                         Error + serde impls

Философия (чего не делать)

Девиз Ktav: «будь другом конфига, а не его экзаменатором». Перед тем как предлагать новую фичу, спросите:

  • Добавляет ли это новое правило, которое читателю придётся держать в голове?
  • Можно ли всё ещё понять строку без её соседей?

Новые правила всегда дорого стоят. Отклоняйте всё, что не проходит эти две проверки.

Лицензия вкладов

Если вы явно не заявите иное, любой вклад, намеренно отправленный для включения в этот проект, в соответствии с определением лицензии Apache-2.0, будет лицензирован на условиях MIT OR Apache-2.0 без каких-либо дополнительных условий или ограничений.