Markup2: Difference between revisions
mNo edit summary |
m (minor fixes) |
||
(3 intermediate revisions by 2 users not shown) | |||
Line 133: | Line 133: | ||
* Запрос должен быть формата '''multipart/form-data''', поле '''file''' должно содержать файл с разметкой | * Запрос должен быть формата '''multipart/form-data''', поле '''file''' должно содержать файл с разметкой | ||
* Запрос должен иметь токен аутентификации | * Запрос должен иметь токен аутентификации | ||
* Пользователь должен иметь доступы на | * Пользователь должен иметь доступы на импорт разметки. Если пользователь '''не имеет''' атрибута '''review master''', то перезапись текущей разметки от '''review master''' не будет производится (т. е. обычный пользователь не сможет изменить разметку review master-а через импорт). | ||
Query параметры: | Query параметры: | ||
Line 215: | Line 215: | ||
Семантика операции Undo следующая: | Семантика операции Undo следующая: | ||
* Разметка, внесенная групповой операцией удаляется. Если она была активной, то ставится предыдущая активная разметка | * Разметка, внесенная групповой операцией, удаляется. Если она была активной, то ставится предыдущая активная разметка | ||
* Комментарии, внесенные групповой операцией, будут удалены только если они не модифицировались после групповой операции | * Комментарии, внесенные групповой операцией, будут удалены только если они не модифицировались после групповой операции | ||
* По умолчанию при отмене операции происходит проверка, является ли она последней групповой операцией на данной ветке. Если она не является последней, то будет ошибка (для принудительной отмены используется параметр <code>check_order</code>) | * По умолчанию при отмене операции происходит проверка, является ли она последней групповой операцией на данной ветке. Если она не является последней, то будет ошибка (для принудительной отмены используется параметр <code>check_order</code>) | ||
* Статус разметок может меняться в зависимости от порядка применений нескольких операций Undo | |||
Для экономии памяти рекомендуется периодически удалять записи из журнала групповых операций. | Для экономии памяти рекомендуется периодически удалять записи из журнала групповых операций. | ||
Line 239: | Line 240: | ||
При использовании операций по импорту разметки или использовании API/UI для выполнения групповых операций по разметке информация о выполненных операциях будет занесена в журнал групповых операций. Журнал фиксирует дату, пользователя и все внесенные изменения: изменение самой разметки и добавленные комментарии. | При использовании операций по импорту разметки или использовании API/UI для выполнения групповых операций по разметке информация о выполненных операциях будет занесена в журнал групповых операций. Журнал фиксирует дату, пользователя и все внесенные изменения: изменение самой разметки и добавленные комментарии. | ||
===== Просмотр журнала операций | ===== Просмотр журнала операций ===== | ||
svacer markup2 --host <host url> --user admin --password admin list | svacer markup2 --host <host url> --user admin --password admin list | ||
Line 250: | Line 251: | ||
85 APPLIED Lua/v5.3 batch-review batch review operation | 85 APPLIED Lua/v5.3 batch-review batch review operation | ||
===== Отмена операции | ===== Отмена операции ===== | ||
svacer markup2 --host localhost:8080 --user admin --password admin undo --id=94 | svacer markup2 --host localhost:8080 --user admin --password admin undo --id=94 | ||
2025-05-14T11:47:33.559+0300 info Log file location /tmp/svacer-client-2025-05-14.log | 2025-05-14T11:47:33.559+0300 info Log file location /tmp/svacer-client-2025-05-14.log | ||
2025-05-14T11:47:33.560+0300 info Scheme not found in the provided host (localhost:8080), assume 'http' | 2025-05-14T11:47:33.560+0300 info Scheme not found in the provided host (localhost:8080), assume 'http' | ||
Line 261: | Line 261: | ||
===== Удаление записей из журнала ===== | ===== Удаление записей из журнала ===== | ||
{{Note|type=warn|text=Удаление записей из журнала не отменяет внесенных изменений (т. е. разметки и комментариев), но после удаления записей из журнала отмена соответствующих изменений будет невозможна}} | |||
Для удаления можно использовать разный набор условий | Для удаления можно использовать разный набор условий | ||
NAME: | NAME: | ||
svacer markup2 delete - Delete entries from batch review operation list. ATTENTION: you cannot undo batch operation if you remove it | svacer markup2 delete - Delete entries from batch review operation list. ATTENTION: you cannot undo batch operation if you remove it | ||
Line 282: | Line 283: | ||
--keep-last-n value Keep last N entries (default: 0) | --keep-last-n value Keep last N entries (default: 0) | ||
--help Show help (default: false) | --help Show help (default: false) | ||
Пример | |||
Пример: оставим последние 10 операций в журнале | |||
svacer markup2 --host localhost:8080 --user admin --password admin delete --keep-last-n 10 | svacer markup2 --host localhost:8080 --user admin --password admin delete --keep-last-n 10 | ||
2025-05-14T11:51:31.121+0300 info Log file location /tmp/svacer-client-2025-05-14.log | 2025-05-14T11:51:31.121+0300 info Log file location /tmp/svacer-client-2025-05-14.log | ||
2025-05-14T11:51:31.121+0300 info Scheme not found in the provided host (localhost:8080), assume 'http' | 2025-05-14T11:51:31.121+0300 info Scheme not found in the provided host (localhost:8080), assume 'http' |
Latest revision as of 16:53, 16 May 2025
Public REST API для экспорта, импорта и копирования разметки
Релиз 10.х Svacer включает новый API, предназначенный для экспорта, импорта и копирования разметки.
Релиз 11.х Svacer добавил журнал групповых операций связанных с импортом разметки и возможность отката внесенных изменений. Для журнала групповых операций доступно public API.
# Импорт, экспорт и копирование разметки POST /api/public/markup/import POST /api/public/markup/export POST /api/public/markup/copy # Работа с журналом групповых операций по разметки GET /api/public/markup/list_operations DELETE /api/public/markup/list_operations POST /api/public/markup/undo
Разметка описывается посредством protobuf схемы:
// Represents exported review (review itself + comments) // Review is associated with invariant and has list of locations message Review { // Defines model for concrete location of the review message Location { string warnClass = 1; string file = 2; uint32 line = 3; string details = 4; string mtid = 5; string function = 10; bytes content_hash = 6; bytes trace_hash = 7; bytes marker_hash = 8; bytes line_hash = 9; string tool = 11; string lang = 12; } // Defines model for comment message Comment { string text = 1; optional string format = 2; google.protobuf.Timestamp create_ts = 3; optional google.protobuf.Timestamp update_ts = 4; string createdBy = 5; string origin_id = 6; optional uint64 review_id = 7; // refers to Review.id field optional string created_by_id = 8; } // Defines model for review itself message ReviewData { string status = 1; string severity = 2; string action = 3; string origin_id = 4; google.protobuf.Timestamp create_ts = 5; string created_by = 6; optional string created_by_id = 7; optional string created_from = 8; } // Invariant of the marker string invariant = 1; // Review information associated with markers having given invariant optional ReviewData review_data = 2; // List of comments associated with all markers having given invariant repeated Comment comments = 3; // List of locations associated with given invariant. Locations can be used to apply fuzzy matching of review with existing data when there is no invariant match repeated Location locations = 4; // Export-specific ID, comments can refer to this id if comment is associated with review operation uint64 id = 5; // Meta-information about export, when exporting to file field is initialized only for the first element optional ReviewExportMeta meta = 6; } // Defines meta-information about exported review message ReviewExportMeta { message Container { string id = 1; string name = 2; } google.protobuf.Timestamp create_ts = 1; // timestamp when export was produced (UTC) string created_by = 2; // user who triggered export string svacer_version = 3; // svacer version optional Container project = 4; // source container (project) optional Container branch = 5; // source container (branch) map<string,string> properties = 6; // extra properties }
Актуальную версию схемы можно получить из Svacer по API: GET /api/public/markup/schema
.
Svacer поддерживает два формата для экспортирования/импортирования разметки:
- JSON с разделением по newline-ам. Каждая строка представляет собой объект типа Review (указано выше) сериализованный в JSON
- Бинарный формат: последовательность блоков
[lenght little endian][proto]
, где первый блок содержит длину следующего блока в форматеu32 little endian
, а второй блок содержит proto-сериализацию объекта Review
В обоих случаях при выгрузке разметки первый элемент типа Review будет содержать мета-информацию об исходном контексте, откуда была выгружена разметка.
Разметка привязывается к инварианту маркера и может содержать собственно разметку (статус маркера) и совокупность комментариев, связанных с данным маркером. При выгрузке разметки также добавляется информация о конкретных локациях предупреждений, ассоциированных с инвариантом. В будущих версиях данная информация будет использоваться для переноса разметки при отсутствии прямого совпадения инвариантов.
Экспорт разметки
POST /api/public/markup/export
- Параметры передаются в body запроса
- Запрос должен иметь токен аутентификации
- Пользователь должен иметь доступы на Public API и экспорт разметки из ветки, откуда производится экспорт
Формат body:
{ "source": ["<project name>","<branch name>"], "source_id": "<branch id>", "skip_comments": <true|false>, "skip_review": <true|false>, "format": "<json|proto>", "export_all": <true|false>, "compressed": <true|false>, "filters" : [ { "pattern": "<regular expression>", "ids": ["<snapshot id>", "<snapshot id>"] } ] }
- Пользователь должен указать либо source элемент, либо source_id
- Опция skip_comments позволяет игнорировать комментарии при выгрузке разметки
- Опция skip_review позволяет игнорировать статусы маркеров при выгрузке разметки (т. е. выгружать только комментарии)
- Опция export_all позволяет выгрузить пустую разметку (т. е. статусы Undecided/Unspecified/Undecided). Это позволяет получить список всех инвариантов для ветки и использовать данные для генерации требуемой разметки для импорта
- Метод возвращает gzipped файл содержащий разметку в указанном формате если
compressed = true
- Поле
filters
позволяет указать набор фильтров для снимков. Все фильтры применяются по принципу AND. Полеpattern
в фильтре задает фильтрацию по имени снимка, полеids
— по ID снимков.
Импорт разметки
POST /api/public/markup/import
- Параметры передаются в query запроса
- Запрос должен быть формата multipart/form-data, поле file должно содержать файл с разметкой
- Запрос должен иметь токен аутентификации
- Пользователь должен иметь доступы на импорт разметки. Если пользователь не имеет атрибута review master, то перезапись текущей разметки от review master не будет производится (т. е. обычный пользователь не сможет изменить разметку review master-а через импорт).
Query параметры:
project — <project name> — имя проекта branch — <branch name> — имя бранча target_id — <branch id> — id бранча. Должно быть либо id бранча, либо имя проекта + имя бранча. Приоритет — id бранча format — <proto|json> — формат импортируемой разметки. Если не указан, будет определяться автоматически overwrite — <none|force|last> — по умолчанию last — контролирует логику применения разметки к бранчу при импорте skip_comments — <true|false> — по умолчанию false — игнорировать комментарии skip_review — <true|false> — по умолчанию false — игнорировать статус разметки (импорт только комментариев) response_with_result — <true|false> — вернуть детальный список разметок, которые были применены, в формате JSON с newline-разделителями. Если не указан, то возвращается краткий статус compressed — <true|false> — формат файла с разметкой, если true то подразумевается gzip-compressed файл
Настоятельно рекомендуется явно указывать параметр overwrite.
В случае успеха метод возвращает body со следующими данными:
{"total":<total number of loaded reviews>,"applied_reviews":<applied reviews>,"applied_comments":<applied comments>,"skipped_reviews":<skipped reviews>,"duplicate_reviews":<duplicate reviews>,"duplicate_comments":<duplicate comments} <json representation of applied review>*
Первая строка body содержит JSON с информацией о выполненных действиях. Если был указан параметр response_with_result, то дальше будут идти newline-separated JSON представления примененных review.
Алгоритм импорта
- Блокируются операции по разметке и импорту на целевой бранч
- Выгружается текущая разметка бранча с комментариями
- Загруженная разметка сопоставляется с текущей и формируется список разметки для применения. Дублирующая разметка и комментарии игнорируются
- Перезапись разметки контролируется параметром overwrite. Если значение none, то разметка не перезаписывается при наличии разметки в целевом бранче. Если значение force, то разметка будет перезаписана. Если значение last, то разметка будет перезаписана, если загруженная разметка имеет более новую дату
- Пустая разметка (Undecided/Unspecified/Undecided) явным образом не применяется к инварианту, если разметка отсутствует на бранче
- Сформированный список применяется к бранчу. При выборе маркера, куда добавлять комментарий, выбирается маркер из наиболее раннего снимка, где маркер с соответствующим инвариантом появился
Допустимые значения полей разметки:
- Status —
"Confirmed", "Won't fix", "False Positive", "Unclear", "Undecided"
- Severity —
"Unspecified", "Critical", "Major", "Minor"
- Action —
"Undecided", "Fix required", "Fix submitted", "Ignore"
Копирование разметки
POST /api/public/markup/copy
- Параметры передаются в body запроса
- Запрос должен иметь токен аутентификации
- Пользователь должен иметь доступы на Public API, экспорт снимков (для исходной ветки), импорт разметки (для целевой ветки), разрешения Update any review и Update any comment (для перезаписи разметки и комментариев ревью мастера)
Формат body:
{ "source": ["<project name>","<branch name>"], "source_id": "<branch id>", "target": ["<project name>","<branch name>"], "target_id": "<branch id>", "skip_comments": <true|false> — по умолчанию false, "skip_review": <true|false> — по умолчанию false, "overwrite": "<none|last|force>", "response_with_result": <true|false> }
В случае успеха, метод возвращает body со следующими данными
{"total":<total number of loaded reviews>,"applied_reviews":<applied reviews>,"applied_comments":<applied comments>,"skipped_reviews":<skipped reviews>,"duplicate_reviews":<duplicate reviews>,"duplicate_comments":<duplicate comments} <json representation of applied review>*
Первая строка body содержит JSON с информацией о выполненных действиях. Если был указан параметр response_with_result, то дальше будут идти newline-separated JSON представления примененных review.
Журнал групповых операций (для версии 11.х.х и выше)
Импорт разметки а также использование групповой разметки (из UI или посредством API) фиксирует операции в журнале групповых операций. Для работы с журналом доступно public REST API:
# Получения списка групповых операций GET /api/public/markup/list_operations
# Удаление записи из журнала групповых операций DELETE /api/public/markup/list_operations
# Отмена изменений, внесенных групповой операцией POST /api/public/markup/undo
Описание параметров доступно в Swagger.
Семантика операции Undo следующая:
- Разметка, внесенная групповой операцией, удаляется. Если она была активной, то ставится предыдущая активная разметка
- Комментарии, внесенные групповой операцией, будут удалены только если они не модифицировались после групповой операции
- По умолчанию при отмене операции происходит проверка, является ли она последней групповой операцией на данной ветке. Если она не является последней, то будет ошибка (для принудительной отмены используется параметр
check_order
) - Статус разметок может меняться в зависимости от порядка применений нескольких операций Undo
Для экономии памяти рекомендуется периодически удалять записи из журнала групповых операций.
CLI API для импорта/экспорта/копирования разметки
Данное API является экспериментальным и может меняться. Основные аргументы будут сохранены. По умолчанию команды под markup2 скрыты. Использовать можно, указывая их явно. Для получения помощи запустить:
# Импорт, экспорт, копирование разметки svacer markup2 --help svacer markup2 copy --help svacer markup2 import --help svacer markup2 export --help
# Работа с журналом групповых операций svacer markup2 list --help svacer markup2 undo --help svacer markup2 delete --help
Описание работы с журналом групповых операций
При использовании операций по импорту разметки или использовании API/UI для выполнения групповых операций по разметке информация о выполненных операциях будет занесена в журнал групповых операций. Журнал фиксирует дату, пользователя и все внесенные изменения: изменение самой разметки и добавленные комментарии.
Просмотр журнала операций
svacer markup2 --host <host url> --user admin --password admin list
id status target action description ts user 94 APPLIED local/b1 import-review import comments as part of raw result import 2025-04-24 13:19:30.675 +0300 MSK admin 91 APPLIED bash/master batch-review batch review operation 2025-04-18 16:09:17.963822 +0300 MSK admin 89 APPLIED dxr-test/master batch-review batch review operation 2025-04-18 14:21:42.82489 +0300 MSK admin 87 APPLIED Lua_clone2/v5.3 copy-review copy review from 61c4290b-d06a-484f-b980-8d7cbb660fb4 to 0588686d-a1da-4f11-b948-d07a9d12fb60 2025-04-18 12:57:09.49 +0300 MSK admin 86 APPLIED Lua_clone1/v5.3 import-review import review by request from WEB or REST API; client address: 10.10.168.102:52020, user agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 YaBrowser/25.2.0.0 Safari/537.36 2025-04-18 12:54:17.239 +0300 MSK admin 85 APPLIED Lua/v5.3 batch-review batch review operation
Отмена операции
svacer markup2 --host localhost:8080 --user admin --password admin undo --id=94
2025-05-14T11:47:33.559+0300 info Log file location /tmp/svacer-client-2025-05-14.log 2025-05-14T11:47:33.560+0300 info Scheme not found in the provided host (localhost:8080), assume 'http' 2025-05-14T11:47:33.560+0300 info Querying server configuration from http://localhost:8080/api/public/server/info 2025-05-14T11:47:33.560+0300 info Server version: [11-0-0] 2025-05-14T11:47:33.599+0300 info Unapplied batch review operations [94]
Удаление записей из журнала
Для удаления можно использовать разный набор условий
NAME: svacer markup2 delete - Delete entries from batch review operation list. ATTENTION: you cannot undo batch operation if you remove it USAGE: svacer markup2 delete [command options] [arguments...] DESCRIPTION: When multiple flags are used to specify conditions, all conditions will be applied in order: --id, (--from, --to), --keep-last-n Flag --last will override values of --from and --to OPTIONS: --id value [ --id value ] ID of the batch operation --from value Set start date for the report. Expected format '2006-01-02 15:04:05' in local timezone --to value Set end date for the report. Expected format '2006-01-02 15:04:05' in local timezone --last value Delete operations for the specified last period of time. Possible values: @hour, @day, @week, @month, @year --keep-last-n value Keep last N entries (default: 0) --help Show help (default: false)
Пример: оставим последние 10 операций в журнале
svacer markup2 --host localhost:8080 --user admin --password admin delete --keep-last-n 10
2025-05-14T11:51:31.121+0300 info Log file location /tmp/svacer-client-2025-05-14.log 2025-05-14T11:51:31.121+0300 info Scheme not found in the provided host (localhost:8080), assume 'http' 2025-05-14T11:51:31.121+0300 info Querying server configuration from http://localhost:8080/api/public/server/info 2025-05-14T11:51:31.122+0300 info Server version: [11-0-0] 2025-05-14T11:51:31.146+0300 info Deleted 37 entries from the list
Описание команд импорта, экспорта и копирования
NAME: svacer markup2 - New [experimental] API for review export/import/copy USAGE: svacer markup2 command [command options] [arguments...] COMMANDS: import Import markup from file and apply to specified branch export Export markup to file or stdout. Command needs either branch ID or project and branch name. When exporting to file, data is gzipped. copy Copy markup between branches help, h Shows a list of commands or help for one command OPTIONS: --ssl Connect to the server using https protocol (default: false) --ssl-ca-certs value Trusted CA cert path. Example: /usr/local/certs/* , /usr/local/certs/ca.crt, /usr/local/certs/ca*.crt --user value Valid user name --password value Valid user password --oidc-client value ClientID for login with OpenID Connect protocol --oidc-secret value Client's secret for login with OpenID Connect protocol --host value Valid host name with running svace history server (default: localhost) [$SVACER_HOST_NAME] --port value Defines port for REST API (default: 8080) [$SVACER_API_PORT] --grpc value Defines port for gRPC API (default: 3002) [$SVACER_GRPC_PORT] --ldap_server value Server for LDAP authentication [$SVACER_LDAP_SERVER] --conn_file value Use connection file [$SVACER_CONN_FILE] --dry-run Do actions but don't commit result to database (default: false) --help Show help (default: false)
Импорт разметки из файла
NAME: svacer markup2 import - Import markup from file and apply to specified branch USAGE: svacer markup2 import [command options] <file> - path to file to import. If file is not specified, data is loaded from stdin OPTIONS: --project value Target project name --branch value Target branch name --branch-id value Target branch ID --skip-review Import comments only (default: false) --skip-comments Import review only (default: false) --overwrite value Overwrite mode: none, force, last --out value Write information about applied reviews to given file (in json format). If not specified, result is printed to stdout --verbose-out Include information about applied reviews (default: false) --format value Specify explicit format for data. If not specified, format will be detected from content --description value Specify optional description the given import operation. If not specified, unique ID will be generated based on hostname, user and time --generated-by value Optional tool generated review information --help Show help (default: false)
При импорте разметки используя флаги --description
и --generated-by
можно задать дополнительную информацию, связанную с данной разметкой. Она будет занесена в журнал операций импорта.
Экспорт разметки в файл
NAME: svacer markup2 export - Export markup to file or stdout. Command needs either branch ID or project and branch name. Use --snapshot-id and --snapshot to filter results by snapshots (filters are applied by AND rule) USAGE: svacer markup2 export [command options] <file name or empty> - if no file name is specified, result is printed to stdout OPTIONS: --project value Source project name --branch value Source branch name. Branch name will be resolved against source project (default: master) --branch-id value Source branch ID --skip-review Export comments only (default: false) --skip-comments Export review only (default: false) --format value Format: json or proto. If format is not specified, proto is used. If output file is not specified and format is not specified, json will be used. --uncompressed Get data in raw format without gzip compression (default: false) --export-all Export empty (undecided) review (default: false) --snapshot-id value [ --snapshot-id value ] Filter results by snapshots with specified IDs. When using --snapshot flag, results will be filtered by name pattern as well --snapshot value Filter results by snapshots matching pattern. Pattern is matched against snapshot name. When using --snapshot-id flag, results will be filtered by ID as well --help
Для экспорта разметки из конкретных снимков можно использовать флаги --snapshot-id
или --snapshot
.
Копирование разметки
NAME: svacer markup2 copy - Copy markup between branches USAGE: svacer markup2 copy [command options] [arguments...] OPTIONS: --target-project value Target project name --target-branch value Target branch name --target-branch-id value Target branch ID --source-project value Source project name --source-branch value Source branch name --source-branch-id value Source branch ID --skip-review Copy comments only (default: false) --skip-comments Copy review only (default: false) --overwrite value Overwrite mode: none, force, last --out value Write information about applied reviews to given file (in json format). If not specified, result is printed to stdout --verbose-out Include information about applied reviews (default: false) --help Show help (default: false)
Примеры использования
svacer markup2 --user admin --password admin copy --overwrite=force --source-project bash --target-project bash --source-branch master --target-branch bash_clone 2024-11-15T13:19:41.735+0300 info Log file location /tmp/svacer-1543671068.log 2024-11-15T13:19:41.735+0300 info Quering server configuration from http://localhost:8080/api/public/server/info 2024-11-15T13:19:41.745+0300 info Server version: [devel] {"total":771,"applied_reviews":0,"applied_comments":0,"skipped_reviews":771,"duplicate_reviews":771,"duplicate_comments":5}
svacer markup2 --user admin --password admin import --overwrite=force --project bash --branch bash_clone /tmp/out.json 2024-11-15T13:20:17.433+0300 info Log file location /tmp/svacer-1480510331.log 2024-11-15T13:20:17.433+0300 info Quering server configuration from http://localhost:8080/api/public/server/info 2024-11-15T13:20:17.435+0300 info Server version: [devel] {"total":771,"applied_reviews":0,"applied_comments":0,"skipped_reviews":771,"duplicate_reviews":771,"duplicate_comments":5}
2024-11-15T15:46:06.809+0300 info Log file location /tmp/svacer-1792255677.log 2024-11-15T15:46:06.809+0300 info Quering server configuration from http://localhost:8080/api/public/server/info 2024-11-15T15:46:06.810+0300 info Server version: [devel] {"invariant":"+1vB4JXkME3AAcbXR7tezA", "review_data":{"status":"Confirmed", "severity":"Unspecified", "action":"Undecided", "create_ts":"2024-10-16T14:44:07.233554Z", "created_by":"admin", "created_from":"1c8cea92-7708-4bb9-9a88-40325f39efe8"}, "locations":[{"warnClass":"PROC_USE.VULNERABLE", "file":"/.build/jobs.c", "line":4207, "details":"b043c5a63bf9d432c816f2cb421c907fe912bf16", "mtid":"SvEng.L.1", "function":"run_sigchld_trap", "content_hash":"s4AMYzKR8Ol8k4OODPpOlPUsSWI=", "marker_hash":"XiVQmRu8HmhzOnq1+XY7AaujT+o=", "tool":"SvEng", "lang":"C_Cpp"}], "id":"699", "meta":{"create_ts":"2024-11-15T12:46:06.835078490Z", "created_by":"admin", "svacer_version":"devel.2024-11-15@15:45:34.a290bc7e", "project":{"id":"0fd645aa-8e70-4a4f-b68b-766c4f337bf2", "name":"bash"}, "branch":{"id":"8925df5a-7a98-4f07-bc88-ee4ea5b43813", "name":"master"}}}