Быстрый структурный инструмент сравнения YAML (YAML diff) со встроенной поддержкой Kubernetes. Одна зависимость, минимальная поверхность атаки, нативные аннотации CI для GitHub, GitLab и Gitea.
📖 Полная документация: szhekpisov.github.io/diffyml
diffyml сравнивает YAML-файлы и показывает осмысленные, структурированные различия — а не построчные текстовые диффы.
Почему diffyml?
Самый быстрый структурный инструмент YAML-диффа при работе с большими файлами. На больших (5K строк) и очень больших (50K строк) входных данных diffyml в 1,5–1,9× быстрее ближайшего YAML-осведомлённого конкурента. На небольших и средних файлах результаты сопоставимы с разницей в несколько миллисекунд — остаточные накладные расходы объясняются возможностями, которых более простым инструментам не хватает (инспекция сертификатов x509, загрузка удалённых URL, AI-сводки). Методология и результаты описаны в PERFORMANCE.md.
Одна зависимость, никаких сюрпризов. Единственная зависимость модуля — yaml.v3 и чистая стандартная библиотека Go. Минимальная поверхность атаки, поддаётся аудиту за считанные минуты.
Правильная обработка YAML. Точечные ключи (dotted keys), сохранение типов (type preservation), списки смешанных типов (mixed-type lists), nil-значения — конкретные граничные случаи, с которыми другие инструменты справляются неверно. diffyml относится к семантике YAML как к объекту первого класса, а не как к чему-то второстепенному.
Сравнение с аналогами
| Возможность | diffyml | dyff | обычный diff |
|---|---|---|---|
YAML-осведомлённость (структурный diff) |
Да |
Да |
Нет (построчный) |
Сопоставление ресурсов Kubernetes |
По apiVersion + kind + name (или generateName) |
По apiVersion + kind + name |
Нет |
Обнаружение переименований (rename detection) |
Да (схожесть содержимого — обрабатывает смену имён) |
Да (по идентификатору — имя должно оставаться неизменным) |
Нет |
Миграция версий API |
Да ( |
Нет |
Нет |
Форматы аннотаций CI |
3 (GitHub, GitLab, Gitea) |
0 |
0 |
Зависимости модуля |
1 (yaml.v3) |
23 |
0 |
Сравнение директорий |
Да |
Нет |
Да |
Внешний diff для Git ( |
Да (авто-определение) |
Вручную (скрипт-обёртка) |
Н/П |
Встроенная подсветка различий (inline diff highlighting) |
Да (на уровне слов) |
Да (на уровне символов) |
Нет |
Настраиваемые цвета |
Да (hex, переменные окружения) |
Нет |
Нет |
Файл конфигурации |
Да ( |
Нет |
Нет |
Производительность (78 КБ) |
19 мс |
120 мс (6.4×) |
6 мс |
Производительность (780 КБ) |
129 мс |
1 146 мс (8.9×) |
45 мс |
Сравнение основано на dyff v1.11.3 и diffyml v1.5.23. Полная методология бенчмарков и результаты сравнения с 5 конкурентами — в PERFORMANCE.md. Откройте issue, если что-то устарело.
Установка
Homebrew
brew tap szhekpisov/diffyml
brew install diffyml
Go Install
go install github.com/szhekpisov/diffyml@latest
Убедитесь, что $GOPATH/bin присутствует в переменной PATH:
export PATH="$(go env GOPATH)/bin:$PATH"
Скрипт установки (Linux / macOS)
curl -fsSL https://szhekpisov.github.io/diffyml/install.sh | sh
Скрипт определяет ОС и архитектуру, загружает соответствующий архив релиза, проверяет его SHA256 по подписанному checksums.txt и устанавливает файл в /usr/local/bin/diffyml. Настраивается через переменные окружения:
| Переменная | По умолчанию | Примечания |
|---|---|---|
|
последний релиз |
Зафиксировать конкретную версию, например |
|
|
Если директория недоступна для записи, используется |
|
|
Укажите |
|
не задан |
Если задан, используется для аутентификации при вызове GitHub API для определения последней версии. Полезно на общих IP-адресах CI. |
# Зафиксировать версию, установить в ~/bin, также проверить cosign-подпись:
DIFFYML_VERSION=1.6.1 INSTALL_DIR="$HOME/bin" VERIFY=cosign \
sh -c "$(curl -fsSL https://szhekpisov.github.io/diffyml/install.sh)"
Пакеты Linux (.deb / .rpm / .apk)
Нативные пакеты для Debian/Ubuntu, RHEL/Fedora и Alpine (amd64 и arm64) прикреплены к каждому релизу. Все архивы пакетов перечислены в подписанном cosign файле checksums.txt, поэтому вы можете проверить их до установки — см. раздел Проверка релизов. Файл .apk использует флаг --allow-untrusted, поскольку пакеты, собранные nfpm, не подписаны GPG; вместо этого следует проверять SHA256 из checksums.txt.
# Debian / Ubuntu
curl -fLO "https://github.com/szhekpisov/diffyml/releases/download/v1.6.1/diffyml_1.6.1_linux_amd64.deb"
sudo dpkg -i diffyml_1.6.1_linux_amd64.deb
# RHEL / Fedora / openSUSE
curl -fLO "https://github.com/szhekpisov/diffyml/releases/download/v1.6.1/diffyml_1.6.1_linux_amd64.rpm"
sudo rpm -i diffyml_1.6.1_linux_amd64.rpm
# Alpine
curl -fLO "https://github.com/szhekpisov/diffyml/releases/download/v1.6.1/diffyml_1.6.1_linux_amd64.apk"
sudo apk add --allow-untrusted diffyml_1.6.1_linux_amd64.apk
Бинарный файл устанавливается в /usr/bin/diffyml.
Прямая загрузка бинарного файла
Если вы предпочитаете не передавать скрипт в sh, те же архивы прикреплены к каждому релизу для Linux и macOS (amd64 и arm64):
VERSION=1.6.1 # проверьте страницу релизов для последней версии
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
ARCH=$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/')
curl -fL "https://github.com/szhekpisov/diffyml/releases/download/v${VERSION}/diffyml_${VERSION}_${OS}_${ARCH}.tar.gz" \
| tar -xz
sudo mv diffyml /usr/local/bin/
Перед установкой ознакомьтесь с разделом Проверка релизов, чтобы убедиться в подлинности подписей и происхождения.
Docker
Мультиархитектурные образы (linux/amd64, linux/arm64) публикуются в GitHub Container Registry:
docker pull ghcr.io/szhekpisov/diffyml:latest
# Сравнить два файла из текущей директории
docker run --rm -v "$PWD:/work" -w /work ghcr.io/szhekpisov/diffyml:latest old.yaml new.yaml
Образы собраны на базе distroless и запускаются от имени непривилегированного пользователя. Используйте :latest или зафиксируйте конкретную версию (например, :1.5.25).
Сборка из исходного кода
git clone https://github.com/szhekpisov/diffyml.git
cd diffyml
go build -o diffyml
Проверка релизов
Опубликованные артефакты релизов никогда не изменяются и не перезагружаются — каждая версия представляет собой однократное, неизменяемое событие. Каждый релиз включает:
-
Контрольные суммы (
checksums.txt) — хэши SHA256 для всех архивов -
Подпись cosign (
checksums.txt.sigstore.json) — беспарольная (keyless) подпись Sigstore -
SBOM (
*.spdx.json) — SPDX Software Bill of Materials (перечень компонентов программного обеспечения) для каждого архива -
Происхождение SLSA — аттестация сборки уровня Level 3
Проверка подписи контрольных сумм:
cosign verify-blob checksums.txt \
--bundle checksums.txt.sigstore.json \
--certificate-identity-regexp 'https://github.com/szhekpisov/diffyml/' \
--certificate-oidc-issuer 'https://token.actions.githubusercontent.com'
# Linux
sha256sum --check checksums.txt --ignore-missing
# macOS
shasum -a 256 --check checksums.txt --ignore-missing
Проверка происхождения SLSA:
gh attestation verify diffyml_<VERSION>_linux_amd64.tar.gz \
--repo szhekpisov/diffyml
Проверка подписи образа контейнера:
cosign verify \
--registry-referrers-mode=oci-1-1 \
--certificate-identity-regexp 'https://github.com/szhekpisov/diffyml/' \
--certificate-oidc-issuer 'https://token.actions.githubusercontent.com' \
ghcr.io/szhekpisov/diffyml:<VERSION>
Быстрый старт
# Сравнить два локальных файла
diffyml old.yaml new.yaml
# Сравнить локальный файл с удалённым URL
diffyml local.yaml https://example.com/remote.yaml
# Использование в CI — код выхода 1 при обнаружении различий
diffyml -s deployment-old.yaml deployment-new.yaml
# Использование в качестве внешнего провайдера diff для kubectl:
export KUBECTL_EXTERNAL_DIFF="diffyml --omit-header --set-exit-code"
Возможности
-
7 форматов вывода — detailed (подробный), compact (компактный), brief (краткий), GitHub, GitLab, Gitea, JSON
-
Фильтрация по путям — включение/исключение путей по точному совпадению или регулярному выражению
-
Удалённые файлы — сравнение напрямую по HTTP/HTTPS URL
-
Инспекция сертификатов — проверка и сравнение встроенных сертификатов x509
-
Chroot-навигация — фокусировка сравнения на конкретном поддереве YAML
-
Интеграция с Git — использование в качестве
GIT_EXTERNAL_DIFFили через.gitattributesдля области действия только на YAML -
Встроенная подсветка различий — выделяет только изменённые части скалярных значений (теги версий, IP-адреса, порты) для быстрого просмотра
-
Настраиваемые цвета — настраиваемая цветовая палитра для обеспечения доступности (удобно для людей с цветовой слепотой)
-
Файл конфигурации — настройки уровня проекта через
.diffyml.yml(поддерживаются все флаги) -
Маскирование чувствительных значений — опциональное скрытие полей
data/stringDataсекретов Kubernetes и произвольных путей; применяется ко всем форматам вывода -
⭐ AI-сводки ⭐ — описание изменений на естественном языке через Anthropic API
Использование
diffyml [flags] <from> <to>
Форматы вывода
| Формат | Флаг | Случай использования |
|---|---|---|
detailed (подробный) |
|
Ручная проверка — полный контекст |
compact (компактный) |
|
Быстрый просмотр изменений |
brief (краткий) |
|
Только сводка |
github |
|
Аннотации GitHub Actions |
gitlab |
|
Аннотации GitLab CI |
gitea |
|
Аннотации Gitea CI |
json |
|
Машиночитаемый — для передачи по конвейеру, скриптов, CI |
Интеграция с CI
Используйте -s / --set-exit-code, чтобы устанавливать код выхода на основе наличия различий:
| Код выхода | Значение |
|---|---|
|
Различий нет (или успех без |
|
Обнаружены различия (только с |
|
Произошла ошибка |
diffyml -s before.yaml after.yaml || echo "Config drift detected"
GitHub Actions — используйте составное действие diffyml-action (без ручной установки бинарного файла):
- uses: szhekpisov/diffyml-action@v1
with:
from: old.yaml
to: new.yaml
Чтобы проверить расхождения без провала задания, считайте вывод has-differences:
- uses: szhekpisov/diffyml-action@v1
id: diff
with:
from: old.yaml
to: new.yaml
fail-on-diff: 'false'
output: github
- if: steps.diff.outputs.has-differences == 'true'
run: echo "Configuration drift detected"
Полный список входных и выходных параметров см. в репозитории действия.
Поддержка Kubernetes
Ресурсы определяются автоматически и сопоставляются по apiVersion + kind + metadata.name (или metadata.generateName), поэтому диффы остаются осмысленными даже при изменении порядка документов.
Обнаружение переименований — когда ресурсы не могут быть сопоставлены по идентификатору (например, при изменении хэш-суффиксов configMapGenerator в kustomize, таких как app-config-abc123 → app-config-def456), diffyml сопоставляет несовпавшие документы по схожести содержимого (порог 60%) и отображает диффы на уровне полей вместо массового добавления/удаления. Отключается флагом --detect-renames=false.
Миграция API — флаг --ignore-api-version исключает apiVersion из ключа сопоставления, поэтому при обновлении с apps/v1beta1 до apps/v1 отображаются диффы на уровне полей вместо удаления + добавления.
Отключение — --detect-kubernetes=false полностью отключает K8s-осведомлённое сопоставление и сравнивает документы по позиции.
# Сравнить два манифеста Kubernetes
diffyml manifests-v1.yaml manifests-v2.yaml
# Миграция API — сопоставление только по kind + name
diffyml --ignore-api-version manifests-v1.yaml manifests-v2.yaml
# Отключить определение Kubernetes
diffyml --detect-kubernetes=false file1.yaml file2.yaml
Сравнение директорий
diffyml принимает две директории в качестве позиционных аргументов. Он рекурсивно обнаруживает все обычные файлы в каждой директории (независимо от расширения), сопоставляет их по относительному пути и отображает агрегированные различия. Файлы, которые не удаётся разобрать как YAML, молча пропускаются.
Это делает diffyml полноценным провайдером KUBECTL_EXTERNAL_DIFF — kubectl передаёт две временные директории, содержащие временные файлы без расширения (например, apps.v1.Deployment.default.nginx), и diffyml обнаруживает их автоматически:
export KUBECTL_EXTERNAL_DIFF="diffyml --omit-header --set-exit-code"
kubectl diff -f manifests/
Интеграция с Git
diffyml может использоваться как внешняя программа diff для git. Git передаёт 7–9 позиционных аргументов, которые diffyml определяет автоматически — не-YAML файлы пропускаются с предупреждением.
# Разовое использование: структурный diff для изменений YAML в рабочем дереве
GIT_EXTERNAL_DIFF=diffyml git diff
# С флагами (например, компактный вывод)
GIT_EXTERNAL_DIFF='diffyml -o compact' git diff
Для постоянной настройки используйте .gitattributes — встроенный diff git нормально обрабатывает все остальные типы файлов:
*.yaml diff=diffyml
*.yml diff=diffyml
git config diff.diffyml.command diffyml
Цвет и truecolor (24-битный цвет) включаются автоматически (пейджер git делает stdout каналом). Используйте --color never для отключения. Флаг --set-exit-code молча игнорируется — git прерывает работу внешних программ diff, которые завершаются с ненулевым кодом. Ошибки разбора не являются фатальными: выводится предупреждение, и git переходит к следующему файлу.
AI-сводка
Генерация описания изменений на естественном языке с использованием Anthropic API:
export ANTHROPIC_API_KEY="sk-ant-..."
# Добавить AI-сводку после вывода diff
diffyml --summary old.yaml new.yaml
# Использовать с форматом brief — заменяет краткий вывод AI-сводкой
diffyml --summary -o brief old.yaml new.yaml
# Использовать другую модель
diffyml --summary --summary-model claude-sonnet-4-5-20250514 old.yaml new.yaml
Сводка добавляется после стандартного вывода diff. Если вызов API завершается с ошибкой, предупреждение выводится в stderr, а вывод diff сохраняется. Код выхода никогда не зависит от успеха или неудачи сводки.
Маскирование чувствительных значений
Маскирование является опциональным. При включении diffyml заменяет значение любого совпадающего диффа на * перед отображением — применяется ко всем форматам вывода (включая json, json-patch и промпт --summary). Диффы по-прежнему показывают факт изменения значения, но не само значение.
# Автоматически маскировать data/stringData ресурсов Kubernetes Secret
diffyml --mask-secrets secrets-old.yaml secrets-new.yaml
# Маскировать дополнительные пути (например, поле ConfigMap, содержащее API-ключ)
diffyml --mask-path 'data.api_key' --mask-path 'data.db_url' old.yaml new.yaml
# Вариант с регулярным выражением — маскировать любое поле, чей путь совпадает
diffyml --mask-path-regexp '(?i)password|token|secret' old.yaml new.yaml
# Пользовательская метка-заглушка
diffyml --mask-secrets --mask-placeholder '<REDACTED>' old.yaml new.yaml
Пути маскирования используют ту же точечную нотацию, что и --filter / --exclude (с учётом совпадения по префиксу). Ведущий индекс документа для многодокументных файлов ([0], [1]) автоматически удаляется перед сопоставлением.
Настройте значения по умолчанию в .diffyml.yml, чтобы маскирование было всегда включено для данного репозитория:
mask-secrets: true
mask-path:
- "data.api_key"
mask-path-regexp:
- "(?i)password"
mask-placeholder: "***"
Фильтрация
# Показывать только изменения по определённому пути
diffyml --filter spec.replicas old.yaml new.yaml
# Исключить «шумные» пути
diffyml --exclude metadata.annotations old.yaml new.yaml
# Ключи с точками используют синтаксис в скобках
diffyml --exclude 'metadata.annotations[argocd.argoproj.io/tracking-id]' old.yaml new.yaml
# Фильтрация с регулярными выражениями
diffyml --filter-regexp 'spec\.containers\[.*\]\.image' old.yaml new.yaml
Аккуратный режим (Neat Mode)
Флаг --neat исключает широко известные «шумные» пути, добавляемые сервером Kubernetes API, kubectl, Helm, ArgoCD и Flux — metadata.managedFields, metadata.resourceVersion, всё поддерево status, meta.helm.sh/release-name, helm.sh/chart, argocd.argoproj.io/tracking-id, kustomize.toolkit.fluxcd.io/* и аналогичные пути. Полный список исключаемых путей находится в doc/neat.md.
# Сравнить манифест, отрендеренный kube-apiserver, с вашим эталонным источником
# (с использованием подстановки процессов; diffyml читает файлы, не stdin)
diffyml --neat <(kubectl get deployment nginx -o yaml) source.yaml
# В рабочем процессе kubectl/helm/argocd diff
KUBECTL_EXTERNAL_DIFF="diffyml --neat" kubectl diff -f deployment.yaml
# Посмотреть, что именно отфильтровал --neat
diffyml --neat --neat-explain old.yaml new.yaml
Опции отказа от отдельных слоёв позволяют сохранить один набор исключений, убрав остальные:
# Показывать диффы версий Helm-чартов, но всё равно убирать ArgoCD/Flux/managedFields
diffyml --neat --no-neat-helm old.yaml new.yaml
--neat-strip-path расширяет набор без пересборки (требует --neat):
diffyml --neat --neat-strip-path '^metadata\.annotations\[my\.org/.*\]$' old.yaml new.yaml
--neat намеренно сохраняет spec.template.metadata.annotations[kubectl.kubernetes.io/restartedAt] (маркер намеренного перезапуска), spec.replicas, data/stringData (для них используйте --mask-secrets) и пользовательские метки/аннотации за пределами канонических шумовых префиксов.
Файл конфигурации
diffyml загружает настройки уровня проекта из .diffyml.yml (или .diffyml.yaml) в текущей директории. Флаги командной строки переопределяют значения из файла конфигурации. Используйте --config для указания пути к пользовательскому файлу конфигурации.
# .diffyml.yml
output: compact
ignore-order-changes: true
detect-kubernetes: false
filter:
- "spec.containers"
exclude:
- "status"
Все флаги командной строки поддерживаются в качестве ключей конфигурации (в формате kebab-case, совпадающем с длинным именем флага). Неизвестные ключи отклоняются для выявления опечаток. Полный справочник со всеми ключами и значениями по умолчанию см. в .diffyml.yml.example.
Настраиваемые цвета
Цвета diff можно настроить для обеспечения доступности (например, палитры для людей с цветовой слепотой). Доступны для настройки пять цветовых ролей: added (добавлено), removed (удалено), modified (изменено), context (контекст) и doc-name (имя документа).
Цвета задаются в формате hex (#rrggbb, #rgb).
Через файл конфигурации:
# .diffyml.yml
colors:
added: "#6aa3a5"
removed: "#702d06"
Через переменные окружения (переопределяют файл конфигурации):
export DIFFYML_COLOR_ADDED="#6aa3a5"
export DIFFYML_COLOR_REMOVED="#702d06"
diffyml old.yaml new.yaml
Доступные переменные окружения: DIFFYML_COLOR_ADDED, DIFFYML_COLOR_REMOVED, DIFFYML_COLOR_MODIFIED, DIFFYML_COLOR_CONTEXT, DIFFYML_COLOR_DOC_NAME.
Все флаги
Вывод
| Флаг | Описание |
|---|---|
|
Стиль вывода: |
|
Использование цвета: |
|
True color (24-бит): |
Сравнение
| Флаг | Описание |
|---|---|
|
Игнорировать изменения порядка в списках |
|
Игнорировать различия в начальных/конечных пробелах |
|
Канонизировать встроенные JSON-строки перед сравнением (подавляет диффы, связанные только с форматированием) |
|
Показывать только структурные изменения, исключать изменения значений |
|
Определять и сопоставлять ресурсы Kubernetes (по умолчанию |
|
Обнаруживать переименованные/перемещённые ресурсы Kubernetes по схожести содержимого (по умолчанию |
|
Игнорировать |
|
Отключить инспекцию сертификатов x509 |
|
Поменять местами файлы from/to |
Фильтрация
| Флаг | Описание |
|---|---|
|
Включать только различия по указанным путям (повторяемый) |
|
Исключать различия по указанным путям (повторяемый) |
|
Фильтровать с использованием регулярных выражений (повторяемый) |
|
Исключать с использованием регулярных выражений (повторяемый) |
|
Дополнительное поле для идентификации элементов списка |
Маскирование чувствительных значений
| Флаг | Описание |
|---|---|
|
Автоматически маскировать |
|
Дополнительный путь для маскирования, точечная нотация с совпадением по префиксу (повторяемый) |
|
Дополнительный путь для маскирования, регулярное выражение (повторяемый) |
|
Метка-заглушка для маскированных значений (по умолчанию |
Отображение
| Флаг | Описание |
|---|---|
|
Не выводить заголовок сводки |
|
Использовать пути в стиле Go-Patch |
|
Строки контекста для многострочных строк (по умолчанию |
Chroot
| Флаг | Описание |
|---|---|
|
Изменить корневой уровень для обоих файлов |
|
Изменить корневой уровень только для файла from |
|
Изменить корневой уровень только для файла to |
|
Рассматривать список chroot как отдельные документы |
AI-сводка
| Флаг | Описание |
|---|---|
|
Генерировать AI-сводку на естественном языке (требует |
|
Модель для AI-сводки (по умолчанию |
Прочее
| Флаг | Описание |
|---|---|
|
Путь к файлу конфигурации (по умолчанию |
|
Код выхода 1, если обнаружены различия |
|
Показать справку |
|
Показать информацию о версии |
Использование в качестве библиотеки
diffyml можно использовать как библиотеку Go для программного сравнения YAML.
import "github.com/szhekpisov/diffyml/pkg/diffyml"
// Сравнить два YAML-документа
from, _ := diffyml.LoadContent("old.yaml")
to, _ := diffyml.LoadContent("new.yaml")
diffs, err := diffyml.Compare(from, to, &diffyml.Options{
DetectKubernetes: true,
})
if err != nil {
log.Fatal(err)
}
// Отформатировать различия
formatter, _ := diffyml.FormatterByName("compact")
fmt.Print(formatter.Format(diffs, diffyml.DefaultFormatOptions()))
Полный справочник API см. в документации пакета.
Безопасность и качество кода
Цепочка поставок (supply chain). Релизы подписаны с помощью cosign (беспарольный Sigstore), содержат SPDX SBOM для каждого артефакта и несут SLSA Level 3 — аттестацию происхождения сборки. Опубликованные теги неизменяемы. Команды верификации см. в разделе Проверка релизов. Репозиторий отслеживается OpenSSF Scorecard (значок выше).
Непрерывные проверки. Каждый push и PR проверяются:
-
govulncheck — обнаружение известных уязвимостей (также запускается на
mainеженедельно) -
zizmor — сканирование безопасности рабочих процессов GitHub Actions
-
golangci-lint с запуском: errcheck, gocritic, gosec, govet (с обнаружением затенения переменных), ineffassign, misspell, staticcheck (все проверки, кроме стилистических соглашений)
Качество тестов. 1 500+ тестов (модульные, e2e, фаззинг, основанные на свойствах), покрытие кода 99,4%, мутационное тестирование контролируется при каждом PR (ни один выживший мутант на изменённых строках) с минимальным порогом эффективности после слияния 85,65%. CI обеспечивает минимальный порог покрытия 99%.
Сообщение об уязвимостях. См. SECURITY.md — предпочтительный путь — частное уведомление безопасности GitHub.
Вклад в проект
Вклад приветствуется! Откройте issue для сообщения об ошибках или запросов функций.
Предварительные требования: Go 1.26.3+, pre-commit
git clone https://github.com/szhekpisov/diffyml.git
cd diffyml
pre-commit install
Pre-commit хуки запускаются автоматически при каждом коммите:
| Хук | Что проверяет |
|---|---|
|
Форматирование кода |
|
Статический анализ |
|
Порог покрытия (99% в целом) |
|
Известные уязвимости |
|
7 линтеров (errcheck, gocritic, gosec, govet, ineffassign, misspell, staticcheck) |
Полезные цели Make:
make test # запустить все тесты
make ci # полный CI-конвейер локально (fmt + vet + test + coverage + security)
make bench # запустить бенчмарки
make bench-compare # сравнить с альтернативными инструментами (см. doc/PERFORMANCE.md)
make coverage # сгенерировать HTML-отчёт о покрытии
make mutation # запустить мутационное тестирование (требует gomutants)
CI-конвейеры (запускаются при каждом push и PR):
-
Tests — модульные тесты + пороги покрытия
-
Security & Static Analysis — govulncheck + golangci-lint (также запускается еженедельно)
-
Benchmark — отслеживание регрессий производительности
-
Mutation Testing — валидация качества тестов через gomutants
Благодарности
Этот проект во многом вдохновлён dyff, и он не был бы возможен без огромной работы мейнтейнеров и контрибьюторов этого проекта.
Лицензия
MIT.
Если этот проект оказался вам полезен, пожалуйста, поставьте ⭐ — это помогает другим его найти.