Review replication: Difference between revisions

From Svacer Wiki
Line 48: Line 48:
'''Шаги решения:'''
'''Шаги решения:'''


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


  svacer markup2 --host=<nowiki>http://localhost:8080</nowiki> --user admin --password admin export --project myproject --branch master  --uncompressed --format json --export-all /tmp/myproject.json
  svacer markup2 --host=<nowiki>http://localhost:8080</nowiki> --user admin --password admin export --project myproject --branch master  --uncompressed --format json --export-all /tmp/myproject.json
2. Написать правила переноса разметки (предикатов переноса) в файл <code>/tmp/map.txt</code>  
2. Написать правила переноса разметки (предикатов переноса) в файл <code>/tmp/map.txt</code>  


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


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

Revision as of 15:33, 4 March 2025

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

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

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

Утилита reviewer предназначена для Svacer версии 10 и выше.

NAME:
   reviewer - Svacer review help tool

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

COMMANDS:
   syntax     Prints help information about rule syntax
   replicate  Replicate non-empty review to invariants according to rules
   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 (default: admin)
   --ldap_server value  Server for LDAP authentication [$SVACER_LDAP_SERVER]
   --token value        Defines access token for svacer server [$SVACER_AUTH_TOKEN]
   --help, -h           show help

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

NAME:
   reviewer replicate - Replicate non-empty review to invariants according to rules

USAGE:
   reviewer replicate [command options] <file name> - path to output file with applied rules

OPTIONS:
   --project value  Project name or id
   --branch value   Branch name or id (default: master)
   --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)
   --rule value     Path to file containing replicate rules
   --html           Produce HTML report showing applied changes.Report wil have name <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)
   --help, -h       show help

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

Задача: В проекте 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):

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

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

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

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

6. Если результат устраивает, то загрузить обновленную разметку в сервер:

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)
  • набор комментариев
  • массив location-ов, которые определяют множество мест, имеющих один и тот же инвариант.

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

Входные данные (разметка), полученные из файла или с сервера разбиваются на два вектора 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

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

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

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

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