Review replication: Difference between revisions
Mitrofanov (talk | contribs) |
m (change link to mediawiki server + some minor fixes) |
||
(9 intermediate revisions by one other user not shown) | |||
Line 1: | Line 1: | ||
== Репликация разметки по правилам (экспериментальная функциональность) == | == Репликация разметки по правилам (экспериментальная функциональность) == | ||
При использовании разных версий Svace (или иных анализаторов), разных настроек CI/CD и прочих факторах возможны ситуации, когда снимки (snapshots) в рамках одной ветки (branch) могут иметь различные инварианты и разметка автоматически не переносится. Для решения задачи переноса разметки в таких случаях разработана утилита | При использовании разных версий Svace (или иных анализаторов), разных настроек CI/CD и прочих факторах возможны ситуации, когда снимки (snapshots) в рамках одной ветки (branch) могут иметь различные инварианты и разметка автоматически не переносится. Для решения задачи переноса разметки в таких случаях разработана утилита '''reviewer''', которая позволяет применить декларативно описанные правила переноса к существующей разметке. В дальнейшем данная функциональность будет включена в Svacer и доступна в веб-интерфейсе. | ||
Использование утилиты подразумевает использование CLI команд <code>svacer markup2 export</code> и <code>svacer markup2 import</code> ([[Markup2|описание markup2]]) для выгрузки и импортирования разметки. Утилита reviewer обеспечивает модификацию выгружаемой разметки с целью копирования существующей разметки на неразмеченные элементы. Правила копирования задаются с использованием булевых выражений и набора предопределенных предикатов. | |||
=== Описание утилиты === | === Описание утилиты === | ||
Утилита | Утилита reviewer предназначена для Svacer версии 10 и выше. Утилита собрана под Linux, скачать можно [https://svacer.ispras.ru/releases/utils/reviewer отсюда]. | ||
==== История изменений ==== | |||
{| class="wikitable" | |||
|+ | |||
!Версия | |||
!Детали | |||
|- | |||
|devel.2025-04-22@06:39:21.a3bc1bc1 | |||
| | |||
* Добавлены предикаты same_go_path и match_go_path для упрощения написания правил при переносе разметки для Go проектов, где версии модулей меняются | |||
|- | |||
|devel.2025-04-21@04:53:47.15a3d5c0 | |||
| | |||
* Добавлена версия | |||
* Добавлена генерация журнала изменений | |||
* Добавлена генерация информации о снимках при работе с сервером | |||
* В результат записываются только обновленные разметки | |||
* Добавлена возможность указания снимков в качестве фильтра (при условии работы с сервером) | |||
|} | |||
==== Использование ==== | |||
NAME: | NAME: | ||
reviewer - Svacer review help tool | reviewer - Svacer review help tool | ||
Line 9: | Line 32: | ||
USAGE: | USAGE: | ||
reviewer [global options] command [command options] [arguments...] | reviewer [global options] command [command options] [arguments...] | ||
VERSION: | |||
devel.2025-04-21@04:53:47.15a3d5c0 | |||
COMMANDS: | COMMANDS: | ||
syntax | syntax Prints help information about rule syntax | ||
replicate | invariants Get information about invariants from branch. Output format is ReviewModificationJournal.SnapshotList with invariants | ||
help, h | 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: | GLOBAL OPTIONS: | ||
Line 20: | Line 55: | ||
--host value Defines URL to svacer server. Format: <nowiki>http://host:port</nowiki> | --host value Defines URL to svacer server. Format: <nowiki>http://host:port</nowiki> | ||
--user value User login. When using env variable SVACER_AUTH_CREDS the format is SVACER_AUTH_CREDS=<login>:<password> (default: admin) [$SVACER_AUTH_CREDS] | --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 | --password value User password | ||
--ldap_server value Server for LDAP authentication [$SVACER_LDAP_SERVER] | --ldap_server value Server for LDAP authentication [$SVACER_LDAP_SERVER] | ||
--token value Defines access token for svacer server [$SVACER_AUTH_TOKEN] | --token value Defines access token for svacer server [$SVACER_AUTH_TOKEN] | ||
--help | --help Show help (default: false) | ||
Основная команда, | --version Print version the program (default: false) | ||
Основная команда — '''replicate''', она позволяет применить декларативные правила к разметке, полученной либо с сервера, либо из файла, куда ранее была выгружена командой <code>svacer markup2 export</code>. Результат работы команды — файл с разметкой, предназначенный для загрузки в Svacer посредством команды <code>svacer markup2 import</code> | |||
NAME: | NAME: | ||
reviewer replicate - Replicate non-empty review to invariants according to rules | 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: | USAGE: | ||
reviewer replicate [command options] <file name> - path to | reviewer replicate [command options] <file name> - path to result file | ||
OPTIONS: | OPTIONS: | ||
--project value | --project value Project name or id | ||
--branch value Branch name or id (default: master) | --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) | --target-project value Project name or id of the target project | ||
--rule value | --target-branch value Branch name or id of the target branch (default: master) | ||
--html | --source-snapshot value Snapshot name or id. Replicate reviews only from given snapshot. Host, project and branch must be provided | ||
--verbose | --target-snapshot value Snapshot name or id. Replicate reviews only to given snapshot. Host, project and branch must be provided | ||
--process-all | --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) | ||
--skip-comments | --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) | ||
--skip-status | --rule value Path to file containing replicate rules | ||
--help, | --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. Опционально, но рекомендуется выгрузить разметку с ветки в файл, используя команду: | 1. Опционально, но рекомендуется выгрузить разметку с ветки в файл, используя команду | ||
<nowiki>svacer markup2 --host=http://localhost:8080 --user admin --password admin export --project myproject --branch master --uncompressed --format json --export-all /tmp/myproject.json</nowiki> | |||
2. Написать правила переноса разметки (предикатов переноса) в файл <code>/tmp/map.txt</code> | 2. Написать правила переноса разметки (предикатов переноса) в файл <code>/tmp/map.txt</code> | ||
3. Если разметка была выгружена (шаг 1 выполнен), то применить утилиту <code> | 3. Если разметка была выгружена (шаг 1 выполнен), то применить утилиту reviewer '''с загрузкой данных из файла'''. Флаг <code>--html</code> создаст дополнительно HTML с информацией об изменениях, имя файла <code>/tmp/out.json.html</code>. Журнал изменений будет записан в файл <code>replicate_journal.json</code> | ||
reviewer replicate --file /tmp/myproject.json --rule /tmp/map.txt --journal /tmp/replicate_journal.json --html /tmp/out.json | |||
4. Если разметка не была выгружена (шаг 1 пропущен) применить утилиту reviewer '''с загрузкой данных с сервера'''. Флаг <code>--html</code> создаст дополнительно HTML с информацией об изменениях, имя файла <code>/tmp/out.json.html</code>. Журнал изменений будет записан в файл <code>replicate_journal.json</code> | |||
<nowiki>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</nowiki> | |||
5. Проанализировать созданный журнал изменений и файл <code>/tmp/out.json.html</code> | |||
6. Если результат устраивает, то загрузить обновленную разметку в сервер из файла <code>/tmp/out.json</code> | |||
<nowiki>svacer markup2 --host=http://localhost:8080 --user admin --password admin import --project myproject --branch master /tmp/out.json</nowiki> | |||
svacer markup2 --host= | |||
'''Примечания''' | |||
Разметка в Svacer привязана к инвариантам. Инвариант это некоторый хэш, формируемый из полей предупреждения. Алгоритм формирования хэша описан в [[Help:Match#Описание_алгоритма|этой статье]]. В рамках одного снимка все инварианты всегда уникальны. | |||
При экспорте | Команда <code>markup2 export</code> с флагом <code>--export-all</code> выгружает все инварианты с ветки с информацией о разметке и комментариях. | ||
При экспорте разметка на инварианте представлена как объект, соответствующий схеме, описанной в статье [[Markup2]]. Технически это: | |||
* статус (тройка <code>status, severity, action</code>) | * статус (тройка <code>status, severity, action</code>) | ||
* набор комментариев | * набор комментариев | ||
* массив | * массив locations, которые определяют множество мест, имеющих один и тот же инвариант | ||
=== Алгоритм переноса разметки === | === Алгоритм переноса разметки === | ||
Входные данные (разметка), полученные из файла или с сервера разбиваются на два вектора source и target. В source включаются все элементы с разметкой отличной от разметки по умолчанию. В target включаются все оставшиеся элементы. Если указана опция <code>--process-all</code> , то в source и target включаются все элементы ( | Входные данные (разметка), полученные из файла или с сервера разбиваются на два вектора source и target. В source включаются все элементы с разметкой, отличной от разметки по умолчанию. В target включаются все оставшиеся элементы. Порядок элементов в source и target соответствует порядку объектов во входных данных (файле). | ||
Если указана опция <code>--process-all</code> , то в source и target включаются все элементы (данную опцию следует использовать для случаев, если мы хотим заместить существующую разметку, а не перенести разметку на неразмеченные элементы) | |||
Процедура проходит по всем парам <code>(source_item,target_item)</code> и для каждой пары вычисляет предикаты из файла с правилами в порядке их определения. Если какой либо предикат вычислен в true, то происходит копирование статусов разметки и комментариев с <code>source_item</code> на <code>target_item | Процедура проходит по всем парам <code>(source_item,target_item)</code> и для каждой пары вычисляет предикаты из файла с правилами в порядке их определения. Если какой-либо предикат вычислен в true, то происходит копирование статусов разметки и комментариев с <code>source_item</code> на <code>target_item</code>. Во избежание перезаписи разметки можно в правилах использовать предикат <code>unprocessed()</code> описанный ниже. | ||
==== Файл задания предикатов переноса ==== | ==== Файл задания предикатов переноса ==== | ||
Формат файла: UTF-8. Правила разделяются <code>;;</code>. В качестве комментариев допустимы <code>/**/ и //</code> | Формат файла: UTF-8. Правила разделяются <code>;;</code>. В качестве комментариев допустимы <code>/**/</code> и <code>//</code> | ||
Правила — это булевы выражение в синтаксисе [https://expr-lang.org/docs/language-definition go-expr], выражения использует операторы <code>&&, ||, !</code>, скобки и следующие дополнительные предикаты: | |||
* <code>unprocessed()</code> — проверка, что target еще не содержит разметки. Рекомендуется использовать, чтобы избежать перезаписи разметки, если несколько правил сработали; при наличии такого предиката разметка будет скопирована лишь один раз для первого сработавшего предиката; | |||
* <code> | * <code>processed()</code> — проверка, что target уже содержит какую-либо не дефолтную разметку; | ||
* <code> | * <code>match_loc(field1, field2, ...)</code> — проверка, содержат ли locations в source и target хотя бы один общий location, который совпадает по указанным полям. Возможные поля: <code>warnclass, function, details, invariant, line, file, mtid, tool, lang</code>; | ||
:Пример: <code>match_loc(warnclass,file,lang,tool,line)</code> | |||
* <code>match_loc_strict(field1, field2, ...)</code> — проверка, содержат ли locations source и target одинаковые location по указанным полям; | |||
:Пример: <code>match_loc_strict(warnclass,file,lang,tool,line)</code> | |||
* <code> | * <code>match_source_re(field, value)</code> — проверка, содержит ли location в source запись, где field совпадает с value. Value — Golang regexp; | ||
* <code> | * <code>match_target_re(field, value)</code> — проверка, содержит ли location в target запись где field совпадает с value. Value — Golang regexp; | ||
* <code> | * <code>source_review(status[, severity, action])</code> — проверка, если разметка source соответствует указанным параметрам. <code>severity, action</code> можно опускать, шаблон <code>"*"</code> соответствует всему; | ||
* <code> | * <code>target_review(status[, severity, action])</code> — проверка, если разметка target соответствует указанным параметрам. <code>severity, action</code> можно опускать, шаблон <code>"*"</code> соответствует всему; | ||
* <code> | * <code>match_source_range(lower_bound,upper_bound)</code> — проверка, если в source есть location, где line попадает в указанный диапазон. Значение <code>-1</code> означает отсутствие границы; | ||
* <code> | * <code>match_target_range(lower_bound,upper_bound)</code> — проверка, если в target есть location, где line попадает в указанный диапазон. Значение <code>-1</code> означает отсутствие границы; | ||
* <code> | * <code>match_suffix_re(field, source_prefix[,target_prefix])</code> — проверка, есть ли location в source и target, который содержит общий суффикс. Суффикс вычисляется путем отрезания префикса source_prefix и target_prefix. Если target_prefix не указан, то считается, что он равен source_prefix. Префикс определяется как Go regexp; | ||
* <code> | * <code>match_source_id(id1, id2, ...)</code> — проверка, если внутренний id source разметки совпадает с одним из аргументов; | ||
* <code> | * <code>match_target_id(id1, id2, ...)</code> — проверка, если внутренний id target разметки совпадает с одним из аргументов; | ||
* <code> | * <code>source_review_ct() time.Time</code> — возвращает время создания разметки в source; | ||
* <code> | * <code>target_review_ct() time.Time</code> — возвращает время создания разметки в target; | ||
* <code> | * <code>source_reviewed_by() string</code> — возвращает автора разметки в source; | ||
* <code>target_reviewed_by() string</code> — возвращает автора разметки в target. | |||
==== Пример ==== | |||
// Перенос разметки для Go, где поменялся формат поля function в последних Svace | // Перенос разметки для Go, где поменялся формат поля function в последних Svace | ||
Line 132: | Line 206: | ||
При использовании опции <code>--html</code>утилита формирует HTML файл с информацией о разметке и операциях по переносу. Файл предназначен для отладки процесса переноса. В будущем, в Svacer UI будет предусмотрен специальный интерфейс для просмотра результатов переноса. | При использовании опции <code>--html</code>утилита формирует HTML файл с информацией о разметке и операциях по переносу. Файл предназначен для отладки процесса переноса. В будущем, в Svacer UI будет предусмотрен специальный интерфейс для просмотра результатов переноса. | ||
[[File:ReviewerHTML1.png|none|thumb]] | [[File:ReviewerHTML1.png|none|thumb]] | ||
При наличии переноса разметки в столбце с Review будет запись Review Source | |||
[[File:ReviewerHTMLReport2.png|none|thumb]]При раскрытии элемента Review Source будут представлены основные поля location | При наличии переноса разметки в столбце с Review будет запись Review Source со ссылкой на элемент, откуда была перенесена разметка. | ||
[[File:ReviewerHTMLReport2.png|none|thumb]] | |||
При раскрытии элемента Review Source будут представлены основные поля location, соответствующих исходной разметке, откуда был сделан перенос. |
Latest revision as of 17:46, 6 May 2025
Репликация разметки по правилам (экспериментальная функциональность)
При использовании разных версий Svace (или иных анализаторов), разных настроек CI/CD и прочих факторах возможны ситуации, когда снимки (snapshots) в рамках одной ветки (branch) могут иметь различные инварианты и разметка автоматически не переносится. Для решения задачи переноса разметки в таких случаях разработана утилита reviewer, которая позволяет применить декларативно описанные правила переноса к существующей разметке. В дальнейшем данная функциональность будет включена в Svacer и доступна в веб-интерфейсе.
Использование утилиты подразумевает использование CLI команд svacer markup2 export
и svacer markup2 import
(описание markup2) для выгрузки и импортирования разметки. Утилита reviewer обеспечивает модификацию выгружаемой разметки с целью копирования существующей разметки на неразмеченные элементы. Правила копирования задаются с использованием булевых выражений и набора предопределенных предикатов.
Описание утилиты
Утилита reviewer предназначена для Svacer версии 10 и выше. Утилита собрана под Linux, скачать можно отсюда.
История изменений
Версия | Детали |
---|---|
devel.2025-04-22@06:39:21.a3bc1bc1 |
|
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
HTML отчет о результатах переноса
При использовании опции --html
утилита формирует HTML файл с информацией о разметке и операциях по переносу. Файл предназначен для отладки процесса переноса. В будущем, в Svacer UI будет предусмотрен специальный интерфейс для просмотра результатов переноса.

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

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