Review replication: Difference between revisions

From Svacer Wiki
mNo edit summary
m (change link to mediawiki server + some minor fixes)
 
(23 intermediate revisions by 2 users not shown)
Line 1: Line 1:
== Репликация разметки по правилам (экспериментальная функциональность) ==
== Репликация разметки по правилам (экспериментальная функциональность) ==
При использовании разных версий Svace (или иных анализаторов), разных настроек CI/CD и прочих факторах возможны ситуации, когда снимки (snapshots) в рамках одной ветки (branch) могут иметь различные инварианты и разметка автоматически не переносится. Для решения задачи переноса разметки в таких случаях разработана утилита <code>reviewer</code>, которая позволяет применить декларативно описанные правила переноса к существующей разметке. В дальнейшем данная функциональность будет включена в Svacer и доступна в веб интерфейсе.
При использовании разных версий Svace (или иных анализаторов), разных настроек CI/CD и прочих факторах возможны ситуации, когда снимки (snapshots) в рамках одной ветки (branch) могут иметь различные инварианты и разметка автоматически не переносится. Для решения задачи переноса разметки в таких случаях разработана утилита '''reviewer''', которая позволяет применить декларативно описанные правила переноса к существующей разметке. В дальнейшем данная функциональность будет включена в Svacer и доступна в веб-интерфейсе.
 
Использование утилиты подразумевает использование CLI команд <code>svacer markup2 export</code> и <code>svacer markup2 import</code> ([[Markup2|описание markup2]]) для выгрузки и импортирования разметки. Утилита reviewer обеспечивает модификацию выгружаемой разметки с целью копирования существующей разметки на неразмеченные элементы. Правила копирования задаются с использованием булевых выражений и набора предопределенных предикатов.


=== Описание утилиты ===
=== Описание утилиты ===
Утилита <code>reviewer</code> предназначена для Svacer версии 10 и выше.  
Утилита 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     Prints help information about rule syntax
     syntax     Prints help information about rule syntax
     replicate Replicate non-empty review to invariants according to rules
    invariants  Get information about invariants from branch. Output format is ReviewModificationJournal.SnapshotList with invariants 
     help, h   Shows a list of commands or help for one command
     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 (default: admin)
     --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, -h          show help
     --help               Show help (default: false)
Основная команда, это <code>replicate</code>  - она позволяет применить декларативные правила к разметке, полученной либо с сервера либо из файла, куда ранее она была выгружена командой <code>svacer markup2 export</code>.
    --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 output file with applied rules
     reviewer replicate [command options] <file name> - path to result file
   
   
  OPTIONS:
  OPTIONS:
     --project value Project name or id
     --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     Path to file containing replicate rules
    --target-branch value    Branch name or id of the target branch (default: master)
     --html           Produce HTML report showing applied changes.Report wil have name <file name>.html (default: false)
    --source-snapshot value  Snapshot name or id. Replicate reviews only from given snapshot. Host, project and branch must be provided
     --verbose       Verbose output of rule applications (default: false)
    --target-snapshot value  Snapshot name or id. Replicate reviews only to given snapshot. Host, project and branch must be provided
     --process-all   Process all reviews, even with non-default values (default: false)
     --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 Skip comments while replicating review information (default: false)
     --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   Skip review status and copy only comments while replicating review information (default: false)
     --rule value             Path to file containing replicate rules
     --help, -h      show 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.
'''Задача:''' в проекте myproject на ветке master необходимо перенести существующую разметку по некоторым правилам. Сервер запущен на localhost на порту 8080.


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


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


  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
  <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>


* написать правила переноса разметки в файл <code>/tmp/map.txt</code> (формат будет описан ниже)
5. Проанализировать созданный журнал изменений и файл <code>/tmp/out.json.html</code>
* (если разметка '''была выгружена''') применить утилиту <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
6. Если результат устраивает, то загрузить обновленную разметку в сервер из файла <code>/tmp/out.json</code>


* ('''без выгрузки''' разметки) применить утилиту <code>reviewer</code> с загрузкой данных с сервера (флаг <code>--html</code> создаст дополнительно HTML с информацией об изменениях , имя файла <code>/tmp/out.json.html</code>)
<nowiki>svacer markup2 --host=http://localhost:8080 --user admin --password admin import --project myproject --branch master /tmp/out.json</nowiki>


reviewer --host=http://localhost:8080 --user admin --password admin replicate --project myproject --branch master --rule /tmp/map.txt --html /tmp/out.json
'''Примечания'''


* просмотреть созданный файл <code>/tmp/out.json.html</code>
Разметка в Svacer привязана к инвариантам. Инвариант это некоторый хэш, формируемый из полей предупреждения. Алгоритм формирования хэша описан в [[Help:Match#Описание_алгоритма|этой статье]]. В рамках одного снимка все инварианты всегда уникальны.
* если результат устраивает, то загрузить обновленную разметку в сервер


svacer markup2 --host=<nowiki>http://localhost:8080</nowiki> --user admin --password admin import --project myproject --branch master /tmp/out.json
Команда <code>markup2 export</code> с флагом <code>--export-all</code> выгружает все инварианты с ветки с информацией о разметке и комментариях.  


==== Пояснения ====
При экспорте разметка на инварианте представлена как объект, соответствующий схеме, описанной в статье [[Markup2]]. Технически это: 
Разметка в Svacer привязана к инвариантам. Инвариант это некоторый хэш, формируемый из полей предупреждения. Алгоритм формирования хэша описан здесь: [[Help:Match|формирование инвариантов]]. В рамках одного снимка все инварианты всегда уникальны.


Команда <code>markup2 export</code> с флагом <code>--export-all</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>. Во избежание перезаписи разметки можно в правилах использовать предикат <code>unprocessed()</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>processed()</code> — проверка, что target уже содержит какую-либо не дефолтную разметку;
 
* <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>match_source_re(field, value)</code> — проверка, содержит ли location в source запись, где field совпадает с value. Value — Golang regexp;
 
* <code>match_target_re(field, value)</code> — проверка, содержит ли location в target запись где field совпадает с value. Value — Golang regexp;
 
* <code>source_review(status[, severity, action])</code> — проверка, если разметка source соответствует указанным параметрам. <code>severity, action</code> можно опускать, шаблон <code>"*"</code> соответствует всему;
 
* <code>target_review(status[, severity, action])</code> — проверка, если разметка target соответствует указанным параметрам. <code>severity, action</code> можно опускать, шаблон <code>"*"</code> соответствует всему;
 
* <code>match_source_range(lower_bound,upper_bound)</code> — проверка, если в source есть location, где line попадает в указанный диапазон. Значение <code>-1</code> означает отсутствие границы;   
 
* <code>match_target_range(lower_bound,upper_bound)</code> — проверка, если в target есть location, где line попадает в указанный диапазон. Значение <code>-1</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>match_source_id(id1, id2, ...)</code> — проверка, если внутренний id source разметки совпадает с одним из аргументов;
 
* <code>match_target_id(id1, id2, ...)</code> — проверка, если внутренний id target разметки совпадает с одним из аргументов;
 
* <code>source_review_ct() time.Time</code> — возвращает время создания разметки в source;
 
* <code>target_review_ct() time.Time</code> — возвращает время создания разметки в target;
 
* <code>source_reviewed_by() string</code> — возвращает автора разметки в source;
 
* <code>target_reviewed_by() string</code> — возвращает автора разметки в 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 отчет о результатах переноса ====
При использовании опции <code>--html</code>утилита формирует HTML файл с информацией о разметке и операциях по переносу. Файл предназначен для отладки процесса переноса. В будущем, в Svacer UI будет предусмотрен специальный интерфейс для просмотра результатов переноса.
[[File:ReviewerHTML1.png|none|thumb]]
 
При наличии переноса разметки в столбце с 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
  • Добавлены предикаты 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

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

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

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

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