mirror of
https://github.com/bia-technologies/sonar-helper.git
synced 2026-06-18 17:24:22 +02:00
1. Добавлена команда для формирования отчета по разработчикам
2. Выполнены рефакторинг и исправление ошибок
This commit is contained in:
@@ -43,8 +43,14 @@ SonarQube может создавать несколько замечаний п
|
||||
|
||||
На данный момент поддерживаются следующие варианты формирования отчета:
|
||||
|
||||
- **JSON** - формируется отчет в формате json, метрики выгружаются дважды - для идентификатора метрики и для русского представления. [Пример: examples\example-report.json](examples\example-report.json)
|
||||
- **HTML** - формируется отчет в формате html, метрики выгнржаются только для русского представления. [Пример: examples\example-report.html](examples\example-report.html)
|
||||
- **JSON** - формируется отчет в формате json, метрики выгружаются дважды - для идентификатора метрики и для русского представления. [Пример: examples\example-report.json](examples/example-report.json)
|
||||
- **HTML** - формируется отчет в формате html, метрики выгнржаются только для русского представления. [Пример: examples\example-report.html](examples/example-report.html)
|
||||
|
||||
### Сводный отчет по разработчикам
|
||||
|
||||
При необходимоси получить отчет по разработчикам (не конкретные замечания, а "температуру") и понять, кто в команде как работает можно вручную собирать информацию по страницам SonarQube, но проще использовать **`sonar-helper`**, вызвав команду **`usr-report`** и проанализировать полученный результат.
|
||||
|
||||
На данный момент поддерживается вариант формирования отчета в формате **JSON**. [Пример отчета: examples\example-usr-report.json](examples/example-usr-report.json)
|
||||
|
||||
## Примеры
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"--token": "2ef785ca946170b7086668132175eb01386943a1",
|
||||
"--server": "http://my.sonar.server:9000",
|
||||
"--projects": "bsp,mdm",
|
||||
"--statuses": "OPEN",
|
||||
"--report-path": "usr-rep.json",
|
||||
"--report-format": "JSON"
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"ДатаФормирования": "2019-05-06T14:17:17.5125591",
|
||||
"СерверSonarQube": "http:\/\/my.sonar.server:9000",
|
||||
"Количество": 2,
|
||||
"Замечания": [
|
||||
{
|
||||
"КлючПроекта": "mdm",
|
||||
"Статус": "OPEN",
|
||||
"Автор": "my.user@mail.domain",
|
||||
"Отвественный": "my.user",
|
||||
"Правило": "RuleCode",
|
||||
"Критичность": "MAJOR",
|
||||
"Тип": "BUG",
|
||||
"Время": 40,
|
||||
"Количество": 20
|
||||
},
|
||||
{
|
||||
"КлючПроекта": "bsp",
|
||||
"Статус": "OPEN",
|
||||
"Автор": "my.user@mail.domain",
|
||||
"Отвественный": "my.user",
|
||||
"Правило": "RuleCode2",
|
||||
"Критичность": "MINOR",
|
||||
"Тип": "CODE_SMELL",
|
||||
"Время": 29,
|
||||
"Количество": 29
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,15 +1,20 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Служебный модуль с реализацией работы команды issue-resolver
|
||||
//
|
||||
// (C) Maximov Valery (aka theshadowco)
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Перем Лог;
|
||||
|
||||
Перем Токен;
|
||||
Перем АдресСервера;
|
||||
Перем РодительскийПроект;
|
||||
Перем ДочерниеПроекты;
|
||||
Перем ИсключаемыеПроекты;
|
||||
Перем Статусы;
|
||||
Перем ИзEDTВКонфигуратор;
|
||||
Перем Теги;
|
||||
Перем МаксимальноеКоличествоСтатусов;
|
||||
|
||||
Перем ПрочитанныеПараметры;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Прикладной интерфейс
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -54,15 +59,19 @@
|
||||
Лог = ДополнительныеПараметры.Лог;
|
||||
ОшибокНет = ПрочитатьПараметрыЗапуска(ПараметрыКоманды);
|
||||
Если НЕ ОшибокНет Тогда
|
||||
Возврат СообщитьОбОшибке("Ошибка запуска");
|
||||
Возврат ОбщегоНазначения.СообщитьОбОшибке("Ошибка запуска");
|
||||
КонецЕсли;
|
||||
|
||||
|
||||
АдресСервера = ПрочитанныеПараметры.Получить("АдресСервера");
|
||||
Токен = ПрочитанныеПараметры.Получить("Токен");
|
||||
РодительскийПроект = ПрочитанныеПараметры.Получить("РодительскийПроект");
|
||||
|
||||
Лог.Информация("Получение информации о проектах");
|
||||
ПроектыSQ = Сонар.ПолучитьПроекты(АдресСервера, Токен);
|
||||
Лог.Информация("Получение информации о родительском проекте");
|
||||
ОписаниеРодительскогоПроекта = ПроектыSQ.Получить(РодительскийПроект);
|
||||
Если ОписаниеРодительскогоПроекта = Неопределено Тогда
|
||||
Возврат СообщитьОбОшибке(СтрШаблон("Родительский проект `%1` в списке проектов не обнаружен", РодительскийПроект));
|
||||
Возврат ОбщегоНазначения.СообщитьОбОшибке(СтрШаблон("Родительский проект `%1` в списке проектов не обнаружен", РодительскийПроект));
|
||||
КонецЕсли;
|
||||
|
||||
Лог.Информация("Получение закрываемых замечаний из родительского проекта");
|
||||
@@ -70,7 +79,7 @@
|
||||
АдресСервера, Токен,
|
||||
ОписаниеРодительскогоПроекта,
|
||||
СтрСоединить(Статусы, ","),
|
||||
ИзEDTВКонфигуратор);
|
||||
ПрочитанныеПараметры.Получить("ИзEDTВКонфигуратор"));
|
||||
|
||||
Если НЕ ЗамечанияРодительскогоПроекта.Количество() Тогда
|
||||
|
||||
@@ -102,6 +111,7 @@
|
||||
КонецЦикла;
|
||||
|
||||
Лог.Информация("Закрытие замечаний в дочерних проектах");
|
||||
Теги = ПрочитанныеПараметры.Получить("Теги");
|
||||
Для Каждого ДочернийПроект Из ДочерниеПроекты Цикл
|
||||
Лог.Информация("Закрытие замечаний в проекте `%1`", ДочернийПроект);
|
||||
ОписаниеПроекта = ПроектыSQ.Получить(СокрЛП(ДочернийПроект));
|
||||
@@ -127,103 +137,33 @@
|
||||
|
||||
Функция ПрочитатьПараметрыЗапуска(ПараметрыКоманды)
|
||||
|
||||
ПрочитанныеПараметры = ОбщегоНазначения.ПрочитатьПараметрыЗапуска(ПараметрыКоманды, Истина);
|
||||
ОшибокНет = ПрочитанныеПараметры.Получить("ОшибокНет");
|
||||
МаксимальноеКоличествоСтатусов = 5;
|
||||
ОшибокНет = Истина;
|
||||
|
||||
Токен = ПараметрыКоманды["--token"];
|
||||
АдресСервера = ПараметрыКоманды["--server"];
|
||||
РодительскийПроект = ПараметрыКоманды["--parent-project"];
|
||||
ДочерниеПроектыСтрокой = ПараметрыКоманды["--child-projects"];
|
||||
ИсключаемыеПроектыСтрокой = ПараметрыКоманды["--exclude-projects"];
|
||||
СтатусыСтрокой = ПараметрыКоманды["--statuses"];
|
||||
Теги = ПараметрыКоманды["--tags"];
|
||||
ИзEDTВКонфигуратор = ПараметрыКоманды["--edt2cfg"];
|
||||
|
||||
ПутьККонфигурационномуФайлу = ПараметрыКоманды["--cfg-file"];
|
||||
Если ПутьККонфигурационномуФайлу <> Неопределено Тогда
|
||||
|
||||
Файл = Новый Файл(ПутьККонфигурационномуФайлу);
|
||||
Если Файл.Существует() Тогда
|
||||
ТекстовыйДокумент = Новый ТекстовыйДокумент();
|
||||
ТекстовыйДокумент.Прочитать(ПутьККонфигурационномуФайлу);
|
||||
Лог.Отладка("Содержимое конфигурационного файла: %1%2", Символы.ПС, ТекстовыйДокумент.ПолучитьТекст());
|
||||
JSON = Новый ЧтениеJSON();
|
||||
JSON.УстановитьСтроку(ТекстовыйДокумент.ПолучитьТекст());
|
||||
ПараметрыИзФайла = ПрочитатьJSON(JSON, Истина);
|
||||
Если Токен = Неопределено Тогда
|
||||
Токен = ПараметрыИзФайла.Получить("--token");
|
||||
КонецЕсли;
|
||||
Если АдресСервера = Неопределено Тогда
|
||||
АдресСервера = ПараметрыИзФайла.Получить("--server");
|
||||
КонецЕсли;
|
||||
Если РодительскийПроект = Неопределено Тогда
|
||||
РодительскийПроект = ПараметрыИзФайла.Получить("--parent-project");
|
||||
КонецЕсли;
|
||||
Если ДочерниеПроектыСтрокой = Неопределено Тогда
|
||||
ДочерниеПроектыСтрокой = ПараметрыИзФайла.Получить("--child-projects");
|
||||
КонецЕсли;
|
||||
Если ИсключаемыеПроектыСтрокой = Неопределено Тогда
|
||||
ИсключаемыеПроектыСтрокой = ПараметрыИзФайла.Получить("--exclude-projects");
|
||||
КонецЕсли;
|
||||
Если СтатусыСтрокой = Неопределено Тогда
|
||||
СтатусыСтрокой = ПараметрыИзФайла.Получить("--statuses");
|
||||
КонецЕсли;
|
||||
Если Теги = Неопределено Тогда
|
||||
Теги = ПараметрыИзФайла.Получить("--tags");
|
||||
КонецЕсли;
|
||||
Если ИзEDTВКонфигуратор = Ложь И ПараметрыИзФайла.Получить("--edt2cfg") <> Неопределено Тогда
|
||||
ИзEDTВКонфигуратор = ПараметрыИзФайла.Получить("--edt2cfg");
|
||||
КонецЕсли;
|
||||
Иначе
|
||||
Лог.Ошибка("Конфигурационный файл по пути `%1` не обнаружен", ОбернутьЗначениеДляПечати(ПутьККонфигурационномуФайлу));
|
||||
ОшибокНет = Ложь;
|
||||
КонецЕсли;
|
||||
|
||||
КонецЕсли;
|
||||
|
||||
Лог.Отладка("Прочитанные параметры:");
|
||||
Лог.Отладка(" Токен = `%1`", ОбернутьЗначениеДляПечати(Токен));
|
||||
Лог.Отладка(" Адрес сервера = `%1`", ОбернутьЗначениеДляПечати(АдресСервера));
|
||||
Лог.Отладка(" Ключ родительского проекта = `%1`", ОбернутьЗначениеДляПечати(РодительскийПроект));
|
||||
Лог.Отладка(" Ключ дочерних проектов (строкой) = `%1`", ОбернутьЗначениеДляПечати(ДочерниеПроектыСтрокой));
|
||||
Лог.Отладка(" Ключ исключаемых проектов (строкой) = `%1`", ОбернутьЗначениеДляПечати(ИсключаемыеПроектыСтрокой));
|
||||
Лог.Отладка(" Статусы строкой = `%1`", ОбернутьЗначениеДляПечати(СтатусыСтрокой));
|
||||
Лог.Отладка(" Устанавливаемые теги = `%1`", ОбернутьЗначениеДляПечати(Теги));
|
||||
Лог.Отладка(" Нужно переводить из EDT = `%1`", ОбернутьЗначениеДляПечати(ИзEDTВКонфигуратор));
|
||||
|
||||
Если Не ЗначениеЗаполнено(Токен) Тогда
|
||||
Лог.Ошибка("Не указан токен для авторизации");
|
||||
ОшибокНет = Ложь;
|
||||
КонецЕсли;
|
||||
|
||||
Если Не ЗначениеЗаполнено(АдресСервера) Тогда
|
||||
Лог.Ошибка("Не указан адрес сервера SonarQube");
|
||||
ОшибокНет = Ложь;
|
||||
КонецЕсли;
|
||||
|
||||
Если Не ЗначениеЗаполнено(РодительскийПроект) Тогда
|
||||
Если Не ЗначениеЗаполнено(ПрочитанныеПараметры.Получить("РодительскийПроект")) Тогда
|
||||
Лог.Ошибка("Не указан ключ родительского проекта");
|
||||
ОшибокНет = Ложь;
|
||||
КонецЕсли;
|
||||
|
||||
Если Не ЗначениеЗаполнено(ДочерниеПроектыСтрокой) Тогда
|
||||
Лог.Ошибка("Не указаны ключ дочерних проектов");
|
||||
Если Не ЗначениеЗаполнено(ПрочитанныеПараметры.Получить("ДочерниеПроектыСтрокой")) Тогда
|
||||
Лог.Ошибка("Не указаны ключи дочерних проектов");
|
||||
ОшибокНет = Ложь;
|
||||
Иначе
|
||||
ДочерниеПроекты = СтрРазделить(ДочерниеПроектыСтрокой, ",", Ложь);
|
||||
ДочерниеПроекты = СтрРазделить(ПрочитанныеПараметры.Получить("ДочерниеПроектыСтрокой"), ", ", Ложь);
|
||||
КонецЕсли;
|
||||
|
||||
ИсключаемыеПроекты = Новый Массив();
|
||||
Если ЗначениеЗаполнено(ИсключаемыеПроектыСтрокой) Тогда
|
||||
ИсключаемыеПроекты = СтрРазделить(ИсключаемыеПроектыСтрокой, ",", Ложь);
|
||||
Если ЗначениеЗаполнено(ПрочитанныеПараметры.Получить("ИсключаемыеПроектыСтрокой")) Тогда
|
||||
ИсключаемыеПроекты = СтрРазделить(ПрочитанныеПараметры.Получить("ИсключаемыеПроектыСтрокой"), ", ", Ложь);
|
||||
КонецЕсли;
|
||||
ИсключаемыеПроекты.Добавить(СокрЛП(РодительскийПроект));
|
||||
ИсключаемыеПроекты.Добавить(СокрЛП(ПрочитанныеПараметры.Получить("РодительскийПроект")));
|
||||
|
||||
Если Не ЗначениеЗаполнено(СтатусыСтрокой) Тогда
|
||||
Если Не ЗначениеЗаполнено(ПрочитанныеПараметры.Получить("СтатусыСтрокой")) Тогда
|
||||
Статусы = СтрРазделить("RESOLVED,CLOSED", ",", Ложь);
|
||||
Иначе
|
||||
Статусы = Новый Массив();
|
||||
СтатусыВрем = СтрРазделить(ВРЕГ(СтатусыСтрокой), ",", Ложь);
|
||||
СтатусыВрем = СтрРазделить(ВРЕГ(ПрочитанныеПараметры.Получить("СтатусыСтрокой")), ", ", Ложь);
|
||||
ВсеСтатусы = СтрРазделить("OPEN,CONFIRMED,REOPENED,RESOLVED,CLOSED", ",");
|
||||
Для Каждого Статус Из СтатусыВрем Цикл
|
||||
Если ВсеСтатусы.Найти(Статус) <> Неопределено Тогда
|
||||
@@ -237,25 +177,11 @@
|
||||
ОшибокНет = Ложь;
|
||||
КонецЕсли;
|
||||
КонецЕсли;
|
||||
|
||||
Если НЕ ЗначениеЗаполнено(Теги) Тогда
|
||||
Теги = "";
|
||||
|
||||
Если НЕ ЗначениеЗаполнено(ПрочитанныеПараметры.Получить("Теги")) Тогда
|
||||
ПрочитанныеПараметры.Вставить("Теги", "");
|
||||
КонецЕсли;
|
||||
|
||||
Возврат ОшибокНет;
|
||||
|
||||
КонецФункции
|
||||
|
||||
Функция ОбернутьЗначениеДляПечати(Знач Значение)
|
||||
Если ЗначениеЗаполнено(Значение) Тогда
|
||||
Возврат Строка(Значение);
|
||||
КонецЕсли;
|
||||
Возврат "<Незаполнено>";
|
||||
КонецФункции
|
||||
|
||||
Функция СообщитьОбОшибке(ТекстОшибки)
|
||||
|
||||
Лог.Ошибка(ТекстОшибки);
|
||||
Возврат МенеджерКомандПриложения.РезультатыКоманд().ОшибкаВремениВыполнения;
|
||||
|
||||
КонецФункции
|
||||
|
||||
@@ -1,13 +1,19 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Служебный модуль с реализацией работы команды report
|
||||
//
|
||||
// (C) Maximov Valery (aka theshadowco)
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Перем Лог;
|
||||
|
||||
Перем Токен;
|
||||
Перем АдресСервера;
|
||||
Перем РодительскийПроект;
|
||||
Перем Проекты;
|
||||
Перем Метрики;
|
||||
Перем ПутьКОтчету;
|
||||
Перем ФорматОтчета;
|
||||
|
||||
Перем ПрочитанныеПараметры;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Прикладной интерфейс
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -17,7 +23,7 @@
|
||||
ОписаниеКоманды = Парсер.ОписаниеКоманды(ИмяКоманды, "Формирует отчет по проекту/списку проектов");
|
||||
Парсер.ДобавитьИменованныйПараметрКоманды(ОписаниеКоманды, "--token", "Токен для авторизации на сервере SonarQube");
|
||||
Парсер.ДобавитьИменованныйПараметрКоманды(ОписаниеКоманды, "--server", "Адрес сервера SonarQube (например http://my.sonar.server:9000)");
|
||||
Парсер.ДобавитьИменованныйПараметрКоманды(ОписаниеКоманды, "--projects", "Ключ проектов, строкой через запятую (например hrm:develop,buh)");
|
||||
Парсер.ДобавитьИменованныйПараметрКоманды(ОписаниеКоманды, "--projects", "Ключи проектов, строкой через запятую (например hrm:develop,buh)");
|
||||
Парсер.ДобавитьИменованныйПараметрКоманды(ОписаниеКоманды, "--total-metrics", "Вывод в отчет метрик по проекту.
|
||||
| Нужные метрики передаются строкой через запятую.
|
||||
| Возможные значения (ключ - расшифровка):
|
||||
@@ -75,20 +81,18 @@
|
||||
Лог = ДополнительныеПараметры.Лог;
|
||||
ОшибокНет = ПрочитатьПараметрыЗапуска(ПараметрыКоманды);
|
||||
Если НЕ ОшибокНет Тогда
|
||||
Возврат СообщитьОбОшибке("Ошибка запуска");
|
||||
Возврат ОбщегоНазначения.СообщитьОбОшибке("Ошибка запуска");
|
||||
КонецЕсли;
|
||||
|
||||
Если ПустаяСтрока(ПутьКОтчету) Тогда
|
||||
ПутьКОтчету = ОбъединитьПути(".", "report." + НРег(ФорматОтчета));
|
||||
КонецЕсли;
|
||||
|
||||
АдресСервера = ПрочитанныеПараметры.Получить("АдресСервера");
|
||||
Токен = ПрочитанныеПараметры.Получить("Токен");
|
||||
|
||||
Лог.Информация("Получение информации о проектах");
|
||||
ПроектыSQ = Сонар.ПолучитьПроекты(АдресСервера, Токен);
|
||||
КоллекцияОтчетов = СоздатьКоллекциюОтчетов(АдресСервера);
|
||||
|
||||
КоллекцияОтчетов = СоздатьКоллекциюОтчетов();
|
||||
Лог.Информация("Формирование отчетов по проектам");
|
||||
|
||||
КоллекцияПроектов = СтрРазделить(Проекты, ",", Ложь);
|
||||
КоллекцияПроектов = СтрРазделить(ПрочитанныеПараметры.Получить("Проекты"), ",", Ложь);
|
||||
|
||||
Для Каждого Проект Из КоллекцияПроектов Цикл
|
||||
Лог.Информация(" Формирование отчета для проекта `%1`", Проект);
|
||||
@@ -115,112 +119,39 @@
|
||||
|
||||
Функция ПрочитатьПараметрыЗапуска(ПараметрыКоманды)
|
||||
|
||||
МаксимальноеКоличествоСтатусов = 5;
|
||||
ОшибокНет = Истина;
|
||||
|
||||
Токен = ПараметрыКоманды["--token"];
|
||||
АдресСервера = ПараметрыКоманды["--server"];
|
||||
Проекты = ПараметрыКоманды["--projects"];
|
||||
Метрики = ПараметрыКоманды["--total-metrics"];
|
||||
ПутьКОтчету = ПараметрыКоманды["--report-path"];
|
||||
ФорматОтчета = ПараметрыКоманды["--report-format"];
|
||||
ПрочитанныеПараметры = ОбщегоНазначения.ПрочитатьПараметрыЗапуска(ПараметрыКоманды, Истина);
|
||||
ОшибокНет = ПрочитанныеПараметры.Получить("ОшибокНет");
|
||||
|
||||
ПутьККонфигурационномуФайлу = ПараметрыКоманды["--cfg-file"];
|
||||
Если ПутьККонфигурационномуФайлу <> Неопределено Тогда
|
||||
|
||||
Файл = Новый Файл(ПутьККонфигурационномуФайлу);
|
||||
Если Файл.Существует() Тогда
|
||||
ТекстовыйДокумент = Новый ТекстовыйДокумент();
|
||||
ТекстовыйДокумент.Прочитать(ПутьККонфигурационномуФайлу);
|
||||
Лог.Отладка("Содержимое конфигурационного файла: %1%2", Символы.ПС, ТекстовыйДокумент.ПолучитьТекст());
|
||||
JSON = Новый ЧтениеJSON();
|
||||
JSON.УстановитьСтроку(ТекстовыйДокумент.ПолучитьТекст());
|
||||
ПараметрыИзФайла = ПрочитатьJSON(JSON, Истина);
|
||||
Если Токен = Неопределено Тогда
|
||||
Токен = ПараметрыИзФайла.Получить("--token");
|
||||
КонецЕсли;
|
||||
Если АдресСервера = Неопределено Тогда
|
||||
АдресСервера = ПараметрыИзФайла.Получить("--server");
|
||||
КонецЕсли;
|
||||
Если Проекты = Неопределено Тогда
|
||||
Проекты = ПараметрыИзФайла.Получить("--projects");
|
||||
КонецЕсли;
|
||||
Если Метрики = Неопределено Тогда
|
||||
Метрики = ПараметрыИзФайла.Получить("--total-metrics");
|
||||
КонецЕсли;
|
||||
Если ПутьКОтчету = Неопределено Тогда
|
||||
ПутьКОтчету = ПараметрыИзФайла.Получить("--report-path");
|
||||
КонецЕсли;
|
||||
Если ФорматОтчета = Неопределено Тогда
|
||||
ФорматОтчета = ПараметрыИзФайла.Получить("--report-format");
|
||||
КонецЕсли;
|
||||
Иначе
|
||||
Лог.Ошибка("Конфигурационный файл по пути `%1` не обнаружен", ОбернутьЗначениеДляПечати(ПутьККонфигурационномуФайлу));
|
||||
ОшибокНет = Ложь;
|
||||
КонецЕсли;
|
||||
|
||||
КонецЕсли;
|
||||
|
||||
Лог.Отладка("Прочитанные параметры:");
|
||||
Лог.Отладка(" Токен = `%1`", ОбернутьЗначениеДляПечати(Токен));
|
||||
Лог.Отладка(" Адрес сервера = `%1`", ОбернутьЗначениеДляПечати(АдресСервера));
|
||||
Лог.Отладка(" Ключи проектов = `%1`", ОбернутьЗначениеДляПечати(Проекты));
|
||||
Лог.Отладка(" Метрики проекта = `%1`", ОбернутьЗначениеДляПечати(Метрики));
|
||||
Лог.Отладка(" Путь к отчету = `%1`", ОбернутьЗначениеДляПечати(ПутьКОтчету));
|
||||
Лог.Отладка(" Формат отчета = `%1`", ОбернутьЗначениеДляПечати(ФорматОтчета));
|
||||
|
||||
Если Не ЗначениеЗаполнено(Токен) Тогда
|
||||
Лог.Ошибка("Не указан токен для авторизации");
|
||||
ОшибокНет = Ложь;
|
||||
КонецЕсли;
|
||||
|
||||
Если Не ЗначениеЗаполнено(АдресСервера) Тогда
|
||||
Лог.Ошибка("Не указан адрес сервера SonarQube");
|
||||
ОшибокНет = Ложь;
|
||||
КонецЕсли;
|
||||
|
||||
Если Не ЗначениеЗаполнено(Проекты) Тогда
|
||||
Если Не ЗначениеЗаполнено(ПрочитанныеПараметры.Получить("Проекты")) Тогда
|
||||
Лог.Ошибка("Не указан ключ(-и) проекта(-ов)");
|
||||
ОшибокНет = Ложь;
|
||||
КонецЕсли;
|
||||
|
||||
Метрики = ПолучитьПравильныеМетрики(Метрики, ОшибокНет);
|
||||
|
||||
Если Не ЗначениеЗаполнено(ПутьКОтчету) Тогда
|
||||
ПутьКОтчету = "";
|
||||
КонецЕсли;
|
||||
Метрики = ПолучитьПравильныеМетрики(ПрочитанныеПараметры.Получить("Метрики"), ОшибокНет);
|
||||
ПутьКОтчету = ПрочитанныеПараметры.Получить("ПутьКОтчету");
|
||||
ФорматОтчета = ПрочитанныеПараметры.Получить("ФорматОтчета");
|
||||
|
||||
Если Не ЗначениеЗаполнено(ФорматОтчета) Тогда
|
||||
ФорматОтчета = "JSON";
|
||||
Иначе
|
||||
ФорматОтчета = ПолучитьПравильныйФорматОтчета(ФорматОтчета, ОшибокНет);
|
||||
КонецЕсли;
|
||||
|
||||
Если Не ЗначениеЗаполнено(ПутьКОтчету) Тогда
|
||||
ПутьКОтчету = ОбъединитьПути(".", "report." + НРег(ФорматОтчета));
|
||||
КонецЕсли;
|
||||
|
||||
Возврат ОшибокНет;
|
||||
|
||||
КонецФункции
|
||||
|
||||
Функция ОбернутьЗначениеДляПечати(Знач Значение)
|
||||
Если ЗначениеЗаполнено(Значение) Тогда
|
||||
Возврат Строка(Значение);
|
||||
КонецЕсли;
|
||||
Возврат "<Незаполнено>";
|
||||
КонецФункции
|
||||
|
||||
Функция СообщитьОбОшибке(ТекстОшибки)
|
||||
|
||||
Лог.Ошибка(ТекстОшибки);
|
||||
Возврат МенеджерКомандПриложения.РезультатыКоманд().ОшибкаВремениВыполнения;
|
||||
|
||||
КонецФункции
|
||||
|
||||
Функция ПолучитьПравильныйФорматОтчета(Знач ВыбранныйФорматОтчета, ОшибокНет)
|
||||
|
||||
ВРЕГВыбранныйФорматОтчета = ВРЕГ(ВыбранныйФорматОтчета);
|
||||
Если НЕ (ВРЕГВыбранныйФорматОтчета = "HTML" ИЛИ ВРЕГВыбранныйФорматОтчета = "JSON") Тогда
|
||||
|
||||
ОшибокНет = Ложь;
|
||||
Лог.Ошибка("Указан неизвестный формат отчета `%1`", ОбернутьЗначениеДляПечати(ВыбранныйФорматОтчета));
|
||||
Лог.Ошибка("Указан неизвестный формат отчета `%1`", ОбщегоНазначения.ОбернутьЗначениеДляПечати(ВыбранныйФорматОтчета));
|
||||
|
||||
КонецЕсли;
|
||||
|
||||
@@ -243,7 +174,7 @@
|
||||
ПравильныеМетрики.Вставить(СокрЛП(Метрика), 0);
|
||||
Иначе
|
||||
ОшибокНет = Ложь;
|
||||
Лог.Ошибка("Указана неизвестная метрика `%1`", ОбернутьЗначениеДляПечати(Метрика));
|
||||
Лог.Ошибка("Указана неизвестная метрика `%1`", ОбщегоНазначения.ОбернутьЗначениеДляПечати(Метрика));
|
||||
КонецЕсли;
|
||||
КонецЦикла;
|
||||
КонецЕсли;
|
||||
@@ -252,7 +183,7 @@
|
||||
|
||||
КонецФункции
|
||||
|
||||
Функция СоздатьКоллекциюОтчетов()
|
||||
Функция СоздатьКоллекциюОтчетов(АдресСервера)
|
||||
|
||||
Результат = Новый Структура();
|
||||
Результат.Вставить("ДатаФормирования", ТекущаяДата());
|
||||
|
||||
@@ -0,0 +1,252 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Служебный модуль с реализацией работы команды report
|
||||
//
|
||||
// (C) Maximov Valery (aka theshadowco)
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Перем Лог;
|
||||
|
||||
Перем ПутьКОтчету;
|
||||
Перем ФорматОтчета;
|
||||
Перем СтатусыСтрокой;
|
||||
|
||||
Перем ПрочитанныеПараметры;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Прикладной интерфейс
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Процедура ЗарегистрироватьКоманду(Знач ИмяКоманды, Знач Парсер) Экспорт
|
||||
|
||||
ОписаниеКоманды = Парсер.ОписаниеКоманды(ИмяКоманды, "Формирует сводный отчет по наличию замечаний пользователей");
|
||||
Парсер.ДобавитьИменованныйПараметрКоманды(ОписаниеКоманды, "--token", "Токен для авторизации на сервере SonarQube");
|
||||
Парсер.ДобавитьИменованныйПараметрКоманды(ОписаниеКоманды, "--server", "Адрес сервера SonarQube (например http://my.sonar.server:9000)");
|
||||
Парсер.ДобавитьИменованныйПараметрКоманды(ОписаниеКоманды, "--projects", "Ключи проектов, строкой через запятую (например hrm:develop,buh)");
|
||||
Парсер.ДобавитьИменованныйПараметрКоманды(ОписаниеКоманды, "--statuses", "Отбор замечаний только соответствующих статусов.
|
||||
| Необходимые статусы необходимо передавать строкой через запятую.
|
||||
| Возможные значения:
|
||||
| OPEN - открытые
|
||||
| CONFIRMED - подтвержденные:
|
||||
| REOPENED - переоткрытые
|
||||
| RESOLVED - решенные
|
||||
| CLOSED - закрытые
|
||||
|
|
||||
| По умолчанию выбираются только OPEN, CONFIRMED и REOPENED");
|
||||
Парсер.ДобавитьИменованныйПараметрКоманды(ОписаниеКоманды, "--report-path", "Путь для сохранения отчета");
|
||||
Парсер.ДобавитьИменованныйПараметрКоманды(ОписаниеКоманды, "--report-format", "Формат сохраняемого отчета.
|
||||
| Возможные варианнты:
|
||||
| HTML - создает html - страницу
|
||||
| JSON - выгружает файл json
|
||||
|
|
||||
| По умолчанию используется формат JSON");
|
||||
Парсер.ДобавитьИменованныйПараметрКоманды(ОписаниеКоманды, "--cfg-file", "Путь к конфигурационному файлу в формате json (utf-8), свойства объекта соответствуют ключам запуска.
|
||||
| Пример конфигурационного файла находится в каталоге examples");
|
||||
|
||||
Парсер.ДобавитьКоманду(ОписаниеКоманды);
|
||||
|
||||
КонецПроцедуры
|
||||
|
||||
// Выполняет логику команды
|
||||
//
|
||||
// Параметры:
|
||||
// ПараметрыКоманды - Соответствие - Соответствие ключей командной строки и их значений
|
||||
// ДополнительныеПараметры - Соответствие - (необязательно) дополнительные параметры
|
||||
//
|
||||
Функция ВыполнитьКоманду(Знач ПараметрыКоманды, Знач ДополнительныеПараметры = Неопределено) Экспорт
|
||||
|
||||
Лог = ДополнительныеПараметры.Лог;
|
||||
ОшибокНет = ПрочитатьПараметрыЗапуска(ПараметрыКоманды);
|
||||
Если НЕ ОшибокНет Тогда
|
||||
Возврат ОбщегоНазначения.СообщитьОбОшибке("Ошибка запуска");
|
||||
КонецЕсли;
|
||||
|
||||
АдресСервера = ПрочитанныеПараметры.Получить("АдресСервера");
|
||||
Токен = ПрочитанныеПараметры.Получить("Токен");
|
||||
|
||||
Лог.Информация("Получение информации о проектах");
|
||||
ПроектыSQ = Сонар.ПолучитьПроекты(АдресСервера, Токен);
|
||||
КоллекцияОтчетов = СоздатьКоллекциюОтчетов(АдресСервера);
|
||||
|
||||
Лог.Информация("Формирование отчетов по проектам");
|
||||
|
||||
Проекты = ПрочитанныеПараметры.Получить("Проекты");
|
||||
Если Не ЗначениеЗаполнено(Проекты) Тогда
|
||||
Проекты = "";
|
||||
КонецЕсли;
|
||||
|
||||
КоллекцияПроектов = СтрРазделить(Проекты, ",", Ложь);
|
||||
Замечания = Неопределено;
|
||||
Для Каждого ОписаниеПроекта Из ПроектыSQ Цикл
|
||||
|
||||
Если КоллекцияПроектов.Количество() И КоллекцияПроектов.Найти(ОписаниеПроекта.Значение.Код) = Неопределено Тогда
|
||||
Продолжить;
|
||||
КонецЕсли;
|
||||
|
||||
Лог.Информация(" Формирование отчета для проекта `%1`", ОписаниеПроекта.Значение.Код);
|
||||
Замечания = Сонар.ПолучитьСводнуюИнформациюПоЗамечаниямиПроекта(АдресСервера, Токен, ОписаниеПроекта.Значение, СтатусыСтрокой, Замечания);
|
||||
|
||||
КонецЦикла;
|
||||
|
||||
КоллекцияОтчетов.Замечания = Замечания;
|
||||
КоллекцияОтчетов.Количество = КоллекцияОтчетов.Замечания.Количество();
|
||||
|
||||
Лог.Информация("Сохранение отчетов в файл '%1'", ПутьКОтчету);
|
||||
СформироватьОтчет(КоллекцияОтчетов);
|
||||
|
||||
Возврат МенеджерКомандПриложения.РезультатыКоманд().Успех;
|
||||
|
||||
КонецФункции
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Функция ПрочитатьПараметрыЗапуска(ПараметрыКоманды)
|
||||
|
||||
ПрочитанныеПараметры = ОбщегоНазначения.ПрочитатьПараметрыЗапуска(ПараметрыКоманды, Истина);
|
||||
ОшибокНет = ПрочитанныеПараметры.Получить("ОшибокНет");
|
||||
МаксимальноеКоличествоСтатусов = 5;
|
||||
|
||||
Если Не ЗначениеЗаполнено(ПрочитанныеПараметры.Получить("СтатусыСтрокой")) Тогда
|
||||
СтатусыСтрокой = "OPEN,CONFIRMED,REOPENED";
|
||||
Иначе
|
||||
Статусы = Новый Массив();
|
||||
СтатусыВрем = СтрРазделить(ВРЕГ(ПрочитанныеПараметры.Получить("СтатусыСтрокой")), ",", Ложь);
|
||||
ВсеСтатусы = СтрРазделить("OPEN,CONFIRMED,REOPENED,RESOLVED,CLOSED", ",");
|
||||
Для Каждого Статус Из СтатусыВрем Цикл
|
||||
Если ВсеСтатусы.Найти(Статус) <> Неопределено Тогда
|
||||
Статусы.Добавить(Статус);
|
||||
Иначе
|
||||
Лог.Ошибка("Неопознанный статус `%1`", Статус);
|
||||
КонецЕсли;
|
||||
КонецЦикла;
|
||||
Если Статусы.Количество() = 0 Тогда
|
||||
Лог.Ошибка("Указанный фильтр по статусам не содержит корректных значений");
|
||||
ОшибокНет = Ложь;
|
||||
КонецЕсли;
|
||||
СтатусыСтрокой = СтрСоединить(Статусы, ",");
|
||||
КонецЕсли;
|
||||
|
||||
ПутьКОтчету = ПрочитанныеПараметры.Получить("ПутьКОтчету");
|
||||
ФорматОтчета = ПрочитанныеПараметры.Получить("ФорматОтчета");
|
||||
|
||||
Если Не ЗначениеЗаполнено(ФорматОтчета) Тогда
|
||||
ФорматОтчета = "JSON";
|
||||
Иначе
|
||||
ФорматОтчета = ПолучитьПравильныйФорматОтчета(ФорматОтчета, ОшибокНет);
|
||||
КонецЕсли;
|
||||
|
||||
Если Не ЗначениеЗаполнено(ПутьКОтчету) Тогда
|
||||
ПутьКОтчету = ОбъединитьПути(".", "report." + НРег(ФорматОтчета));
|
||||
КонецЕсли;
|
||||
|
||||
Возврат ОшибокНет;
|
||||
|
||||
КонецФункции
|
||||
|
||||
Функция ПолучитьПравильныйФорматОтчета(Знач ВыбранныйФорматОтчета, ОшибокНет)
|
||||
|
||||
ВРЕГВыбранныйФорматОтчета = ВРЕГ(ВыбранныйФорматОтчета);
|
||||
Если ВРЕГВыбранныйФорматОтчета <> "JSON" Тогда
|
||||
|
||||
ОшибокНет = Ложь;
|
||||
Лог.Ошибка("Указан неизвестный формат отчета `%1`", ОбщегоНазначения.ОбернутьЗначениеДляПечати(ВыбранныйФорматОтчета));
|
||||
|
||||
КонецЕсли;
|
||||
|
||||
Возврат ВРЕГВыбранныйФорматОтчета;
|
||||
|
||||
КонецФункции
|
||||
|
||||
Функция СоздатьКоллекциюОтчетов(АдресСервера)
|
||||
|
||||
Результат = Новый Структура();
|
||||
Результат.Вставить("ДатаФормирования", ТекущаяДата());
|
||||
Результат.Вставить("СерверSonarQube", АдресСервера);
|
||||
Результат.Вставить("Количество", 0);
|
||||
Результат.Вставить("Замечания", Неопределено);
|
||||
|
||||
Возврат Результат;
|
||||
|
||||
КонецФункции
|
||||
|
||||
Процедура СформироватьОтчет(КоллекцияОтчетов)
|
||||
|
||||
Если ФорматОтчета = "JSON" Тогда
|
||||
ЗаписьJSON = Новый ЗаписьJSON();
|
||||
ЗаписьJSON.ОткрытьФайл(ПутьКОтчету);
|
||||
КоллекцияОтчетов.Замечания = ТаблицаЗначенийВМассив(КоллекцияОтчетов.Замечания);
|
||||
ЗаписатьJSON(ЗаписьJSON, КоллекцияОтчетов);
|
||||
ЗаписьJSON.Закрыть();
|
||||
КонецЕсли;
|
||||
|
||||
КонецПроцедуры
|
||||
|
||||
Функция ТаблицаЗначенийВМассив(ТаблицаЗначений, РезультатВФиксированнуюКоллекцию = Ложь)
|
||||
|
||||
МассивРезультат = Новый Массив();
|
||||
СтруктураСтрокой = "";
|
||||
НоваяСтрока = Неопределено;
|
||||
|
||||
КолонкиСТипомТЧ = Новый Массив;
|
||||
|
||||
Если ТипЗнч(ТаблицаЗначений) = Тип("ТаблицаЗначений") Тогда
|
||||
|
||||
КолонкиТаблицы = ТаблицаЗначений.Колонки;
|
||||
|
||||
ИначеЕсли ТипЗнч(ТаблицаЗначений) = Тип("Массив") И ТипЗнч(ТаблицаЗначений[0]) = Тип("СтрокаТаблицыЗначений") Тогда
|
||||
|
||||
КолонкиТаблицы = ТаблицаЗначений[0].Владелец().Колонки;
|
||||
|
||||
Иначе
|
||||
|
||||
ВызватьИсключение "Не поддерживаемый тип параметра";
|
||||
|
||||
КонецЕсли;
|
||||
|
||||
Если ТаблицаЗначений.Количество() = 0 Тогда
|
||||
|
||||
Возврат МассивРезультат;
|
||||
|
||||
КонецЕсли;
|
||||
|
||||
Для Каждого Колонка Из КолонкиТаблицы Цикл
|
||||
|
||||
СтруктураСтрокой = СтруктураСтрокой + ?(ПустаяСтрока(СтруктураСтрокой), "", ",") + Колонка.Имя ;
|
||||
|
||||
КонецЦикла;
|
||||
|
||||
Для Каждого Строка Из ТаблицаЗначений Цикл
|
||||
|
||||
НоваяСтрока = Новый Структура(СтруктураСтрокой);
|
||||
ЗаполнитьЗначенияСвойств(НоваяСтрока, Строка);
|
||||
|
||||
Для Каждого КолонкаСТипомТЧ Из КолонкиСТипомТЧ Цикл
|
||||
|
||||
Если ТипЗнч(Строка[КолонкаСТипомТЧ]) = Тип("ТаблицаЗначений") Тогда
|
||||
|
||||
НоваяСтрока[КолонкаСТипомТЧ] = ТаблицаЗначенийВМассив(Строка[КолонкаСТипомТЧ], РезультатВФиксированнуюКоллекцию);
|
||||
|
||||
КонецЕсли;
|
||||
|
||||
КонецЦикла;
|
||||
|
||||
Если РезультатВФиксированнуюКоллекцию Тогда
|
||||
|
||||
НоваяСтрока = Новый ФиксированнаяСтруктура(НоваяСтрока);
|
||||
|
||||
КонецЕсли;
|
||||
|
||||
МассивРезультат.Добавить(НоваяСтрока);
|
||||
|
||||
КонецЦикла;
|
||||
|
||||
Если РезультатВФиксированнуюКоллекцию Тогда
|
||||
|
||||
МассивРезультат = Новый ФиксированныйМассив(МассивРезультат);
|
||||
|
||||
КонецЕсли;
|
||||
|
||||
Возврат МассивРезультат;
|
||||
|
||||
КонецФункции // ТаблицаЗначенийВМассив
|
||||
@@ -0,0 +1,148 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Служебный модуль с общими методами приложения
|
||||
//
|
||||
// (C) Maximov Valery (aka theshadowco)
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// ОбернутьЗначениеДляПечати
|
||||
// Формирует строку из значения для удобной печати
|
||||
// Параметры:
|
||||
// Значение - Произвольное - Значение, которое необходимо преобразовать в строку для последующей печати
|
||||
//
|
||||
// Возвращаемое значение:
|
||||
// Строка - Преобразованное в строку входное значение. Если значение не заполнено, то вернется "<Незаполнено>"
|
||||
//
|
||||
Функция ОбернутьЗначениеДляПечати(Знач Значение) Экспорт
|
||||
|
||||
Если ЗначениеЗаполнено(Значение) Тогда
|
||||
Возврат Строка(Значение);
|
||||
КонецЕсли;
|
||||
|
||||
Возврат "<Незаполнено>";
|
||||
|
||||
КонецФункции
|
||||
|
||||
// ПрочитатьПараметрыЗапуска
|
||||
// Читает входные параметры включа конфигурационный файл
|
||||
// Параметры:
|
||||
// ПараметрыКоманды - Соответствие - Входные параметры приложения
|
||||
// ВыполнятьПроверкуАвторизацииСразу - Булево - Выполнение проверки корректности параметров авторизации
|
||||
//
|
||||
// Возвращаемое значение:
|
||||
// Соответствие - Ключи и значения параметров запуска
|
||||
//
|
||||
Функция ПрочитатьПараметрыЗапуска(ПараметрыКоманды, ВыполнятьПроверкуАвторизацииСразу) Экспорт
|
||||
|
||||
Лог = Логирование.ПолучитьЛог(ПараметрыСистемы.ИмяЛогаСистемы());
|
||||
|
||||
ПрочитанныеПараметры = Новый Соответствие();
|
||||
ОшибокНет = Истина;
|
||||
|
||||
ВозможныеКлючи = ВозможныеКлючи();
|
||||
Для Каждого ВозможныйКлюч Из ВозможныеКлючи Цикл
|
||||
|
||||
ПрочитанныеПараметры.Вставить(ВозможныйКлюч.Ключ, ПараметрыКоманды.Получить(ВозможныйКлюч.Значение));
|
||||
|
||||
КонецЦикла;
|
||||
|
||||
ПутьККонфигурационномуФайлу = ПараметрыКоманды["--cfg-file"];
|
||||
|
||||
Если ПутьККонфигурационномуФайлу <> Неопределено Тогда
|
||||
|
||||
Файл = Новый Файл(ПутьККонфигурационномуФайлу);
|
||||
Если Файл.Существует() Тогда
|
||||
|
||||
ТекстовыйДокумент = Новый ТекстовыйДокумент();
|
||||
ТекстовыйДокумент.Прочитать(ПутьККонфигурационномуФайлу);
|
||||
Лог.Отладка("Содержимое конфигурационного файла: %1%2", Символы.ПС, ТекстовыйДокумент.ПолучитьТекст());
|
||||
JSON = Новый ЧтениеJSON();
|
||||
JSON.УстановитьСтроку(ТекстовыйДокумент.ПолучитьТекст());
|
||||
ПараметрыИзФайла = ПрочитатьJSON(JSON, Истина);
|
||||
|
||||
Для Каждого ВозможныйКлюч Из ВозможныеКлючи Цикл
|
||||
|
||||
ЗначениеИзФайла = ПараметрыИзФайла.Получить(ВозможныйКлюч.Значение);
|
||||
Если ЗначениеИзФайла <> Неопределено И ПрочитанныеПараметры.Получить(ВозможныйКлюч.Ключ) = Неопределено Тогда
|
||||
ПрочитанныеПараметры.Вставить(ВозможныйКлюч.Ключ, ЗначениеИзФайла);
|
||||
КонецЕсли;
|
||||
|
||||
КонецЦикла;
|
||||
|
||||
Иначе
|
||||
|
||||
Лог.Ошибка("Конфигурационный файл по пути `%1` не обнаружен", ОбернутьЗначениеДляПечати(ПутьККонфигурационномуФайлу));
|
||||
ОшибокНет = ЛОЖЬ;
|
||||
|
||||
КонецЕсли;
|
||||
|
||||
КонецЕсли;
|
||||
|
||||
Лог.Отладка("Прочитанные параметры:");
|
||||
Для Каждого ПрочитанныйПараметр Из ПрочитанныеПараметры Цикл
|
||||
|
||||
Лог.Отладка(" %2 = `%1`", ОбернутьЗначениеДляПечати(ПрочитанныйПараметр.Значение), ПрочитанныйПараметр.Ключ);
|
||||
|
||||
КонецЦикла;
|
||||
|
||||
Если ВыполнятьПроверкуАвторизацииСразу Тогда
|
||||
|
||||
Если Не ЗначениеЗаполнено(ПрочитанныеПараметры.Получить("Токен")) Тогда
|
||||
|
||||
Лог.Ошибка("Не указан токен для авторизации");
|
||||
ОшибокНет = Ложь;
|
||||
|
||||
КонецЕсли;
|
||||
|
||||
Если Не ЗначениеЗаполнено(ПрочитанныеПараметры.Получить("АдресСервера")) Тогда
|
||||
|
||||
Лог.Ошибка("Не указан адрес сервера SonarQube");
|
||||
ОшибокНет = Ложь;
|
||||
|
||||
КонецЕсли;
|
||||
|
||||
КонецЕсли;
|
||||
|
||||
ПрочитанныеПараметры.Вставить("ОшибокНет", ОшибокНет);
|
||||
|
||||
Возврат ПрочитанныеПараметры;
|
||||
|
||||
КонецФункции
|
||||
|
||||
// СообщитьОбОшибке
|
||||
// Выводит сообщение об ошибке и возвращает статус ошибочного завершения приложения
|
||||
// Параметры:
|
||||
// ТекстОшибки - Строка - Выводимое сообщение об ошибке
|
||||
//
|
||||
// Возвращаемое значение:
|
||||
// Число - Код ошибки выполнения
|
||||
//
|
||||
Функция СообщитьОбОшибке(ТекстОшибки) Экспорт
|
||||
|
||||
Лог = Логирование.ПолучитьЛог(ПараметрыСистемы.ИмяЛогаСистемы());
|
||||
Лог.Ошибка(ТекстОшибки);
|
||||
Возврат МенеджерКомандПриложения.РезультатыКоманд().ОшибкаВремениВыполнения;
|
||||
|
||||
КонецФункции
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Функция ВозможныеКлючи()
|
||||
|
||||
ВозможныеКлючи = Новый Структура();
|
||||
ВозможныеКлючи.Вставить("Токен", "--token");
|
||||
ВозможныеКлючи.Вставить("АдресСервера", "--server");
|
||||
ВозможныеКлючи.Вставить("РодительскийПроект", "--parent-project");
|
||||
ВозможныеКлючи.Вставить("ИсключаемыеПроектыСтрокой", "--exclude-projects");
|
||||
ВозможныеКлючи.Вставить("СтатусыСтрокой", "--statuses");
|
||||
ВозможныеКлючи.Вставить("Теги", "--tags");
|
||||
ВозможныеКлючи.Вставить("ИзEDTВКонфигуратор", "--edt2cfg");
|
||||
ВозможныеКлючи.Вставить("Проекты", "--projects");
|
||||
ВозможныеКлючи.Вставить("Метрики", "--total-metrics");
|
||||
ВозможныеКлючи.Вставить("ПутьКОтчету", "--report-path");
|
||||
ВозможныеКлючи.Вставить("ФорматОтчета", "--report-format");
|
||||
|
||||
Возврат ВозможныеКлючи;
|
||||
|
||||
КонецФункции
|
||||
@@ -50,6 +50,7 @@
|
||||
ВозможныеКомандыПриложения.Вставить("ПоказатьВерсию", "version");
|
||||
ВозможныеКомандыПриложения.Вставить("ЗакрытьИшузы", "issue-resolver");
|
||||
ВозможныеКомандыПриложения.Вставить("СгенерироватьОтчет", "report");
|
||||
ВозможныеКомандыПриложения.Вставить("СгенерироватьОтчетПоПользователям", "usr-report");
|
||||
|
||||
ВозможныеКомандыПриложения = Новый ФиксированнаяСтруктура(ВозможныеКомандыПриложения);
|
||||
|
||||
@@ -61,12 +62,11 @@
|
||||
|
||||
Процедура ПриРегистрацииКомандПриложения(Знач КлассыРеализацииКоманд) Экспорт
|
||||
|
||||
КлассыРеализацииКоманд[ВозможныеКоманды().Помощь] = "КомандаСправкаПоПараметрам";
|
||||
КлассыРеализацииКоманд[ИмяКомандыВерсия()] = "КомандаVersion";
|
||||
КлассыРеализацииКоманд[ВозможныеКоманды().ЗакрытьИшузы] = "КомандаЗакрытьИшузы";
|
||||
КлассыРеализацииКоманд[ВозможныеКоманды().СгенерироватьОтчет] = "КомандаСгенерироватьОтчет";
|
||||
//...
|
||||
//КлассыРеализацииКоманд["<имя команды>"] = "<КлассРеализации>";
|
||||
КлассыРеализацииКоманд[ВозможныеКоманды().Помощь] = "КомандаСправкаПоПараметрам";
|
||||
КлассыРеализацииКоманд[ИмяКомандыВерсия()] = "КомандаVersion";
|
||||
КлассыРеализацииКоманд[ВозможныеКоманды().ЗакрытьИшузы] = "КомандаЗакрытьИшузы";
|
||||
КлассыРеализацииКоманд[ВозможныеКоманды().СгенерироватьОтчет] = "КомандаСгенерироватьОтчет";
|
||||
КлассыРеализацииКоманд[ВозможныеКоманды().СгенерироватьОтчетПоПользователям] = "КомандаСгенерироватьОтчетПоПользователям";
|
||||
|
||||
КонецПроцедуры // ПриРегистрацииКомандПриложения
|
||||
|
||||
|
||||
+122
-1
@@ -176,6 +176,127 @@
|
||||
|
||||
КонецФункции
|
||||
|
||||
// ПолучитьСводнуюИнформациюПоЗамечаниямиПроекта
|
||||
// Возвращает свернутую таблицу с пользователями и их замечаниями на проекте проекта
|
||||
// Параметры:
|
||||
// АдресСервера - Строка - Адрес (хост) сервера SonarQube
|
||||
// Токен - Строка - Токен пользователя, от имени которого выполняются запросы к API
|
||||
// ОписаниеПроекта - Структура - Описание проекта SonarQube
|
||||
// * Идентификатор - Строка - Идентификатор проекта
|
||||
// * Код - Строка - Код (Ключ) проекта
|
||||
// СтатусыСтрокой - Строка - Строка с идентификаторами статусов замечаний
|
||||
// Замечания - ТаблицаЗначений - Таблица со сводной информацией замечаний, аналогичная выходной. Используется при необходимости дополнять для нескольких проектов
|
||||
//
|
||||
// Возвращаемое значение:
|
||||
// ТаблицаЗначения - Содвная таблица с замечаниями
|
||||
// * КлючПроекта - Строка - Ключ проекта sonarqube
|
||||
// * Статус - Строка - Статус замечания
|
||||
// * Автор - Строка - Пользователь, автор замечания по git (email)
|
||||
// * Отвественный - Строка, NULL - Пользователь, на которого назначено замечание (учетная запись)
|
||||
// * Правило - Строка - Ключ правила
|
||||
// * Критичность - Строка - Критичность замечания
|
||||
// * Тип - Строка - Тип замечания
|
||||
// * Время - Число - Время на исправление замечания (в минутах)
|
||||
// * Количество - Число - Количество замечаний
|
||||
//
|
||||
Функция ПолучитьСводнуюИнформациюПоЗамечаниямиПроекта(АдресСервера, Токен, ОписаниеПроекта, СтатусыСтрокой, Замечания = Неопределено) Экспорт
|
||||
|
||||
КлючиКомпонентов = ПолучитьКлючиКомпонентов(АдресСервера, Токен, ОписаниеПроекта.Код, СтатусыСтрокой);
|
||||
URLШаблон = "issues/search?ps=500&componentKeys=%1%2";
|
||||
Если Не ПустаяСтрока(СтатусыСтрокой) Тогда
|
||||
URLШаблон = URLШаблон + "&statuses=" + СтатусыСтрокой;
|
||||
КонецЕсли;
|
||||
URLШаблон = URLШаблон + "&p=";
|
||||
|
||||
КоличествоКомпонентов = КлючиКомпонентов.Количество();
|
||||
|
||||
Если Замечания = Неопределено Тогда
|
||||
Замечания = Новый ТаблицаЗначений();
|
||||
Замечания.Колонки.Добавить("КлючПроекта");
|
||||
Замечания.Колонки.Добавить("Статус");
|
||||
Замечания.Колонки.Добавить("Автор");
|
||||
Замечания.Колонки.Добавить("Отвественный");
|
||||
Замечания.Колонки.Добавить("Правило");
|
||||
Замечания.Колонки.Добавить("Критичность");
|
||||
Замечания.Колонки.Добавить("Тип");
|
||||
Замечания.Колонки.Добавить("Время");
|
||||
Замечания.Колонки.Добавить("Количество");
|
||||
КонецЕсли;
|
||||
|
||||
Для Ит = 0 По КоличествоКомпонентов - 1 Цикл
|
||||
КлючКомпонента = КлючиКомпонентов[Ит];
|
||||
|
||||
НомерСтраницы = 1;
|
||||
URL = СтрШаблон(URLШаблон, КлючКомпонента, "");
|
||||
Пока Истина Цикл
|
||||
|
||||
Ответ = ВыполнитьЗапрос(АдресСервера, Токен, URL + Формат(НомерСтраницы, "ЧГ="), "GET");
|
||||
Если Ответ.total > МаксимальныйРазмерПорцииДанных Тогда
|
||||
// прочитаем компоненты, перенесем их в общий список, а по текущем прочтем только те, что висят именно на нем
|
||||
КлючиДочернихКомпонентов = ПолучитьКлючиКомпонентов(АдресСервера, Токен, КлючКомпонента, СтатусыСтрокой, Ложь);
|
||||
Для Каждого КлючДочернегоКомпонента Из КлючиДочернихКомпонентов Цикл
|
||||
КлючиКомпонентов.Добавить(КлючДочернегоКомпонента);
|
||||
КонецЦикла;
|
||||
КоличествоКомпонентов = КлючиКомпонентов.Количество();
|
||||
URL = СтрШаблон(URLШаблон, КлючКомпонента, "&onComponentOnly=true");
|
||||
Ответ = ВыполнитьЗапрос(АдресСервера, Токен, URL + Формат(НомерСтраницы, "ЧГ="), "GET");
|
||||
КонецЕсли;
|
||||
|
||||
Для Каждого ОписаниеОшибки Из Ответ.issues Цикл
|
||||
|
||||
Замечание = Замечания.Добавить();
|
||||
Замечание.КлючПроекта = ОписаниеПроекта.Код;
|
||||
Замечание.Автор = ОписаниеОшибки.author;
|
||||
Если Не ОписаниеОшибки.Свойство("assignee") Тогда
|
||||
Замечание.Отвественный = NULL;
|
||||
Иначе
|
||||
Замечание.Отвественный = ОписаниеОшибки.assignee;
|
||||
КонецЕсли;
|
||||
|
||||
Замечание.Правило = ОписаниеОшибки.rule;
|
||||
Замечание.Статус = ОписаниеОшибки.status;
|
||||
Замечание.Критичность = ОписаниеОшибки.severity;
|
||||
Замечание.Тип = ОписаниеОшибки.type;
|
||||
Замечание.Количество = 1;
|
||||
Замечание.Время = 0;
|
||||
|
||||
Если ОписаниеОшибки.Свойство("debt") Тогда
|
||||
ВремяСтрокой = СтрЗаменить(ОписаниеОшибки.debt, "min", "");
|
||||
Поз = СтрНайти(ВремяСтрокой, "h");
|
||||
Если Поз <> СтрДлина(ВремяСтрокой) Тогда
|
||||
ВремяСтрокой = СтрЗаменить(ВремяСтрокой, "h", "*60+");
|
||||
Иначе
|
||||
ВремяСтрокой = СтрЗаменить(ВремяСтрокой, "h", "*60");
|
||||
КонецЕсли;
|
||||
|
||||
Поз = СтрНайти(ВремяСтрокой, "d");
|
||||
Если Поз <> СтрДлина(ВремяСтрокой) Тогда
|
||||
ВремяСтрокой = СтрЗаменить(ВремяСтрокой, "d", "*480+"); // рабочие дни
|
||||
Иначе
|
||||
ВремяСтрокой = СтрЗаменить(ВремяСтрокой, "d", "*480");
|
||||
КонецЕсли;
|
||||
|
||||
Замечание.Время = Вычислить(ВремяСтрокой);
|
||||
|
||||
КонецЕсли;
|
||||
КонецЦикла;
|
||||
|
||||
Если БольшеНетДанных(Ответ) Тогда
|
||||
Прервать;
|
||||
КонецЕсли;
|
||||
|
||||
НомерСтраницы = НомерСтраницы + 1;
|
||||
|
||||
КонецЦикла;
|
||||
|
||||
КонецЦикла;
|
||||
|
||||
Замечания.Свернуть("КлючПроекта, Автор, Отвественный, Правило, Критичность, Тип, Статус", "Время, Количество");
|
||||
|
||||
Возврат Замечания;
|
||||
|
||||
КонецФункции
|
||||
|
||||
// ЗаполнитьКоличествоОдинаковыхЗамечанийПроекта
|
||||
// По сформированному набору замечаний дополняет общее количество замечаний со всеми статусами с тем же хэшем
|
||||
// Параметры:
|
||||
@@ -474,7 +595,6 @@
|
||||
|
||||
HTTPЗапрос = Новый HTTPЗапрос;
|
||||
HTTPЗапрос.АдресРесурса = Префикс + "api/" + URL;
|
||||
Сообщить(HTTPЗапрос.АдресРесурса);
|
||||
HTTPЗапрос.Заголовки.Вставить("Content-Type", "application/json");
|
||||
|
||||
HTTP = Новый HTTPСоединение(АдресСервера, , Токен);
|
||||
@@ -485,6 +605,7 @@
|
||||
КонецЕсли;
|
||||
|
||||
Если ОтветHTTP.КодСостояния = 200 Тогда
|
||||
// Сообщить(ОтветHTTP.ПолучитьТелоКакСтроку());
|
||||
json = Новый ЧтениеJSON();
|
||||
json.УстановитьСтроку(ОтветHTTP.ПолучитьТелоКакСтроку());
|
||||
Возврат ПрочитатьJson(json);
|
||||
|
||||
Reference in New Issue
Block a user