1
0
mirror of https://github.com/bia-technologies/precommit4onec.git synced 2025-05-31 23:09:33 +02:00

Merge branch 'release/1.0.2'

This commit is contained in:
Maxmov Valery 2017-09-15 19:16:43 +03:00
commit 179bd35778
11 changed files with 769 additions and 69 deletions

View File

@ -35,9 +35,42 @@
- `РазборОтчетОбработокРасширений` - при выполнении данного сценария, файлы внешних отчетов, обработок и расширений средствами платформы будут разложены на исходные файлы и помещены в каталог исходных файлов репозитория в подкаталоги, соответствующие расширениям. Например внешний отчет `ВнешнийОтчет1.erf` будет разложен в каталог `src\erf\ВнешнийОтчет1`
- `РазборОбычныхФормНаИсходники` - при выполнении данного сценария, файлы обычных форм (`Form.bin`) раскладываются на исходные файлы с помощью инструмента `v8unpack`
## Изменение настроек
precommit4onec может читать настройки своей работы из специального конфигурационного файла.
Управление настройками происходит с использованием команды `configure`:
- Печать настроек - `precommit4onec configure -global`
- Сброс настроек на заводские - `precommit4onec configure -global -reset`
- Интерактивное изменение настроек - `precommit4onec configure -global -config`.
Конфигурирование дает возможности:
- Изменить список сценариев обработки файлов
- Активизировать алгоритм подключния сценариев из каталогов репозитория
## Расширение функциональности
Для добавления своих сценариев обработки файлов необходимо создать новый сценарий в каталоге `СценарииОбработки` скрипта используя соответствующий шаблон. Новый сценарий автоматически подключится.
Для создания нового сценария обработки файлов необходимо воспользваться шаблоном, находящимся в каталоге `СценарииОбработки` скрипта.
### Установка сценария для всех репозиториев
Чтобы сценарий работал для всех репозиториев необходимо
- сохранить файл сценария в каталог `СценарииОбработки`
- выполнить команду сброса настроек либо интерактивного изменения, где указать сценарий в списке загружаемых
### Установка сценария для конкретного репозитория
Чтобы сценарий работал в конкретном репозитории необходимо
- Решить, в каком каталоге в репозиториях будут хранится сценарии, например `tools\СценарииОбработки`
- Создать каталог в репозитории и скопировать в него файл сценария
- Вызвать команду конфигурирования, в которой включить использование сценариев из репозитория
- Указать имя каталога
Если при выполнении precommit4onec не найдет файлов сценариев в указанном каталоге, либо не найдет каталог, он об этом сообщит в лог и продолжит работу без ошибок.
## Ссылки

View File

@ -0,0 +1,32 @@
# language: ru
Функциональность: Настройка конфигурации прекоммита
Как разработчик
Я хочу иметь возможность изменять настройки precommit4onec
Чтобы автоматически выполнять обработку исходников перед фиксацией изменений в репозитории
Сценарий: Печать текущих настроек precommit4onec
Когда Я выполняю команду "oscript" c параметрами "<КаталогПроекта>/src/main.os configure -global"
Тогда Код возврата команды "oscript" равен 0
И Я сообщаю вывод команды "oscript"
И Вывод команды "oscript" содержит "precommit4onec v1.0.2"
И Вывод команды "oscript" содержит "Установленные настройки:"
И Вывод команды "oscript" содержит "ИспользоватьСценарииРепозитория ="
И Вывод команды "oscript" содержит "КаталогЛокальныхСценариев ="
И Вывод команды "oscript" содержит "ГлобальныеСценарии ="
Сценарий: Сброс настроек к значениям по умолчанию
Когда Я выполняю команду "oscript" c параметрами "<КаталогПроекта>/src/main.os configure -global -reset"
Тогда Код возврата команды "oscript" равен 0
И Я выполняю команду "oscript" c параметрами "<КаталогПроекта>/src/main.os configure -global"
И Код возврата команды "oscript" равен 0
И Я сообщаю вывод команды "oscript"
И Вывод команды "oscript" содержит
"""
precommit4onec v1.0.2
Установленные настройки:
ИспользоватьСценарииРепозитория = Нет
КаталогЛокальныхСценариев =
ГлобальныеСценарии = РазборОбычныхФормНаИсходники.os,РазборОтчетовОбработокРасширений.os
"""

View File

@ -14,7 +14,7 @@
Сценарий: Получение версии продукта
Когда Я выполняю команду "oscript" c параметрами "src/main.os version"
Тогда Я сообщаю вывод команды "oscript"
И Вывод команды "oscript" содержит "1.0.1"
И Вывод команды "oscript" содержит "1.0.2"
И Вывод команды "oscript" не содержит "precommit4onec v"
И Код возврата команды "oscript" равен 0
@ -22,12 +22,13 @@
Когда Я выполняю команду "oscript" c параметрами "src/main.os help"
Тогда Вывод команды "oscript" содержит
"""
precommit4onec v1.0.1
precommit4onec v1.0.2
Возможные команды:
help - Выводит справку по командам
version - Выводит версию приложения
precommit - Выполняет сценарии precommit
install - Выполняет подключение (установку) precommit hook'а в репозиторий
configure - Выполняет настройку репозитория
"""
И Код возврата команды "oscript" равен 0
@ -35,11 +36,12 @@
Когда Я выполняю команду "oscript" c параметрами "src/main.os"
Тогда Вывод команды "oscript" содержит
"""
precommit4onec v1.0.1
precommit4onec v1.0.2
Возможные команды:
help - Выводит справку по командам
version - Выводит версию приложения
precommit - Выполняет сценарии precommit
install - Выполняет подключение (установку) precommit hook'а в репозиторий
configure - Выполняет настройку репозитория
"""
И Код возврата команды "oscript" равен 5

View File

@ -14,25 +14,25 @@
И я создаю новый репозиторий "rep1" в каталоге "КаталогРепозиториев" и запоминаю его как "Репозиторий1"
И я создаю новый репозиторий "rep2" в каталоге "КаталогРепозиториев" и запоминаю его как "Репозиторий2"
Сценарий: Установка precommi4onec в репозиторий
Сценарий: Установка precommit4onec в репозиторий
Когда Я выполняю команду "oscript" c параметрами "<КаталогПроекта>/src/main.os install rep1"
Тогда Код возврата команды "oscript" равен 0
И Я сообщаю вывод команды "oscript"
И Вывод команды "oscript" содержит "precommit4onec v1.0.1"
И Вывод команды "oscript" содержит "precommit4onec v1.0.2"
И Вывод команды "oscript" содержит "Pre-commit hook для rep1 создан"
И В каталоге ".git/hooks" репозитория "Репозиторий1" есть файл "pre-commit"
Сценарий: precommi4onec не устанавливается в пустой каталог
Сценарий: precommit4onec не устанавливается в пустой каталог
Когда Я выполняю команду "oscript" c параметрами "<КаталогПроекта>/src/main.os install ./"
Тогда Код возврата команды "oscript" равен 0
И Я сообщаю вывод команды "oscript"
И Вывод команды "oscript" содержит "precommit4onec v1.0.1"
И Вывод команды "oscript" содержит "precommit4onec v1.0.2"
И Вывод команды "oscript" содержит "не является репозиторием git"
Сценарий: Установка precommi4onec во вложенные каталоги
Сценарий: Установка precommit4onec во вложенные каталоги
Когда Я выполняю команду "oscript" c параметрами "<КаталогПроекта>/src/main.os install ./ -r"
Тогда Код возврата команды "oscript" равен 0
И Я сообщаю вывод команды "oscript"
И Вывод команды "oscript" содержит "precommit4onec v1.0.1"
И Вывод команды "oscript" содержит "precommit4onec v1.0.2"
И В каталоге ".git/hooks" репозитория "Репозиторий1" есть файл "pre-commit"
И В каталоге ".git/hooks" репозитория "Репозиторий2" есть файл "pre-commit"

View File

@ -15,4 +15,5 @@
.ВключитьФайл("src")
.ВключитьФайл("features")
.ВключитьФайл("tasks")
.ВключитьФайл("v8config.json")
.ИсполняемыйФайл("src/main.os", ИмяПродукта);

View File

@ -0,0 +1,266 @@
///////////////////////////////////////////////////////////////////////////////
//
// Служебный модуль с реализацией работы команды <configuration>
//
// (с) BIA Technologies, LLC
//
///////////////////////////////////////////////////////////////////////////////
#Использовать gitrunner
Перем Лог;
///////////////////////////////////////////////////////////////////////////////
Процедура НастроитьКоманду(Знач Команда, Знач Парсер) Экспорт
// Добавление параметров команды
Парсер.ДобавитьПараметрФлагКоманды(Команда, "-global", "Работа с глобальными настройками.");
// TODO: пока оция не используется Парсер.ДобавитьИменованныйПараметрКоманды(Команда, "-rep-path", "Каталог репозитория, настройки которого интересуют.");
Парсер.ДобавитьПараметрФлагКоманды(Команда, "-reset", "Сброс настроек на значения по умолчанию. Если редактируются настройки репозитория, то происходит удаление файла настроек.");
Парсер.ДобавитьПараметрФлагКоманды(Команда, "-config", "Интерактивное конфигурирование настроек.");
КонецПроцедуры // НастроитьКоманду
// Выполняет логику команды
//
// Параметры:
// ПараметрыКоманды - Соответствие - Соответствие ключей командной строки и их значений
// Приложение - Модуль - Модуль менеджера приложения
//
Функция ВыполнитьКоманду(Знач ПараметрыКоманды, Знач Приложение) Экспорт
Лог = Приложение.ПолучитьЛог();
Если НЕ ПараметрыКоманды["-global"] Тогда
// TODO: Пока не используется И НЕ ЗначениеЗаполнено(ПараметрыКоманды["-rep-path"]) Тогда
// TODO: пока не используется Лог.Ошибка("Для конфгурирования необходимо передать флаг -global или указать каталог репозитория параметром -rep-path");
Лог.Ошибка("Для конфгурирования необходимо передать флаг -global");
Возврат Приложение.РезультатыКоманд().НеверныеПараметры;
КонецЕсли;
Если ПараметрыКоманды["-global"] Тогда
КаталогРепозитория = Приложение.ПутьКРодительскомуКаталогу();
Иначе
КаталогРепозитория = ПараметрыКоманды["-rep-path"];
КонецЕсли;
УправлениеНастройками = Новый НастройкиРепозитория(КаталогРепозитория);
Если ПараметрыКоманды["-reset"] Тогда
Если ПараметрыКоманды["-global"] Тогда
ЗаписатьГлобальныеНастройкиПоУмолчанию(УправлениеНастройками, Приложение.КаталогСценариев());
Иначе
СброситьНастройкиРепозитория(УправлениеНастройками);
КонецЕсли;
ИначеЕсли ПараметрыКоманды["-config"] Тогда
ИнтерактивнаяНастройка(КаталогРепозитория, УправлениеНастройками, ПараметрыКоманды["-global"], Приложение.КаталогСценариев());
Иначе
НапечататьНастройки(УправлениеНастройками);
КонецЕсли;
// При успешном выполнении возвращает код успеха
Возврат Приложение.РезультатыКоманд().Успех;
КонецФункции // ВыполнитьКоманду
Процедура НапечататьНастройки(УправлениеНастройками)
Если УправлениеНастройками.ЭтоНовый() Тогда
Лог.Информация("Файл настроек не обнаружен");
Возврат;
КонецЕсли;
НастройкиПрекоммита = УправлениеНастройками.НастройкиПриложения("Precommt4onecСценарии");
Если НЕ ЗначениеЗаполнено(НастройкиПрекоммита) Тогда
Лог.Информация("Настройки в файле отсутствуют");
Возврат;
КонецЕсли;
Сообщить("Установленные настройки: ");
Для Каждого НастройкаПрекоммита Из НастройкиПрекоммита Цикл
Если ТипЗнч(НастройкаПрекоммита.Значение) = Тип("Массив") Тогда
ЗначениеПараметра = СтрСоединить(НастройкаПрекоммита.Значение, ",");
Иначе
ЗначениеПараметра = НастройкаПрекоммита.Значение;
КонецЕсли;
Сообщить(Символы.Таб + НастройкаПрекоммита.Ключ + " = " + ЗначениеПараметра);
КонецЦикла;
КонецПроцедуры
Процедура ЗаписатьГлобальныеНастройкиПоУмолчанию(УправлениеНастройками, ТекущийКаталогСценариев)
ИмяПриложения = "Precommt4onecСценарии";
СброситьНастройкиРепозитория(УправлениеНастройками);
УправлениеНастройками.ЗаписатьНастройку(ИмяПриложения + "\ИспользоватьСценарииРепозитория", Ложь);
УправлениеНастройками.ЗаписатьНастройку(ИмяПриложения + "\КаталогЛокальныхСценариев", "");
ГлобальныеСценарии = ПолучитьИменаСценариев(ТекущийКаталогСценариев);
УправлениеНастройками.ЗаписатьНастройку(ИмяПриложения + "\ГлобальныеСценарии", ГлобальныеСценарии);
КонецПроцедуры
Процедура СброситьНастройкиРепозитория(УправлениеНастройками)
Если УправлениеНастройками.ЭтоНовый() Тогда
Возврат;
КонецЕсли;
ИмяПриложения = "Precommt4onecСценарии";
УправлениеНастройками.УдалитьНастройкиПриложения(ИмяПриложения);
КонецПроцедуры
Функция ПолучитьИменаСценариев(КаталогСценариев)
НайденныеСценарии = Новый Массив;
ФайлыСценариев = НайтиФайлы(КаталогСценариев, "*.os");
Для Каждого ФайлСценария Из ФайлыСценариев Цикл
Если СтрСравнить(ФайлСценария.ИмяБезРасширения, "ШаблонСценария") = 0 Тогда
Продолжить;
КонецЕсли;
НайденныеСценарии.Добавить(ФайлСценария.Имя);
КонецЦикла;
Возврат НайденныеСценарии;
КонецФункции
Процедура ИнтерактивнаяНастройка(КаталогРепозитория, УправлениеНастройками, ГлобальныеНастройки, КаталогГлобальныхСценариев)
Сообщить("Настройка конфигурации precommit");
Если ГлобальныеНастройки Тогда
ГлобальныеСценарии = ПолучитьНастройкуМассив("Выберите подключаемые глобальные сценарии: ", ПолучитьИменаСценариев(КаталогГлобальныхСценариев));
ИспользоватьСценарииРепозитория = ПолучитьНастройкуБулево("Нужно использовать сценарии локальных репозиториев?", ЛОЖЬ);
КаталогЛокальныхСценариев = "";
Если ИспользоватьСценарииРепозитория Тогда
КаталогЛокальныхСценариев = ПолучитьНастройкуСтрока("Укажите относительный путь к сценариям в репозитории: ");
КонецЕсли;
ИмяПриложения = "Precommt4onecСценарии";
СброситьНастройкиРепозитория(УправлениеНастройками);
УправлениеНастройками.ЗаписатьНастройку(ИмяПриложения + "\ИспользоватьСценарииРепозитория", ИспользоватьСценарииРепозитория);
УправлениеНастройками.ЗаписатьНастройку(ИмяПриложения + "\КаталогЛокальныхСценариев", КаталогЛокальныхСценариев);
УправлениеНастройками.ЗаписатьНастройку(ИмяПриложения + "\ГлобальныеСценарии", ГлобальныеСценарии);
Иначе
// todo
// пока нет, будет в будущем
КонецЕсли;
КонецПроцедуры
Функция ПолучитьНастройкуБулево(ТекстПодсказки, ЗначениеПоУмолчанию)
ВыбранноеЗначение = Формат(ЗначениеПоУмолчанию, "БЛ=n; БИ=y");
Пока ИСТИНА Цикл
Сообщить(ТекстПодсказки + " [" + Формат(ЗначениеПоУмолчанию, "БЛ=n; БИ=y") + "]. Введите y[es]/n[o]");
ВвестиСтроку(ВыбранноеЗначение);
Если СтрНайти("yY", ВыбранноеЗначение) Тогда
ВыбранноеЗначение = ИСТИНА;
Прервать;
ИначеЕсли СтрНайти("nN", ВыбранноеЗначение) Тогда
ВыбранноеЗначение = ЛОЖЬ;
Прервать;
ИначеЕсли ВыбранноеЗначение = Символы.ПС Тогда
ВыбранноеЗначение = ИСТИНА;
Прервать;
КонецЕсли;
КонецЦикла;
Возврат ВыбранноеЗначение;
КонецФункции
Функция ПолучитьНастройкуМассив(ТекстПодсказки, ДоступныйМассив)
Сообщить(ТекстПодсказки);
ВыбранныеЭлементы = Новый Массив;
Для Ит = 0 По ДоступныйМассив.Количество() - 1 Цикл
ЗначениеМассива = ДоступныйМассив[Ит];
ТекстПодсказкиМассив = Символы.Таб + ЗначениеМассива;
Если ПолучитьНастройкуБулево(ТекстПодсказкиМассив, ИСТИНА) Тогда
ВыбранныеЭлементы.Добавить(ЗначениеМассива);
КонецЕсли;
КонецЦикла;
Возврат ВыбранныеЭлементы;
КонецФункции
Функция ПолучитьНастройкуСтрока(ТекстПодсказки)
ВыбранноеЗначение = "";
Пока Истина Цикл
Сообщить(ТекстПодсказки);
ВвестиСтроку(ВыбранноеЗначение);
ВыбранноеЗначение = СокрЛП(ВыбранноеЗначение);
Если Не ПустаяСтрока(ВыбранноеЗначение) Тогда
Прервать;
КонецЕсли;
КонецЦикла;
Возврат ВыбранноеЗначение;
КонецФункции

View File

@ -15,7 +15,7 @@
///////////////////////////////////////////////////////////////////////////////
Процедура НастроитьКоманду(Знач Команда, Знач Парсер) Экспорт
// Добавление параметров команды
Парсер.ДобавитьПозиционныйПараметрКоманды(Команда, "КаталогРепозитория", "Каталог анализируемого репозитория");
Парсер.ДобавитьИменованныйПараметрКоманды(Команда, "-source-dir", "Каталог расположения исходных файлов относительно корня репозитория. По умолчанию <src>");
@ -31,77 +31,78 @@
Функция ВыполнитьКоманду(Знач ПараметрыКоманды, Знач Приложение) Экспорт
Лог = Приложение.ПолучитьЛог();
ЗагрузитьСценарииОбработки();
КаталогРепозитория = ПараметрыКоманды["КаталогРепозитория"];
ФайлКаталогРепозитория = Новый Файл(КаталогРепозитория);
Если НЕ ФайлКаталогРепозитория.Существует() ИЛИ ФайлКаталогРепозитория.ЭтоФайл() Тогда
Лог.Ошибка("Каталог репозитория '%1' не существует или это файл", КаталогРепозитория);
Возврат Приложение.РезультатыКоманд().НеверныеПараметры;
КонецЕсли;
УправлениеНастройками = Новый НастройкиРепозитория(Приложение.ПутьКРодительскомуКаталогу());
ЗагрузитьСценарииОбработки(Приложение.КаталогСценариев(), УправлениеНастройками, КаталогРепозитория);
КаталогИсходныхФайлов = ПараметрыКоманды["-source-dir"];
Если Не ЗначениеЗаполнено(КаталогИсходныхФайлов) Тогда
КаталогИсходныхФайлов = "src";
КонецЕсли;
ТекущийКаталогИсходныхФайлов = ОбъединитьПути(КаталогРепозитория, КаталогИсходныхФайлов);
ФайлТекущийКаталогИсходныхФайлов = Новый Файл(ТекущийКаталогИсходныхФайлов);
ТекущийКаталогИсходныхФайлов = ФайлТекущийКаталогИсходныхФайлов.ПолноеИмя;
Если НЕ ФайлТекущийКаталогИсходныхФайлов.Существует() Тогда
СоздатьКаталог(ТекущийКаталогИсходныхФайлов);
КонецЕсли;
КаталогРепозитория = ФайлКаталогРепозитория.ПолноеИмя;
РепозиторийGit = Новый ГитРепозиторий();
РепозиторийGit.УстановитьРабочийКаталог(КаталогРепозитория);
Если НЕ РепозиторийGit.ЭтоРепозиторий() Тогда
Если НЕ РепозиторийGit.ЭтоРепозиторий() Тогда
Лог.Ошибка("Каталог '%1' не является репозиторием git", КаталогРепозитория);
Возврат Приложение.РезультатыКоманд().НеверныеПараметры;
КонецЕсли;
ЖурналИзменений = ПолучитьЖурналИзменений();
Ит = 0;
ПараметрыОбработки = Новый Структура("Лог, ФайлыДляПостОбработки, ИзмененныеКаталоги, КаталогРепозитория", Лог, Новый Массив, Новый Массив, КаталогРепозитория);
Пока Ит < ЖурналИзменений.Количество() Цикл
АнализируемыйФайл = Новый Файл(ОбъединитьПути(КаталогРепозитория, ЖурналИзменений[Ит].ИмяФайла));
Лог.Отладка("Анализируется файл <%1>", АнализируемыйФайл.Имя);
Для Каждого СценарийОбработки Из СценарииОбработки Цикл
ФайлОбработан = СценарийОбработки.Сценарий.ОбработатьФайл(АнализируемыйФайл, ТекущийКаталогИсходныхФайлов, ПараметрыОбработки);
Если ФайлОбработан Тогда
Для каждого ФайлДляДопОбработки Из ПараметрыОбработки.ФайлыДляПостОбработки Цикл
ЖурналИзменений.Добавить(Новый Структура("ИмяФайла, ТипИзменения", СтрЗаменить(ФайлДляДопОбработки, КаталогРепозитория, ""), ВариантИзмененийФайловGit.Изменен));
КонецЦикла;
ПараметрыОбработки.ФайлыДляПостОбработки.Очистить();
Продолжить;
КонецЕсли;
КонецЦикла;
Ит = Ит + 1;
КонецЦикла;
// измененные каталоги необходимо добавить в индекс
Лог.Отладка("Добавление измененных каталогов в индекс git");
Для Каждого Каталог Из ПараметрыОбработки.ИзмененныеКаталоги Цикл
@ -118,7 +119,7 @@
///////////////////////////////////////////////////////////////////////////////
Функция ПолучитьЖурналИзменений()
ПараметрыКомандыGit = Новый Массив;
ПараметрыКомандыGit.Добавить("diff-index --name-status --cached HEAD");
РепозиторийGit.ВыполнитьКоманду(ПараметрыКомандыGit);
@ -127,35 +128,35 @@
РепозиторийGit.ВыполнитьКоманду(ПараметрыКомандыGit);
РезультатВывода = РепозиторийGit.ПолучитьВыводКоманды();
СтрокиВывода = СтрРазделить(РезультатВывода, Символы.ПС);
ЖурналИзменений = Новый Массив;
Для Каждого СтрокаВывода Из СтрокиВывода Цикл
Лог.Отладка(" <%1>", СтрокаВывода);
СтрокаВывода = СокрЛП(СтрокаВывода);
ПозицияПробела = СтрНайти(СтрокаВывода, " ");
СимволИзменения = Лев(СтрокаВывода, 1);
Если СимволИзменения = "?" Тогда
Продолжить;
КонецЕсли;
ТипИзменения = ВариантИзмененийФайловGit.ОпределитьВариантИзменения(СимволИзменения);
ИмяФайла = СокрЛП(СтрЗаменить(Сред(СтрокаВывода, ПозицияПробела + 1), """", ""));
Если ТипИзменения = ВариантИзмененийФайловGit.Переименован Тогда
// это два события - удален и добавлен
ПозицияСтрелки = СтрНайти(ИмяФайла, "->");
ИмяФайлаУдален = СокрЛП(Лев(ИмяФайла, ПозицияСтрелки - 1));
ЖурналИзменений.Добавить(Новый Структура("ИмяФайла, ТипИзменения", ИмяФайлаУдален, ВариантИзмененийФайловGit.Удален));
Лог.Отладка(" В журнале git %2 файл <%1>", ИмяФайлаУдален, ВариантИзмененийФайловGit.Удален);
ИмяФайла = СокрЛП(Сред(ИмяФайла, ПозицияСтрелки + 2));
ТипИзменения = ВариантИзмененийФайловGit.Добавлен;
КонецЕсли;
ЖурналИзменений.Добавить(Новый Структура("ИмяФайла, ТипИзменения", ИмяФайла, ТипИзменения));
@ -167,36 +168,82 @@
КонецФункции
Процедура ЗагрузитьСценарииОбработки()
Процедура ЗагрузитьСценарииОбработки(ТекущийКаталогСценариев, УправлениеНастройками, КаталогРепозитория)
СценарииОбработки = Новый Массив;
ФайлыСценариев = НайтиФайлы(ОбъединитьПути(ТекущийСценарий().Каталог, "..", "СценарииОбработки"), "*.os");
Для Каждого ФайлСценария Из ФайлыСценариев Цикл
ФайлыГлобальныхСценариев = НайтиФайлы(ТекущийКаталогСценариев, "*.os");
ФайлыЛокальныхСценариев = Новый Массив;
ИменаЗагружаемыхСценариев = Новый Массив;
Если НЕ УправлениеНастройками.ЭтоНовый() Тогда
Если СтрСравнить(ФайлСценария.ИмяБезРасширения, "ШаблонСценария") = 0 Тогда
Продолжить;
Лог.Информация("Читаем настройки");
ИменаЗагружаемыхСценариев = УправлениеНастройками.Настройка("Precommt4onecСценарии\ГлобальныеСценарии");
Если УправлениеНастройками.Настройка("Precommt4onecСценарии\ИспользоватьСценарииРепозитория") Тогда
ЛокальныйКаталог = УправлениеНастройками.Настройка("Precommt4onecСценарии\КаталогЛокальныхСценариев");
ПутьКЛокальнымСценариям = ОбъединитьПути(КаталогРепозитория, ЛокальныйКаталог);
ФайлПутьКЛокальнымСценариям = Новый Файл(ПутьКЛокальнымСценариям);
Если Не ФайлПутьКЛокальнымСценариям.Существует() ИЛИ ФайлПутьКЛокальнымСценариям.ЭтоФайл() Тогда
Лог.Ошибка("Сценарии из репозитория не загружены т.к. отсутствует каталог %1", ЛокальныйКаталог);
Иначе
ФайлыЛокальныхСценариев = НайтиФайлы(ФайлПутьКЛокальнымСценариям.ПолноеИмя, "*.os");
КонецЕсли;
КонецЕсли;
Попытка
СценарийОбработки = ЗагрузитьСценарий(ФайлСценария.ПолноеИмя);
СценарииОбработки.Добавить(Новый Структура("ИмяСценария, Сценарий", СценарийОбработки.ИмяСценария(), СценарийОбработки));
КонецЕсли;
Исключение
Лог.Ошибка("Ошибка загрузки сценария %1: %2", ФайлСценария.ПолноеИмя, ОписаниеОшибки());
Продолжить;
КонецПопытки;
КонецЦикла;
ЗагрузитьСценарииИзКаталога(СценарииОбработки, ФайлыГлобальныхСценариев, ИменаЗагружаемыхСценариев);
ЗагрузитьСценарииИзКаталога(СценарииОбработки, ФайлыЛокальныхСценариев);
Если СценарииОбработки.Количество() = 0 Тогда
ВызватьИсключение "Нет доступных сценариев обработки файлов";
КонецЕсли;
КонецПроцедуры
Процедура ЗагрузитьСценарииИзКаталога(СценарииОбработки, ФайлыСценариев, Знач ИменаЗагружаемыхСценариев = Неопределено)
Если ИменаЗагружаемыхСценариев = Неопределено Тогда
ИменаЗагружаемыхСценариев = Новый Массив;
КонецЕсли;
Для Каждого ФайлСценария Из ФайлыСценариев Цикл
Если СтрСравнить(ФайлСценария.ИмяБезРасширения, "ШаблонСценария") = 0 Тогда
Продолжить;
КонецЕсли;
Если ИменаЗагружаемыхСценариев.Количество() И ИменаЗагружаемыхСценариев.Найти(ФайлСценария.Имя) = Неопределено Тогда
Продолжить;
КонецЕсли;
Попытка
СценарийОбработки = ЗагрузитьСценарий(ФайлСценария.ПолноеИмя);
СценарииОбработки.Добавить(Новый Структура("ИмяСценария, Сценарий", СценарийОбработки.ИмяСценария(), СценарийОбработки));
Исключение
Лог.Ошибка("Ошибка загрузки сценария %1: %2", ФайлСценария.ПолноеИмя, ОписаниеОшибки());
Продолжить;
КонецПопытки;
КонецЦикла;
КонецПроцедуры

View File

@ -0,0 +1,269 @@
///////////////////////////////////////////////////////////////////
//
// Работает с настройками в конфигурационном файле репозитория 1С
// в Git
//
// (с) BIA Technologies, LLC
//
///////////////////////////////////////////////////////////////////
#Использовать json
///////////////////////////////////////////////////////////////////
Перем ИнициализацияВыпонена; // содержит признак инициализации репозитория
Перем НовыйКонфиг; // содержит признак нового конфига
Перем Конфигурация; // описание конфигурации
Перем АдресКонфигурационногоФайла; // адрес нахождения конфигурационного файла
Перем ОбновлятьКонфигурацию; // флаг необходимости обновления конфигурации / затирания
///////////////////////////////////////////////////////////////////
// Программный интерфейс
///////////////////////////////////////////////////////////////////
// ЭтоНовый
// Возвращает признак нового конфига, т.е. отсутствие файла
//
// Возвращаемое значение:
// Булево - Признак отсутствия файла
//
Функция ЭтоНовый() Экспорт
Возврат НовыйКонфиг;
КонецФункции // ЭтоНовый()
// ГлобальныеНастройки
// Возврает набор глобальных настроек
//
// Возвращаемое значение:
// Соответствие - Набор глобальных настроек при их наличии, если настроек нет то будет возвращено пустое соответствие
//
Функция ГлобальныеНастройки() Экспорт
ПроверкаИницализации();
Возврат НастройкиПриложения("GLOBAL");
КонецФункции // ГлобальныеНастройки() Экспорт
// НастройкиПриложения
// Возврает набор настроек для приложения
//
// Параметры:
// ИмяПриложения - Строка - Имя приложения
//
// Возвращаемое значение:
// Соответствие - Набор гнастроек при их наличии, если настроек нет то будет возвращено пустое соответствие
//
Функция НастройкиПриложения(ИмяПриложения) Экспорт
ПроверкаИницализации();
Если ПустаяСтрока(ИмяПриложения) Тогда
ВызватьИсключение "Не указано имя приложения";
КонецЕсли;
ИскомыеНастройки = Конфигурация.Получить(ИмяПриложения);
Если ИскомыеНастройки = Неопределено Тогда
ИскомыеНастройки = Новый Соответствие;
КонецЕсли;
Возврат ИскомыеНастройки;
КонецФункции // НастройкиПриложения()
// Настройка
// Возвращает значение искомой настройки
//
// Параметры:
// ИмяНастройки - Строка - Имя искомой настройки. Возможные форматы
// - "МояНастройка" - для чтения глобальной настройки
// - "МоеПриложение\МояНастройка" - для чтения настройки приложения
//
// Возвращаемое значение:
// Произвольный - Значение настройки
//
Функция Настройка(ИмяНастройки)Экспорт
ПроверкаИницализации();
РазложенноеИмяНастройки = РазобратьИмяНастройки(ИмяНастройки);
ИскомоеПриложение = НастройкиПриложения(РазложенноеИмяНастройки.ИмяПриложения);
Возврат ИскомоеПриложение.Получить(РазложенноеИмяНастройки.ИмяНастройки);
КонецФункции // Настройка(ИмяНастройки)
// ЗаписатьНастройку
// Записывает настройку в конфигурационный файл
//
// Параметры:
// ИмяНастройки - Строка - Имя искомой настройки. Возможные форматы
// - "МояНастройка" - для чтения глобальной настройки
// - "МоеПриложение\МояНастройка" - для чтения настройки приложения
//
// Значение - Произвольный - Значение настройки, сериализуемое в JSON
//
Процедура ЗаписатьНастройку(ИмяНастройки, Значение) Экспорт
ПроверкаИницализации();
РазложенноеИмяНастройки = РазобратьИмяНастройки(ИмяНастройки);
ИскомоеПриложение = НастройкиПриложения(РазложенноеИмяНастройки.ИмяПриложения);
Если ОбновлятьКонфигурацию ИЛИ ИскомоеПриложение.Получить(РазложенноеИмяНастройки.ИмяНастройки) = Неопределено Тогда
ИскомоеПриложение.Вставить(РазложенноеИмяНастройки.ИмяНастройки, Значение);
КонецЕсли;
Конфигурация.Вставить(РазложенноеИмяНастройки.ИмяПриложения, ИскомоеПриложение);
ОбновитьКонфигурационныйФайл();
КонецПроцедуры // ЗаписатьНастройку(ИмяНастройки, Значение)
// ЗаписатьНастройкиПриложения
// Записывает набор настроек приложения
//
// Параметры:
// ИмяПриложения - Строка - Имя приложения
// Значение - Соответствие - Набор настроек приложения
//
Процедура ЗаписатьНастройкиПриложения(ИмяПриложения, Значение) Экспорт
ПроверкаИницализации();
Если ПустаяСтрока(ИмяПриложения) Тогда
ВызватьИсключение "Не указано имя приложения";
КонецЕсли;
Если ТипЗнч(Значение) <> Тип("Соответствие") Тогда
ВызватьИсключение "Тип значения должен быть Соответствие";
КонецЕсли;
Конфигурация.Вставить(ИмяПриложения, Значение);
ОбновитьКонфигурационныйФайл();
КонецПроцедуры // ЗаписатьНастройкиПриложения()
// УдалитьНастройкиПриложения
// Удаляет набор набор настроек приложения
//
// Параметры:
// ИмяПриложения - Строка - Имя приложения
//
Процедура УдалитьНастройкиПриложения(ИмяПриложения) Экспорт
ПроверкаИницализации();
Если ПустаяСтрока(ИмяПриложения) Тогда
ВызватьИсключение "Не указано имя приложения";
КонецЕсли;
Конфигурация.Удалить(ИмяПриложения);
ОбновитьКонфигурационныйФайл();
КонецПроцедуры // УдалитьНастройкиПриложения()
///////////////////////////////////////////////////////////////////
// Служебный функционал
///////////////////////////////////////////////////////////////////
Функция ПроверкаИницализации()
Если Не ИнициализацияВыпонена Тогда
ВызватьИсключение "Необходимо выполнить инициализацию"
КонецЕсли;
КонецФункции // ПроверкаИницализации()
Функция РазобратьИмяНастройки(Знач ИмяНастройки)
Если ПустаяСтрока(ИмяНастройки) Тогда
ВызватьИсключение "Не передано имя настройки"
КонецЕсли;
ИмяПриложения = "GLOBAL";
ПозицияРазделителя = СтрНайти(ИмяНастройки, "\");
Если ПозицияРазделителя > 0 Тогда
ИмяПриложения = Лев(ИмяНастройки, ПозицияРазделителя - 1);
ИмяНастройки = Сред(ИмяНастройки, ПозицияРазделителя + 1);
КонецЕсли;
Возврат Новый Структура("ИмяПриложения, ИмяНастройки", ИмяПриложения, ИмяНастройки);
КонецФункции // РазобратьИмяНастройки()
Функция ОбновитьКонфигурационныйФайл()
ПарсерJSON = Новый ПарсерJSON;
ТекстКонфигурации = ПарсерJSON.ЗаписатьJSON(Конфигурация);
Запись = Новый ЗаписьТекста(АдресКонфигурационногоФайла);
Запись.Записать(ТекстКонфигурации);
Запись.Закрыть();
НовыйКонфиг = ЛОЖЬ;
КонецФункции // ОбновитьКонфигурационныйФайл()
///////////////////////////////////////////////////////////////////
// ПриСозданииОбъекта
// Инициализирует объект при создании
//
// Параметры:
// КаталогРепозитория - Строка - Адрес каталога репозитория
// ОбновлятьКонф - Булево - флаг необходимости обновления конфигурации / затирания
//
Процедура ПриСозданииОбъекта(КаталогРепозитория, ОбновлятьКонф = ЛОЖЬ)
ИнициализацияВыпонена = ЛОЖЬ;
НовыйКонфиг = ЛОЖЬ;
Конфигурация = Неопределено;
АдресКонфигурационногоФайла = "";
ОбновлятьКонфигурацию = ?(ОбновлятьКонф = Неопределено, ЛОЖЬ, ОбновлятьКонф);
Файл = Новый Файл(КаталогРепозитория);
Если НЕ (Файл.Существует() И Файл.ЭтоКаталог()) Тогда
ВызватьИсключение "Каталог репозитория '" + КаталогРепозитория + "' не обнаружен либо это файл"
КонецЕсли;
АдресКонфигурационногоФайла = ОбъединитьПути(КаталогРепозитория, "v8config.json");
Файл = Новый Файл(АдресКонфигурационногоФайла);
Если Файл.Существует() Тогда
Чтение = Новый ЧтениеТекста(АдресКонфигурационногоФайла);
ТекстКонфигурации = Чтение.Прочитать();
Чтение.Закрыть();
ПарсерJSON = Новый ПарсерJSON;
Конфигурация = ПарсерJSON.ПрочитатьJSON(ТекстКонфигурации);
Иначе
НовыйКонфиг = ИСТИНА;
Конфигурация = Новый Соответствие;
КонецЕсли;
ИнициализацияВыпонена = ИСТИНА;
КонецПроцедуры // ПриСозданииОбъекта()

View File

@ -209,13 +209,27 @@
КонецФункции // ИмяПродукта
//Возвращает путь к исполняемому файлу
// Возвращает путь к исполняемому файлу
Функция ПутьКИсполняемомуФайлу() Экспорт
Возврат ОбъектНастроек.ПутьКИсполняемомуФайлу();
КонецФункции // ПутьКИсполняемомуФайлу
// Возвращает путь к каталогу основного скрипта
Функция ПутьКРодительскомуКаталогу() Экспорт
Возврат ОбъектНастроек.ПутьКРодительскомуКаталогу();
КонецФункции // ПутьКРодительскомуКаталогу
// Возвращает путь к каталогу сценариев
Функция КаталогСценариев() Экспорт
Возврат ОбъектНастроек.КаталогСценариев();
КонецФункции // КаталогСценариев
// Выводит справку по всем командам приложения
Процедура ВывестиСправкуПоКомандам() Экспорт

View File

@ -22,7 +22,7 @@
//
Функция ВерсияПродукта() Экспорт
Возврат "1.0.1";
Возврат "1.0.2";
КонецФункции // ВерсияПродукта
@ -46,10 +46,35 @@
//
Функция ПутьКИсполняемомуФайлу() Экспорт
Возврат ОбъединитьПути(ТекущийСценарий().Каталог, "..", "main.os");
Возврат ОбъединитьПути(ПутьКРодительскомуКаталогу(), "src", "main.os");
КонецФункции // ПутьКИсполняемомуФайлу
// ПутьКРодительскомуКаталогу
// Возвращает путь к каталогу основного скрипта
//
// Возвращаемое значение:
// Строка - Путь к каталогу основного скрипта
//
Функция ПутьКРодительскомуКаталогу() Экспорт
Файл = Новый Файл(ОбъединитьПути(ТекущийСценарий().Каталог, "..", ".."));
Возврат Файл.ПолноеИмя;
КонецФункции // ПутьКРодительскомуКаталогу
// КаталогСценариев
// Возвращает путь к каталогу сценариев
//
// Возвращаемое значение:
// Строка - Путь к каталогу сценариев
//
Функция КаталогСценариев() Экспорт
Возврат ОбъединитьПути(ПутьКРодительскомуКаталогу(), "src", "СценарииОбработки");
КонецФункции // КаталогСценариев
///////////////////////////////////////////////////////////////////////////////
// ЛОГИРОВАНИЕ
///////////////////////////////////////////////////////////////////////////////
@ -125,5 +150,6 @@
Приложение.ДобавитьКоманду(ИмяКомандыВерсия(), "КомандаVersion", "Выводит версию приложения");
Приложение.ДобавитьКоманду("precommit", "КомандаПрекоммит", "Выполняет сценарии precommit");
Приложение.ДобавитьКоманду("install", "КомандаИнсталл", "Выполняет подключение (установку) precommit hook'а в репозиторий");
Приложение.ДобавитьКоманду("configure", "КомандаКонфигуратион", "Выполняет настройку репозитория");
КонецПроцедуры // ПриРегистрацииКомандПриложения

10
v8config.json Normal file
View File

@ -0,0 +1,10 @@
{
"Precommt4onecСценарии": {
"ИспользоватьСценарииРепозитория": false,
"КаталогЛокальныхСценариев": "",
"ГлобальныеСценарии": [
"РазборОбычныхФормНаИсходники.os",
"РазборОтчетовОбработокРасширений.os"
]
}
}