1
0
mirror of https://github.com/bia-technologies/precommit4onec.git synced 2025-02-05 13:14:55 +02:00

#ONECICD-186

Реализация команды проверить репозиторий по сценариям
This commit is contained in:
Dmitriy Medvedev 2020-02-21 19:11:26 +03:00
parent 78b2eb5290
commit 5fd6411d6c
6 changed files with 258 additions and 52 deletions

View File

@ -24,11 +24,12 @@
"""
precommit4onec v1.20.1
Возможные команды:
help - Выводит справку по командам
version - Выводит версию приложения
precommit - Выполняет сценарии precommit
install - Выполняет подключение (установку) precommit hook'а в репозиторий
configure - Выполняет настройку репозитория
help - Выводит справку по командам
version - Выводит версию приложения
precommit - Выполняет сценарии precommit
install - Выполняет подключение (установку) precommit hook'а в репозиторий
configure - Выполняет настройку репозитория
exec-rules - Выполняет указанные сценарии в каталоге репозитория принудительно, без обращения к git
"""
И Код возврата команды "oscript" равен 0
@ -38,10 +39,11 @@
"""
precommit4onec v1.20.1
Возможные команды:
help - Выводит справку по командам
version - Выводит версию приложения
precommit - Выполняет сценарии precommit
install - Выполняет подключение (установку) precommit hook'а в репозиторий
configure - Выполняет настройку репозитория
help - Выводит справку по командам
version - Выводит версию приложения
precommit - Выполняет сценарии precommit
install - Выполняет подключение (установку) precommit hook'а в репозиторий
configure - Выполняет настройку репозитория
exec-rules - Выполняет указанные сценарии в каталоге репозитория принудительно, без обращения к git
"""
И Код возврата команды "oscript" равен 5

View File

@ -0,0 +1,169 @@
///////////////////////////////////////////////////////////////////////////////
//
// Служебный модуль с реализацией работы команды <exec-rules>
//
// (с) BIA Technologies, LLC
//
///////////////////////////////////////////////////////////////////////////////
#Использовать gitrunner
Перем Лог;
Перем РепозиторийGit;
///////////////////////////////////////////////////////////////////////////////
Процедура НастроитьКоманду(Знач Команда, Знач Парсер) Экспорт
// Добавление параметров команды
Парсер.ДобавитьПозиционныйПараметрКоманды(Команда, "КаталогРепозитория",
"Каталог анализируемого репозитория");
Парсер.ДобавитьИменованныйПараметрКоманды(Команда, "-source-dir",
"Каталог расположения исходных файлов относительно корня репозитория. По умолчанию <src>");
Парсер.ДобавитьИменованныйПараметрКоманды(Команда, "-rules",
"Перечень правил для применения. Если сценариев несколько, указываются в кавычках через ,");
Парсер.ДобавитьИменованныйПараметрКоманды(Команда, "-cfg-file",
"Путь к конфигурационному файлу с настройками. Если не указан, используются настройки репозитория либо глобальные");
КонецПроцедуры // НастроитьКоманду
// Выполняет логику команды
//
// Параметры:
// ПараметрыКоманды - Соответствие - Соответствие ключей командной строки и их значений
// Приложение - Модуль - Модуль менеджера приложения
//
Функция ВыполнитьКоманду(Знач ПараметрыКоманды, Знач Приложение) Экспорт
Лог = Приложение.ПолучитьЛог();
КаталогРепозитория = ПараметрыКоманды["КаталогРепозитория"];
ФайлКаталогРепозитория = Новый Файл(КаталогРепозитория);
Если НЕ ФайлКаталогРепозитория.Существует() ИЛИ ФайлКаталогРепозитория.ЭтоФайл() Тогда
Лог.Ошибка("Каталог репозитория '%1' не существует или это файл", КаталогРепозитория);
Возврат Приложение.РезультатыКоманд().НеверныеПараметры;
КонецЕсли;
АдресПоискаКонфигурационногоФайла = КаталогРепозитория;
Если ЗначениеЗаполнено(ПараметрыКоманды["-cfg-file"]) Тогда
АдресПоискаКонфигурационногоФайла = ПараметрыКоманды["-cfg-file"];
КонецЕсли;
КаталогИсходныхФайлов = ПараметрыКоманды["-source-dir"];
Если Не ЗначениеЗаполнено(КаталогИсходныхФайлов) Тогда
КаталогИсходныхФайлов = "src";
КонецЕсли;
ТекущийКаталогИсходныхФайлов = ОбъединитьПути(КаталогРепозитория, КаталогИсходныхФайлов);
ФайлТекущийКаталогИсходныхФайлов = Новый Файл(ТекущийКаталогИсходныхФайлов);
ТекущийКаталогИсходныхФайлов = ФайлТекущийКаталогИсходныхФайлов.ПолноеИмя;
Если НЕ ФайлТекущийКаталогИсходныхФайлов.Существует() Тогда
Лог.Ошибка("Каталога <%1> не существует", ТекущийКаталогИсходныхФайлов);
КонецЕсли;
КаталогРепозитория = ФайлКаталогРепозитория.ПолноеИмя;
ИменаЗагружаемыхСценариев = Неопределено;
Если ЗначениеЗаполнено(ПараметрыКоманды["-rules"]) Тогда
ПараметрИменаСценариев = СтрЗаменить(ПараметрыКоманды["-rules"], " ", "");
ИменаЗагружаемыхСценариев = СтрРазделить(ПараметрИменаСценариев, ",", Ложь);
КонецЕсли;
ОбрабатываемыеФайлы = НайтиФайлы(ТекущийКаталогИсходныхФайлов, "*", Истина);
Ит = 0;
УправлениеНастройками = МенеджерНастроек.НастройкиРепозитория(АдресПоискаКонфигурационногоФайла);
НаборНастроек = СценарииОбработки.ПолучитьСценарииСПараметрамиВыполнения(КаталогРепозитория, ИменаЗагружаемыхСценариев);
КритичныеОшибки = Новый Массив;
ПараметрыОбработки = СценарииОбработки.ПолучитьСтандартныеПараметрыОбработки();
Пока Ит < ОбрабатываемыеФайлы.Количество() Цикл
АнализируемыйФайл = ОбрабатываемыеФайлы[Ит];
Если АнализируемыйФайл.ЭтоКаталог() Тогда
Ит = Ит + 1;
Продолжить;
КонецЕсли;
Лог.Информация("Анализируется файл <%1>", АнализируемыйФайл.ПолноеИмя);
ИмяФайла = ФайловыеОперации.ПолучитьНормализованныйОтносительныйПуть(КаталогРепозитория,
СтрЗаменить(АнализируемыйФайл.ПолноеИмя, КаталогРепозитория, ""));
ИмяПроекта = МенеджерНастроек.ИмяПроектаДляФайла(ИмяФайла);
НастройкаОбработки = НаборНастроек[ИмяПроекта];
Если НЕ ЗначениеЗаполнено(НастройкаОбработки) Тогда
ВызватьИсключение СтрШаблон("Не удалось получить настройки для %1", ИмяФайла);
КонецЕсли;
ПараметрыОбработки.Настройки = НастройкаОбработки.НастройкиСценариев.Получить("НастройкиСценариев");
ПараметрыОбработки.КаталогРепозитория = КаталогРепозитория;
Для Каждого СценарийОбработки Из НастройкаОбработки.СценарииОбработки Цикл
Попытка
ФайлОбработан = СценарийОбработки.ОбработатьФайл(АнализируемыйФайл,
ТекущийКаталогИсходныхФайлов,
ПараметрыОбработки);
Если НЕ ФайлОбработан Тогда
Продолжить;
КонецЕсли;
Для Каждого ФайлДляДопОбработки Из ПараметрыОбработки.ФайлыДляПостОбработки Цикл
ОбрабатываемыеФайлы.Добавить(ФайлДляДопОбработки);
КонецЦикла;
ПараметрыОбработки.ФайлыДляПостОбработки.Очистить();
Исключение
Ошибка = ОписаниеОшибки();
КритичныеОшибки.Добавить(Ошибка);
Лог.Информация("Критичная ошибка: %1", Ошибка);
КонецПопытки;
КонецЦикла;
Ит = Ит + 1;
КонецЦикла;
// В отличие от прекоммита, здесь лучше вывести все криты в конце одним блоком еще раз.
Если КритичныеОшибки.Количество() Тогда
Лог.Ошибка("В результате выполнения возникли исключения:");
Для Каждого ОписаниеОшибки Из КритичныеОшибки Цикл
Лог.Ошибка(ОписаниеОшибки);
КонецЦикла;
КонецЕсли;
// При успешном выполнении возвращает код успеха
Возврат Приложение.РезультатыКоманд().Успех;
КонецФункции // ВыполнитьКоманду

View File

@ -149,7 +149,10 @@
Приложение.ДобавитьКоманду(ИмяКомандыПомощь(), "КомандаСправкаПоПараметрам", "Выводит справку по командам");
Приложение.ДобавитьКоманду(ИмяКомандыВерсия(), "КомандаVersion", "Выводит версию приложения");
Приложение.ДобавитьКоманду("precommit", "КомандаПрекоммит", "Выполняет сценарии precommit");
Приложение.ДобавитьКоманду("install", "КомандаИнсталл", "Выполняет подключение (установку) precommit hook'а в репозиторий");
Приложение.ДобавитьКоманду("install", "КомандаИнсталл",
"Выполняет подключение (установку) precommit hook'а в репозиторий");
Приложение.ДобавитьКоманду("configure", "КомандаКонфигуратион", "Выполняет настройку репозитория");
Приложение.ДобавитьКоманду("exec-rules", "КомандаВыполнитьСценарии",
"Выполняет указанные сценарии в каталоге репозитория принудительно, без обращения к git");
КонецПроцедуры // ПриРегистрацииКомандПриложения

View File

@ -1,13 +1,11 @@
Функция Загрузить(КаталогРепозитория, Проект, ПараметрИменаЗагружаемыхСценариев = Неопределено) Экспорт
Функция Загрузить(КаталогРепозитория, Проект, Знач ПараметрИменаЗагружаемыхСценариев = Неопределено) Экспорт
ТекущийКаталогСценариев = МенеджерПриложения.КаталогСценариев();
ВсеЗагруженные = Новый Массив;
ФайлыГлобальныхСценариев = НайтиФайлы(ТекущийКаталогСценариев, "*.os");
ФайлыЛокальныхСценариев = Новый Массив;
Лог = МенеджерПриложения.ПолучитьЛог();
Если ПараметрИменаЗагружаемыхСценариев <> Неопределено Тогда
@ -15,17 +13,17 @@
ИменаЗагружаемыхСценариев = ПараметрИменаЗагружаемыхСценариев;
Иначе
ИменаЗагружаемыхСценариев = МенеджерНастроек.ИменаЗагружаемыхСценариев(Проект);
КонецЕсли;
Если НЕ МенеджерНастроек.ЭтоНовый() Тогда
Если НЕ МенеджерНастроек.ЭтоНовый() Тогда
Лог.Информация("Читаем настройки " + Проект);
ИспользоватьСценарииРепозитория = МенеджерНастроек.ЗначениеНастройки("ИспользоватьСценарииРепозитория", Проект, Ложь);
Если ИспользоватьСценарииРепозитория Тогда
ЛокальныйКаталог = МенеджерНастроек.ЗначениеНастройки("КаталогЛокальныхСценариев", Проект);
@ -59,9 +57,9 @@
КонецФункции
Процедура ЗагрузитьИзКаталога(ВсеЗагруженные, ФайлыСценариев,
Знач ИменаЗагружаемыхСценариев = Неопределено,
ЗагрузитьВсе = Ложь) Экспорт
Процедура ЗагрузитьИзКаталога(ВсеЗагруженные, ФайлыСценариев,
Знач ИменаЗагружаемыхСценариев = Неопределено,
ЗагрузитьВсе = Ложь) Экспорт
Лог = МенеджерПриложения.ПолучитьЛог();
Если ИменаЗагружаемыхСценариев = Неопределено Тогда
@ -70,7 +68,7 @@
КонецЕсли;
Для Каждого ФайлСценария Из ФайлыСценариев Цикл
Для Каждого ФайлСценария Из ФайлыСценариев Цикл
Если СтрСравнить(ФайлСценария.ИмяБезРасширения, "ШаблонСценария") = 0 Тогда
@ -78,9 +76,9 @@
КонецЕсли;
Если НЕ ЗагрузитьВсе
И ИменаЗагружаемыхСценариев.Найти(ФайлСценария.Имя) = Неопределено
И ИменаЗагружаемыхСценариев.Найти(ФайлСценария.ИмяБезРасширения) = Неопределено Тогда
Если НЕ ЗагрузитьВсе
И ИменаЗагружаемыхСценариев.Найти(ФайлСценария.Имя) = Неопределено
И ИменаЗагружаемыхСценариев.Найти(ФайлСценария.ИмяБезРасширения) = Неопределено Тогда
Продолжить;
@ -110,7 +108,7 @@
ПараметрыОбработки.Вставить("ИзмененныеКаталоги", Новый Массив);
ПараметрыОбработки.Вставить("КаталогРепозитория", Неопределено);
ПараметрыОбработки.Вставить("Настройки", Неопределено);
Возврат ПараметрыОбработки;
КонецФункции
@ -118,47 +116,50 @@
// <Возвращает соответствие со сценариями и их настройками>
//
// Параметры:
// КаталогРепозитория - <Строка> - <описание параметра>
// УправлениеНастройками - <Тип.Вид> - <описание параметра>
// ИменаЗагружаемыхСценариев - <Тип.Вид> - <описание параметра>
// КаталогРепозитория - <Строка> - <Адрес каталога репозитория>
// ИменаЗагружаемыхСценариев - <Массив.Строка> - <Предназначен для переопределения сценариев,
// Если задан загрузятся только они >
//
// Возвращаемое значение:
// <Соответствие> - <ключ - Ключ структуры настроек прокоммит или
// путь к каталогу, который обрабатывается
// нестандартными правилами >
// <Соответствие> - <ключ - Ключ структуры настроек прекоммит или
// путь к каталогу, который обрабатывается
// нестандартными правилами >
//
Функция ПолучитьСценарииСПараметрамиВыполнения(КаталогРепозитория, ИменаЗагружаемыхСценариев = Неопределено) Экспорт
ПараметрыОбработки = СценарииОбработки.ПолучитьСтандартныеПараметрыОбработки();
ПараметрыОбработки.КаталогРепозитория = КаталогРепозитория;
НастройкиПроектов = МенеджерНастроек.ПроектыКонфигурации();
НаборНастроек = Новый Соответствие;
Для Каждого ИмяПроекта Из НастройкиПроектов Цикл
Настройка = НастройкаОбработкиПроекта(ИмяПроекта, КаталогРепозитория);
Для Каждого ИмяПроекта Из НастройкиПроектов Цикл
Настройка = НастройкаОбработкиПроекта(ИмяПроекта, КаталогРепозитория, ИменаЗагружаемыхСценариев);
НаборНастроек.Вставить(ИмяПроекта, Настройка);
КонецЦикла;
ИмяПроекта = ""; // Базовые настройки
Настройка = НастройкаОбработкиПроекта(ИмяПроекта, КаталогРепозитория);
Настройка = НастройкаОбработкиПроекта(ИмяПроекта, КаталогРепозитория, ИменаЗагружаемыхСценариев);
НаборНастроек.Вставить(ИмяПроекта, Настройка);
Возврат НаборНастроек;
КонецФункции
Функция НастройкаОбработкиПроекта(ИмяПроекта, КаталогРепозитория)
Функция НастройкаОбработкиПроекта(ИмяПроекта, КаталогРепозитория, Знач ИменаЗагружаемыхСценариев = Неопределено)
Настройка = Новый Структура("СценарииОбработки, НастройкиСценариев");
Если ИменаЗагружаемыхСценариев = Неопределено Тогда
ИменаЗагружаемыхСценариев = МенеджерНастроек.ИменаЗагружаемыхСценариев(ИмяПроекта)
КонецЕсли;
Настройка.СценарииОбработки = СценарииОбработки.Загрузить(КаталогРепозитория,
ИмяПроекта,
МенеджерНастроек.ИменаЗагружаемыхСценариев(ИмяПроекта));
ИменаЗагружаемыхСценариев);
Настройка.НастройкиСценариев = МенеджерНастроек.НастройкиПроекта(ИмяПроекта);
Возврат Настройка;
КонецФункции
Функция ПолучитьПараметрыОбработкиФайла(ИмяФайла, НастройкиПроектов) Экспорт
@ -206,8 +207,8 @@
КонецЕсли;
НастройкиСценариев = Новый Соответствие;
Рефлектор = Новый Рефлектор;
НастройкиСценариев = Новый Соответствие;
Рефлектор = Новый Рефлектор;
Для Каждого ИмяСценария Из ИменаСценариев Цикл
@ -215,10 +216,10 @@
Если Рефлектор.МетодСуществует(ОбъектСценария, "ПолучитьСтандартныеНастройкиСценария") Тогда
СтруктураНастроек = Рефлектор.ВызватьМетод(ОбъектСценария, "ПолучитьСтандартныеНастройкиСценария");
СтруктураНастроек = Рефлектор.ВызватьМетод(ОбъектСценария, "ПолучитьСтандартныеНастройкиСценария");
НастройкиСценариев.Вставить(СтруктураНастроек.ИмяСценария, СтруктураНастроек.Настройка);
КонецЕсли;
КонецЕсли;
КонецЦикла;

View File

@ -130,9 +130,13 @@
// Строка - относительный путь файла
//
Функция ПолучитьНормализованныйОтносительныйПуть(Знач ПутьКорневогоКаталога, Знач ОтносительныйПутьФайла) Экспорт
ПроверитьКорневойКаталог(ПутьКорневогоКаталога);
Если СтрНачинаетсяС(ОтносительныйПутьФайла, ПолучитьРазделительПути()) Тогда
ОтносительныйПутьФайла = Сред(ОтносительныйПутьФайла, 2);
КонецЕсли;
ПолныйПутьФайла = ОбъединитьПути(ПутьКорневогоКаталога, ОтносительныйПутьФайла);
ОтносительныйПуть = ОтносительныйПуть(ПутьКорневогоКаталога, ПолныйПутьФайла, ПолучитьРазделительПути());
Файл = Новый Файл(ПолныйПутьФайла);

View File

@ -26,7 +26,8 @@
ВсеТесты.Добавить("ТестДолжен_ПроверитьЧтоСценарийИсправлениеНеКаноническогоНаписанияНеИндексируетНеизмененные");
ВсеТесты.Добавить("ТестДолжен_ПроверитьЧтоСценарийИсправлениеНеКаноническогоНаписанияИсправляетТолькоНаписание");
ВсеТесты.Добавить("ТестДолжен_ПроверитьЧтоСинхронизацияОбъектовМетаданныхВызываетИсключение");
ВсеТесты.Добавить("ТестДолжен_ПроверитьЗагрузкуСценариевПоИмени");
Возврат ВсеТесты;
КонецФункции
@ -176,6 +177,32 @@
КонецПроцедуры
Процедура ТестДолжен_ПроверитьЗагрузкуСценариевПоИмени() Экспорт
Файл = Новый Файл(МенеджерВременныхФайлов.СоздатьФайл("bsl"));
Имена = Новый Массив;
Имена.Добавить("ПроверкаДублейПроцедурИФункций");
Сценарии = СценарииОбработки.Загрузить(Файл.Путь, "", Имена);
Ожидаем.Что(Сценарии.Количество(), "Сценарий не получен").Равно(1);
Имена.Добавить("ПроверкаДублейПроцедурИФункций");
Сценарии = СценарииОбработки.Загрузить(Файл.Путь, "", Имена);
Ожидаем.Что(Сценарии.Количество(), "Добавлен один и тот же сценарий").Равно(1);
Имена.Добавить("ПроверкаДублейПроцедурИФункций.os");
Сценарии = СценарииОбработки.Загрузить(Файл.Путь, "", Имена);
Ожидаем.Что(Сценарии.Количество(), "Добавлен один и тот же сценарий").Равно(1);
Имена.Добавить("РазборОтчетовОбработокРасширений.os");
Сценарии = СценарииОбработки.Загрузить(Файл.Путь, "", Имена);
Ожидаем.Что(Сценарии.Количество(), "С массивом загружаемых сценариев что-то пошло не так").Равно(2);
КонецПроцедуры
#КонецОбласти
#КонецОбласти
#Область СинхронизацияОбъектовМетаданныхИФайлов