You've already forked gitlab-ci-for-1c
mirror of
https://github.com/nixel2007/gitlab-ci-for-1c.git
synced 2025-12-03 22:39:14 +02:00
430 lines
24 KiB
Plaintext
430 lines
24 KiB
Plaintext
#Использовать "../vendor/oscript-library/src/v8runner"
|
|
#Использовать "../vendor/oscript-library/src/tempfiles"
|
|
// logos объявлен в одном из модулей. Ждем фикса от разработчиков библиотеки
|
|
// #Использовать "../vendor/oscript-library/src/logos"
|
|
|
|
Перем Лог;
|
|
Перем Соединение;
|
|
Перем КодВозврата;
|
|
|
|
Перем СписокОбработокДляОбновления;
|
|
|
|
Процедура Инициализация()
|
|
|
|
Лог = Логирование.ПолучитьЛог("oscript.app.gitlab-deploy");
|
|
Лог.УстановитьРаскладку(ЭтотОбъект);
|
|
|
|
КодВозврата = 0;
|
|
СписокОбработокДляОбновления = Новый Массив;
|
|
|
|
КонецПроцедуры
|
|
|
|
Функция Форматировать(Знач Уровень, Знач Сообщение) Экспорт
|
|
|
|
Возврат СтрШаблон("%1: %2 - %3", ТекущаяДата(), УровниЛога.НаименованиеУровня(Уровень), Сообщение);
|
|
|
|
КонецФункции
|
|
|
|
Процедура ВывестиГоризонтальнуюЧерту()
|
|
|
|
Лог.Информация("------------------------------------------");
|
|
|
|
КонецПроцедуры
|
|
|
|
Процедура ВыполнитьОбновлениеБазы()
|
|
|
|
Если КодВозврата > 0 Тогда
|
|
Возврат;
|
|
КонецЕсли;
|
|
|
|
ВывестиГоризонтальнуюЧерту();
|
|
Лог.Информация("Выполняем обновление базы...");
|
|
ВывестиГоризонтальнуюЧерту();
|
|
|
|
СтрокаИзмененныхФайлов = ПолучитьСтрокуИзмененныхФайлов("src/cf/");
|
|
|
|
Если НЕ ЗначениеЗаполнено(СтрокаИзмененныхФайлов) Тогда
|
|
Лог.Информация("Обновление базы не требуется.");
|
|
Возврат;
|
|
КонецЕсли;
|
|
|
|
Лог.Информация("Строка измененных файлов: " + СтрокаИзмененныхФайлов);
|
|
|
|
Конфигуратор = Новый УправлениеКонфигуратором();
|
|
УстановитьКонтекстКонфигуратора(Конфигуратор);
|
|
|
|
ПараметрыЗапуска = Конфигуратор.ПолучитьПараметрыЗапуска();
|
|
// Временно отключаем инкрементальную загрузку. см #109
|
|
//КомандаЗапуска = "/LoadConfigFromFiles ""%1"" -Files ""%2""";
|
|
//КомандаЗапуска = СтрШаблон(КомандаЗапуска, ОбъединитьПути(ТекущийКаталог(), "source", "cf"), СтрокаИзмененныхФайлов);
|
|
КомандаЗапуска = "/LoadConfigFromFiles ""%1""";
|
|
КомандаЗапуска = СтрШаблон(КомандаЗапуска, ОбъединитьПути(ТекущийКаталог(), "source", "cf"));
|
|
|
|
Лог.Информация("Команда обновления конфигурации: " + КомандаЗапуска);
|
|
|
|
ПараметрыЗапуска.Добавить(КомандаЗапуска);
|
|
|
|
Попытка
|
|
Конфигуратор.ВыполнитьКоманду(ПараметрыЗапуска);
|
|
ВыводКоманды = Конфигуратор.ВыводКоманды();
|
|
Если ЗначениеЗаполнено(ВыводКоманды) Тогда
|
|
Лог.Информация(ВыводКоманды);
|
|
КонецЕсли;
|
|
Исключение
|
|
|
|
Лог.Ошибка(Конфигуратор.ВыводКоманды());
|
|
КодВозврата = 1;
|
|
Возврат;
|
|
|
|
КонецПопытки;
|
|
|
|
ВывестиГоризонтальнуюЧерту();
|
|
Лог.Информация("Конфигурация обновлена.");
|
|
|
|
ВывестиГоризонтальнуюЧерту();
|
|
Лог.Информация("Выполняем обновление конфигурации БД");
|
|
|
|
Попытка
|
|
Конфигуратор.ОбновитьКонфигурациюБазыДанных();
|
|
ВыводКоманды = Конфигуратор.ВыводКоманды();
|
|
Если ЗначениеЗаполнено(ВыводКоманды) Тогда
|
|
Лог.Информация(ВыводКоманды);
|
|
КонецЕсли;
|
|
Исключение
|
|
|
|
Лог.Ошибка(Конфигуратор.ВыводКоманды());
|
|
КодВозврата = 2;
|
|
Возврат;
|
|
|
|
КонецПопытки;
|
|
|
|
ВывестиГоризонтальнуюЧерту();
|
|
Лог.Информация("Обновление конфигурации завершено.");
|
|
|
|
КонецПроцедуры
|
|
|
|
Процедура ЗагрузитьВнешниеОтчетыИОбработки()
|
|
|
|
Если КодВозврата > 0 Тогда
|
|
Возврат;
|
|
КонецЕсли;
|
|
|
|
ПутьКИсходникам = "src/processings";
|
|
|
|
ВывестиГоризонтальнуюЧерту();
|
|
Лог.Информация("Выполняем обновление обрабток...");
|
|
ВывестиГоризонтальнуюЧерту();
|
|
|
|
СтрокаИзмененныхФайлов = ПолучитьСтрокуИзмененныхФайлов(ПутьКИсходникам);
|
|
|
|
Если НЕ ЗначениеЗаполнено(СтрокаИзмененныхФайлов) Тогда
|
|
Лог.Информация("Обновление обработок не требуется.");
|
|
Возврат;
|
|
КонецЕсли;
|
|
|
|
Лог.Информация("Строка измененных файлов: " + СтрокаИзмененныхФайлов);
|
|
|
|
ВывестиГоризонтальнуюЧерту();
|
|
Лог.Информация("Собираем дополнительные отчеты и обработки");
|
|
ВывестиГоризонтальнуюЧерту();
|
|
|
|
СобратьКаталог(ПутьКИсходникам, "processings", СтрокаИзмененныхФайлов);
|
|
|
|
ВывестиГоризонтальнуюЧерту();
|
|
Лог.Информация("Обновляем обработки в базе");
|
|
ВывестиГоризонтальнуюЧерту();
|
|
|
|
СтрокаСоединения = ПолучитьСтрокуСоединенияКБазе();
|
|
V83COMConnector = Новый COMОбъект("V83.COMConnector");
|
|
Попытка
|
|
Соединение = V83COMConnector.Connect(СтрокаСоединения);
|
|
Исключение
|
|
Лог.Ошибка("Не удалось подключиться к базе-приемнику для обновления обработок");
|
|
Лог.Ошибка(ОписаниеОшибки());
|
|
КодВозврата = 4;
|
|
Возврат;
|
|
КонецПопытки;
|
|
|
|
Соединение.НачатьТранзакцию();
|
|
|
|
КаталогОбработок = ОбъединитьПути(ТекущийКаталог(), "processings");
|
|
ЗагрузитьКаталогОбработокВБазу(КаталогОбработок);
|
|
|
|
Соединение.ЗафиксироватьТранзакцию();
|
|
|
|
ВывестиГоризонтальнуюЧерту();
|
|
Лог.Информация("Обновление обработок в базе завершено.");
|
|
|
|
КонецПроцедуры
|
|
|
|
Процедура СобратьКаталог(Знач ПутьКИсходникам, Знач КаталогВыгрузки, Знач СтрокаИзмененныхФайлов)
|
|
|
|
ТекущийКаталог = ТекущийКаталог();
|
|
|
|
ПолныйПутьКИсходникам = ОбъединитьПути(ТекущийКаталог, ПутьКИсходникам);
|
|
СписокФайловВКаталоге = НайтиФайлы(ПолныйПутьКИсходникам);
|
|
|
|
ПолныйПутьКаталогВыгрузки = ОбъединитьПути(ТекущийКаталог, КаталогВыгрузки);
|
|
Если НЕ Новый Файл(ПолныйПутьКаталогВыгрузки).Существует() Тогда
|
|
СоздатьКаталог(ПолныйПутьКаталогВыгрузки);
|
|
КонецЕсли;
|
|
|
|
Для Каждого Файл Из СписокФайловВКаталоге Цикл
|
|
|
|
Если НЕ Файл.ЭтоКаталог() Тогда
|
|
Продолжить;
|
|
КонецЕсли;
|
|
|
|
Если ЭтоПутьКИсходнымКодамОбработок(Файл.ПолноеИмя) И СтрНайти(СтрокаИзмененныхФайлов, Файл.ПолноеИмя) Тогда
|
|
|
|
КомандаЗапуска = "oscript -encoding=utf-8 vendor/precommit1c/v8files-extractor.os --compile ""%1"" ""%2""";
|
|
КомандаЗапуска = СтрШаблон(КомандаЗапуска, ОбъединитьПути(ПутьКИсходникам, Файл.Имя), КаталогВыгрузки);
|
|
Процесс = СоздатьПроцесс(КомандаЗапуска, ТекущийКаталог, Истина, , КодировкаТекста.UTF8);
|
|
Процесс.Запустить();
|
|
|
|
Пока НЕ Процесс.Завершен Цикл
|
|
Пока Процесс.ПотокВывода.ЕстьДанные Цикл
|
|
СтрокаВывода = Процесс.ПотокВывода.ПрочитатьСтроку();
|
|
Сообщить(СтрокаВывода);
|
|
КонецЦикла;
|
|
КонецЦикла;
|
|
|
|
Если Процесс.КодВозврата <> 0 Тогда
|
|
ВызватьИсключение "Ошибка сбора обработки из исходников";
|
|
КонецЕсли;
|
|
|
|
ИмяСобранногоФайла = ОбъединитьПути(ТекущийКаталог, КаталогВыгрузки, Файл.Имя);
|
|
СписокОбработокДляОбновления.Добавить(ИмяСобранногоФайла + ".erf");
|
|
СписокОбработокДляОбновления.Добавить(ИмяСобранногоФайла + ".epf");
|
|
|
|
Иначе
|
|
НовыйПутьКИсходникам = ОбъединитьПути(ПутьКИсходникам, Файл.Имя);
|
|
НовыйПутьВыгрузки = ОбъединитьПути(КаталогВыгрузки, Файл.Имя);
|
|
СобратьКаталог(НовыйПутьКИсходникам, НовыйПутьВыгрузки, СтрокаИзмененныхФайлов);
|
|
КонецЕсли;
|
|
|
|
КонецЦикла;
|
|
|
|
КонецПроцедуры
|
|
|
|
Процедура ЗагрузитьКаталогОбработокВБазу(Знач КаталогОбработок)
|
|
|
|
Файлы = НайтиФайлы(КаталогОбработок, ПолучитьМаскуВсеФайлы());
|
|
|
|
Для Каждого Файл Из Файлы Цикл
|
|
|
|
Если Файл.ЭтоКаталог() Тогда
|
|
ЗагрузитьКаталогОбработокВБазу(Файл.ПолноеИмя);
|
|
ИначеЕсли ЭтоФайлОтчетаИлиОбработки(Файл) И СписокОбработокДляОбновления.Найти(Файл.ПолноеИмя) <> Неопределено Тогда
|
|
Попытка
|
|
ЗагрузитьОбработкуВБазу(Файл.ПолноеИмя);
|
|
Исключение
|
|
ВывестиГоризонтальнуюЧерту();
|
|
Лог.Ошибка("Ошибка загрузки обработок, откат изменений");
|
|
ВызватьИсключение ОписаниеОшибки();
|
|
КонецПопытки;
|
|
КонецЕсли;
|
|
|
|
КонецЦикла
|
|
|
|
КонецПроцедуры
|
|
|
|
Процедура ЗагрузитьОбработкуВБазу(ИмяФайла)
|
|
|
|
Лог.Информация("Загрузка обработки <" + ИмяФайла + ">");
|
|
|
|
ПараметрыРегистрации = Соединение.NewObject("Структура");
|
|
ПараметрыРегистрации.Вставить("ИмяФайла", "");
|
|
ПараметрыРегистрации.Вставить("ЭтоОтчет", Неопределено);
|
|
ПараметрыРегистрации.Вставить("ОтключатьКонфликтующие", Ложь);
|
|
ПараметрыРегистрации.Вставить("Конфликтующие", Соединение.NewObject("СписокЗначений"));
|
|
ПараметрыРегистрации.Вставить("АдресДанныхОбработки", "");
|
|
|
|
ДД = Соединение.NewObject("ДвоичныеДанные", ИмяФайла);
|
|
АдресДанныхОбработки = Соединение.ПоместитьВоВременноеХранилище(ДД, Соединение.NewObject("УникальныйИдентификатор"));
|
|
ПараметрыРегистрации.АдресДанныхОбработки = АдресДанныхОбработки;
|
|
|
|
ФайлОбработки = Новый Файл(ИмяФайла);
|
|
ПараметрыРегистрации.ИмяФайла = ФайлОбработки.Имя;
|
|
|
|
РасширениеФайла = ВРег(ФайлОбработки.Расширение);
|
|
Если РасширениеФайла = ".ERF" Тогда
|
|
ПараметрыРегистрации.ЭтоОтчет = Истина;
|
|
ИначеЕсли РасширениеФайла = ".EPF" Тогда
|
|
ПараметрыРегистрации.ЭтоОтчет = Ложь;
|
|
Иначе
|
|
ВызватьИсключение("Расширение файла не соответствует расширению внешнего отчета (ERF) или обработки (EPF): " + РасширениеФайла);
|
|
Возврат;
|
|
КонецЕсли;
|
|
|
|
// Вызов сервера
|
|
РезультатРегистрации = ЗарегистрироватьОбработку(ПараметрыРегистрации);
|
|
|
|
// Обработка результата работы сервера
|
|
Если РезультатРегистрации.Успешно = Истина Тогда
|
|
|
|
РезультатРегистрации.ОбъектСправочника.ХранилищеОбработки = Соединение.NewObject("ХранилищеЗначения" , ДД, Соединение.NewObject("СжатиеДанных", 9));
|
|
|
|
РезультатРегистрации.ОбъектСправочника.Записать();
|
|
Лог.Информация("Обработка <" + ПараметрыРегистрации.ИмяФайла + "> успешно загружена");
|
|
Возврат;
|
|
|
|
КонецЕсли;
|
|
|
|
// Разбор причины отказа загрузки обработки и отображение информации пользователю
|
|
Если РезультатРегистрации.ИмяОбъектаЗанято = Ложь Тогда
|
|
|
|
// Причина отказа в КраткоеПредставлениеОшибки
|
|
ВызватьИсключение(РезультатРегистрации.КраткоеПредставлениеОшибки);
|
|
|
|
Иначе
|
|
|
|
// Представление занявших объектов
|
|
КоличествоКонфликтующих = РезультатРегистрации.Конфликтующие.Количество();
|
|
ПредставлениеЗанявших = "";
|
|
Для Каждого ЭлементСписка Из РезультатРегистрации.Конфликтующие Цикл
|
|
ПредставлениеЗанявших = ПредставлениеЗанявших
|
|
+ ?(ПредставлениеЗанявших = "", "", ", ")
|
|
+ СокрЛП(ЭлементСписка.Представление);
|
|
Если СтрДлина(ПредставлениеЗанявших) > 80 Тогда
|
|
ПредставлениеЗанявших = Лев(ПредставлениеЗанявших, 70)
|
|
+ "... ("
|
|
+ Формат(КоличествоКонфликтующих, "ЧН=0; ЧГ=")
|
|
+ " "
|
|
+ Соединение.НСтр("ru = 'шт'")
|
|
+ ")";
|
|
Прервать;
|
|
КонецЕсли;
|
|
КонецЦикла;
|
|
|
|
ТекстВопроса = СтрШаблон(
|
|
Соединение.НСтр("ru = 'Имя ""%1"" уже занято другими дополнительными отчетами (обработками):
|
|
|%2.'"),
|
|
РезультатРегистрации.ИмяОбъекта,
|
|
ПредставлениеЗанявших
|
|
);
|
|
|
|
КонецЕсли;
|
|
|
|
// Отменить загрузку
|
|
ВызватьИсключение("Не удалось записать обработку <" + ИмяФайла + ">");
|
|
|
|
КонецПроцедуры
|
|
|
|
Функция ЗарегистрироватьОбработку(ПараметрыРегистрации)
|
|
|
|
СсылкаСправочника = Соединение.Справочники.ДополнительныеОтчетыИОбработки.НайтиПоРеквизиту("ИмяФайла", ПараметрыРегистрации.ИмяФайла);
|
|
Если СсылкаСправочника.Пустая() Тогда
|
|
Лог.Информация("Обработка <" + ПараметрыРегистрации.ИмяФайла + "> не найдена, создаем элемент");
|
|
ОбъектСправочника = Соединение.Справочники.ДополнительныеОтчетыИОбработки.СоздатьЭлемент();
|
|
ОбъектСправочника.Заполнить(Неопределено);
|
|
ОбъектСправочника.ИспользоватьДляФормыОбъекта = Истина;
|
|
ОбъектСправочника.ИспользоватьДляФормыСписка = Истина;
|
|
Иначе
|
|
Лог.Информация("Обработка <" + ПараметрыРегистрации.ИмяФайла + "> найдена в базе. Используем существующий элемент");
|
|
ОбъектСправочника = СсылкаСправочника.ПолучитьОбъект();
|
|
КонецЕсли;
|
|
|
|
Результат = Соединение.ДополнительныеОтчетыИОбработки.ЗарегистрироватьОбработку(ОбъектСправочника, ПараметрыРегистрации);
|
|
АдресРазрешений = Соединение.ПоместитьВоВременноеХранилище(ОбъектСправочника.Разрешения.Выгрузить());
|
|
|
|
Результат.Вставить("ОбъектСправочника", ОбъектСправочника);
|
|
|
|
Возврат Результат;
|
|
|
|
КонецФункции
|
|
|
|
Функция ЭтоФайлОтчетаИлиОбработки(Знач Файл)
|
|
|
|
РасширениеФайла = ВРег(Файл.Расширение);
|
|
Возврат РасширениеФайла = ".EPF" ИЛИ РасширениеФайла = ".ERF";
|
|
|
|
КонецФункции
|
|
|
|
Функция ЭтоПутьКИсходнымКодамОбработок(ПутьКПапке)
|
|
|
|
ФайлПереименования = Новый Файл(ОбъединитьПути(ПутьКПапке, "renames.txt"));
|
|
Возврат ФайлПереименования.Существует();
|
|
|
|
КонецФункции
|
|
|
|
Функция ПолучитьСтрокуИзмененныхФайлов(Знач ОтборПоНачалуСтроки = "")
|
|
|
|
ТекущийКаталог = ТекущийКаталог();
|
|
|
|
КоманднаяСтрока = "git diff --name-only HEAD^ HEAD";
|
|
|
|
Процесс = СоздатьПроцесс(КоманднаяСтрока, ТекущийКаталог, Истина, , КодировкаТекста.UTF8);
|
|
Процесс.Запустить();
|
|
|
|
Процесс.ОжидатьЗавершения();
|
|
|
|
СтрокаИзмененныхФайлов = "";
|
|
Пока Процесс.ПотокВывода.ЕстьДанные Цикл
|
|
|
|
СтрокаВывода = Процесс.ПотокВывода.ПрочитатьСтроку();
|
|
Если НЕ ЗначениеЗаполнено(ОтборПоНачалуСтроки) ИЛИ СтрНачинаетсяС(СтрокаВывода, ОтборПоНачалуСтроки) Тогда
|
|
ТекущаяСтрока = ОбъединитьПути(ТекущийКаталог, СтрокаВывода);
|
|
ТекущаяСтрока = СтрЗаменить(ТекущаяСтрока, "/", ПолучитьРазделительПути());
|
|
СтрокаИзмененныхФайлов = СтрокаИзмененныхФайлов + ТекущаяСтрока + ",";
|
|
КонецЕсли;
|
|
|
|
КонецЦикла;
|
|
|
|
Если ЗначениеЗаполнено(СтрокаИзмененныхФайлов) Тогда
|
|
СтрокаИзмененныхФайлов = Лев(СтрокаИзмененныхФайлов, СтрДлина(СтрокаИзмененныхФайлов) - 1);
|
|
КонецЕсли;
|
|
|
|
Возврат СтрокаИзмененныхФайлов;
|
|
|
|
КонецФункции
|
|
|
|
Функция ПолучитьПараметрыПодключенияКБазе()
|
|
|
|
СтруктураПодключения = Новый Структура;
|
|
|
|
СистемнаяИнформация = Новый СистемнаяИнформация;
|
|
|
|
Сервер = СистемнаяИнформация.ПолучитьПеременнуюСреды("SERVER_1C");
|
|
База = СистемнаяИнформация.ПолучитьПеременнуюСреды("SERVER_REF");
|
|
Пользователь = СистемнаяИнформация.ПолучитьПеременнуюСреды("1C_USERNAME");
|
|
Пароль = СистемнаяИнформация.ПолучитьПеременнуюСреды("1C_PASSWORD");
|
|
|
|
СтруктураПодключения.Вставить("Сервер", Сервер);
|
|
СтруктураПодключения.Вставить("База", База);
|
|
СтруктураПодключения.Вставить("Пользователь", Пользователь);
|
|
СтруктураПодключения.Вставить("Пароль", Пароль);
|
|
|
|
Возврат СтруктураПодключения;
|
|
|
|
КонецФункции
|
|
|
|
Процедура УстановитьКонтекстКонфигуратора(УправлениеКонфигуратором)
|
|
|
|
Параметры = ПолучитьПараметрыПодключенияКБазе();
|
|
|
|
СтрокаСоединения = "/IBConnectionString""Srvr=%1;Ref=%2;""";
|
|
СтрокаСоединения = СтрШаблон(СтрокаСоединения, Параметры.Сервер, Параметры.База);
|
|
|
|
УправлениеКонфигуратором.УстановитьКонтекст(СтрокаСоединения, Параметры.Пользователь, Параметры.Пароль);
|
|
|
|
КонецПроцедуры
|
|
|
|
Функция ПолучитьСтрокуСоединенияКБазе()
|
|
|
|
Параметры = ПолучитьПараметрыПодключенияКБазе();
|
|
|
|
СтрокаСоединения = "Srvr=%1;Ref=%2;Usr=%3;Pwd=%4;";
|
|
СтрокаСоединения = СтрШаблон(СтрокаСоединения, Параметры.Сервер, Параметры.База, Параметры.Пользователь, Параметры.Пароль);
|
|
|
|
Возврат СтрокаСоединения;
|
|
|
|
КонецФункции
|
|
|
|
Инициализация();
|
|
ВыполнитьОбновлениеБазы();
|
|
ЗагрузитьВнешниеОтчетыИОбработки();
|
|
ВременныеФайлы.Удалить();
|
|
|
|
ЗавершитьРаботу(КодВозврата);
|