From 9d2f281bd099d4bfacb2eb43c2285b7d32f0d336 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=B5=D0=B4=D0=B2=D0=B5=D0=B4=D0=B5=D0=B2=20=D0=94?= =?UTF-8?q?=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9=20=D0=90=D0=BB=D0=B5=D0=BA?= =?UTF-8?q?=D1=81=D0=B0=D0=BD=D0=B4=D1=80=D0=BE=D0=B2=D0=B8=D1=87=20=28000?= =?UTF-8?q?095681=29?= Date: Thu, 29 Sep 2022 10:08:15 +0300 Subject: [PATCH 1/2] =?UTF-8?q?ORAIS-421=20/=20=D0=98=D0=BD=D1=81=D1=82?= =?UTF-8?q?=D1=80=D1=83=D0=BC=D0=B5=D0=BD=D1=82=20=D0=B4=D0=BB=D1=8F=20?= =?UTF-8?q?=D0=BF=D0=B5=D1=80=D0=B5=D0=BD=D0=BE=D1=81=D0=B0=20=D0=BE=D1=88?= =?UTF-8?q?=D0=B8=D0=B1=D0=BE=D0=BA=20EDT=20=D0=B2=20SQ?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 4 + README.md | 51 +- custom-rules.json | 1184 +++++++++++++++++ edt-ripper-0.7.ospx | Bin 0 -> 21416 bytes packagedef | 19 + src/main.os | 61 + ...207\320\265\321\202\320\276\320\262BSL.os" | 136 ++ ...21\202\320\260\320\225\320\224\320\242.os" | 69 + ...21\200\320\260\320\262\320\270\320\273.os" | 14 + ...21\200\320\260\320\262\320\270\320\273.os" | 145 ++ ...21\200\320\260\321\206\320\270\321\217.os" | 155 +++ ...21\207\320\260\320\275\320\270\320\271.os" | 55 + ...20\266\320\265\320\275\320\270\321\217.os" | 119 ++ ...21\210\320\270\320\261\320\276\320\272.os" | 245 ++++ ...21\207\320\260\320\275\320\270\320\271.os" | 55 + ...21\200\320\260\321\206\320\270\320\270.os" | 106 ++ .../diagnostic.json" | 17 + .../fileinfo.json" | 4 + .../report.json" | 8 + tasks/test.os | 82 ++ ...21\207\320\265\321\202\320\276\320\262.os" | 57 + ...21\210\320\270\320\261\320\276\320\272.os" | 0 ...21\200\320\260\321\206\320\270\320\270.os" | 72 + ...21\200\320\260\320\262\320\270\320\273.os" | 0 v8config.json | 23 + 25 files changed, 2680 insertions(+), 1 deletion(-) create mode 100644 .gitignore create mode 100755 custom-rules.json create mode 100644 edt-ripper-0.7.ospx create mode 100644 packagedef create mode 100644 src/main.os create mode 100644 "src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\223\320\265\320\275\320\265\321\200\320\260\321\202\320\276\321\200\320\236\321\202\321\207\320\265\321\202\320\276\320\262BSL.os" create mode 100644 "src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\274\320\260\320\275\320\264\320\260\320\237\320\260\321\200\321\201\320\265\321\200\320\236\321\202\321\207\320\265\321\202\320\260\320\225\320\224\320\242.os" create mode 100644 "src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\274\320\260\320\275\320\264\320\260\320\237\321\203\320\261\320\273\320\270\320\272\320\260\321\206\320\270\321\217\320\237\321\200\320\260\320\262\320\270\320\273.os" create mode 100644 "src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\245\321\200\320\260\320\275\320\270\320\273\320\270\321\211\320\265\320\237\321\200\320\260\320\262\320\270\320\273.os" create mode 100644 "src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\232\320\276\320\275\321\204\320\270\320\263\321\203\321\200\320\260\321\206\320\270\321\217.os" create mode 100644 "src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\232\321\200\320\270\321\202\320\270\321\207\320\275\320\276\321\201\321\202\321\214\320\227\320\260\320\274\320\265\321\207\320\260\320\275\320\270\320\271.os" create mode 100644 "src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213\320\237\321\200\320\270\320\273\320\276\320\266\320\265\320\275\320\270\321\217.os" create mode 100644 "src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\237\320\260\321\200\321\201\320\265\321\200\320\236\321\210\320\270\320\261\320\276\320\272.os" create mode 100644 "src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\242\320\270\320\277\321\213\320\227\320\260\320\274\320\265\321\207\320\260\320\275\320\270\320\271.os" create mode 100644 "src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\244\320\260\320\271\320\273\320\276\320\262\321\213\320\265\320\236\320\277\320\265\321\200\320\260\321\206\320\270\320\270.os" create mode 100644 "src/\320\240\320\265\321\201\321\203\321\200\321\201\321\213/diagnostic.json" create mode 100644 "src/\320\240\320\265\321\201\321\203\321\200\321\201\321\213/fileinfo.json" create mode 100644 "src/\320\240\320\265\321\201\321\203\321\200\321\201\321\213/report.json" create mode 100644 tasks/test.os create mode 100644 "tests/\320\223\320\265\320\275\320\265\321\200\320\260\321\202\320\276\321\200\320\236\321\202\321\207\320\265\321\202\320\276\320\262.os" create mode 100644 "tests/\320\237\320\260\321\200\321\201\320\265\321\200\320\236\321\210\320\270\320\261\320\276\320\272.os" create mode 100644 "tests/\320\244\320\260\320\271\320\273\320\276\320\262\321\213\320\265\320\236\320\277\320\265\321\200\320\260\321\206\320\270\320\270.os" create mode 100644 "tests/\320\245\321\200\320\260\320\275\320\270\320\273\320\270\321\211\320\265\320\237\321\200\320\260\320\262\320\270\320\273.os" create mode 100644 v8config.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..20b3621 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.vscode/launch.json +edt-validate-results +edt-validate-results-en +out.json \ No newline at end of file diff --git a/README.md b/README.md index 83dc27a..f1bfb08 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,51 @@ -# edt_to_sonar_export +# edt-ripper +Консольная утилита для работы с замечаниями ЕДТ и файлами правил для SQ. выполняет разбор EDT отчета анализа проекта. Формирует результат в формате bsl-ls. +Мапит обнаруженные замечания с правилами (внутренний файл правил, внешний файл правил) + +## Возможности + + 1. Команда `parse` - Преобразует файл с результатом анализа проекта из ЕДТ в отчет формата BSL LS. Если замечание будет новое, для которого еще нет правила, оно будет добавлено в хранилище правил. + + 2. Команда `publish` - удалит всю служебную информацию из хранилища правил. Итоговый файл готов к загрузке в SQ. + +## Ограничения + ++ Версия EDT > 2021.2 + +## Предварительные настройки и порядок использования + +Действия выполняются через UI SQ или через sonar.properties + ++ Активировать в SQ свойство `sonar.bsl.edt.enabled` ++ Активировать в SQ свойство `sonar.bsl.edt.createExternalIssues` - опционально, но количество внешних замечаний позволит замечать необходимость обновить правила. ++ Заполнить в SQ свойство `sonar.bsl.edt.rulesPaths` и положить ваш файл с правилами (или экспортированный командой `publish`) по этому пути в SQ. ++ Перезагрузить SQ чтобы правила отобразились в связанных с EDT профилях качества. ++ Проверить что правила появились. Ввиду особенности работы SQ может потребоваться удалить и установить плагин sonar-bsl чтобыправила обновились в профиле качества. ++ Путь к файлу с результатом работы программы указывается в свойстве `sonar.bsl.languageserver.reportPaths` сканера SQ + +## Пример использования + ++ Разобрать замечания ЕДТ для проекта *configuration* в репозитории *my_awersome_rep* с внешним файлом правил и создать отчет *out.json*. + +``` + edt-ripper -f /mnt/share/custom-rules.json parse ./edt-validate-results ./my_awersome_rep/ configuration ./out.json +``` + ++ Разобрать замечания ЕДТ для проекта *configuration* в репозитории *my_awersome_rep* с внутренним файлом правил и создать отчет *out.json* + +``` + edt-ripper parse ./edt-validate-results ./my_awersome_rep/ configuration ./out.json +``` + ++ Разобрать замечания для проектов *configuration* и *exts* в репозитории *my_awersome_rep* с внутренним файлом правил и создать отчет *out.json* + +``` + edt-ripper parse ./edt-validate-results ./my_awersome_rep/ configuration exts ./out.json +``` + +## todo + ++ Поддержка файла исключений ++ Хранение и обновление файла custom-rules на Nexus ++ Команда для мержа n разных файлов правил diff --git a/custom-rules.json b/custom-rules.json new file mode 100755 index 0000000..1c1ed99 --- /dev/null +++ b/custom-rules.json @@ -0,0 +1,1184 @@ +{ + "Rules": [ + { + "Code": "edt-001", + "InternalCode": "Переменная %1 не определена", + "Name": "Переменная %1 не определена", + "Description": "\n\n\n\n

Например, имеем следущий код в модулях конфигурации:

\n
ШаблонТекста = НСтр(\"ru='Первый параметр %1, второй параметр %2'\");
Текст = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ШаблонТекста, 1, 2);
\n

Избавимся от прослойки вызовов и лишних методов с помощью метода СтрШаблон():

\n
ШаблонТекста = НСтр(\"ru='Первый параметр %1, второй параметр %2'\");
Текст = СтрШаблон(ШаблонТекста, 1, 2);
\n

Конфигурация не всегда сразу полностью переводится на другой язык. И, если в системе будет работать пользователь, у которого будет установлен язык не RU, то первый код отработает корректно, а второй выдаст ошибку исполнения.

\n

Во втором случае локализованной строки нет, следовательно, параметров в строке нет,  следовательно, возникает ошибка исполнения.

\n

В связи с этим, в модулях конфигураций принято решение не использовать СтрШаблон() до исправления ошибки платформы.

", + "Type": "BUG", + "Severity": "CRITICAL", + "EffortMinutes": 1, + "Active": true + }, + { + "Code": "EDT-2", + "InternalCode": "com.e1c.v8codestyle.bsl:invocation-form-event-handler", + "Name": "Программный вызов обработчика события формы", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "INFO", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-3", + "InternalCode": "com.e1c.v8codestyle.bsl:empty-except-statement", + "Name": "не содержит кода в исключении", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-4", + "InternalCode": "Возвращает тип, который имеет отличное окружение от контекста вызова", + "Name": "Возвращает тип, который имеет отличное окружение от контекста вызова", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-5", + "InternalCode": "Возможно, выражение не является объектом коллекции", + "Name": "Возможно, выражение не является объектом коллекции", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-6", + "InternalCode": "Возможно, недостижимое выражение", + "Name": "Возможно, недостижимое выражение", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-7", + "InternalCode": "com.e1c.v8codestyle.bsl:module-unused-local-variable", + "Name": "Возможно, переменная еще не была проинициализирована", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-8", + "InternalCode": "Возможно, строковый литерал содержит ошибку", + "Name": "Возможно, строковый литерал содержит ошибку", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-9", + "InternalCode": "com.e1c.v8codestyle.bsl:new-color", + "Name": "Для изменения оформления следует использовать элементы стиля, а не задавать конкретные значения непосредственно в элементах управления", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-10", + "InternalCode": "Для объекта определен ручной порядок подсистем, но подсистема отсутствует в порядке подсистем", + "Name": "Для объекта определен ручной порядок подсистем, но подсистема отсутствует в порядке подсистем", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-11", + "InternalCode": "com.e1c.v8codestyle.md:mdo-scheduled-job-description", + "Name": "Задано наименование предопределенного регламентного задания", + "Description": "Отсутствует", + "Type": "BUG", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-12", + "InternalCode": "com.e1c.v8codestyle.bsl:use-non-recommended-method", + "Name": "Используется не рекомендуемый метод", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-13", + "InternalCode": "com.e1c.v8codestyle.bsl:using-isinrole", + "Name": "Используйте функцию вместо", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-14", + "InternalCode": "com.e1c.v8codestyle.bsl:structure-consructor-too-many-keys", + "Name": "Конструктор структуры содержит более чем 5 ключей", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-15", + "InternalCode": "Менеджер записи не может быть использован для регистра с режимом записи", + "Name": "Менеджер записи не может быть использован для регистра с режимом записи", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-16", + "InternalCode": "com.e1c.v8codestyle.bsl:lock-out-of-try", + "Name": "Метод Заблокировать() вне блока Попытка-Исключение", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-17", + "InternalCode": "com.e1c.v8codestyle.bsl:module-accessibility-at-client", + "Name": "Метод доступен НаКлиенте", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-18", + "InternalCode": "Метод устарел", + "Name": "Метод устарел", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-19", + "InternalCode": "com.e1c.v8codestyle.bsl:bsl-nstr-string-literal-format", + "Name": "НСтр метод должен принимать строку первым параметром", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-20", + "InternalCode": "Не рекомендуется создавать подсистемы глубиной вложенности более трех", + "Name": "Не рекомендуется создавать подсистемы глубиной вложенности более трех", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-21", + "InternalCode": "com.e1c.v8codestyle.bsl:export-method-in-command-form-module", + "Name": "Не следует размещать экспортные процедуры и функции в модулях команд и форм. К этим модулям нет возможности обращаться из внешнего по отношению к ним кода, поэтому экспортные процедуры и функции в этих модулях не имеют смысла.", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-22", + "InternalCode": "Неизвестное имя типа", + "Name": "Неизвестное имя типа", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-23", + "InternalCode": "com.e1c.v8codestyle.bsl:module-unused-method", + "Name": "Неиспользуемый метод", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-24", + "InternalCode": "Некорректное значение свойства XDTO-пакета. Пространство имен пакета совпадает с пространством имен пакета", + "Name": "Некорректное значение свойства XDTO-пакета. Пространство имен пакета совпадает с пространством имен пакета", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-25", + "InternalCode": "Нельзя передавать объект типа между клиентом и сервером", + "Name": "Нельзя передавать объект типа между клиентом и сервером", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-26", + "InternalCode": "Нельзя присваивать атрибуту формы значение типа", + "Name": "Нельзя присваивать атрибуту формы значение типа", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-27", + "InternalCode": "Нет соответствия между ожидаемыми типами", + "Name": "Нет соответствия между ожидаемыми типами", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-28", + "InternalCode": "Объект данного тип не может быть создан через оператор", + "Name": "Объект данного тип не может быть создан через оператор", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-29", + "InternalCode": "com.e1c.v8codestyle.bsl:doc-comment-procedure-return-section", + "Name": "Описание процедуры не должно содержать блок", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-30", + "InternalCode": "com.e1c.v8codestyle.bsl:event-heandler-boolean-param", + "Name": "Параметр должен устанавливаться в Ложь, но выражение может заменить текущее значение в Истина", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-31", + "InternalCode": "com.e1c.v8codestyle.bsl:doc-comment-parameter-section", + "Name": "Пропущено определение параметра для", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-32", + "InternalCode": "com.e1c.v8codestyle.bsl:module-empty-method", + "Name": "Пустой метод", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-33", + "InternalCode": "Свойство объекта не обнаружено", + "Name": "Свойство объекта не обнаружено", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-34", + "InternalCode": "Свойство устарело", + "Name": "Свойство устарело", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-35", + "InternalCode": "com.e1c.v8codestyle.bsl:doc-comment-ref-link", + "Name": "Ссылка на несуществующий объект", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-36", + "InternalCode": "com.e1c.v8codestyle.ql:ql-camel-case-string-literal", + "Name": "Строковый литерал содержит не CamelCase символы", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-37", + "InternalCode": "Тип устарел", + "Name": "Тип устарел", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-38", + "InternalCode": "com.e1c.v8codestyle.form:input-field-list-choice-mode", + "Name": "У поля ввода формы с заполненным списком выбора отключено свойство", + "Description": "Отсутствует", + "Type": "BUG", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-39", + "InternalCode": "Функция должна возвращать значение", + "Name": "Функция должна возвращать значение", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-40", + "InternalCode": "Элемент с таким именем уже есть в глобальном контексте", + "Name": "Элемент с таким именем уже есть в глобальном контексте", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-41", + "InternalCode": "com.e1c.dt.check.form:form-named-element-name", + "Name": "Имя именованного элемента формы пустое", + "Description": "Отсутствует", + "Type": "BUG", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-42", + "InternalCode": "com.e1c.v8codestyle.bsl:form-module-pragma", + "Name": "Использована директива компиляции модуля формы", + "Description": "Отсутствует", + "Type": "BUG", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-43", + "InternalCode": "com.e1c.v8codestyle.ql:ql-temp-table-index", + "Name": "Новая временная таблица должна содержать индексы", + "Description": "Отсутствует", + "Type": "BUG", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-44", + "InternalCode": "com.e1c.v8codestyle.bsl:notify-description-to-server-procedure", + "Name": "Описание оповещения на серверную процедуру", + "Description": "Отсутствует", + "Type": "BUG", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-45", + "InternalCode": "com.e1c.v8codestyle.bsl:doc-comment-export-function-return-section", + "Name": "Описание экспортируемой функции должно содержать блок", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-46", + "InternalCode": "com.e1c.v8codestyle.ql:ql-virtual-table-filters", + "Name": "Отбор ABCXYZКлассификацияКлиентовСрезПоследних.ТипКлассификации для виртуальной таблицы ABCXYZКлассификацияКлиентовСрезПоследних должен быть в параметрах", + "Description": "Отсутствует", + "Type": "BUG", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-47", + "InternalCode": "com.e1c.v8codestyle.bsl:data-exchange-load", + "Name": "Отсутствует обязательная проверка признака ОбменДанными.Загрузка в обработчике события", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-48", + "InternalCode": "com.e1c.v8codestyle.md:shceduled-job-periodicity-too-short", + "Name": "Периодичность выполнения регламентного задания меньше 60сек", + "Description": "Отсутствует", + "Type": "BUG", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-49", + "InternalCode": "com.e1c.v8codestyle.right:right-start-web-client", + "Name": "Право роли установлено для", + "Description": "Отсутствует", + "Type": "VULNERABILITY", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-50", + "InternalCode": "com.e1c.v8codestyle.right:right-output-to-printer-file-clipboard", + "Name": "Право роли установлено для", + "Description": "Отсутствует", + "Type": "VULNERABILITY", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-51", + "InternalCode": "com.e1c.v8codestyle.right:right-interactive-set-deletion-mark-predefined-data", + "Name": "Право роли установлено для", + "Description": "Отсутствует", + "Type": "VULNERABILITY", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-52", + "InternalCode": "com.e1c.v8codestyle.right:right-interactive-clear-deletion-mark-predefined-data", + "Name": "Право роли установлено для", + "Description": "Отсутствует", + "Type": "VULNERABILITY", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-53", + "InternalCode": "com.e1c.v8codestyle.right:right-interactive-delete", + "Name": "Право роли установлено для", + "Description": "Отсутствует", + "Type": "VULNERABILITY", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-54", + "InternalCode": "com.e1c.v8codestyle.right:right-interactive-delete-marked-predefined-data", + "Name": "Право роли установлено для", + "Description": "Отсутствует", + "Type": "VULNERABILITY", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-55", + "InternalCode": "com.e1c.v8codestyle.right:right-interactive-delete-predefined-data", + "Name": "Право роли установлено для", + "Description": "Отсутствует", + "Type": "VULNERABILITY", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-56", + "InternalCode": "com.e1c.v8codestyle.right:right-exclusive-mode", + "Name": "Право роли установлено для", + "Description": "Отсутствует", + "Type": "VULNERABILITY", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-57", + "InternalCode": "com.e1c.v8codestyle.right:right-save-user-data", + "Name": "Право роли установлено для", + "Description": "Отсутствует", + "Type": "VULNERABILITY", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-58", + "InternalCode": "com.e1c.v8codestyle.right:right-start-thin-client", + "Name": "Право роли установлено для", + "Description": "Отсутствует", + "Type": "VULNERABILITY", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-59", + "InternalCode": "com.e1c.v8codestyle.bsl:form-module-missing-pragma", + "Name": "Пропущена директива компиляции", + "Description": "Отсутствует", + "Type": "BUG", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-60", + "InternalCode": "com.e1c.dt.check.form:form-data-path", + "Name": "Свойство имеет некорректное значение", + "Description": "Отсутствует", + "Type": "BUG", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-61", + "InternalCode": "com.e1c.v8codestyle.ql:ql-join-to-sub-query", + "Name": "Соединение в запросе с подзапросом не разрешено", + "Description": "Отсутствует", + "Type": "BUG", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-62", + "InternalCode": "com.e1c.v8codestyle.bsl:module-structure-top-region", + "Name": "Стандартная область структуры модуля является вложенной", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-63", + "InternalCode": "com.e1c.v8codestyle.bsl:doc-comment-use-minus", + "Name": "Только символ дефис-минуса разрешено использовать в документирующем комментарии, но найдено", + "Description": "Отсутствует", + "Type": "BUG", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-64", + "InternalCode": "com.e1c.v8codestyle.md:common-module-name-global", + "Name": "Глобальный общий модуль должен оканчиваться на суффикс", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "CRITICAL", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-65", + "InternalCode": "com.e1c.v8codestyle.md:mdo-name-length", + "Name": "Длина имени объекта метаданного должна быть меньше чем 80", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "CRITICAL", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-66", + "InternalCode": "com.e1c.v8codestyle.bsl:query-in-loop", + "Name": "Цикл содержит вызов метода с запросом", + "Description": "Отсутствует", + "Type": "BUG", + "Severity": "CRITICAL", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-67", + "InternalCode": "Can be only one default item in root subgroup", + "Name": "Can be only one default item in root subgroup", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-68", + "InternalCode": "Duplicate id", + "Name": "Duplicate id", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-69", + "InternalCode": "Для команды категория группы команд по умолчанию может быть только Панель навигации или Панель действий", + "Name": "Для команды категория группы команд по умолчанию может быть только Панель навигации или Панель действий", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-70", + "InternalCode": "Для команды формы назначен обработчик, но метод с таким именем отсутствует в модуле формы", + "Name": "Для команды формы назначен обработчик, но метод с таким именем отсутствует в модуле формы", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-71", + "InternalCode": "Для события элемента формы назначен обработчик, но метод с таким именем отсутствует в модуле формы", + "Name": "Для события элемента формы назначен обработчик, но метод с таким именем отсутствует в модуле формы", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-72", + "InternalCode": "Для события формы назначен обработчик, но метод с таким именем отсутствует в модуле формы", + "Name": "Для события формы назначен обработчик, но метод с таким именем отсутствует в модуле формы", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-73", + "InternalCode": "Код никогда не будет скомпилирован", + "Name": "Код никогда не будет скомпилирован", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-74", + "InternalCode": "Лексическое значение значения по умолчанию не соответствует типу \"{http", + "Name": "Лексическое значение значения по умолчанию не соответствует типу \"{http", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-75", + "InternalCode": "Не найден обработчик для Подписки на событие", + "Name": "Не найден обработчик для Подписки на событие", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-76", + "InternalCode": "Не найден обработчик для Регламентного задания", + "Name": "Не найден обработчик для Регламентного задания", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-77", + "InternalCode": "Недостаточное число параметров", + "Name": "Недостаточное число параметров", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-78", + "InternalCode": "Некорректное значение свойства характеристики. Значение свойства не определено", + "Name": "Некорректное значение свойства характеристики. Значение свойства не определено", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-79", + "InternalCode": "Некорректное значение свойства. Дублирование имени объекта метаданных", + "Name": "Некорректное значение свойства. Дублирование имени объекта метаданных", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-80", + "InternalCode": "Некорректный тип параметра для стандартной команды. Допустимые типы, а получены", + "Name": "Некорректный тип параметра для стандартной команды. Допустимые типы, а получены", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-81", + "InternalCode": "Неподдерживаемый оператор", + "Name": "Неподдерживаемый оператор", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-82", + "InternalCode": "Переменная не определена", + "Name": "Переменная не определена", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-83", + "InternalCode": "Поле связи параметра выбора не указано или некорректно", + "Name": "Поле связи параметра выбора не указано или некорректно", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-84", + "InternalCode": "Поле связи параметра выбора не является допустимым", + "Name": "Поле связи параметра выбора не является допустимым", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-85", + "InternalCode": "Процедура или функция не определена", + "Name": "Процедура или функция не определена", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-86", + "InternalCode": "Процедура или функция с таким именем уже определена", + "Name": "Процедура или функция с таким именем уже определена", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-87", + "InternalCode": "Свойство не предназначено для записи у типа", + "Name": "Свойство не предназначено для записи у типа", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-88", + "InternalCode": "Синтаксическая ошибка. Недопустимая лексема в данном контексте", + "Name": "Синтаксическая ошибка. Недопустимая лексема в данном контексте", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-89", + "InternalCode": "Синтаксическая ошибка. Пропущена лексема у", + "Name": "Синтаксическая ошибка. Пропущена лексема у", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-90", + "InternalCode": "Слишком много параметров", + "Name": "Слишком много параметров", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-91", + "InternalCode": "Слишком много параметров для типа(ов)", + "Name": "Слишком много параметров для типа(ов)", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-92", + "InternalCode": "Тип не может иметь фасет", + "Name": "Тип не может иметь фасет", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-93", + "InternalCode": "Тип неопределен", + "Name": "Тип неопределен", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-94", + "InternalCode": "Функция не определена", + "Name": "Функция не определена", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-95", + "InternalCode": "Этот тип не может входить в состав составного типа", + "Name": "Этот тип не может входить в состав составного типа", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MAJOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-96", + "InternalCode": "Данный модуль не поддерживает данный тип директив компиляции", + "Name": "Данный модуль не поддерживает данный тип директив компиляции", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-97", + "InternalCode": "com.e1c.v8codestyle.right:right-view-event-log", + "Name": "Право роли установлено для", + "Description": "Отсутствует", + "Type": "VULNERABILITY", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-98", + "InternalCode": "com.e1c.v8codestyle.right:right-interactive-open-external-data-processors", + "Name": "Право роли установлено для", + "Description": "Отсутствует", + "Type": "VULNERABILITY", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-99", + "InternalCode": "com.e1c.v8codestyle.right:right-interactive-open-external-reports", + "Name": "Право роли установлено для", + "Description": "Отсутствует", + "Type": "VULNERABILITY", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-100", + "InternalCode": "com.e1c.v8codestyle.md:common-module-name-client-server", + "Name": "Клиент-серверный общий модуль должен оканчиваться на суффикс", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-101", + "InternalCode": "Duplicate column name", + "Name": "Duplicate column name", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-102", + "InternalCode": "Duplicate content", + "Name": "Duplicate content", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-103", + "InternalCode": "Illegal ShortCut", + "Name": "Illegal ShortCut", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-104", + "InternalCode": "Данный модуль может содержать только процедуры и функции", + "Name": "Данный модуль может содержать только процедуры и функции", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-105", + "InternalCode": "Недостаточное число параметров для типа(ов)", + "Name": "Недостаточное число параметров для типа(ов)", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-106", + "InternalCode": "Неизвестный оператор", + "Name": "Неизвестный оператор", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-107", + "InternalCode": "Некорректное значение свойства. Указан нумератор. Свойства документа должны совпадать с соответствующими свойствами нумератора.", + "Name": "Некорректное значение свойства. Указан нумератор. Свойства документа должны совпадать с соответствующими свойствами нумератора.", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-108", + "InternalCode": "Некорректное значение свойства реквизита. Тип использования реквизита противоречит выбранному типу иерархии", + "Name": "Некорректное значение свойства реквизита. Тип использования реквизита противоречит выбранному типу иерархии", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-109", + "InternalCode": "Оператор может использоваться только внутри процедур и функций", + "Name": "Оператор может использоваться только внутри процедур и функций", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-110", + "InternalCode": "Процедура вызывается как функция", + "Name": "Процедура вызывается как функция", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-111", + "InternalCode": "Синтаксическая ошибка. Неверная лексема - ожидается", + "Name": "Синтаксическая ошибка. Неверная лексема - ожидается", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-112", + "InternalCode": "Синтаксическая ошибка. Неверный ввод - ожидается", + "Name": "Синтаксическая ошибка. Неверный ввод - ожидается", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-113", + "InternalCode": "Указанный обработчик события не существует", + "Name": "Указанный обработчик события не существует", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-114", + "InternalCode": "Встроенная функция может быть использована только в выражении.", + "Name": "Встроенная функция может быть использована только в выражении.", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-115", + "InternalCode": "Ошибочный порядок грамматических элементов", + "Name": "Ошибочный порядок грамматических элементов", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-116", + "InternalCode": "Синтаксическая ошибка. Неверный ввод", + "Name": "Синтаксическая ошибка. Неверный ввод", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-117", + "InternalCode": "Тип не определен", + "Name": "Тип не определен", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 3 + }, + { + "Code": "EDT-118", + "InternalCode": "Синтаксическая ошибка. Неизвестная лексема", + "Name": "Синтаксическая ошибка. Неизвестная лексема", + "Description": "Отсутствует", + "Type": "CODE_SMELL", + "Severity": "MINOR", + "Active": true, + "EffortMinutes": 3 + } + ] +} \ No newline at end of file diff --git a/edt-ripper-0.7.ospx b/edt-ripper-0.7.ospx new file mode 100644 index 0000000000000000000000000000000000000000..78770c8a47e9ea2d06d35906425388b8c1b8eaec GIT binary patch literal 21416 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 literal 0 HcmV?d00001 diff --git a/packagedef b/packagedef new file mode 100644 index 0000000..729e246 --- /dev/null +++ b/packagedef @@ -0,0 +1,19 @@ +ПутКПараметрам = ОбъединитьПути(ТекущийСценарий().Каталог, "src", "Модули", "ПараметрыПриложения.os"); +Параметры = ЗагрузитьСценарий(ПутКПараметрам); + +Описание.Имя(Параметры.ИмяПриложения()) + .Версия(Параметры.Версия()) + .Автор("") + .АдресАвтора("") + .Описание("Отправка замечаний edt в отчет для сонара") + .ВерсияСреды("1.7.0") + .ВключитьФайл("src") + .ВключитьФайл("doc") + .ВключитьФайл("tasks") + .ВключитьФайл("custom-rules.json") + .ЗависитОт("logos") + .ЗависитОт("cli") + .ЗависитОт("fs") + .ЗависитОт("v8metadata-reader") + .ИсполняемыйФайл("src/main.os") + ; diff --git a/src/main.os b/src/main.os new file mode 100644 index 0000000..99f49e0 --- /dev/null +++ b/src/main.os @@ -0,0 +1,61 @@ +#Использовать "." +#Использовать cli + +Перем Лог; + +Процедура ВыполнитьПриложение() + + Приложение = Новый КонсольноеПриложение(ПараметрыПриложения.ИмяПриложения(), + "Приложение для работы с файлами ошибок статических анализаторов", + ЭтотОбъект); + + Приложение.Версия("version", ПараметрыПриложения.Версия()); + + Приложение.Опция("v verbose", Ложь, "Вывод отладочной информация в процессе выполнения") + .Флаговый(); + + Приложение.Опция("f file", "", "Путь к внешнему файлу-коллектору замечаний") + .ТСтрока(); + + Приложение.ДобавитьКоманду("parse", "Создание отчета", + Новый КомандаПарсерОтчетаЕДТ); + + Приложение.ДобавитьКоманду("publish", "Удаление из выбранного файла правил служебных блоков, + | результирующий файл готов для загрузки в сонар", + Новый КомандаПубликацияПравил); + + Приложение.Запустить(АргументыКоманднойСтроки); + +КонецПроцедуры + +Процедура ПередВыполнениемКоманды(Знач Команда) Экспорт + + ОтладкаВключена = Команда.ЗначениеОпции("verbose"); + + ПараметрыПриложения.УстановитьРежимОтладки(ОтладкаВключена); + + ВнешнийФайлОписаний = Команда.ЗначениеОпции("file"); + + Если ЗначениеЗаполнено(ВнешнийФайлОписаний) Тогда + Файл = Новый Файл(ВнешнийФайлОписаний); + Если НЕ (Файл.Существует() И Файл.ЭтоФайл()) Тогда + Лог.КритичнаяОшибка("Файл %1 недоступен", ВнешнийФайлОписаний); + КонецЕсли; + КонецЕсли; + + ПараметрыПриложения.УстановитьКонтекстСохранения(ВнешнийФайлОписаний); + +КонецПроцедуры + +Лог = ПараметрыПриложения.Лог(); + +Попытка + + ВыполнитьПриложение(); + +Исключение + + Лог.КритичнаяОшибка(ОписаниеОшибки()); + ЗавершитьРаботу(1); + +КонецПопытки; diff --git "a/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\223\320\265\320\275\320\265\321\200\320\260\321\202\320\276\321\200\320\236\321\202\321\207\320\265\321\202\320\276\320\262BSL.os" "b/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\223\320\265\320\275\320\265\321\200\320\260\321\202\320\276\321\200\320\236\321\202\321\207\320\265\321\202\320\276\320\262BSL.os" new file mode 100644 index 0000000..a624388 --- /dev/null +++ "b/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\223\320\265\320\275\320\265\321\200\320\260\321\202\320\276\321\200\320\236\321\202\321\207\320\265\321\202\320\276\320\262BSL.os" @@ -0,0 +1,136 @@ +#Использовать fs + +#Область ОписаниеПеременных + +// Содержит формируемый отчет в формате BSL LS +Перем Отчет; + +// Переменная для логирования +Перем Лог; + +#КонецОбласти + +#Область ПрограммныйИнтерфейс + +// Создает новое пустое замечание для файла и пополняет коллекци замечаний. +// +// Параметры: +// Путь - Строка - Путь к bsl файлу для регистрации нового замечания +// +// Возвращаемое значение: +// Структура - Все поля описаны в файле diagnostic.json +// +Функция НовыйЗамечаниеДляОбъекта(Путь) Экспорт + + // СырыеДанныеСтрокой() - промежуточный слой для хранения замечаний. Ключ для регистрации - имя файла. + РазделЗамечанияДляФайла = Отчет[СырыеДанныеСтрокой()].Получить(Путь); + + Если РазделЗамечанияДляФайла = Неопределено Тогда + + Отчет[СырыеДанныеСтрокой()].Вставить(Путь, Новый Структура("diagnostics", Новый Массив)); + + КонецЕсли; + + Замечание = Замечание(); + + Отчет[СырыеДанныеСтрокой()][Путь].diagnostics.Добавить(Замечание); + + Возврат Замечание; + +КонецФункции + +// Записывает отчет в файл, если путь не передан, отчет запишется в текущий каталог запуска +// +// Параметры: +// Путь - Строка - Путь к файлу, куда будет записан отчет в формате BSL LS +// +Процедура ЗаписатьОтчет(Путь = Неопределено) Экспорт + + Если Путь = Неопределено Тогда + Путь = ОбъединитьПути(ТекущийКаталог(), "edt-bsl-report.json"); + КонецЕсли; + + ЗаписьJSON = Новый ЗаписьJSON; + ЗаписьJSON.ОткрытьФайл(Путь, "UTF-8", , Новый ПараметрыЗаписиJSON(, Символы.Таб)); + + ИзменитьСтруктуруОтчета(); + + ЗаписатьJSON(ЗаписьJSON, Отчет); + ЗаписьJSON.Закрыть(); + + Лог.Информация("Записан файл %1", Путь); + +КонецПроцедуры + +#КонецОбласти + +#Область СлужебныеПроцедурыИФункции + +Процедура ИзменитьСтруктуруОтчета() + + Для Каждого ОбъектЗамечаний Из Отчет[СырыеДанныеСтрокой()] Цикл + + Замечание = Новый Соответствие; + Замечание.Вставить("path", ОбъектЗамечаний.Ключ); + Замечание.Вставить("diagnostics", ОбъектЗамечаний.Значение.diagnostics); + Отчет["fileinfos"].Добавить(Замечание); + + КонецЦикла; + + Отчет.Удалить(СырыеДанныеСтрокой()); + +КонецПроцедуры + +Функция СырыеДанныеСтрокой() + + Возврат "fileinfos_dirty"; + +КонецФункции + +Функция ПрочитатьОбъект(ПутьКФайлу, ВСоответствие = Истина) + + ЧтениеJSON = Новый ЧтениеJSON; + ЧтениеJSON.ОткрытьФайл(ПутьКФайлу, "UTF-8"); + + Объект = ПрочитатьJSON(ЧтениеJSON, ВСоответствие); + ЧтениеJSON.Закрыть(); + + Возврат Объект; + +КонецФункции + +Функция ШаблонОтчет() + + Возврат ОбъединитьПути(ТекущийСценарий().Каталог, "..", Ресурсы(), "report.json"); + +КонецФункции + +Функция ШаблонЗамечания() + + Возврат ОбъединитьПути(ТекущийСценарий().Каталог, "..", Ресурсы(), "diagnostic.json"); + +КонецФункции + +Функция Ресурсы() + + Возврат "Ресурсы"; + +КонецФункции + +Функция Замечание() + + Возврат ПрочитатьОбъект(ШаблонЗамечания(), Ложь); + +КонецФункции + +Процедура ПриСозданииОбъекта() + + Отчет = ПрочитатьОбъект(ШаблонОтчет()); + + Отчет["date"] = Формат(ТекущаяУниверсальнаяДата(), "ДФ='yyyy-MM-dd HH:mm:ss'"); + +КонецПроцедуры + +#КонецОбласти + +Лог = ПараметрыПриложения.Лог(); diff --git "a/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\274\320\260\320\275\320\264\320\260\320\237\320\260\321\200\321\201\320\265\321\200\320\236\321\202\321\207\320\265\321\202\320\260\320\225\320\224\320\242.os" "b/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\274\320\260\320\275\320\264\320\260\320\237\320\260\321\200\321\201\320\265\321\200\320\236\321\202\321\207\320\265\321\202\320\260\320\225\320\224\320\242.os" new file mode 100644 index 0000000..4cffc64 --- /dev/null +++ "b/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\274\320\260\320\275\320\264\320\260\320\237\320\260\321\200\321\201\320\265\321\200\320\236\321\202\321\207\320\265\321\202\320\260\320\225\320\224\320\242.os" @@ -0,0 +1,69 @@ +Процедура ОписаниеКоманды(Команда) Экспорт + + Команда.Аргумент("PATH", "", "Файл с отчетом") + .ТСтрока(); + + Команда.Аргумент("WORKDIR", "", "Корень репозитория или проектной области") + .ТСтрока(); + + Команда.Аргумент("PROJECTS", Новый Массив, "Список проектов, которые были переданы в ЕДТ для анализа") + .ТМассивСтрок(); + + Команда.Аргумент("OUT", "", "Путь к файлу отчета в формате BSL LS") + .ТСтрока(); + + Команда.Опция("nixPath", Истина, "Использовать пути как в линукс системах") + .ТБулево(); + +КонецПроцедуры + +Процедура ПередВыполнениемКоманды(Знач Команда) Экспорт + + Лог = ПараметрыПриложения.Лог(); + + БылиОшибки = Ложь; + + ФайлДляОбработки = Новый Файл(Команда.ЗначениеАргумента("PATH")); + + Если НЕ (ФайлДляОбработки.Существует() И ФайлДляОбработки.ЭтоФайл()) Тогда + Лог.Ошибка("Не найден файл %1", Команда.ЗначениеАргумента("PATH")); + БылиОшибки = Истина; + КонецЕсли; + + Репозиторий = Новый Файл(Команда.ЗначениеАргумента("WORKDIR")); + + Если НЕ (Репозиторий.Существует() И Репозиторий.ЭтоКаталог()) Тогда + Лог.Ошибка("Не найден корневой каталог проектов %1", Команда.ЗначениеАргумента("WORKDIR")); + БылиОшибки = Истина; + КонецЕсли; + + Проекты = Команда.ЗначениеАргумента("PROJECTS"); + + Для Каждого Проект Из Проекты Цикл + + ДиректорияПроекта = Новый Файл(ОбъединитьПути(Команда.ЗначениеАргумента("WORKDIR"), Проект)); + + Если НЕ (ДиректорияПроекта.Существует() И ДиректорияПроекта.ЭтоКаталог()) Тогда + Лог.Ошибка("Не найден корневой каталог проекта %1 в %2", Проект, Команда.ЗначениеАргумента("WORKDIR")); + БылиОшибки = Истина; + КонецЕсли; + + КонецЦикла; + + Если БылиОшибки Тогда + ВызватьИсключение "Продолжение работы невозможно"; + КонецЕсли; + +КонецПроцедуры + +Процедура ВыполнитьКоманду(Знач Команда) Экспорт + + ФайлДляОбработки = Команда.ЗначениеАргумента("PATH"); + Репозиторий = Команда.ЗначениеАргумента("WORKDIR"); + Проекты = Команда.ЗначениеАргумента("PROJECTS"); + ФайлРезультата = Команда.ЗначениеАргумента("OUT"); + ПутиКакВЛинукс = Команда.ЗначениеОпции("nixPath"); + + ПарсерОшибок.Прочитать(ФайлДляОбработки, Репозиторий, Проекты, ФайлРезультата, ПутиКакВЛинукс); + +КонецПроцедуры diff --git "a/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\274\320\260\320\275\320\264\320\260\320\237\321\203\320\261\320\273\320\270\320\272\320\260\321\206\320\270\321\217\320\237\321\200\320\260\320\262\320\270\320\273.os" "b/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\274\320\260\320\275\320\264\320\260\320\237\321\203\320\261\320\273\320\270\320\272\320\260\321\206\320\270\321\217\320\237\321\200\320\260\320\262\320\270\320\273.os" new file mode 100644 index 0000000..b0109f4 --- /dev/null +++ "b/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\274\320\260\320\275\320\264\320\260\320\237\321\203\320\261\320\273\320\270\320\272\320\260\321\206\320\270\321\217\320\237\321\200\320\260\320\262\320\270\320\273.os" @@ -0,0 +1,14 @@ +Процедура ОписаниеКоманды(Команда) Экспорт + + Команда.Аргумент("OUT", "", "Путь к файлу отчета в формате BSL LS") + .ТСтрока(); + +КонецПроцедуры + +Процедура ВыполнитьКоманду(Знач Команда) Экспорт + + ФайлРезультата = Команда.ЗначениеАргумента("OUT"); + ХранилищеПравил = Новый ХранилищеПравил; + ХранилищеПравил.Опубликовать(ФайлРезультата); + +КонецПроцедуры diff --git "a/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\245\321\200\320\260\320\275\320\270\320\273\320\270\321\211\320\265\320\237\321\200\320\260\320\262\320\270\320\273.os" "b/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\245\321\200\320\260\320\275\320\270\320\273\320\270\321\211\320\265\320\237\321\200\320\260\320\262\320\270\320\273.os" new file mode 100644 index 0000000..456af81 --- /dev/null +++ "b/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\245\321\200\320\260\320\275\320\270\320\273\320\270\321\211\320\265\320\237\321\200\320\260\320\262\320\270\320\273.os" @@ -0,0 +1,145 @@ +#Область ОписаниеПеременных + +// Хранилище правилы +Перем Правила; +#КонецОбласти + +#Область ПрограммныйИнтерфейс + +// Ищет в коллекции правил элемент по имени правила +// +// Параметры: +// Код - Строка - Код правила - нормализованная строка пригодная быть в качестве кода либо сам код из ЕДТ +// +// Возвращаемое значение: +// Структура - Структура с описанием правила (подробнее см НовыйПравило) +// +Функция НайтиПоКоду (Код) Экспорт + + Возврат Правила.ПоКоду.Получить(Код); + +КонецФункции + +// Считает количество добавленных правил +// +// Возвращаемое значение: +// Число - количество правил, сохраненных в файле с описанием правил +// +Функция Количество() Экспорт + + Возврат Правила.ПоКоду.Количество(); + +КонецФункции + +// Добавляет новые правила в хранилище правил +// +// Параметры: +// МассивДобавлений - <Массив> - Массив с новыми правилами, которые будут записаны в итоговый файл +// +Процедура Дополнить(МассивДобавлений) Экспорт + + Объект = ПравилаКакОбъект(); + + Для Каждого Добавление Из МассивДобавлений Цикл + + Объект.Rules.Добавить(Добавление.Значение); + + КонецЦикла; + + ЗаписатьОбъект(ПараметрыПриложения.ПолучитьКонтекст(), Объект); + +КонецПроцедуры + +// Обрабатывает хранилище правил во внутреннем формате и создает файл, пригодный для экспорта в SQ +// +// Параметры: +// Путь - Строка - Путь к файлу результата. +// +Процедура Опубликовать(Путь) Экспорт + + Объект = ПравилаКакОбъект(); + + МаксимальнаяДлиннаИмениПравила = 198; + Для Каждого Правило Из Объект.Rules Цикл + // InternalCode используется для внутреннего сопоставления и для SQ будет являться лишним атрибутом + Правило.Удалить("InternalCode"); + + Если СтрДлина(Правило.Name) >= 198 Тогда + + Правило.Description = Правило.Name; + Правило.Name = Лев(Правило.Name, 198); + + КонецЕсли; + + КонецЦикла; + + ЗаписатьОбъект(Путь, Объект); + +КонецПроцедуры + +// Создает базовое описание нового правила по замечанию, которое нашло ЕДТ. +// +// Параметры: +// ВнутреннийКод - Строка - Код из ЕДТ или нормализованное имя правила +// Имя - Строка - Имя правила +// Тип - ТипыЗамечаний - Тип замечания (см ТипыЗамечаний) +// Критичность - КритичностьЗамечаний- Критичность замечания (см КритичностьЗамечаний) +// +// Возвращаемое значение: +// Структура- Описание нового правила +// +Функция НовыйПравило(ВнутреннийКод, Имя, Тип, Критичность) Экспорт + + Правило = Новый Структура; + Правило.Вставить("Code", ""); + Правило.Вставить("InternalCode", ВнутреннийКод); + Правило.Вставить("Name", Имя); + Правило.Вставить("Description", "Отсутствует"); + Правило.Вставить("Type", Тип); + Правило.Вставить("Severity", Критичность); + Правило.Вставить("Active", true); + Правило.Вставить("EffortMinutes", 3); + + Возврат Правило; + +КонецФункции + +#КонецОбласти + +Процедура ЗаписатьОбъект(ПутьКФайлу, ОбъектЗаписи) + + ЗаписьJSON = Новый ЗаписьJSON; + ЗаписьJSON.ОткрытьФайл(ПутьКФайлу, "UTF-8", , Новый ПараметрыЗаписиJSON(, Символы.Таб)); + ЗаписатьJSON(ЗаписьJSON, ОбъектЗаписи); + ЗаписьJSON.Закрыть(); + +КонецПроцедуры + +Функция ПрочитатьОбъект(ИмяФайла) + + ЧтениеJSON = Новый ЧтениеJSON; + ЧтениеJSON.ОткрытьФайл(ИмяФайла, "UTF-8"); + Объект = ПрочитатьJSON(ЧтениеJSON, Ложь); + ЧтениеJSON.Закрыть(); + Возврат Объект; + +КонецФункции + +Функция ПравилаКакОбъект() + + Возврат ПрочитатьОбъект(ПараметрыПриложения.ПолучитьКонтекст()); + +КонецФункции + +Процедура ПриСозданииОбъекта() + + Объект = ПравилаКакОбъект(); + ПоКоду = Новый Соответствие(); + + Для Каждого Правило Из Объект.Rules Цикл + ПоКоду.Вставить(Правило.InternalCode, Правило); + КонецЦикла; + + Правила = Новый Структура("ПоКоду", ПоКоду); + +КонецПроцедуры diff --git "a/src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\232\320\276\320\275\321\204\320\270\320\263\321\203\321\200\320\260\321\206\320\270\321\217.os" "b/src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\232\320\276\320\275\321\204\320\270\320\263\321\203\321\200\320\260\321\206\320\270\321\217.os" new file mode 100644 index 0000000..04e0c8f --- /dev/null +++ "b/src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\232\320\276\320\275\321\204\320\270\320\263\321\203\321\200\320\260\321\206\320\270\321\217.os" @@ -0,0 +1,155 @@ +#Использовать v8metadata-reader +#Использовать fs + +#Область ОписаниеПеременных + +#КонецОбласти + +#Область ПрограммныйИнтерфейс + +// Нормализует пути, заменяя раздетилель пути на тот, который используется на SQ +// +// Параметры: +// Путь - Строка - любой путь на ФС +// КакВЛинукс - Булево - Использовать разделитель пути как в линукс +// +// Возвращаемое значение: +// Строка - Нормализованный путь +// +Функция НормализованыйПуть(Путь, КакВЛинукс = Истина) Экспорт + + КонечныйПуть = ""; + + Если КакВЛинукс Тогда + КонечныйПуть = СтрЗаменить(Путь, "\", "/"); + Иначе + КонечныйПуть = СтрЗаменить(Путь, "/", "\"); + КонецЕсли; + + Возврат КонечныйПуть; + +КонецФункции + +// Нормализует пути, заменяя раздетилель пути на тот, который используется на SQ +// +// Параметры: +// Файл - Файл - Объект типа +// КакВЛинукс - Булево - Использовать разделитель пути как в линукс +// +// Возвращаемое значение: +// Строка - Нормализованный путь +// +Функция НормализованныйПутьФайла(Файл, КакВЛинукс = Истина) Экспорт + + Возврат НормализованыйПуть(Файл.ПолноеИмя, КакВЛинукс); + +КонецФункции + +// Определяет путь на ФС по которому находится объект метаданных +// +// Параметры: +// Генератор - v8metadata-reader.Путь1СПоМетаданным - Объект класса для поиска пути +// ОбъектМетаданных - Строка - Представление объекта метаданных +// +// Возвращаемое значение: +// Строка - Путь к объекту конфигурации на ФС +// +Функция ПутьКОбъектуКонфигурации(Генератор, ОбъектМетаданных) Экспорт + + Возврат Генератор.Путь(ОбъектМетаданных); + +КонецФункции + +// Возвращает нормализованный путь на ФС к объекту конфигурации +// +// Параметры: +// Генератор - v8metadata-reader.Путь1СПоМетаданным - Объект класса для поиска пути +// Объект - Строка - Представление объекта метаданных +// КакВЛинукс - Булево - Использовать пути как в линукс +// +// Возвращаемое значение: +// Строка - Нормализованный путь к объекту конфигурации на ФС +// +Функция НормализованныйПутьКОбъектуКонфигурации(Генератор, Объект, КакВЛинукс = Истина) Экспорт + + Возврат НормализованыйПуть(ПутьКОбъектуКонфигурации(Генератор, Объект), КакВЛинукс); + +КонецФункции + +// Проверяет существует ли путь на ФС к модулю объекта конфигурации, если путь не существует +// ищет верхнеуровневые модули. +// +// Параметры: +// Генератор - v8metadata-reader.Путь1СПоМетаданным - Объект класса для поиска пути +// Объект - Строка - Представление объекта метаданных +// +// Возвращаемое значение: +// Строка - Путь к модулю объекта конфигурации либо к модулю переопределенного объекта +// +Функция ПодобратьМодуль(Генератор, Знач Объект) Экспорт + + Переопределение = ""; + Шаблон = "%1.%2"; + ТипыМодулей = Новый Массив; + ТипыМодулей.Добавить(СтрШаблон(Шаблон, Объект, "Модуль")); + ТипыМодулей.Добавить(СтрШаблон(Шаблон, Объект, "МодульОбъекта")); + ТипыМодулей.Добавить(СтрШаблон(Шаблон, Объект, "МодульМенеджера")); + ТипыМодулей.Добавить(СтрШаблон(Шаблон, Объект, "МодульНабораЗаписей")); + ТипыМодулей.Добавить(СтрШаблон(Шаблон, Объект, "МодульКоманды")); + ТипыМодулей.Добавить(СтрШаблон(Шаблон, Объект, "МодульМенеджераЗначения")); + ТипыМодулей.Добавить(МодульПриложенияСтрокой()); + ТипыМодулей.Добавить(МодульОбычногоПриложенияСтрокой()); + ТипыМодулей.Добавить(МодульСеансаСтрокой()); + + Для Каждого ТипМодуля Из ТипыМодулей Цикл + + Если МожноИспользоватьВЗамечаниях(Генератор, ТипМодуля) Тогда + Переопределение = ТипМодуля; + Прервать; + КонецЕсли; + + КонецЦикла; + + Возврат Переопределение; + +КонецФункции + +#КонецОбласти + +#Область СлужебныеПроцедурыИФункции + +Функция МодульПриложенияСтрокой() + + Возврат "Конфигурация.МодульУправляемогоПриложения"; + +КонецФункции + +Функция МодульОбычногоПриложенияСтрокой() + + Возврат "Конфигурация.МодульОбычногоПриложения"; + +КонецФункции + +Функция МодульСеансаСтрокой() + + Возврат "Конфигурация.МодульСеанса"; + +КонецФункции + +Функция МожноИспользоватьВЗамечаниях(Знач Генератор, Знач Объект) + + Результат = Истина; + + Путь = НормализованныйПутьКОбъектуКонфигурации(Генератор, Объект); + + Если НЕ ЗначениеЗаполнено(Путь) ИЛИ НЕ ФС.ФайлСуществует(Путь) Тогда + Результат = Ложь; + КонецЕсли; + + Возврат Результат; + +КонецФункции + +#КонецОбласти + +Лог = ПараметрыПриложения.Лог(); diff --git "a/src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\232\321\200\320\270\321\202\320\270\321\207\320\275\320\276\321\201\321\202\321\214\320\227\320\260\320\274\320\265\321\207\320\260\320\275\320\270\320\271.os" "b/src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\232\321\200\320\270\321\202\320\270\321\207\320\275\320\276\321\201\321\202\321\214\320\227\320\260\320\274\320\265\321\207\320\260\320\275\320\270\320\271.os" new file mode 100644 index 0000000..6b08f62 --- /dev/null +++ "b/src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\232\321\200\320\270\321\202\320\270\321\207\320\275\320\276\321\201\321\202\321\214\320\227\320\260\320\274\320\265\321\207\320\260\320\275\320\270\320\271.os" @@ -0,0 +1,55 @@ +#Область ОписаниеПеременных + +Перем Информационное Экспорт; +Перем Незначительное Экспорт; +Перем Важное Экспорт; +Перем Критическое Экспорт; +Перем Блокирующее Экспорт; + +#КонецОбласти + +/////////////////////////////////////////////////////////////////////////////// + +// Сопоставляет уровень критичности из отчета ЕДТ и уровень критичности правила для сонара +// +// Параметры: +// Критичность - Строка - Уровень критичности замечания из ЕДТ +// +// Возвращаемое значение: +// Строка - Уровень критичности для правила в BSL LS +// +Функция Определить(Критичность) Экспорт + + Если Критичность = "Тривиальная" Тогда + + Возврат Информационное; + + ИначеЕсли Критичность = "Незначительная" Тогда + + Возврат Незначительное; + + ИначеЕсли Критичность = "Значительная" Тогда + + Возврат Важное; + + ИначеЕсли Критичность = "Критическая" Тогда + + Возврат Критическое; + + ИначеЕсли Критичность = "Ошибка конфигурации" Тогда + + Возврат Важное; + + Иначе + + Возврат Незначительное; + + КонецЕсли; + +КонецФункции + +Информационное = "INFO"; +Незначительное = "MINOR"; +Важное = "MAJOR"; +Критическое = "CRITICAL"; +Блокирующее = "BLOCKER"; diff --git "a/src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213\320\237\321\200\320\270\320\273\320\276\320\266\320\265\320\275\320\270\321\217.os" "b/src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213\320\237\321\200\320\270\320\273\320\276\320\266\320\265\320\275\320\270\321\217.os" new file mode 100644 index 0000000..e5ac8da --- /dev/null +++ "b/src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213\320\237\321\200\320\270\320\273\320\276\320\266\320\265\320\275\320\270\321\217.os" @@ -0,0 +1,119 @@ +#Использовать logos + +#Область ОписаниеПеременных + +Перем Лог; + +Перем Контекст; + +#КонецОбласти + +#Область ПрограммныйИнтерфейс + +// Возвращает объект лог для фиксации сообщений +// +// Возвращаемое значение: +// logos.Лог - объект типа +// +Функция Лог() Экспорт + + Если Лог = Неопределено Тогда + Лог = Логирование.ПолучитьЛог(ИмяЛогаПриложения()); + КонецЕсли; + + Возврат Лог; + +КонецФункции + +// Устанавливает место, откуда будут читаться старые замечания и записываться новые. +// +// Параметры: +// ПутьКФайлу - Строка - Путь к внешнему файлу правил +// +Процедура УстановитьКонтекстСохранения(Знач ПутьКФайлу) Экспорт + + Если ЗначениеЗаполнено(ПутьКФайлу) Тогда + Контекст = ПутьКФайлу; + + Иначе + Контекст = ЛокальныйКонтекст(); + КонецЕсли; + + Лог().Информация("Установлен контекст сохранения замечаний %1", Контекст); + +КонецПроцедуры + +// Устанавливает способ сохранения замечаний и возвращает выбранный контекст +// +// Возвращаемое значение: +// Строка - контекст для работы с сохранением правил +// +Функция ПолучитьКонтекст() Экспорт + + Если Контекст = Неопределено Тогда + УстановитьКонтекстСохранения(Неопределено); + КонецЕсли; + + Возврат Контекст; + +КонецФункции + +// Путь к локальному файлу с сохраненными правилами +// +// Возвращаемое значение: +// Строка - Путь к файлу +// +Функция ЛокальныйКонтекст() Экспорт + + Возврат ОбъединитьПути(ТекущийСценарий().Каталог, "../..", "custom-rules.json"); + +КонецФункции + +// Возвращает имя лога приложения +// +// Возвращаемое значение: +// Строка - Имя лога +// +Функция ИмяЛогаПриложения() Экспорт + Возврат "oscript.app." + ИмяПриложения(); +КонецФункции + +// Возвращает имя приложения +// +// Возвращаемое значение: +// Строка - Имя приложения +// +Функция ИмяПриложения() Экспорт + + Возврат "edt-ripper"; + +КонецФункции + +// Версия приложения +// +// Возвращаемое значение: +// Строка - Строка с версией приложения +// +Функция Версия() Экспорт + + Возврат "0.7"; + +КонецФункции + +// Устанавливает режим отладки для логирования приложения +// +// Параметры: +// РежимОтладки - Булево - Если Истина отладка включается, если ложь - выключается +// +Процедура УстановитьРежимОтладки(Знач РежимОтладки) Экспорт + + Если РежимОтладки Тогда + + Лог().УстановитьУровень(УровниЛога.Отладка); + Лог.Отладка("Установлен уровень логов ОТЛАДКА"); + + КонецЕсли; + +КонецПроцедуры + +#КонецОбласти diff --git "a/src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\237\320\260\321\200\321\201\320\265\321\200\320\236\321\210\320\270\320\261\320\276\320\272.os" "b/src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\237\320\260\321\200\321\201\320\265\321\200\320\236\321\210\320\270\320\261\320\276\320\272.os" new file mode 100644 index 0000000..6d02dfc --- /dev/null +++ "b/src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\237\320\260\321\200\321\201\320\265\321\200\320\236\321\210\320\270\320\261\320\276\320\272.os" @@ -0,0 +1,245 @@ +#Область ОписаниеПеременных + +Перем КешПрочитанныхФайлов; +Перем Лог; + +#КонецОбласти + +#Область ПрограммныйИнтерфейс + +// Разбирает отчет из ЕДТ и формирует отчет в формате bsl ls +// +// Параметры: +// Файл - Строка - Путь к файлу, результату работы ЕДТ +// ПутьКРепозиторию - Строка - Путь к репозиторию с проектами +// СписокПроектов - Массив - Список проектов в репозитории +// ФайлРезультата - Строка - Файл, куда будет записан отчет +// ПутиКакВЛинукс - Строка - Использовать пути как в линукс в отчете +// +Процедура Прочитать(Файл, ПутьКРепозиторию, СписокПроектов, ФайлРезультата, ПутиКакВЛинукс) Экспорт + + Чтение = Новый ЧтениеТекста; + Чтение.Открыть(Файл, "UTF-8", , , Ложь); + + Строка = Чтение.ПрочитатьСтроку(); + Отчет = Новый ГенераторОтчетовBSL(); + + ВыражениеУбратьКавычки = Новый РегулярноеВыражение("(\s*[:\[][\S\s]+)"); + ВыражениеУбратьКавычки2 = Новый РегулярноеВыражение("(\s\([\S\s]+?\))"); + ВыражениеУбратьКавычки3 = Новый РегулярноеВыражение("(\s*(?>""'|[""'])[\S\s]*?(?>'""|['""]))"); + + МассивДобавлений = Новый Соответствие; + ХранилищеПравил = Новый ХранилищеПравил; + + // проверка EDT могла быть запущена по мультипроектам с одним файлом результата(напр. конфа + расширения) + ГенераторыПутей = ИнициализироватьГенераторы(ПутьКРепозиторию, СписокПроектов); + + Пока Строка <> Неопределено Цикл + + СыроеЗамечание = РазобратьЗамечаниеВСтруктуру(Строка); + + Если СтрНачинаетсяС(СыроеЗамечание.Сообщение, "[BSL LS]") Тогда + Строка = Чтение.ПрочитатьСтроку(); + Продолжить; + КонецЕсли; + + ГенераторПутей = ГенераторыПутей.Получить(СыроеЗамечание.Проект); + + Если ГенераторПутей = Неопределено Тогда + //Выкинуть в лог? + ВызватьИсключение "Неизвестный проект " + СыроеЗамечание.Проект + "Невозможно подобрать путь"; + КонецЕсли; + + Позиция = НайтиПозициюВСтрокеЗамечания(СыроеЗамечание.Позиция); + + МетаданныеЗамечания = ""; + ЗамечаниеПеренесено = Ложь; + + Если Позиция = Неопределено Тогда // это не модуль + + МетаданныеЗамечания = Конфигурация.ПодобратьМодуль(ГенераторПутей, СыроеЗамечание.Объект); + ЗамечаниеПеренесено = Истина; + + Иначе + МетаданныеЗамечания = СыроеЗамечание.Объект; + КонецЕсли; + + ОбъектЗамечания = Конфигурация.НормализованныйПутьКОбъектуКонфигурации(ГенераторПутей, МетаданныеЗамечания, ПутиКакВЛинукс); + + Если ЗамечаниеПеренесено Тогда + Позиция = ПолучитьЗначимуюСтроку(ОбъектЗамечания); + КонецЕсли; + + Замечание = Отчет.НовыйЗамечаниеДляОбъекта(ОбъектЗамечания); + + //Описание замечания берется из выхлопа EDT + Замечание.message = ?(ЗамечаниеПеренесено, СыроеЗамечание.РасширенноеСообщение, СыроеЗамечание.Сообщение); + + // Диапазон срабатывания - позиция вычисленная ранее + Замечание.range.start.line = Позиция - 1; + Замечание.range.start.character = 0; + Замечание.range.end.line = Позиция - 1; + Замечание.range.end.character = 1; + + // Определение кода события. Изначально если присутствует берется из EDT. + // Отсутствующий код берется из файла правил сонар. + КодПравила = СыроеЗамечание.Код; + + Имя = ВыражениеУбратьКавычки.Заменить(СыроеЗамечание.Сообщение, ""); + Имя = ВыражениеУбратьКавычки3.Заменить(Имя, ""); + Имя = СокрЛП(ВыражениеУбратьКавычки2.Заменить(Имя, ""));; + + Код = НайтиСоздатьПравило(ХранилищеПравил, КодПравила, Имя,СыроеЗамечание.Тип, СыроеЗамечание, МассивДобавлений); + + Замечание.code = Код; + + Строка = Чтение.ПрочитатьСтроку(); + КонецЦикла; + Чтение.Закрыть(); + + Добавлено = МассивДобавлений.Количество(); + Если Добавлено Тогда + ХранилищеПравил.Дополнить(МассивДобавлений); + КонецЕсли; + + Отчет.ЗаписатьОтчет(ФайлРезультата); + +КонецПроцедуры + +#КонецОбласти + +#Область СлужебныеПроцедурыИФункции + +Функция НайтиСоздатьПравило(ХранилищеПравил, КодПравила, Имя, Тип, Важность, МассивДобавлений) + + СтрокаПоиска = ""; + Если ЗначениеЗаполнено(КодПравила) Тогда + СтрокаПоиска = КодПравила; + Иначе + СтрокаПоиска = Имя; + КонецЕсли; + + Правило = ХранилищеПравил.НайтиПоКоду(СтрокаПоиска); + + ПравилоОтсутствуетВХранилище = Правило = Неопределено; + НовоеПравило = МассивДобавлений.Получить(СтрокаПоиска); + + Если НовоеПравило <> Неопределено Тогда + + Возврат НовоеПравило.Code; + + ИначеЕсли ПравилоОтсутствуетВХранилище Тогда + + НовоеПравило = ХранилищеПравил.НовыйПравило(СтрокаПоиска, Имя, ТипыЗамечаний.Определить(Тип), КритичностьЗамечаний.Определить(Важность)); + НовоеПравило.Code = "EDT" + "-" + (ХранилищеПравил.Количество() + МассивДобавлений.Количество() + 1); + МассивДобавлений.Вставить(СтрокаПоиска, НовоеПравило); + + Возврат НовоеПравило.Code; + + Иначе + Возврат Правило.Code; + КонецЕсли; + +КонецФункции + +Функция ИнициализироватьГенераторы(Репо, Проекты) + + Генераторы = Новый Соответствие(); + + Для Каждого Проект Из Проекты Цикл + + Путь = ОбъединитьПути(Репо, Проект, "src"); + ПараметрыПриложения.Лог().Отладка("Использован путь проекта %1", Путь); + Генераторы.Вставить(Проект, Новый Путь1СПоМетаданным(Путь)); + КонецЦикла; + + Возврат Генераторы; + +КонецФункции + +Функция НайтиПозициюВСтрокеЗамечания(Позиция) + + НайденаяПозиция = Неопределено; + + Если ЗначениеЗаполнено(Позиция) Тогда + + Попытка + НайденаяПозиция = Число(СтрЗаменить(Позиция, "строка ", "")); + Исключение + Попытка + НайденаяПозиция = Число(СтрЗаменить(Позиция, "line ", "")); + Исключение + НайденаяПозиция = Неопределено; + КонецПопытки; + КонецПопытки; + КонецЕсли; + + Возврат НайденаяПозиция; + +КонецФункции + +Функция ПолучитьЗначимуюСтроку(ПутьКФайлу) + + Если КешПрочитанныхФайлов.Получить(ПутьКФайлу) = Неопределено Тогда + ЗначимаяСтрока = ЗначимаяСтрокаФайла(ПутьКФайлу); + КешПрочитанныхФайлов.Вставить(ПутьКФайлу, ЗначимаяСтрока); + Возврат ЗначимаяСтрока; + Иначе; + Возврат КешПрочитанныхФайлов.Получить(ПутьКФайлу) + КонецЕсли; + +КонецФункции + +Функция ЗначимаяСтрокаФайла(ПутьКФайлу) + ЗначимаяСтрока = 0; + Текст = Новый ЧтениеТекста(); + + Попытка + + Текст.Открыть(ПутьКФайлу); + Строка = Текст.ПрочитатьСтроку(); + + Пока Строка <> Неопределено Цикл + + Если НЕ ПустаяСтрока(Строка) Тогда + Прервать; + КонецЕсли; + + ЗначимаяСтрока = ЗначимаяСтрока + 1; + Строка = Текст.ПрочитатьСтроку(); + КонецЦикла; + + Исключение + Текст.Закрыть(); + КонецПопытки; + + Текст.Закрыть(); + + ЗначимаяСтрока = ЗначимаяСтрока + 1; + + Возврат ЗначимаяСтрока; + +КонецФункции + +Функция РазобратьЗамечаниеВСтруктуру(Строка) + + ОписаниеЗамечания = СтрРазделить(Строка, Символы.Таб, Истина); + Замечание = Новый Структура; + Замечание.Вставить("Дата", ОписаниеЗамечания[0]); + Замечание.Вставить("Важность", ОписаниеЗамечания[1]); + Замечание.Вставить("Тип", ОписаниеЗамечания[2]); + Замечание.Вставить("Проект", ОписаниеЗамечания[3]); + Замечание.Вставить("Код", ОписаниеЗамечания[4]); + Замечание.Вставить("Объект", ОписаниеЗамечания[5]); + Замечание.Вставить("Позиция", ОписаниеЗамечания[6]); + Замечание.Вставить("Сообщение", ОписаниеЗамечания[7]); + Замечание.Вставить("РасширенноеСообщение", ОписаниеЗамечания[5] + "->" + ОписаниеЗамечания[7]); + + Возврат Замечание; + +КонецФункции; + +#КонецОбласти + +КешПрочитанныхФайлов = Новый Соответствие(); +Лог = ПараметрыПриложения.Лог(); diff --git "a/src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\242\320\270\320\277\321\213\320\227\320\260\320\274\320\265\321\207\320\260\320\275\320\270\320\271.os" "b/src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\242\320\270\320\277\321\213\320\227\320\260\320\274\320\265\321\207\320\260\320\275\320\270\320\271.os" new file mode 100644 index 0000000..d61e4ab --- /dev/null +++ "b/src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\242\320\270\320\277\321\213\320\227\320\260\320\274\320\265\321\207\320\260\320\275\320\270\320\271.os" @@ -0,0 +1,55 @@ +Перем Ошибка Экспорт; +Перем ДефектКода Экспорт; +Перем Уязвимость Экспорт; + +/////////////////////////////////////////////////////////////////////////////// + +// Сопоставляет тип замечания из отчета ЕДТ и тип замечания для правила сонара +// +// Параметры: +// ТипЗамечания - Строка - Тип замечания из ЕДТ +// +// Возвращаемое значение: +// Строка - Подобраный тип замечания для правила в BSL LS +// +Функция Определить(ТипЗамечания) Экспорт + + Если ТипЗамечания = "Производительность" Тогда + + Возврат Ошибка; + + ИначеЕсли ТипЗамечания = "Переносимость" Тогда + + Возврат ДефектКода; + + ИначеЕсли ТипЗамечания = "Предупреждение" Тогда + + Возврат ДефектКода; + + ИначеЕсли ТипЗамечания = "Ошибка конфигурации" Тогда + + Возврат Ошибка; + + ИначеЕсли ТипЗамечания = "Стандарты кодирования" Тогда + + Возврат ДефектКода; + + ИначеЕсли ТипЗамечания = "Безопасность" Тогда + + Возврат Уязвимость; + + ИначеЕсли ТипЗамечания = "Стандарты разработки интерфейсов" Тогда + + Возврат Ошибка; + + Иначе + + Возврат ДефектКода; + + КонецЕсли; + +КонецФункции + +Ошибка = "BUG"; +ДефектКода = "CODE_SMELL"; +Уязвимость = "VULNERABILITY"; diff --git "a/src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\244\320\260\320\271\320\273\320\276\320\262\321\213\320\265\320\236\320\277\320\265\321\200\320\260\321\206\320\270\320\270.os" "b/src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\244\320\260\320\271\320\273\320\276\320\262\321\213\320\265\320\236\320\277\320\265\321\200\320\260\321\206\320\270\320\270.os" new file mode 100644 index 0000000..9ba95ef --- /dev/null +++ "b/src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\244\320\260\320\271\320\273\320\276\320\262\321\213\320\265\320\236\320\277\320\265\321\200\320\260\321\206\320\270\320\270.os" @@ -0,0 +1,106 @@ +#Область ПрограммныйИнтерфейс + +// Читает json файл и преобразует его в объект +// +// Параметры: +// ПутьКФайлу - Строка - Путь к файлу, который будет прочитан +// ВСоответствие - Булево - От значения параметра зависит в какой тип будет происходить чтение +// +// Возвращаемое значение: +// Соответствие,Структура - Объект из json файла +// +Функция ПрочитатьОбъект(ПутьКФайлу, ВСоответствие = Истина) Экспорт + ЧтениеJSON = Новый ЧтениеJSON; + ЧтениеJSON.ОткрытьФайл(ПутьКФайлу, "UTF-8"); + Объект = ПрочитатьJSON(ЧтениеJSON, ВСоответствие); + ЧтениеJSON.Закрыть(); + Возврат Объект; +КонецФункции + +// Записывает произвольный объект в json файл +// +// Параметры: +// ПутьКФайлу - Строка - Путь json файлу +// ОбъектЗаписи - Объект - Объект для серриализации +// +Процедура ЗаписатьОбъект(ПутьКФайлу, ОбъектЗаписи) Экспорт + ЗаписьJSON = Новый ЗаписьJSON; + ЗаписьJSON.ОткрытьФайл(ПутьКФайлу, "UTF-8", , Новый ПараметрыЗаписиJSON(, Символы.Таб)); + ЗаписатьJSON(ЗаписьJSON, ОбъектЗаписи); + ЗаписьJSON.Закрыть(); + +КонецПроцедуры + +// Находит шаблон для отчета +// +// Возвращаемое значение: +// Строка - путь к файлу с шаблоном отчета +// +Функция РесурсОтчет() Экспорт + + Возврат ОбъединитьПути(Ресурсы(), "report.json"); + +КонецФункции + +// Находит шаблон замечания +// +// Возвращаемое значение: +// Строка - Путь к шаблону замечания +// +Функция РесурсЗамечание() Экспорт + + Возврат ОбъединитьПути(Ресурсы(), "diagnostic.json"); + +КонецФункции + +#КонецОбласти + +#Область СлужебныйПрограммныйИнтерфейс + +// Находит путь к каталогу с ресурсами +// +// Возвращаемое значение: +// Строка - путь к каталогу с ресурсами +// +Функция Ресурсы() Экспорт + + Возврат ОбъединитьПути(КаталогИсходников(), ДиректорияРесурсов()); + +КонецФункции + +// Находит путь к каталогу исходных файлов программы +// +// Возвращаемое значение: +// Строка - Каталог исходных файлов программы +// +Функция КаталогИсходников() Экспорт + Возврат ОбъединитьПути(ТекущийСценарий().Каталог, ".."); +КонецФункции + +// Находит путь к корневому каталогу программы +// +// Возвращаемое значение: +// Строка - Путь к корневому каталогу программы +// +Функция КаталогПрограммы() Экспорт + Возврат ОбъединитьПути(КаталогИсходников(), ".."); +КонецФункции + +// Находит внутренний файл правил +// +// Возвращаемое значение: +// Строка - Путь к внутреннему файлу правил +// +Функция ФайлПравилПрограммы() Экспорт + Возврат ОбъединитьПути(КаталогПрограммы(), "custom-rules.json"); +КонецФункции + +#КонецОбласти + +#Область СлужебныеПроцедурыИФункции + +Функция ДиректорияРесурсов() + Возврат "Ресурсы"; +КонецФункции + +#КонецОбласти diff --git "a/src/\320\240\320\265\321\201\321\203\321\200\321\201\321\213/diagnostic.json" "b/src/\320\240\320\265\321\201\321\203\321\200\321\201\321\213/diagnostic.json" new file mode 100644 index 0000000..c32b6ab --- /dev/null +++ "b/src/\320\240\320\265\321\201\321\203\321\200\321\201\321\213/diagnostic.json" @@ -0,0 +1,17 @@ +{ + "range": { + "start": { + "line": 0, + "character": 0 + }, + "end": { + "line": 0, + "character": 0 + } + }, + "severity": "Information", + "code": "", + "source": "edt-rules", + "message": "", + "relatedInformation": null +} \ No newline at end of file diff --git "a/src/\320\240\320\265\321\201\321\203\321\200\321\201\321\213/fileinfo.json" "b/src/\320\240\320\265\321\201\321\203\321\200\321\201\321\213/fileinfo.json" new file mode 100644 index 0000000..0a9e7b1 --- /dev/null +++ "b/src/\320\240\320\265\321\201\321\203\321\200\321\201\321\213/fileinfo.json" @@ -0,0 +1,4 @@ +{ + "diagnostics": [ + ] +} \ No newline at end of file diff --git "a/src/\320\240\320\265\321\201\321\203\321\200\321\201\321\213/report.json" "b/src/\320\240\320\265\321\201\321\203\321\200\321\201\321\213/report.json" new file mode 100644 index 0000000..34964a1 --- /dev/null +++ "b/src/\320\240\320\265\321\201\321\203\321\200\321\201\321\213/report.json" @@ -0,0 +1,8 @@ +{ + "date": "", + "fileinfos": [ + ], + "fileinfos_dirty": { + + } +} \ No newline at end of file diff --git a/tasks/test.os b/tasks/test.os new file mode 100644 index 0000000..10059c3 --- /dev/null +++ b/tasks/test.os @@ -0,0 +1,82 @@ +#Использовать 1bdd +#Использовать 1testrunner +#Использовать fs + +Функция ПрогнатьТесты() + + Тестер = Новый Тестер; + Тестер.УстановитьФорматЛогФайла(Тестер.ФорматыЛогФайла().GenericExec); + + ПутьКТестам = "tests"; + ПутьКОтчетуJUnit = "out"; + + ФС.ОбеспечитьПустойКаталог(ПутьКОтчетуJUnit); + + РезультатТестирования = Тестер.ТестироватьКаталог( + Новый Файл(ПутьКТестам), + Новый Файл(ПутьКОтчетуJUnit) + ); + + Успешно = РезультатТестирования = 0; + + Возврат Успешно; +КонецФункции // ПрогнатьТесты() + +Функция ПрогнатьФичи() + + ПутьОтчетаJUnit = ОбъединитьПути(ТекущийКаталог(), "out", "bdd-log.xml"); + + КаталогФич = ОбъединитьПути(".", "features"); + + Файл_КаталогФич = Новый Файл(КаталогФич); + + ИсполнительБДД = Новый ИсполнительБДД; + РезультатыВыполнения = ИсполнительБДД.ВыполнитьФичу(Файл_КаталогФич, Файл_КаталогФич); + ИтоговыйРезультатВыполнения = ИсполнительБДД.ПолучитьИтоговыйСтатусВыполнения(РезультатыВыполнения); + + СтатусВыполнения = ИсполнительБДД.ВозможныеСтатусыВыполнения().НеВыполнялся; + Если РезультатыВыполнения.Строки.Количество() > 0 Тогда + + СтатусВыполнения = ИсполнительБДД.ПолучитьИтоговыйСтатусВыполнения(РезультатыВыполнения); + + КонецЕсли; + + ГенераторОтчетаJUnit = Новый ГенераторОтчетаJUnit; + ГенераторОтчетаJUnit.Сформировать(РезультатыВыполнения, СтатусВыполнения, ПутьОтчетаJUnit); + + Сообщить(СтрШаблон("Результат прогона фич <%1> + |", ИтоговыйРезультатВыполнения)); + + Возврат ИтоговыйРезультатВыполнения <> ИсполнительБДД.ВозможныеСтатусыВыполнения().Сломался; +КонецФункции // ПрогнатьФичи() + +// основной код + +ТекКаталог = ТекущийКаталог(); + +Попытка + ТестыПрошли = ПрогнатьТесты(); +Исключение + ТестыПрошли = Ложь; + Сообщить(СтрШаблон("Тесты через 1testrunner выполнены неудачно + |%1", ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()))); +КонецПопытки; + +УстановитьТекущийКаталог(ТекКаталог); + +Попытка + ФичиПрошли = ПрогнатьФичи(); +Исключение + ФичиПрошли = Ложь; + Сообщить(СтрШаблон("Тесты поведения через 1bdd выполнены неудачно + |%1", ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()))); +КонецПопытки; + +Если Не ТестыПрошли Или Не ФичиПрошли Тогда + ВызватьИсключение "Тестирование завершилось неудачно!"; +Иначе + Сообщить(СтрШаблон("Результат прогона тестов <%1> + |", ТестыПрошли)); + Сообщить(СтрШаблон("Результат прогона основных фич <%1> + |", ФичиПрошли)); +КонецЕсли; diff --git "a/tests/\320\223\320\265\320\275\320\265\321\200\320\260\321\202\320\276\321\200\320\236\321\202\321\207\320\265\321\202\320\276\320\262.os" "b/tests/\320\223\320\265\320\275\320\265\321\200\320\260\321\202\320\276\321\200\320\236\321\202\321\207\320\265\321\202\320\276\320\262.os" new file mode 100644 index 0000000..dc542b9 --- /dev/null +++ "b/tests/\320\223\320\265\320\275\320\265\321\200\320\260\321\202\320\276\321\200\320\236\321\202\321\207\320\265\321\202\320\276\320\262.os" @@ -0,0 +1,57 @@ +#Использовать asserts +#Использовать logos +#Использовать tempfiles +#Использовать "../src" + +Перем юТест; +Перем Лог; +Перем МенеджерВременныхФайлов; + +// Основная точка входа +Функция ПолучитьСписокТестов(ЮнитТестирование) Экспорт + + ПередЗапускомТестов(); + + юТест = ЮнитТестирование; + + ВсеТесты = Новый Массив; + + ВсеТесты.Добавить("Тест_ГенераторОтчетов"); + + Возврат ВсеТесты; + +КонецФункции + +Процедура ПередЗапускомТестов() + + Попытка + ВремТестер = Новый Тестер; + Лог = Логирование.ПолучитьЛог(ВремТестер.ИмяЛога()); + Исключение + Лог = Логирование.ПолучитьЛог("Test"); + КонецПопытки; + +КонецПроцедуры + +Процедура ПередЗапускомТеста() Экспорт + + ПараметрыПриложения.УстановитьРежимОтладки(); + + МенеджерВременныхФайлов = Новый МенеджерВременныхФайлов; + +КонецПроцедуры + + +Процедура ПослеЗапускаТеста() Экспорт + + МенеджерВременныхФайлов.Удалить(); + МенеджерВременныхФайлов = Неопределено; + +КонецПроцедуры + +Процедура Тест_ГенераторОтчетов() Экспорт + + Отчет = Новый ГенераторОтчетовBSL(); + + Ожидаем.Что(ЗначениеЗаполнено(Отчет.Получить("date"))).ЭтоИстина(); +КонецПроцедуры diff --git "a/tests/\320\237\320\260\321\200\321\201\320\265\321\200\320\236\321\210\320\270\320\261\320\276\320\272.os" "b/tests/\320\237\320\260\321\200\321\201\320\265\321\200\320\236\321\210\320\270\320\261\320\276\320\272.os" new file mode 100644 index 0000000..e69de29 diff --git "a/tests/\320\244\320\260\320\271\320\273\320\276\320\262\321\213\320\265\320\236\320\277\320\265\321\200\320\260\321\206\320\270\320\270.os" "b/tests/\320\244\320\260\320\271\320\273\320\276\320\262\321\213\320\265\320\236\320\277\320\265\321\200\320\260\321\206\320\270\320\270.os" new file mode 100644 index 0000000..cd61648 --- /dev/null +++ "b/tests/\320\244\320\260\320\271\320\273\320\276\320\262\321\213\320\265\320\236\320\277\320\265\321\200\320\260\321\206\320\270\320\270.os" @@ -0,0 +1,72 @@ +#Использовать asserts +#Использовать logos +#Использовать tempfiles +#Использовать fs +#Использовать "../src" + +Перем юТест; +Перем Лог; +Перем МенеджерВременныхФайлов; + +// Основная точка входа +Функция ПолучитьСписокТестов(ЮнитТестирование) Экспорт + + ПередЗапускомТестов(); + + юТест = ЮнитТестирование; + + ВсеТесты = Новый Массив; + + ВсеТесты.Добавить("Тест_ПолучениеРесурсов"); + ВсеТесты.Добавить("Тест_СериализацияИДесериализация"); + + Возврат ВсеТесты; + +КонецФункции + +Процедура ПередЗапускомТестов() + + Попытка + ВремТестер = Новый Тестер; + Лог = Логирование.ПолучитьЛог(ВремТестер.ИмяЛога()); + Исключение + Лог = Логирование.ПолучитьЛог("Test"); + КонецПопытки; + +КонецПроцедуры + +Процедура ПередЗапускомТеста() Экспорт + + ПараметрыПриложения.УстановитьРежимОтладки(); + + МенеджерВременныхФайлов = Новый МенеджерВременныхФайлов; + +КонецПроцедуры + +Процедура ПослеЗапускаТеста() Экспорт + + МенеджерВременныхФайлов.Удалить(); + МенеджерВременныхФайлов = Неопределено; + +КонецПроцедуры + +Процедура Тест_ПолучениеРесурсов() Экспорт + + Файл = Новый Файл(ФайловыеОперации.Ресурсы()); + + Ожидаем.Что(Файл.Существует(), "Директории не существует").ЭтоИстина(); + Ожидаем.Что(Файл.ЭтоКаталог(), "Не является директорией").ЭтоИстина(); + Ожидаем.Что(НайтиФайлы(ФайловыеОперации.Ресурсы(), "*.json").Количество(), "Изменилось количество ресурсов").Равно(4); + +КонецПроцедуры + +Процедура Тест_СериализацияИДесериализация() Экспорт + + ПутьКФайлу = МенеджерВременныхФайлов.СоздатьФайл("test.json"); + + Объект = ФайловыеОперации.ПрочитатьОбъект(ФайловыеОперации.РесурсОтчет(), Истина); + Ожидаем.Что(ТипЗнч(Объект), "Типы не совпали").Равно(Тип("Соответствие")); + + ФайловыеОперации.ЗаписатьОбъект(ПутьКФайлу, Объект); + +КонецПроцедуры diff --git "a/tests/\320\245\321\200\320\260\320\275\320\270\320\273\320\270\321\211\320\265\320\237\321\200\320\260\320\262\320\270\320\273.os" "b/tests/\320\245\321\200\320\260\320\275\320\270\320\273\320\270\321\211\320\265\320\237\321\200\320\260\320\262\320\270\320\273.os" new file mode 100644 index 0000000..e69de29 diff --git a/v8config.json b/v8config.json new file mode 100644 index 0000000..000735c --- /dev/null +++ b/v8config.json @@ -0,0 +1,23 @@ +{ + "Precommt4onecСценарии": { + "ИспользоватьСценарииРепозитория": false, + "КаталогЛокальныхСценариев": "", + "ГлобальныеСценарии": [ + "ЗапретИспользованияПерейти.os", + "УдалениеЛишнихПустыхСтрок.os", + "ПроверкаДублейПроцедурИФункций.os", + "ДобавлениеПробеловПередКлючевымиСловами.os", + "ПроверкаКорректностиИнструкцийПрепроцессора.os", + "ПроверкаКорректностиОбластей.os", + "ИсправлениеНеКаноническогоНаписания.os", + "УдалениеЛишнихКонцевыхПробелов.os" + ], + "ОтключенныеСценарии": [], + "НастройкиСценариев": { + "СортировкаДереваМетаданных": { + "УчитываяПрефикс": "" + } + }, + "Проекты": {} + } +} \ No newline at end of file From d83f33c7efa43ff8368f7818d6d451fbd8e551ae Mon Sep 17 00:00:00 2001 From: Valery Maximov Date: Fri, 30 Sep 2022 09:52:30 +0300 Subject: [PATCH 2/2] =?UTF-8?q?=D0=9F=D0=B5=D1=80=D0=B2=D1=8B=D0=B9=20?= =?UTF-8?q?=D0=BF=D1=83=D0=B1=D0=BB=D0=B8=D1=87=D0=BD=D1=8B=D0=B9=20=D1=80?= =?UTF-8?q?=D0=B5=D0=BB=D0=B8=D0=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 ++- edt-ripper-0.7.ospx | Bin 21416 -> 0 bytes installlocalhost.bat | 12 ++++++++++++ ...\320\266\320\265\320\275\320\270\321\217.os" | 2 +- 4 files changed, 15 insertions(+), 2 deletions(-) delete mode 100644 edt-ripper-0.7.ospx create mode 100644 installlocalhost.bat diff --git a/.gitignore b/.gitignore index 20b3621..b52e27e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .vscode/launch.json edt-validate-results edt-validate-results-en -out.json \ No newline at end of file +out.json +*.ospx diff --git a/edt-ripper-0.7.ospx b/edt-ripper-0.7.ospx deleted file mode 100644 index 78770c8a47e9ea2d06d35906425388b8c1b8eaec..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21416 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 diff --git a/installlocalhost.bat b/installlocalhost.bat new file mode 100644 index 0000000..fb6f30a --- /dev/null +++ b/installlocalhost.bat @@ -0,0 +1,12 @@ +@echo off +call del "*.ospx" + +for /f %%i in ('"oscript -version"') do set result=%%i + +if %result%==1.0.19.105 ( + call opm build . -mf ./packagedef -out . +) else ( + call opm build -m ./packagedef -o . +) + +call opm install -f *.ospx diff --git "a/src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213\320\237\321\200\320\270\320\273\320\276\320\266\320\265\320\275\320\270\321\217.os" "b/src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213\320\237\321\200\320\270\320\273\320\276\320\266\320\265\320\275\320\270\321\217.os" index e5ac8da..ac505a8 100644 --- "a/src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213\320\237\321\200\320\270\320\273\320\276\320\266\320\265\320\275\320\270\321\217.os" +++ "b/src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213\320\237\321\200\320\270\320\273\320\276\320\266\320\265\320\275\320\270\321\217.os" @@ -96,7 +96,7 @@ // Функция Версия() Экспорт - Возврат "0.7"; + Возврат "22.09"; КонецФункции