├── .gitignore ├── README.md ├── installlocalhost.bat ├── packagedef └── src ├── cmd ├── main.os ├── Классы │ ├── КомандаВосстановление.os │ ├── КомандаИнформация.os │ ├── КомандаКонвертация.os │ ├── КомандаСохранениеДампа.os │ └── КомандаУстановкаХука.os └── Модули │ └── ПараметрыПриложения.os ├── core ├── Классы │ ├── Конвертор.os │ └── Метаданные.os └── Модули │ └── ОбщегоНазначения.os └── templates ├── pre-commit-1 ├── pre-commit-2 ├── pre-commit-3 └── pre-commit-4 /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode/ 2 | temp/ 3 | 4 | *.ospx 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Приложение для построчного версионирования файла `ParentConfigurations.bin` 2 | 3 | ## Что делает? 4 | 5 | - Делит файл на строки. Один объект поддержки - одна строка. 6 | - К каждой строке добавляется имя объекта в 1С. 7 | 8 | ## Как управлять? 9 | 10 | Приложение имеет команды 11 | - `convert` - делит исходный файл на строки и добавляет имена 1С 12 | - `restore` - склеивает файл до исходного состояния (полное совпадение с исходным, включая BOM) 13 | - `set-hook` - устанавливает хук `pre-commit` 14 | - `info` - выводит информацию о поддержке в зависимости от опций 15 | - `dump-cache` - подготавливает файл дампа конфигурации для версионирования: без идентификаторов версий и упорядоченно по имени метаданного (и идентификатору свойств) 16 | 17 | > PS: начальная реализация была выполнена через плагин `gitsync` (см. [здесь](https://github.com/240596448/gitsync-plugins/commit/8cc0744fd449ab72d108521ceb4cb57bc5adcc92)). 18 | 19 | ## Как это работает? 20 | 21 | Исходный файл состоит из множества записей `0,0,{ГУИД},{ГУИД},` записанных в одну строку 22 | Дубли `{ГУИД}` сокращаются. Каждый Гуид переносится на отдельную строку. 23 | 24 | Из файла `ConfigDumpInfo.xml` читаются сопоставления гуидов именам объектов 1С. Имена каждого объекта поддержки добавляются в каждую строку. 25 | 26 | Новые строки имеют вид `0,0,{ГУИД}, # Имя_в_1С` 27 | 28 | ## Какая польза? 29 | 30 | При снятии объекта с поддержки или изменении режима поддержки в `git diff` теперь возможно увидеть измененнения по каждому объекту. 31 | 32 | ```sh 33 | 1,0,a3f5e643-b9c4-4763-9c5d-91fc9be92710, # Configuration.ДокументооборотКОРП 34 | 0,0,7c9bc131-bc25-474d-979f-b84ebdb2145c, # Language.Русский 35 | 0,0,adbb653b-752d-45cf-8b2d-6f6030c33b43, # Subsystem.АдминистрированиеСервиса 36 | 0,0,e4993f80-2a2f-4b8e-ad88-a9e2c93472a1, # Subsystem.АдминистрированиеСервиса.Subsystem.ОбластиДанных 37 | 0,0,b913837a-e6bf-4de3-8b61-9b742a1947ba, # Subsystem.АдминистрированиеСервиса.Subsystem.ОчередьЗаданий 38 | 0,0,000932fc-f508-4326-93c6-e2351be1cf25, # Subsystem.АдминистрированиеСервиса.Subsystem.ПоставляемыеДанные 39 | 0,0,4d475095-19b1-45f0-8864-d6f161f6da1a, # Subsystem.АдминистрированиеСервиса.Subsystem.РазмерПриложений 40 | 0,0,b0c18399-297a-4617-9d6e-3c02294ebd35, # Subsystem.АдминистрированиеСервиса.Subsystem.Сообщения 41 | 0,0,69f8b7f9-a81b-4b6a-88f7-2f2dccc11717, # Subsystem.АдминистрированиеСервиса.Subsystem.Тарификация 42 | ... 43 | ``` 44 | 45 | Командой `info` можно вывести объекты добавленные в конфигурацию (объекты без поддержки, см.опцию `--added`). 46 | Или посмотреть Все объекты снятые с подержки. (см.опцию `--filter`). Это так же можно сделать следующим скриптом. 47 | 48 | ```sh 49 | grep ^[^0],-?0, src/Ext/ParentConfigurations.bin | perl -pe 's/,\w{8}-\w{4}-\w{4}-\w{4}-\w{12},//' 50 | ``` 51 | 52 | ## Известные фишки 53 | 54 | - `{6,0,3,...` 55 | - первая цифра `6` ...? (всегда одинакова); 56 | - вторая цифра `0` - флаг _Включить возможность изменения_ поддержки: `1` - изменение запрещено, `0` - изменение разрешено; 57 | - третья цифра `3` - количество поставок в файле; 58 | 59 | - _{6,0,3,ГУИД,0,ГУИД,"2.5.12.147","Фирма ""1С""","УправлениеПредприятием"_,`137634`,... 60 | - последнее число - количество объектов в каждой поставке; 61 | 62 | - `0,0,`_ГУИД_ 63 | - первая цифра - вариант поддержки (см. [здесь](https://github.com/Stepa86/v8metadata-reader/blob/61b53bda9b90e8d21b38c1a60873ee9991aa8421/src/%D0%9A%D0%BB%D0%B0%D1%81%D1%81%D1%8B/%D0%9F%D0%BE%D0%B4%D0%B4%D0%B5%D1%80%D0%B6%D0%BA%D0%B0.os#L40), спасибо автору) 64 | 65 | - 0 - на замке 66 | - 1 - на поддержке 67 | - 2 - снято с поддержки 68 | - 3 - нет поддержки 69 | - 4 - не удалось определить уровень поддержки. 70 | 71 | - вторая цифра режим поставки 72 | - 0 - изменения разрешены 73 | - 1 - измерения не рекомендуются 74 | - 2 - изменения запрещены 75 | - -1 - включение в конфигурацию не рекомендуется 76 | 77 | 78 | - в последней строке `0,0,0,1,0,0,0,1,0,1,0,1,1,1,1,1,1,1,0,1,0,1,1,1,1,0,0,1,0,1,0,1,1,1,1}` каждые 10 цифр (с конца) принадлежат отдельной поставке. Предположительно являются флагами настроек обновления. 79 | -------------------------------------------------------------------------------- /installlocalhost.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | SET OSPX_DIR=temp_ospx 3 | md %OSPX_DIR% 2> nul 4 | del %OSPX_DIR%\*.ospx 2> nul 5 | call opm build -m ./packagedef -o ./%OSPX_DIR%/ 6 | call opm install -f ./%OSPX_DIR%/*.ospx 7 | del %OSPX_DIR%\*.ospx 8 | rd %OSPX_DIR% 9 | echo Installation completed successfully... 10 | -------------------------------------------------------------------------------- /packagedef: -------------------------------------------------------------------------------- 1 | Описание.Имя("ParentConfigConverter") 2 | .Версия("1.4.1") 3 | .Автор("Vladimir Nadulich") 4 | .АдресАвтора("vladimir.nadulich@gmail.com") 5 | .ВерсияСреды("1.8.4") 6 | .ВключитьФайл("src") 7 | .ВключитьФайл("README.md") 8 | .ЗависитОт("logos", "1.4.0") 9 | .ЗависитОт("cli", "0.10.2") 10 | .ЗависитОт("fs", "1.2.0") 11 | .ИсполняемыйФайл("src/cmd/main.os", "ParentConfigConverter"); 12 | -------------------------------------------------------------------------------- /src/cmd/main.os: -------------------------------------------------------------------------------- 1 | #Использовать cli 2 | #Использовать "../core" 3 | #Использовать "." 4 | /////////////////////////////////////////////////////////////////////////////// 5 | 6 | Процедура ВыполнитьПриложение() 7 | 8 | Приложение = Новый КонсольноеПриложение(ПараметрыПриложения.Имя(), "Преобразование файла ParentConfigurations.bin для версионирования в git"); 9 | Приложение.Версия("v version", ПараметрыПриложения.Версия()); 10 | 11 | Приложение.ДобавитьКоманду("c convert", "Преобразование файла в построчный формат", Новый КомандаКонвертация); 12 | Приложение.ДобавитьКоманду("r restore", "Восстановление файла", Новый КомандаВосстановление); 13 | Приложение.ДобавитьКоманду("h set-hook", "Установка хука pre-commit в git репозиторий", Новый КомандаУстановкаХука); 14 | Приложение.ДобавитьКоманду("info", "Вывод информации по поддержке", Новый КомандаИнформация); 15 | Приложение.ДобавитьКоманду("dc dump-cache", "Версионирование dump-файла ConfigDumpInfo упорядоченно и без идентификаторов версий", Новый КомандаСохранениеДампа); 16 | 17 | Приложение.Запустить(АргументыКоманднойСтроки); 18 | 19 | КонецПроцедуры 20 | 21 | /////////////////////////////////////////////////////// 22 | 23 | Лог = ПараметрыПриложения.Лог(); 24 | 25 | Попытка 26 | ВыполнитьПриложение(); 27 | Исключение 28 | Лог.КритичнаяОшибка(ОписаниеОшибки()); 29 | ЗавершитьРаботу(1); 30 | КонецПопытки; 31 | -------------------------------------------------------------------------------- /src/cmd/Классы/КомандаВосстановление.os: -------------------------------------------------------------------------------- 1 | Процедура ОписаниеКоманды(Команда) Экспорт 2 | 3 | Команда.Аргумент("REPO", ".", "Путь к git-репозиторию") 4 | .ТСтрока(); 5 | 6 | Команда.Опция("in mod", "mod/ParentConfigurations_mod.bin", 7 | "Относительный путь к сконвертированному файлу ParentConfigurations_mod.bin внутри репозитория") 8 | .ТСтрока(); 9 | 10 | Команда.Опция("out orig", "src/Ext/ParentConfigurations.bin", 11 | "Относительный путь к восстановленному файлу внутри репозитория") 12 | .ТСтрока(); 13 | 14 | Команда.Опция("dump-recovery", "", 15 | "Относительный путь к файлу пар Id-Name файлу внутри репозитория. Значения будут восстановлены из модифицированного файла (опция --in)") 16 | .ТСтрока(); 17 | 18 | КонецПроцедуры 19 | 20 | // Выполняет логику команды 21 | Процедура ВыполнитьКоманду(Знач Команда) Экспорт 22 | 23 | Лог = ПараметрыПриложения.Лог(); 24 | 25 | КаталогРепозитория = Команда.ЗначениеАргумента("REPO"); 26 | ПутьККонвертированномуФайлу = Команда.ЗначениеОпции("in"); 27 | ПутьКВосстановленномуФайлу = Команда.ЗначениеОпции("out"); 28 | ВосстановитьДанныеДампФайла = Команда.ЗначениеОпции("dump-recovery"); 29 | 30 | Файл = Новый Файл(КаталогРепозитория); 31 | КаталогРепозитория = Файл.ПолноеИмя; 32 | 33 | УстановитьТекущийКаталог(КаталогРепозитория); 34 | 35 | Файл = Новый Файл(ПутьКВосстановленномуФайлу); 36 | Если Файл.Существует() И Файл.ЭтоКаталог() Тогда 37 | Лог.Ошибка("Файл --out=%1 не может быть каталогом", ПутьКВосстановленномуФайлу); 38 | ВызватьИсключение ""; 39 | КонецЕсли; 40 | 41 | ИмяВременногоФайлаЦелевой = ПолучитьИмяВременногоФайла(); 42 | 43 | Конвертор = Новый Конвертор(КаталогРепозитория); 44 | Успех = Конвертор.ВыполнитьВосстановление(ПутьККонвертированномуФайлу, ИмяВременногоФайлаЦелевой); 45 | // Успех = Истина; 46 | Если НЕ Успех Тогда 47 | Лог.Предупреждение("Восстановление файла поддержки не выполнено. Нет данных к восстановлению."); 48 | Возврат; 49 | КонецЕсли; 50 | 51 | Если НЕ ЗначениеЗаполнено(ПутьКВосстановленномуФайлу) Тогда 52 | ПутьКВосстановленномуФайлу = ПутьККонвертированномуФайлу; 53 | КонецЕсли; 54 | 55 | УдалитьФайлы(ПутьКВосстановленномуФайлу); 56 | ПереместитьФайл(ИмяВременногоФайлаЦелевой, ПутьКВосстановленномуФайлу); 57 | 58 | Лог.Информация("Выполнено восстановление файла поддержки %1", ПутьКВосстановленномуФайлу); 59 | 60 | // dump-recovery 61 | Если ЗначениеЗаполнено(ВосстановитьДанныеДампФайла) Тогда 62 | Таблица = Конвертор.ПолучитьТаблицуОбъектовНаПоддержке(ПутьККонвертированномуФайлу); 63 | Метаданные = Новый Метаданные; 64 | Метаданные.Преобразовать(Таблица); 65 | Метаданные.СоздатьКэш(ВосстановитьДанныеДампФайла, Истина); 66 | 67 | Лог.Информация("Кэш идентификаторов метаданных %1 восстановлен из файла поддержки %2", ВосстановитьДанныеДампФайла, ПутьККонвертированномуФайлу); 68 | КонецЕсли; 69 | 70 | КонецПроцедуры 71 | 72 | -------------------------------------------------------------------------------- /src/cmd/Классы/КомандаИнформация.os: -------------------------------------------------------------------------------- 1 | Процедура ОписаниеКоманды(Команда) Экспорт 2 | 3 | Команда.Аргумент("SRC", ".", "Путь к каталогу исходников src или другая папка, относительно которй будут указаны пути опций file и dump") 4 | .ТСтрока() 5 | .Обязательный(Истина); 6 | 7 | Команда.Опция("file", "Ext/ParentConfigurations.bin", 8 | "Относительный путь к файлу ParentConfigurations.bin внутри каталога исходников") 9 | .ТСтрока(); 10 | 11 | Команда.Опция("dump", "ConfigDumpInfo.xml", 12 | "Путь к файлу ConfigDumpInfo.xml внутри каталога исходников") 13 | .ТСтрока(); 14 | 15 | Команда.Опция("added", False, "Вывести в консоль объекты без поддержки (добавленные в основную конефигурацию), булево") 16 | .Флаг(); 17 | 18 | Команда.Опция("filter", "", "Вывести в консоль объекты с определенным статусом поддержки в формате '\d,\d' (например, '1,0')") 19 | .ТСтрока(); 20 | 21 | КонецПроцедуры 22 | 23 | // Выполняет логику команды 24 | Процедура ВыполнитьКоманду(Знач Команда) Экспорт 25 | 26 | Лог = ПараметрыПриложения.Лог(); 27 | 28 | КаталогИсходников = Команда.ЗначениеАргумента("SRC"); 29 | ПутьКФайлуПоддержки = Команда.ЗначениеОпции("file"); 30 | ПутьКФайлуДампа = Команда.ЗначениеОпции("dump"); 31 | 32 | ОпцияБезПоддержки = Команда.ЗначениеОпции("added"); 33 | ОпцияФильроватьПоСтатусу = Команда.ЗначениеОпции("filter"); 34 | 35 | Если НЕ ОпцияБезПоддержки 36 | И НЕ ЗначениеЗаполнено(ОпцияФильроватьПоСтатусу) Тогда 37 | Лог.Предупреждение("Не выбрана ни одна опция вывода информации. Укажите опции 'added' и(или) 'filter'"); 38 | Возврат; 39 | КонецЕсли; 40 | 41 | Файл = Новый Файл(КаталогИсходников); 42 | КаталогИсходников = Файл.ПолноеИмя; 43 | 44 | УстановитьТекущийКаталог(КаталогИсходников); 45 | 46 | Метаданные = Новый Метаданные(); 47 | Метаданные.ОпределитьИменаМетаданных(ПутьКФайлуДампа); 48 | СоответствиеИменID = Метаданные.СоответствиеИменID(); 49 | 50 | Конвертор = Новый Конвертор(КаталогИсходников); 51 | Таблица = Конвертор.ПолучитьТаблицуОбъектовНаПоддержке(ПутьКФайлуПоддержки); 52 | 53 | СоотвествиеIDПоддержки = Новый Соответствие(); 54 | Для каждого Стр Из Таблица Цикл 55 | СоотвествиеIDПоддержки.Вставить(Стр.ГУИД, Стр.Режим); 56 | КонецЦикла; 57 | 58 | Если ОпцияБезПоддержки Тогда 59 | Сообщить(" --- Объекты без поддержки (добавленные в конфигурацию) --- "); 60 | Для каждого КЗ Из СоответствиеИменID Цикл 61 | Если СоотвествиеIDПоддержки[КЗ.Ключ] = Неопределено Тогда 62 | Сообщить(КЗ.Значение); 63 | КонецЕсли; 64 | КонецЦикла; 65 | КонецЕсли; 66 | 67 | Если ЗначениеЗаполнено(ОпцияФильроватьПоСтатусу) Тогда 68 | Сообщить(" --- Объекты со статусом поддержки '" + ОпцияФильроватьПоСтатусу + "' --- "); 69 | Для каждого Стр Из Таблица Цикл 70 | Если Стр.Режим = ОпцияФильроватьПоСтатусу Тогда 71 | Если ЗначениеЗаполнено(Стр.Имя) Тогда 72 | Сообщить(Стр.Имя); 73 | ИначеЕсли СоответствиеИменID[Стр.ГУИД] <> Неопределено Тогда 74 | // для неконвертированного файла 75 | Сообщить(СоответствиеИменID[Стр.ГУИД]); 76 | КонецЕсли; 77 | 78 | // данный способ сопоставления намеренно упрощен по сравнению с конвертацией 79 | // гуиды в файле поддержки могут повторяться, если поставок несколько 80 | // тогда в основной поставке будет парный гуид, а в "дополнительных" - непарный, часто с режимом 2,0 81 | 82 | КонецЕсли; 83 | КонецЦикла; 84 | КонецЕсли; 85 | 86 | КонецПроцедуры 87 | 88 | -------------------------------------------------------------------------------- /src/cmd/Классы/КомандаКонвертация.os: -------------------------------------------------------------------------------- 1 | 2 | Процедура ОписаниеКоманды(Команда) Экспорт 3 | 4 | Команда.Аргумент("REPO", ".", "Путь к git-репозиторию") 5 | .ТСтрока(); 6 | 7 | Команда.Опция("dump", "src/ConfigDumpInfo.xml", 8 | "Путь к файлу ConfigDump* внутри репозитория для получения соотвествия Id-Name. Файл должен содержать строки вида 'name=""Имя"" id=""Гуид""'") 9 | .ТСтрока(); 10 | 11 | Команда.Опция("in orig", "src/Ext/ParentConfigurations.bin", 12 | "Относительный путь к файлу ParentConfigurations.bin внутри репозитория") 13 | .ТСтрока(); 14 | 15 | Команда.Опция("out mod", "src/Ext/ParentConfigurations_mod.bin", 16 | "Относительный путь к сконвертированному файлу внутри репозитория") 17 | .ТСтрока(); 18 | 19 | Команда.Опция("dump-cache", "", 20 | "Сохранять пары Name-Id, полученные из дампа, в отдельный файл (например, mod/ConfigID.xml)") 21 | .ТСтрока(); 22 | 23 | Команда.Опция("clear", Ложь, 24 | "Удалять устаревшие ГУИДЫ без сопоставления с метаданными") 25 | .Флаг(); 26 | 27 | КонецПроцедуры 28 | 29 | // Выполняет логику команды 30 | Процедура ВыполнитьКоманду(Знач Команда) Экспорт 31 | 32 | Лог = ПараметрыПриложения.Лог(); 33 | 34 | КаталогРепозитория = Команда.ЗначениеАргумента("REPO"); 35 | ПутьКФайлуПоддержки = Команда.ЗначениеОпции("in"); 36 | ПутьКНовомуФайлуПоддержки = Команда.ЗначениеОпции("out"); 37 | ПутьКФайлуДампа = Команда.ЗначениеОпции("dump"); 38 | ПутьКФайлуКэшаИдентификаторов = Команда.ЗначениеОпции("dump-cache"); 39 | ОчищатьГуидыБезСопоставлений = Команда.ЗначениеОпции("clear"); 40 | 41 | Файл = Новый Файл(КаталогРепозитория); 42 | КаталогРепозитория = Файл.ПолноеИмя; 43 | 44 | УстановитьТекущийКаталог(КаталогРепозитория); 45 | 46 | Файл = Новый Файл(ПутьКФайлуПоддержки); 47 | Если Файл.Размер() < 20 Тогда 48 | Лог.Информация("Конвертация файла поддержки не выполнена. Вероятно конфигурация снята с поддержки."); 49 | Возврат; 50 | КонецЕсли; 51 | 52 | Файл = Новый Файл(ПутьКНовомуФайлуПоддержки); 53 | Если Файл.Существует() И Файл.ЭтоКаталог() Тогда 54 | Лог.Ошибка("Файл --out=%1 не может быть каталогом", ПутьКНовомуФайлуПоддержки); 55 | ВызватьИсключение ""; 56 | КонецЕсли; 57 | 58 | ОбщегоНазначения.ПодготовитьФайлКЗаписи(ПутьКНовомуФайлуПоддержки); 59 | ОбщегоНазначения.ПодготовитьФайлКЗаписи(ПутьКФайлуКэшаИдентификаторов); 60 | 61 | ИмяВременногоФайлаИсходный = ПолучитьИмяВременногоФайла(); 62 | КопироватьФайл(ПутьКФайлуПоддержки, ИмяВременногоФайлаИсходный); 63 | 64 | ИмяВременногоФайлаЦелевой = ПолучитьИмяВременногоФайла(); 65 | 66 | Метаданные = Новый Метаданные(); 67 | Метаданные.ОпределитьИменаМетаданных(ПутьКФайлуДампа); 68 | Если ЗначениеЗаполнено(ПутьКФайлуКэшаИдентификаторов) Тогда 69 | Метаданные.СоздатьКэш(ПутьКФайлуКэшаИдентификаторов, Истина); 70 | КонецЕсли; 71 | 72 | Конвертор = Новый Конвертор(КаталогРепозитория); 73 | Ошибка = Конвертор.ВыполнитьКонвертацию(Метаданные, ИмяВременногоФайлаИсходный, ИмяВременногоФайлаЦелевой, ОчищатьГуидыБезСопоставлений); 74 | 75 | Если НЕ ПустаяСтрока(Ошибка) Тогда 76 | УдалитьФайлы(ИмяВременногоФайлаИсходный); 77 | УдалитьФайлы(ИмяВременногоФайлаЦелевой); 78 | Лог.Ошибка(Ошибка); 79 | Возврат; 80 | КонецЕсли; 81 | 82 | ПереместитьФайл(ИмяВременногоФайлаЦелевой, ПутьКНовомуФайлуПоддержки); 83 | Лог.Информация("Выполнена конвертация файла поддержки %1 в файл %2", ПутьКФайлуПоддержки, ПутьКНовомуФайлуПоддержки); 84 | 85 | УдалитьФайлы(ИмяВременногоФайлаИсходный); 86 | 87 | КонецПроцедуры 88 | -------------------------------------------------------------------------------- /src/cmd/Классы/КомандаСохранениеДампа.os: -------------------------------------------------------------------------------- 1 | 2 | Процедура ОписаниеКоманды(Команда) Экспорт 3 | 4 | Команда.Аргумент("REPO", ".", "Путь к git-репозиторию") 5 | .ТСтрока(); 6 | 7 | Команда.Опция("in dump", "src/ConfigDumpInfo.xml", 8 | "Путь к файлу ConfigDump* внутри репозитория для получения соотвествия Id-Name. Файл должен содержать строки вида 'name=""Имя"" id=""Гуид""'") 9 | .ТСтрока(); 10 | 11 | Команда.Опция("out file", "mod/ConfigID.xml", 12 | "Сохранять пары Name-Id, полученные из дампа, в отдельный файл") 13 | .ТСтрока(); 14 | 15 | КонецПроцедуры 16 | 17 | // Выполняет логику команды 18 | Процедура ВыполнитьКоманду(Знач Команда) Экспорт 19 | 20 | Лог = ПараметрыПриложения.Лог(); 21 | 22 | КаталогРепозитория = Команда.ЗначениеАргумента("REPO"); 23 | ПутьКФайлуДампа = Команда.ЗначениеОпции("dump"); 24 | ПутьКФайлуКэшаИдентификаторов = Команда.ЗначениеОпции("file"); 25 | 26 | Файл = Новый Файл(КаталогРепозитория); 27 | КаталогРепозитория = Файл.ПолноеИмя; 28 | 29 | УстановитьТекущийКаталог(КаталогРепозитория); 30 | 31 | Если НЕ ФС.ФайлСуществует(ПутьКФайлуДампа) Тогда 32 | Лог.Предупреждение("Отсуствует исходный дамп-файл %1", ПутьКФайлуДампа); 33 | Возврат; 34 | КонецЕсли; 35 | 36 | ОбщегоНазначения.ПодготовитьФайлКЗаписи(ПутьКФайлуКэшаИдентификаторов); 37 | 38 | Метаданные = Новый Метаданные(); 39 | Метаданные.ОпределитьИменаМетаданных(ПутьКФайлуДампа); 40 | Если ЗначениеЗаполнено(ПутьКФайлуКэшаИдентификаторов) Тогда 41 | Метаданные.СоздатьКэш(ПутьКФайлуКэшаИдентификаторов, Истина); 42 | КонецЕсли; 43 | 44 | Лог.Информация("Сохранен кэш дамп-файла %1 в файл %2", ПутьКФайлуДампа, ПутьКФайлуКэшаИдентификаторов); 45 | 46 | КонецПроцедуры 47 | -------------------------------------------------------------------------------- /src/cmd/Классы/КомандаУстановкаХука.os: -------------------------------------------------------------------------------- 1 | Процедура ОписаниеКоманды(Команда) Экспорт 2 | 3 | Команда.Аргумент("REPO", , 4 | "Путь к git-репозиторию для установки hook pre-commit") 5 | .ТСтрока() 6 | .Обязательный(Истина); 7 | 8 | Команда.Опция("hv hook-version", 1, "Вариант хука (см templates) 9 | | - 1: конвертация без создания файла кэша 10 | | - 2: grep-кэш (без сортировки) + чтение сопоставлений из кэш-файла + конвертация 11 | | - 3: чтение дампа 1С + кэширование с сортировкой (при конвертации) + конвертация 12 | | - 4: кэширование с сортировкой (при конвертации) 13 | | ") 14 | .ТЧисло() 15 | .Обязательный(Истина); 16 | 17 | Команда.Опция("in orig", "src/Ext/ParentConfigurations.bin", 18 | "Относительный путь к файлу ParentConfigurations.bin внутри репозитория") 19 | .ТСтрока(); 20 | 21 | Команда.Опция("out mod", "src/Ext/ParentConfigurations_mod.bin", 22 | "Относительный путь к сконвертированному файлу внутри репозитория") 23 | .ТСтрока(); 24 | 25 | Команда.Опция("dump", "src/ConfigDumpInfo.xml", 26 | "Путь к файлу ConfigDump* внутри репозитория для получения соотвествия Id-Name. Файл должен содержать строки вида 'name=""Имя"" id=""Гуид""' 27 | | ") 28 | .ТСтрока(); 29 | 30 | Команда.Опция("dump-cache", "mod/ConfigID.xml", 31 | "Сохранять пары Name-Id, полученные из дампа, в отдельный файл (например, mod/ConfigID.xml)") 32 | .ТСтрока(); 33 | 34 | КонецПроцедуры 35 | 36 | // Выполняет логику команды 37 | Процедура ВыполнитьКоманду(Знач Команда) Экспорт 38 | 39 | ВариантШаблона = Команда.ЗначениеОпции("hv"); 40 | 41 | КаталогРепозитория = Команда.ЗначениеАргумента("REPO"); 42 | ПутьКФайлуПоддержки = Команда.ЗначениеОпции("in"); 43 | ПутьКНовомуФайлуПоддержки = Команда.ЗначениеОпции("out"); 44 | ПутьКФайлуДампа = Команда.ЗначениеОпции("dump"); 45 | ПутьКФайлуКэшаИдентификаторов = Команда.ЗначениеОпции("dump-cache"); 46 | 47 | ФайлПуть = Новый Файл(КаталогРепозитория); 48 | Если НЕ ФайлПуть.ЭтоКаталог() Тогда 49 | ВызватьИсключение СтрШаблон("Путь %1 не является каталогом. Укажите каталог репозитория", КаталогРепозитория); 50 | КонецЕсли; 51 | 52 | Файлы = НайтиФайлы(КаталогРепозитория, ".git", Истина); 53 | Если Файлы.Количество() = 0 Тогда 54 | ВызватьИсключение СтрШаблон("GIT-репозиторий не найден или не инициализирован: %1", ФайлПуть.ПолноеИмя); 55 | 56 | ИначеЕсли Файлы.Количество() > 1 Тогда 57 | ТекстОшибки = Новый Массив(); 58 | ТекстОшибки.Добавить(СтрШаблон("Обнаружено более одного GIT-репозитория в папке: %1", ФайлПуть.ПолноеИмя)); 59 | Для каждого Файл Из Файлы Цикл 60 | ТекстОшибки.Добавить(Файл.ПолноеИмя); 61 | КонецЦикла; 62 | ВызватьИсключение СтрСоединить(ТекстОшибки, Символы.ПС); 63 | 64 | ИначеЕсли НЕ Файлы[0].ЭтоКаталог() Тогда 65 | ВызватьИсключение "Файл .git не является каталогом" 66 | 67 | КонецЕсли; 68 | 69 | ПутьКHooks = ОбъединитьПути(Файлы[0].ПолноеИмя, "hooks"); 70 | ПутьКPrecommit = ОбъединитьПути(ПутьКHooks, "pre-commit"); 71 | ИмяПриложения = ПараметрыПриложения.Имя(); 72 | 73 | ПутьКШаблонам = ПараметрыПриложения.ПутьКШаблонам(); 74 | ТекстШаблона = ОбщегоНазначения.ПрочитатьФайлВТекст(ОбъединитьПути(ПутьКШаблонам, "pre-commit-" + ВариантШаблона)); 75 | 76 | Файл = Новый Файл(ПутьКPrecommit); 77 | Если Файл.Существует() Тогда 78 | Текст = ОбщегоНазначения.ПрочитатьФайлВТекст(ПутьКPrecommit); 79 | НовыйТекст = Новый Массив(); 80 | Для НомерСтроки = 1 По СтрЧислоСтрок(Текст) Цикл 81 | Строка = СтрПолучитьСтроку(Текст, НомерСтроки); 82 | Если НЕ ПустаяСтрока(Строка) И СтрНайти(Строка, ИмяПриложения) = 0 Тогда 83 | НовыйТекст.Добавить(Строка); 84 | КонецЕсли; 85 | КонецЦикла; 86 | Если ПустаяСтрока(СокрЛП(СтрСоединить(НовыйТекст, ""))) Тогда 87 | НачальнаяСтрока = 1; 88 | Иначе 89 | НачальнаяСтрока = 2; 90 | КонецЕсли; 91 | Для НомерСтроки = НачальнаяСтрока По СтрЧислоСтрок(ТекстШаблона) Цикл 92 | НовыйТекст.Добавить(СтрПолучитьСтроку(ТекстШаблона, НомерСтроки)); 93 | КонецЦикла; 94 | ТекстФайла = СтрСоединить(НовыйТекст, Символы.ПС); 95 | Сообщить("Дополнен файл хука: " + ПутьКPrecommit); 96 | Иначе 97 | ТекстФайла = ТекстШаблона; 98 | Сообщить("Создан файл хука: " + ПутьКPrecommit); 99 | КонецЕсли; 100 | 101 | ТекстФайла = СтрЗаменить(ТекстФайла, "{appname}", ИмяПриложения); 102 | ТекстФайла = СтрЗаменить(ТекстФайла, "{repo}", КаталогРепозитория); 103 | ТекстФайла = СтрЗаменить(ТекстФайла, "{in_file}", ПутьКФайлуПоддержки); 104 | ТекстФайла = СтрЗаменить(ТекстФайла, "{out_file}", ПутьКНовомуФайлуПоддержки); 105 | ТекстФайла = СтрЗаменить(ТекстФайла, "{dump_file}", ПутьКФайлуДампа); 106 | ТекстФайла = СтрЗаменить(ТекстФайла, "{dump_cache}", ПутьКФайлуКэшаИдентификаторов); 107 | 108 | ЗаписьТекста = Новый ЗаписьТекста(ПутьКPrecommit, КодировкаТекста.UTF8NoBOM, Символы.ПС, Ложь, Символы.ПС); 109 | ЗаписьТекста.Записать(ТекстФайла); 110 | ЗаписьТекста.Закрыть(); 111 | 112 | Сообщить("Хук pre-commit установлен"); 113 | 114 | СисИнфо = Новый СистемнаяИнформация; 115 | ЭтоWindows = Найти(НРег(СисИнфо.ВерсияОС), "windows") > 0; 116 | Если НЕ ЭтоWindows Тогда 117 | ЗапуститьПриложение("chmod +x " + ПутьКPrecommit); 118 | КонецЕсли; 119 | 120 | КонецПроцедуры -------------------------------------------------------------------------------- /src/cmd/Модули/ПараметрыПриложения.os: -------------------------------------------------------------------------------- 1 | #Использовать logos 2 | 3 | Перем Лог; 4 | 5 | Функция Имя() Экспорт 6 | 7 | Возврат "ParentConfigConverter"; 8 | 9 | КонецФункции 10 | 11 | Функция Версия() Экспорт 12 | 13 | Возврат "1.4.1"; 14 | 15 | КонецФункции 16 | 17 | Функция ИмяЛога() Экспорт 18 | 19 | Возврат "oscript.app.parentconfig"; 20 | 21 | КонецФункции 22 | 23 | Функция Лог() Экспорт 24 | 25 | Если Лог = Неопределено Тогда 26 | Лог = Логирование.ПолучитьЛог(ИмяЛога()); 27 | КонецЕсли; 28 | 29 | Возврат Лог; 30 | 31 | КонецФункции 32 | 33 | Функция ПутьКШаблонам() Экспорт 34 | 35 | Возврат ОбъединитьПути(СтартовыйСценарий().Каталог, "..", "templates"); 36 | 37 | КонецФункции 38 | -------------------------------------------------------------------------------- /src/core/Классы/Конвертор.os: -------------------------------------------------------------------------------- 1 | 2 | Перем КаталогРепозитория; 3 | 4 | Процедура ПриСозданииОбъекта(Знач ПутьККаталогуРепозитория) Экспорт 5 | 6 | КаталогРепозитория = ПутьККаталогуРепозитория; 7 | 8 | Если НЕ ЗначениеЗаполнено(КаталогРепозитория) Тогда 9 | ВызватьИсключение "Каталог репозитория не указан"; 10 | КонецЕсли; 11 | Файл = Новый Файл(КаталогРепозитория); 12 | Если НЕ Файл.Существует() Или НЕ Файл.ЭтоКаталог() Тогда 13 | ВызватьИсключение "Каталог репозитория не существует: " + Файл.ПолноеИмя; 14 | КонецЕсли; 15 | 16 | КонецПроцедуры 17 | 18 | Функция ВыполнитьКонвертацию(Метаданные, Источник, Приемник, ОчищатьГуидыБезСопоставлений) Экспорт 19 | 20 | СоответствиеИменID = Метаданные.СоответствиеИменID(); 21 | 22 | ТекстСодержимогоФайла = ОбщегоНазначения.ПрочитатьФайлВТекст(Источник); 23 | Если СтрЧислоСтрок(ТекстСодержимогоФайла) > 1 Тогда 24 | Возврат "Конвертация файла поддержки не требуется. Файл уже сконвентирован."; 25 | КонецЕсли; 26 | 27 | РВ = Новый РегулярноеВыражение("(\d,-?\d,)(\w{8}-\w{4}-\w{4}-\w{4}-\w{12},)\2"); // парные повторяющиеся гуиды 28 | ТекстИзмененный = РВ.Заменить(ТекстСодержимогоФайла, Символы.ПС + "$1$2 #" + Символы.ПС); 29 | 30 | РВ = Новый РегулярноеВыражение("(\d,-?\d,)(\w{8}-\w{4}-\w{4}-\w{4}-\w{12},){2}"); // не парные гуиды 31 | ТекстИзмененный = РВ.Заменить(ТекстИзмененный, Символы.ПС + "$0 #" + Символы.ПС); 32 | 33 | мТекстИзмененный = СтрРазделить(ТекстИзмененный, Символы.ПС, Ложь); 34 | 35 | СконвертированныйТекст = Новый Массив(); 36 | 37 | // подстановка имен в парные гуиды 38 | РВ_ПарныеГуиды = Новый РегулярноеВыражение("\d,-?\d,(\w{8}-\w{4}-\w{4}-\w{4}-\w{12}), #"); 39 | РВ_РазныеГуиды = Новый РегулярноеВыражение("\d,-?\d,(\w{8}-\w{4}-\w{4}-\w{4}-\w{12}),(\w{8}-\w{4}-\w{4}-\w{4}-\w{12}), #"); 40 | Для Каждого Стр Из мТекстИзмененный Цикл 41 | Совпадения1 = РВ_ПарныеГуиды.НайтиСовпадения(Стр); 42 | Если Совпадения1.Количество() Тогда 43 | ID = Совпадения1[0].Группы[1].Значение; 44 | ИмяМета = СоответствиеИменID[ID]; 45 | Если ИмяМета = Неопределено Тогда 46 | Если ОчищатьГуидыБезСопоставлений Тогда 47 | Продолжить; 48 | КонецЕсли; 49 | ИмяМета = ""; 50 | КонецЕсли; 51 | Если ЗначениеЗаполнено(ИмяМета) Тогда 52 | Стр = Стр + " " + ИмяМета; 53 | КонецЕсли; 54 | Иначе 55 | Совпадения2 = РВ_РазныеГуиды.НайтиСовпадения(Стр); 56 | Если Совпадения2.Количество() Тогда 57 | ID1 = Совпадения2[0].Группы[1].Значение; 58 | ID2 = Совпадения2[0].Группы[2].Значение; 59 | Если СоответствиеИменID[ID1] <> Неопределено Тогда 60 | ИмяМета = СоответствиеИменID[ID1]; 61 | НомерИдентификатора = "1"; 62 | ИначеЕсли СоответствиеИменID[ID2] <> Неопределено Тогда 63 | ИмяМета = СоответствиеИменID[ID2]; 64 | НомерИдентификатора = "2"; 65 | ИначеЕсли ОчищатьГуидыБезСопоставлений Тогда 66 | Продолжить; 67 | Иначе 68 | ИмяМета = ""; 69 | КонецЕсли; 70 | Если ЗначениеЗаполнено(ИмяМета) Тогда 71 | Стр = СтрШаблон("%1 %2:%3", Стр, НомерИдентификатора, ИмяМета); 72 | КонецЕсли; 73 | КонецЕсли; 74 | КонецЕсли; 75 | СконвертированныйТекст.Добавить(Стр); 76 | КонецЦикла; 77 | 78 | ОбщегоНазначения.ЗаписатьТекстВФайл(Приемник, СтрСоединить(СконвертированныйТекст, Символы.ПС)); 79 | 80 | Возврат ""; 81 | 82 | КонецФункции 83 | 84 | Функция ВыполнитьВосстановление(Источник, Приемник) Экспорт 85 | 86 | ЧтениеТекста = Новый ЧтениеТекста(); 87 | ЧтениеТекста.Открыть(Источник, КодировкаТекста.UTF8); 88 | 89 | ВосстановленныйТекст = Новый Массив(); 90 | ЕстьВосстановленныеСтроки = Ложь; 91 | 92 | РВ_ПарныеГуиды = Новый РегулярноеВыражение("\d,-?\d,(\w{8}-\w{4}-\w{4}-\w{4}-\w{12},)( #.*)"); 93 | РВ_РазныеГуиды = Новый РегулярноеВыражение("\d,-?\d,(\w{8}-\w{4}-\w{4}-\w{4}-\w{12},){2}( #.*)"); 94 | Стр = ЧтениеТекста.ПрочитатьСтроку(); 95 | Пока Стр <> Неопределено Цикл 96 | Совпадения1 = РВ_ПарныеГуиды.НайтиСовпадения(Стр); 97 | Если Совпадения1.Количество() Тогда 98 | ID = Совпадения1[0].Группы[1].Значение; 99 | ИмяМета = Совпадения1[0].Группы[2].Значение; 100 | Стр = СтрЗаменить(Стр, ИмяМета, ID); 101 | ЕстьВосстановленныеСтроки = Истина; 102 | Иначе 103 | Совпадения2 = РВ_РазныеГуиды.НайтиСовпадения(Стр); 104 | Если Совпадения2.Количество() Тогда 105 | ИмяМета = Совпадения2[0].Группы[2].Значение; 106 | Стр = СтрЗаменить(Стр, ИмяМета, ""); 107 | ЕстьВосстановленныеСтроки = Истина; 108 | КонецЕсли; 109 | КонецЕсли; 110 | ВосстановленныйТекст.Добавить(Стр); 111 | Стр = ЧтениеТекста.ПрочитатьСтроку(); 112 | КонецЦикла; 113 | 114 | ЧтениеТекста.Закрыть(); 115 | 116 | Если ЕстьВосстановленныеСтроки Тогда 117 | ОбщегоНазначения.ЗаписатьТекстВФайл(Приемник, СтрСоединить(ВосстановленныйТекст, "")); 118 | КонецЕсли; 119 | 120 | Возврат ЕстьВосстановленныеСтроки; 121 | 122 | КонецФункции 123 | 124 | Функция ПолучитьТаблицуОбъектовНаПоддержке(Источник) Экспорт 125 | 126 | Таблица = Новый ТаблицаЗначений(); 127 | Таблица.Колонки.Добавить("ГУИД"); // Основной идентификатор 128 | Таблица.Колонки.Добавить("Режим"); // Режим поддержки 0,0 129 | Таблица.Колонки.Добавить("Имя"); // Имя объекта 1С 130 | 131 | ТекстСодержимогоФайла = ОбщегоНазначения.ПрочитатьФайлВТекст(Источник); 132 | Если СтрЧислоСтрок(ТекстСодержимогоФайла) > 1 Тогда 133 | // конвертированный файл 134 | 135 | РВ_ПарныеГуиды = Новый РегулярноеВыражение("(\d,-?\d),(\w{8}-\w{4}-\w{4}-\w{4}-\w{12}), #(.*)"); 136 | РВ_РазныеГуиды = Новый РегулярноеВыражение("(\d,-?\d),(\w{8}-\w{4}-\w{4}-\w{4}-\w{12},\w{8}-\w{4}-\w{4}-\w{4}-\w{12}), #(.*)"); 137 | МассивСтрок = СтрРазделить(ТекстСодержимогоФайла, Символы.ПС); 138 | Для каждого Стр Из МассивСтрок Цикл 139 | Совпадения1 = РВ_ПарныеГуиды.НайтиСовпадения(Стр); 140 | Если Совпадения1.Количество() Тогда 141 | СтрТаблицы = Таблица.Добавить(); 142 | СтрТаблицы.Режим = Совпадения1[0].Группы[1].Значение; 143 | СтрТаблицы.ГУИД = Совпадения1[0].Группы[2].Значение; 144 | СтрТаблицы.Имя = СокрЛП(Совпадения1[0].Группы[3].Значение); 145 | Иначе 146 | Совпадения2 = РВ_РазныеГуиды.НайтиСовпадения(Стр); 147 | Если Совпадения2.Количество() Тогда 148 | СтрТаблицы = Таблица.Добавить(); 149 | СтрТаблицы.Режим = Совпадения1[0].Группы[1].Значение; 150 | СтрТаблицы.ГУИД = Совпадения1[0].Группы[2].Значение; 151 | СтрТаблицы.Имя = СокрЛП(Совпадения1[0].Группы[3].Значение); 152 | КонецЕсли; 153 | КонецЕсли; 154 | КонецЦикла; 155 | 156 | Иначе 157 | // оригинальный файл 158 | 159 | РВ = Новый РегулярноеВыражение("(\d,-?\d),(\w{8}-\w{4}-\w{4}-\w{4}-\w{12},){2}"); 160 | Совпадения = РВ.НайтиСовпадения(ТекстСодержимогоФайла); 161 | Для каждого Совпадение Из Совпадения Цикл 162 | СтрТаблицы = Таблица.Добавить(); 163 | СтрТаблицы.Режим = Совпадение.Группы[1].Значение; 164 | ГУИД = Совпадение.Группы[2].Значение; 165 | СтрТаблицы.ГУИД = Лев(ГУИД, СтрДлина(ГУИД) - 1); 166 | КонецЦикла; 167 | 168 | КонецЕсли; 169 | 170 | Возврат Таблица; 171 | 172 | КонецФункции 173 | 174 | -------------------------------------------------------------------------------- /src/core/Классы/Метаданные.os: -------------------------------------------------------------------------------- 1 | Перем СоответствиеИменID; 2 | Перем Таблица; 3 | 4 | Процедура ПриСозданииОбъекта() Экспорт 5 | 6 | СоответствиеИменID = Новый Соответствие(); 7 | 8 | Таблица = Новый ТаблицаЗначений(); 9 | Таблица.Колонки.Добавить("Имя"); 10 | Таблица.Колонки.Добавить("ГУИД"); 11 | Таблица.Колонки.Добавить("Порядок"); 12 | 13 | КонецПроцедуры 14 | 15 | Функция СоответствиеИменID() Экспорт 16 | Возврат СоответствиеИменID; 17 | КонецФункции 18 | 19 | Функция ОпределитьИменаМетаданных(ПутьКФайлуДампа) Экспорт 20 | 21 | ТекстСодержимогоФайла = ОбщегоНазначения.ПрочитатьФайлВТекст(ПутьКФайлуДампа); 22 | 23 | // заполнение соответствия ID -> Name 24 | РВ = Новый РегулярноеВыражение("name=""(?.+?)"" id=""(?.+?)"""); 25 | Совпадения = РВ.НайтиСовпадения(ТекстСодержимогоФайла); 26 | Для каждого Совпадение Из Совпадения Цикл 27 | 28 | ГУИД = Совпадение.Группы.ПоИмени("id").Значение; 29 | Если СтрНайти(ГУИД, ".") Тогда 30 | Продолжить; 31 | КонецЕсли; 32 | Имя = Совпадение.Группы.ПоИмени("name").Значение; 33 | СоответствиеИменID.Вставить(ГУИД, Имя); 34 | 35 | СтрТЗ = Таблица.Добавить(); 36 | СтрТЗ.Имя = Имя; 37 | СтрТЗ.ГУИД = ГУИД; 38 | 39 | КонецЦикла; 40 | 41 | Возврат СоответствиеИменID; 42 | 43 | КонецФункции 44 | 45 | Функция СоздатьКэш(ПутьКФайлу, УпорядочитьПринудительно = Ложь) Экспорт 46 | 47 | Если УпорядочитьПринудительно Тогда 48 | Для каждого Стр Из Таблица Цикл 49 | Стр.Порядок = ЗначениеУпорядочивания(Стр); 50 | КонецЦикла; 51 | Таблица.Сортировать("Порядок"); 52 | КонецЕсли; 53 | 54 | ЗаписьТекста = Новый ЗаписьТекста(ПутьКФайлу, КодировкаТекста.UTF8); 55 | ЗаписьТекста.ЗаписатьСтроку(""); 56 | 57 | Шаблон = ""; 58 | Для каждого Стр Из Таблица Цикл 59 | ЗаписьТекста.ЗаписатьСтроку(СтрШаблон(Шаблон, Стр.Имя, Стр.ГУИД)); 60 | КонецЦикла; 61 | 62 | ЗаписьТекста.Закрыть(); 63 | 64 | КонецФункции 65 | 66 | Процедура Преобразовать(пТаблица) Экспорт 67 | Таблица.Очистить(); 68 | Для каждого Стр1 Из пТаблица Цикл 69 | Стр2 = Таблица.Добавить(); 70 | Стр2.Имя = Стр1.Имя; 71 | Стр2.ГУИД = Стр1.ГУИД; 72 | КонецЦикла; 73 | КонецПроцедуры 74 | 75 | Функция ЗначениеУпорядочивания(СтрТЗ) 76 | 77 | Имя = СтрТЗ.Имя; 78 | Если СтрНайти(Имя, ".Attribute") 79 | Или СтрНайти(Имя, ".TabularSection") 80 | Или СтрНайти(Имя, ".Dimension") 81 | Или СтрНайти(Имя, ".Resource") Тогда 82 | ЗначениеУпорядочивания = Лев(Имя, СтрНайти(Имя, ".", , , 2) - 1) + " " + СтрТЗ.Гуид; 83 | Иначе 84 | ЗначениеУпорядочивания = Имя; 85 | КонецЕсли; 86 | 87 | Возврат ЗначениеУпорядочивания; 88 | 89 | КонецФункции -------------------------------------------------------------------------------- /src/core/Модули/ОбщегоНазначения.os: -------------------------------------------------------------------------------- 1 | #Использовать fs 2 | 3 | Функция ПрочитатьФайлВТекст(ИмяФайла) Экспорт 4 | ЧтениеТекста = Новый ЧтениеТекста(ИмяФайла, КодировкаТекста.UTF8); 5 | Текст = ЧтениеТекста.Прочитать(); 6 | ЧтениеТекста.Закрыть(); 7 | Возврат Текст; 8 | КонецФункции 9 | 10 | Процедура ЗаписатьТекстВФайл(ИмяФайла, Текст, Знач Кодировка = Неопределено) Экспорт 11 | 12 | Если Кодировка = Неопределено Тогда 13 | Кодировка = КодировкаТекста.UTF8; 14 | КонецЕсли; 15 | 16 | ЗаписьТекста = Новый ЗаписьТекста(ИмяФайла, Кодировка); 17 | ЗаписьТекста.Записать(Текст); 18 | ЗаписьТекста.Закрыть(); 19 | 20 | КонецПроцедуры 21 | 22 | Процедура ПодготовитьФайлКЗаписи(ИмяФайла) Экспорт 23 | 24 | Файл = Новый Файл(ИмяФайла); 25 | ФС.ОбеспечитьКаталог(Файл.Путь); 26 | 27 | ЗаписатьТекстВФайл(ИмяФайла, "Тест прав на запись файла и на валидность имени"); 28 | УдалитьФайлы(ИмяФайла); 29 | 30 | КонецПроцедуры -------------------------------------------------------------------------------- /src/templates/pre-commit-1: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | if [ -n "$(git status --porcelain | grep {in_file})" ] # {appname} 3 | then # {appname} 4 | echo 'Запуск pre-commit хука: {appname} convert' 5 | {appname} convert --in={in_file} --out={out_file} --dump={dump_file} {repo} && git add {out_file} 6 | fi # {appname} 7 | -------------------------------------------------------------------------------- /src/templates/pre-commit-2: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo '' > {repo}/{dump_cache} # {appname} 4 | grep -Po 'name=".+?" id=".+?"' ${dump_file} | grep -vP 'id=".+\.' | perl -pe 's/(.+)/<$1\/>/' > {repo}/{dump_cache} # {appname} 5 | git add {repo}/{dump_cache} # {appname} 6 | 7 | if [ -n "$(git status --porcelain | grep {in_file})" ] # {appname} 8 | then # {appname} 9 | echo 'Запуск pre-commit хука: {appname} convert' 10 | {appname} convert --in={in_file} --out={out_file} --dump={dump_cache} {repo} && git add {out_file} 11 | fi # {appname} 12 | -------------------------------------------------------------------------------- /src/templates/pre-commit-3: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | if [ -n "$(git status --porcelain | grep {in_file})" ] # {appname} 3 | then # {appname} 4 | echo 'Запуск pre-commit хука: {appname} convert' 5 | {appname} convert --in={in_file} --out={out_file} --dump={dump_file} --dump-cache={dump_cache} {repo} && git add {out_file} {dump_cache} 6 | fi # {appname} 7 | -------------------------------------------------------------------------------- /src/templates/pre-commit-4: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | if test -f {dump_file}; then echo 'Запуск pre-commit хука: {appname} dump-cache' && {appname} dump-cache --dump={dump_file} --out={dump_cache} {repo} && git add {dump_cache}; fi --------------------------------------------------------------------------------