Review replication: Difference between revisions

From Svacer Wiki
m (minor fixes)
 
Line 18: Line 18:
* Добавлена команда <code>reviewer migrate restore</code> для восстановления разметки и комментариев
* Добавлена команда <code>reviewer migrate restore</code> для восстановления разметки и комментариев


Вышеприведенные команды предназначены для исправления пропущенной разметки или комментариев при апгрейде со старых версих Svacer на последний релиз.  
Команды предназначены для исправления пропущенной разметки или комментариев при апгрейде со старых версий Svacer на последний релиз.  


Команды работают напрямую с базой. Могут так же использоваться для бэкапа данных разметки и комментариев
Команды работают напрямую с базой. Могут также использоваться для бэкапа данных разметки и комментариев
|-
|-
|devel.2025-09-15@04:26:40.654d90f2
|devel.2025-09-15@04:26:40.654d90f2

Latest revision as of 15:14, 18 December 2025

Репликация разметки по правилам (экспериментальная функциональность)

При использовании разных версий Svace (или иных анализаторов), разных настроек CI/CD и прочих факторах возможны ситуации, когда снимки (snapshots) в рамках одной ветки (branch) могут иметь различные инварианты и разметка автоматически не переносится. Для решения задачи переноса разметки в таких случаях разработана утилита reviewer, которая позволяет применить декларативно описанные правила переноса к существующей разметке. В дальнейшем данная функциональность будет включена в Svacer и доступна в веб-интерфейсе.

Использование утилиты подразумевает использование CLI команд svacer markup2 export и svacer markup2 import (описание markup2) для выгрузки и импортирования разметки. Утилита reviewer обеспечивает модификацию выгружаемой разметки с целью копирования существующей разметки на неразмеченные элементы. Правила копирования задаются с использованием булевых выражений и набора предопределенных предикатов.

Описание утилиты

Утилита reviewer предназначена для Svacer версии 10 и выше. Утилита собрана под Linux, скачать можно отсюда.

История изменений

Версия Детали
devel.2025-12-18@05:11:18.075773d1
  • Добавлена команда reviewer migrate save для сохранения разметки и комментариев из базы
  • Добавлена команда reviewer migrate restore для восстановления разметки и комментариев

Команды предназначены для исправления пропущенной разметки или комментариев при апгрейде со старых версий Svacer на последний релиз.

Команды работают напрямую с базой. Могут также использоваться для бэкапа данных разметки и комментариев

devel.2025-09-15@04:26:40.654d90f2
  • Добавлен флаг --autofix-duplicate-invariants для дублей инвариантов
  • Добавлен флаг --autofix-all для дублей комментариев, инвариантов и потенциально иных проблем
  • Добавлена команда safe-copyдля копирования разметки между ветками с автоисправлением дублей комментариев и инвариантов
devel.2025-07-16@07:20:59.90a60fcd
  • Добавлен флаг --autofix-duplicate-comments для удаления дублей комментариев, которые по какой-либо причине могут быть в исходных данных
devel.2025-07-14@07:20:15.74259281
  • В журнал операций добавлены old/new статусы при операции replicate
  • Добавлены вспомогательные функции source_review_ct и target_review_ct для получения времени разметки на source и target. Их можно использовать в предикатах
  • Добавлено ассоциирование комментария с разметкой при репликации
  • Добавлен ряд вспомогательных команд
devel.2025-06-03@09:35:03.ab170f00
  • Исправлена работа при репликации разметки между разными проектами/ветками
devel.2025-05-26@06:18:01.853591f1
  • Улучшено HTML-представление отчета
  • Добавлен предикат match_prefix_re по аналогии с match_suffix_re
devel.2025-04-22@06:39:21.a3bc1bc1
  • Добавлены предикаты same_go_path и match_go_path для упрощения написания правил при переносе разметки для Go проектов, где версии модулей меняются
devel.2025-04-21@04:53:47.15a3d5c0
  • Добавлена версия
  • Добавлена генерация журнала изменений
  • Добавлена генерация информации о снимках при работе с сервером
  • В результат записываются только обновленные разметки
  • Добавлена возможность указания снимков в качестве фильтра (при условии работы с сервером)

Использование

NAME:
   reviewer - Svacer review help tool

USAGE:
   reviewer [global options] command [command options] [arguments...]

VERSION:
   devel.2025-04-21@04:53:47.15a3d5c0

COMMANDS:
   syntax      Prints help information about rule syntax
   invariants  Get information about invariants from branch. Output format is ReviewModificationJournal.SnapshotList with invariants  
   replicate   Replicate non-empty review to invariants according to rules.
               Review can be loaded either from file(s) or from server. 

               Review is replicated from source project/branch or file to target project/branch or file.

               If no target project/branch or file is specified, replication is applied to source project/branch or file. This can be used to copy review within the same container.

               Result is written to stdout or file. Reviewer does not update data on server.

   help, h     Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --debug              Enabled debug output (default: false)
   --log-file value     Define log file for output
   --host value         Defines URL to svacer server. Format: http://host:port
   --user value         User login. When using env variable SVACER_AUTH_CREDS the format is SVACER_AUTH_CREDS=<login>:<password> (default: admin) [$SVACER_AUTH_CREDS]
   --password value     User password
   --ldap_server value  Server for LDAP authentication [$SVACER_LDAP_SERVER]
   --token value        Defines access token for svacer server [$SVACER_AUTH_TOKEN]
   --help               Show help (default: false)
   --version            Print version the program (default: false)

Основная команда — replicate, она позволяет применить декларативные правила к разметке, полученной либо с сервера, либо из файла, куда ранее была выгружена командой svacer markup2 export. Результат работы команды — файл с разметкой, предназначенный для загрузки в Svacer посредством команды svacer markup2 import

NAME:
   reviewer replicate - Replicate non-empty review to invariants according to rules.
                        Review can be loaded either from file(s) or from server. 

                        Review is replicated from source project/branch or file to target project/branch or file.

                        If no target project/branch or file is specified, replication is applied to source project/branch or file. This can be used to copy review within the same container.

                        Result is written to stdout or file. Reviewer does not update data on server.


USAGE:
   reviewer replicate [command options] <file name> - path to result file

OPTIONS:
   --project value          Project name or id
   --branch value           Branch name or id (default: master)
   --target-project value   Project name or id of the target project
   --target-branch value    Branch name or id of the target branch (default: master)
   --source-snapshot value  Snapshot name or id. Replicate reviews only from given snapshot. Host, project and branch must be provided
   --target-snapshot value  Snapshot name or id. Replicate reviews only to given snapshot. Host, project and branch must be provided
   --file value             Load review from file instead of server. File must be in 'json with new line separator' format. File may be gzipped (must have *.gz extension)
   --target-file value      Load target review from file instead of server. File must be in 'json with new line separator' format. File may be gzipped (must have *.gz extension)
   --rule value             Path to file containing replicate rules
   --html                   Produce HTML report describing applied changes. Report is saved to <result file name>.html (default: false)
   --verbose                Verbose output of rule applications (default: false)
   --process-all            Process all reviews, even with non-default values (default: false)
   --skip-comments          Skip comments while replicating review information (default: false)
   --skip-status            Skip review status and copy only comments while replicating review information (default: false)
   --journal value          Write journal of modifications to specified file
   --help                   Show help (default: false)

Опция --journal позволяет указать файл, куда будет записана информация о проведенных изменениях в JSON формате. Пример такого файла

{
    "actions": [
        {
            "source_invariant": "LX/DOWQxqWSdqMw1zBGr/A",
            "target_invariant": "7YlVnmb/kAkwyxNBjCagiQ",
            "rule": "unprocessed() &&  // ensure target has no review\n        match_loc(warnclass,file,lang,tool,mtid, line) && // ensure main fields are the same\n        match_suffix_re (function, \"(.+/)\" /* regexp for prefix */ ) // trim prefix and match suffix",
            "source_id": "1",
            "target_id": "13"
        }
    ]
} 

Шаги применения утилиты

Задача: в проекте myproject на ветке master необходимо перенести существующую разметку по некоторым правилам. Сервер запущен на localhost на порту 8080.

Шаги решения:

1. Опционально, но рекомендуется выгрузить разметку с ветки в файл, используя команду

svacer markup2 --host=http://localhost:8080 --user admin --password admin export --project myproject --branch master --uncompressed --format json --export-all /tmp/myproject.json

2. Написать правила переноса разметки (предикатов переноса) в файл /tmp/map.txt

3. Если разметка была выгружена (шаг 1 выполнен), то применить утилиту reviewer с загрузкой данных из файла. Флаг --html создаст дополнительно HTML с информацией об изменениях, имя файла /tmp/out.json.html. Журнал изменений будет записан в файл replicate_journal.json

reviewer replicate --file /tmp/myproject.json --rule /tmp/map.txt --journal /tmp/replicate_journal.json --html /tmp/out.json

4. Если разметка не была выгружена (шаг 1 пропущен) применить утилиту reviewer с загрузкой данных с сервера. Флаг --html создаст дополнительно HTML с информацией об изменениях, имя файла /tmp/out.json.html. Журнал изменений будет записан в файл replicate_journal.json

reviewer --host=http://localhost:8080 --user admin --password admin replicate --project myproject --branch master --rule /tmp/map.txt --journal /tmp/replicate_journal.json --html /tmp/out.json

5. Проанализировать созданный журнал изменений и файл /tmp/out.json.html

6. Если результат устраивает, то загрузить обновленную разметку в сервер из файла /tmp/out.json

svacer markup2 --host=http://localhost:8080 --user admin --password admin import --project myproject --branch master /tmp/out.json

Примечания

Разметка в Svacer привязана к инвариантам. Инвариант это некоторый хэш, формируемый из полей предупреждения. Алгоритм формирования хэша описан в этой статье. В рамках одного снимка все инварианты всегда уникальны.

Команда markup2 export с флагом --export-all выгружает все инварианты с ветки с информацией о разметке и комментариях.

При экспорте разметка на инварианте представлена как объект, соответствующий схеме, описанной в статье Markup2. Технически это:

  • статус (тройка status, severity, action)
  • набор комментариев
  • массив locations, которые определяют множество мест, имеющих один и тот же инвариант

Алгоритм переноса разметки

Входные данные (разметка), полученные из файла или с сервера разбиваются на два вектора source и target. В source включаются все элементы с разметкой, отличной от разметки по умолчанию. В target включаются все оставшиеся элементы. Порядок элементов в source и target соответствует порядку объектов во входных данных (файле).

Если указана опция --process-all , то в source и target включаются все элементы (данную опцию следует использовать для случаев, если мы хотим заместить существующую разметку, а не перенести разметку на неразмеченные элементы)

Процедура проходит по всем парам (source_item,target_item) и для каждой пары вычисляет предикаты из файла с правилами в порядке их определения. Если какой-либо предикат вычислен в true, то происходит копирование статусов разметки и комментариев с source_item на target_item. Во избежание перезаписи разметки можно в правилах использовать предикат unprocessed() описанный ниже.

Файл задания предикатов переноса

Формат файла: UTF-8. Правила разделяются ;;. В качестве комментариев допустимы /**/ и //

Правила — это булевы выражение в синтаксисе go-expr, выражения использует операторы &&, ||, !, скобки и следующие дополнительные предикаты:

  • unprocessed() — проверка, что target еще не содержит разметки. Рекомендуется использовать, чтобы избежать перезаписи разметки, если несколько правил сработали; при наличии такого предиката разметка будет скопирована лишь один раз для первого сработавшего предиката;
  • processed() — проверка, что target уже содержит какую-либо не дефолтную разметку;
  • match_loc(field1, field2, ...) — проверка, содержат ли locations в source и target хотя бы один общий location, который совпадает по указанным полям. Возможные поля: warnclass, function, details, invariant, line, file, mtid, tool, lang;
Пример: match_loc(warnclass,file,lang,tool,line)
  • match_loc_strict(field1, field2, ...) — проверка, содержат ли locations source и target одинаковые location по указанным полям;
Пример: match_loc_strict(warnclass,file,lang,tool,line)
  • match_source_re(field, value) — проверка, содержит ли location в source запись, где field совпадает с value. Value — Golang regexp;
  • match_target_re(field, value) — проверка, содержит ли location в target запись где field совпадает с value. Value — Golang regexp;
  • source_review(status[, severity, action]) — проверка, если разметка source соответствует указанным параметрам. severity, action можно опускать, шаблон "*" соответствует всему;
  • target_review(status[, severity, action]) — проверка, если разметка target соответствует указанным параметрам. severity, action можно опускать, шаблон "*" соответствует всему;
  • match_source_range(lower_bound,upper_bound) — проверка, если в source есть location, где line попадает в указанный диапазон. Значение -1 означает отсутствие границы;   
  • match_target_range(lower_bound,upper_bound) — проверка, если в target есть location, где line попадает в указанный диапазон. Значение -1 означает отсутствие границы;
  • match_suffix_re(field, source_prefix[,target_prefix]) — проверка, есть ли location в source и target, который содержит общий суффикс. Суффикс вычисляется путем отрезания префикса source_prefix и target_prefix. Если target_prefix не указан, то считается, что он равен source_prefix. Префикс определяется как Go regexp;
  • match_source_id(id1, id2, ...) — проверка, если внутренний id source разметки совпадает с одним из аргументов;
  • match_target_id(id1, id2, ...) — проверка, если внутренний id target разметки совпадает с одним из аргументов;
  • source_review_ct() time.Time — возвращает время создания разметки в source;
  • target_review_ct() time.Time — возвращает время создания разметки в target;
  • source_reviewed_by() string — возвращает автора разметки в source;
  • target_reviewed_by() string — возвращает автора разметки в target.

Пример предиката

// Перенос разметки для Go, где поменялся формат поля function в последних Svace

unprocessed() &&  // ensure target has no review
        match_loc(warnclass,file,lang,tool,mtid, line) && // ensure main fields are the same
        match_suffix_re (function, "(.+/)" /* regexp for prefix */ ) // trim prefix and match suffix

Файл с тремя предикатами, для случая изменения версий go модулей в пакете go-jmespath (jmespath -> go-jmespath)

// common case for function changes
unprocessed() && 
        match_loc(warnclass,file,lang,tool,mtid, line) &&
        match_suffix_re (function, "(.+/)" /* regexp for prefix */ ) 
;;
// handle go-jmespath case
unprocessed() && 
        match_source_re(lang, "GO|Go") && match_target_re(lang, "GO|Go") && 
        match_loc(warnclass,file,lang,tool,mtid, line, details)
;;
// handle go mod versions
unprocessed() && 
        match_loc(warnclass,lang,tool,mtid, line) &&
        match_source_re(lang, "GO|Go") && match_target_re(lang, "GO|Go") && 
        same_go_path() &&
        match_suffix_re (function, "(.+/)" /* regexp for prefix */ ) 

HTML отчет о результатах переноса

При использовании опции --htmlутилита формирует HTML файл с информацией о разметке и операциях по переносу. Файл предназначен для отладки процесса переноса. В будущем, в Svacer UI будет предусмотрен специальный интерфейс для просмотра результатов переноса.

При наличии переноса разметки в столбце с Review будет запись Review Source со ссылкой на элемент, откуда была перенесена разметка.

При раскрытии элемента Review Source будут представлены основные поля location, соответствующих исходной разметке, откуда был сделан перенос.