gifts2017

Публикация конфигурации 1С на GitHub

Опубликовал Сергей Карташев (Elisy) в раздел Администрирование - Сервисные утилиты

Статья показывает, как можно подготовить конфигурацию 1С к публикации в системах версионирования, отличных от хранилища конфигурации 1C. В операции задействован .Net framework и C#, позволяющий аккуратно распределить проект 1С по папкам.
Пример публикации конфигурации на основе старых обновлений БСП четырехлетней давности (с 1.0.7.5 по 1.1.3.1) можно посмотреть по адресу https://github.com/elisy/ssl . Таким же образом теоретически можно публиковать конфигурации в другие системы версионирования.

Публикация конфигурации 1С на GitHub

Статья показывает, как можно подготовить конфигурацию 1С к публикации в системах версионирования, отличных от хранилища конфигурации 1C. В операции задействован .Net framework и C#, позволяющий аккуратно распределить проект 1С по папкам.

Пример публикации конфигурации на основе старых обновлений БСП четырехлетней давности (с 1.0.7.5 по 1.1.3.1) можно посмотреть по адресу https://github.com/elisy/ssl . Таким же образом теоретически можно публиковать конфигурации в другие системы версионирования.

Этап 1: выгрузка конфигурации 1С 8.3 в файлы XML

Начиная с версии 8.3, 1С может выгружать конфигурацию в виде XML-файлов.

Делается это через Конфигурация – Выгрузить конфигурацию в файлы… Нужно указать каталог и нажать ОК. Конфигурация будет выгружена в набор файлов xml, txt, html.

Через командную строку выгрузить файлы можно с параметром /DumpConfigToFiles каталог выгрузки, где каталог выгрузки — каталог, в который будет выгружена конфигурация.

На этом можно было бы закончить подготовку конфигурации к публикации, но возникает одна проблема. Все файлы конфигурации будут находиться в одном каталоге. Например, для УТ 11.0.7 файлов будет около 10000 (десяти тысяч) размером примерно 430 Мбайт. Удобней было бы иметь эти файлы разложенными по каталогам, где каждая папка отвечает за файлы одного типа.

Разложить файлы по каталогам поможет специально написанная программа. В данном случае на C#.

Этап 2: распределение файлов XML по папкам

Суть помещения файлов по каталогам сводится к следующему: на основании имени файла, разложенного с разделителем «точка», получается его полный путь с тем же расширением. Так первое слово до точки определяет каталог типа объекта, следующее слово определяет каталог названия объекта внутри типа. И так далее – каждое слово за точкой – новый каталог.

Есть исключения: формы, макеты и помощь. К ним дополнительно в каталог переносится xml с определением формы/макета или помощи из родительского каталога. Подсистемы отличаются тем, что внутри подсистем есть определения подчиненных подсистем. Файлы, начинающиеся на «Configuration.» помещаются в корень.

Код по получению относительного пути будет следующим:

private string GetRelativePath(string id)
{
    var nameParts = Path.GetFileNameWithoutExtension(id).Split('.');
    string newPath = id;
    if (String.Compare(nameParts[0], "Configuration", true) == 0)
        //Configuration.ManagedApplicationModule.txt
        newPath = id;
    else if (nameParts.Length == 2)
        //AccumulationRegister.ВыручкаИСебестоимостьПродаж.xml
        newPath = Path.Combine(nameParts[0], nameParts[1], nameParts[1] + Path.GetExtension(id));
    else if (nameParts.Length == 4 && String.Compare(nameParts[0], "CommonPicture", true) == 0 && String.Compare(nameParts[2], "Picture", true) == 0 && String.Compare(nameParts[3], "Picture", true) == 0)
    {
        //CommonPicture.BCGВопросы.Picture.Picture.png
        newPath = Path.Combine(nameParts[0], nameParts[1], nameParts[3] + Path.GetExtension(id));
    }
    else if (nameParts.Length == 4 && String.Compare(nameParts[0], "CommonForm", true) == 0 && String.Compare(nameParts[2], "form", true) == 0 && String.Compare(nameParts[3], "module", true) == 0)
    {
        //CommonForm.АвтоматическийОбменСПодключаемымОборудованиемOffline.Form.Module.txt
        newPath = Path.Combine(nameParts[0], nameParts[1], nameParts[3] + Path.GetExtension(id));
    }
    else if (nameParts.Length == 4 && String.Compare(nameParts[2], "form", true) == 0)
    {
        //AccumulationRegister.ДенежныеСредстваБезналичные.Form.ФормаСписка.xml
        newPath = Path.Combine(nameParts[0], nameParts[1], nameParts[2], nameParts[3], nameParts[3] + Path.GetExtension(id));
    }
    else if (nameParts.Length == 6 && String.Compare(nameParts[4], "form", true) == 0 && String.Compare(nameParts[5], "module", true) == 0)
    {
        //Catalog.АвансовыйОтчетПрисоединенныеФайлы.Form.ФормаСписка.Form.Module.txt
        newPath = Path.Combine(nameParts[0], nameParts[1], nameParts[2], nameParts[3], nameParts[5] + Path.GetExtension(id));
    }
    else if (nameParts.Length == 4 && String.Compare(nameParts[2], "template", true) == 0)
    {
        //Catalog.Банки.Template.КлассификаторБанков.xml
        newPath = Path.Combine(nameParts[0], nameParts[1], nameParts[2], nameParts[3], nameParts[3] + Path.GetExtension(id));
    }
    else if (String.Compare(nameParts[nameParts.Length - 1], "help", true) == 0)
    {
        //AccumulationRegister.ТоварыПереданныеНаКомиссию.Help.xml
        //SettingsStorage.ХранилищеВариантовОтчетов.Form.ФормаЗагрузки.Help.xml
        //Subsystem.Маркетинг.Subsystem.МаркетинговыеМероприятия.Help.xml
        List<string> pathParts = new List<string>();
        pathParts.AddRange(nameParts.Take(nameParts.Length));
        pathParts.Add(nameParts[nameParts.Length - 1] + Path.GetExtension(id));
        newPath = Path.Combine(pathParts.ToArray());
    }
    else if (nameParts.Length > 3 && String.Compare(nameParts[nameParts.Length - 2], "Subsystem", true) == 0)
    {
        //Subsystem.Маркетинг.Subsystem.МаркетинговыеМероприятия.xml
        List<string> pathParts = new List<string>();
        pathParts.AddRange(nameParts.Take(nameParts.Length));
        pathParts.Add(nameParts[nameParts.Length - 1] + Path.GetExtension(id));
        newPath = Path.Combine(pathParts.ToArray());
    }
    else if (nameParts.Length > 2)
    {
        List<string> pathParts = new List<string>();
        pathParts.AddRange(nameParts.Take(nameParts.Length - 1));
        pathParts.Add(nameParts[nameParts.Length - 1] + Path.GetExtension(id));
        newPath = Path.Combine(pathParts.ToArray());
    }
    return newPath;
}
 
 

Копирование файла сопровождается проверкой на наличие каталога, куда он копируется (если каталога нет - создается) и проверкой наличия конечного файла (если файл есть – перед копированием удаляется).

string fullPath = Path.Combine(destinationDirectory, file.Path);
if (File.Exists(fullPath))
    File.Delete(fullPath);
string fullPathDirectory = Path.GetDirectoryName(fullPath);
if (!Directory.Exists(fullPathDirectory))
    Directory.CreateDirectory(fullPathDirectory);
File.Copy(Path.Combine(sourceDirectory, file.Id), fullPath);
Этап 3: публикация на GitHub

После регистрации на GitHub нужно создать репозитарий. В данном случае репозитарий называется ssl.

Для синхронизации локального каталога с сайтом GitHub нужно скачать Windows-клиент с веб-сайта github.com. После установки приложения запускается файл GitHub.exe.

Через настройки (плюс сверху слева приложения) локальный каталог необходимо связать с репозитарием. После этого запущенный клиент GitHub.exe начнет отслеживать изменения каталога автоматически. Выдаст добавленные или измененные файлы.

Отсылка изменений на сервер или получение измененных файлов выполняется через команду Sync – кнопка справа сверху приложения.

Выводы

В истории были примеры публикации конфигураций, выгруженных из cf-файлов. Но представление файлов во внутреннем формате 1С не обладает наглядностью. Более привлекательным представляется формат XML, выгрузка в котором появилась только в 1С 8.3.

Опыт публикации конфигурации на GitHub добавил в арсенал средств 1С еще один мощный инструмент. Преимущества GitHub по сравнению с хранилищем конфигураций 1С очевидны: ветвления, встроенный багтрэккер, возможность ревизии и обсуждения кода, исправление кода в браузере, отчеты и графики, открытый API.

Не смотря на кажущуюся привлекательность, только практика работы сможет доказать жизнеспособность методики. Хранилище 1С, не смотря на критику, худо-бедно работает годами. Какие сложности скрывает переход на другие системы версионирования можно только догадываться. Возможно, в версиях может быть неудобно отслеживать изменения XML файлов из-за специфики этого формата (см. макет).

См. также

PowerTools от 1 000
Подписаться Добавить вознаграждение

Комментарии

1. Иван Баринов (izidavld) 24.02.15 00:14
Вообще инструментария для методологии CI, работы с тем же github, а тем более применение unittest-ов в 1С сильно не хватает. Нашелся бы умелец... )
2. Константин Юрин (kostyaomsk) 24.02.15 08:05
Посмотрел реализацию альтернативного механизма. Так полагаю, "подсад" на разработчика? В чем получается практическое преимущество в отличие от стандартного механизма хранилища?
Если только большая надежность хранения данных (выгрузка текстов в XML пишут даже помогает увидеть глюки стандартного сравнения и объединения при обновлениях)?
Путешествовать по веб-каталогу еще затруднительнее. В конфигураторе то сразу видно где что и как?
Прикрепленные файлы:
3. Евгений Ванжула (minimajack) 24.02.15 08:32
(2) kostyaomsk, вы смотрите не туда
в гите смотреть сюда
4. Евгений Сосна (pumbaE) 24.02.15 09:20
1. Нет разбора толстых форм, которые не так просто раскладываются.
2. Нет сборки обратно, я поменял текст в файле модуля, как мне обратно загрузить это все в cf файл?
3. При загрузке обратно из исходников поведение и результат сборки отличаются от ручного варианта и автоматического.
4. Для макетов и сейчас нет никакой возможности нормально смержить результат, а для просмотра различий можно этот xml преобразовать в табличный документ и рассматривать различия с помощью стандартных средств 1с.
5. Для кириллицы необходимы специфичные настройки git.
6. В некоторых случаях длина пути для git не должна превышать 260 символов (в windows) - для длинных наименований метаданных это часто встречается.

Итого: Как концепт - плюс, реализация - минус(велосипед).
ya.Avoronov; ojiojiowka; kostyaomsk; +3 Ответить
5. Константин Юрин (kostyaomsk) 24.02.15 09:30
Посмотрел. Вижу структурированный каталог с описанием объектов 1С 8 на одной странице в *.txt и *.xml. В чем удобство? Только если это корпоративный стандарт работы. Видно, правда что все на одной странице и проще найти что-то в модулях, но зачем?!
6. Евгений Сосна (pumbaE) 24.02.15 09:33
(1) izidavld, про тестирование здесь http://infostart.ru/public/326820/ , http://infostart.ru/public/328695/
Для ci использую jenkins, можно teamcity, некоторые даже bamboo(но сложнее).
7. Евгений Сосна (pumbaE) 24.02.15 09:39
(5) kostyaomsk, все ради этого , и этого . Скорость сравнения значительно быстрее чем у хранилища, скорость сравнения 3х веток значительно лучше чем у 1с(у 1с даже нет сравнения 3х cf файлов(от вендора, вашего измененого, от вендора нового)), в git есть возможность частичного объединения (когда вы объединили 2 или 3 подиситемы, разрешели конфликты и вечером сохранили промежуточный результат), в 1с такого нет.
kote; kostyaomsk; +2 Ответить 2
8. Константин Юрин (kostyaomsk) 24.02.15 09:44
(7) pumbaE, может быть для таких специфических задач и нужны сторонние решения, но, чувствую этот самый "гит" платный?
9. Евгений Ванжула (minimajack) 24.02.15 10:17
(8) kostyaomsk, Git свободный продукт, распространяется бесплатно. Можно поднять свой приватный сервер.
Публичные популярные репозитории:
на гитхабе публичные бесплатные, приватные - платные
на битбакете бесплатные и публичные и приватные
10. Василий Казьмин (awk) 24.02.15 11:49
(7) pumbaE, gradle скрипт для сборок-разборок. тебе должно понравиться.


// Очистить директории
task clean {
    delete 'src'
    mkdir 'src'
}

// Выгрузить конфигурацию в текстовые файлы
task dumpSrc(type:Exec) {
	workingDir './'
 	standardOutput = new ByteArrayOutputStream()
	args = ['DESIGNER', '/F"./db"', '/DumpConfigToFiles"./target"'];
	executable = 'C:/Program Files (x86)/1cv8/8.3.5.1443/bin/1cv8.exe'
	
 	ext.output = {
    	return standardOutput.toString()
  	}
}

// Запуск конфигуратора
task conf(type:Exec) {
	workingDir './'
 	standardOutput = new ByteArrayOutputStream()
	args = ['DESIGNER', '/F"./db"'];
	executable = 'C:/Program Files (x86)/1cv8/8.3.5.1443/bin/1cv8.exe'
	
 	ext.output = {
    	return standardOutput.toString()
  	}
}

// Загрузка конфигурации из исходников
task loadSrc(type:Exec) {
	workingDir './'
 	standardOutput = new ByteArrayOutputStream()
	args = ['DESIGNER', '/F"./db"', '/LoadConfigFromFiles"./target"'];
	executable = 'C:/Program Files (x86)/1cv8/8.3.5.1443/bin/1cv8.exe'
	
 	ext.output = {
    	return standardOutput.toString()
  	}
}

// Построить каталоги
task imp(type: Copy) {
    from 'target'
    into 'src'
    // Исключено из-за непонятных ошибок
    exclude '**/*.cf'
    rename { String fileName ->
        fileName = fileName.replace('.','/')
        if(fileName.toLowerCase().endsWith('txt')) {
        	fileName = fileName.replace('/txt','.oneC')
        } else { 
    		fileName = fileName.replaceAll('(/[^/]+)/([^/]+)$','$1/$1.$2')
    	}
    	fileName
    }

}
...Показать Скрыть
11. Сергей Карташев (Elisy) 24.02.15 12:43
Кстати, впервые статью публиковал на Хабре. На нем можно найти много хороших и дельных комментариев
http://habrahabr.ru/post/248303/
12. Сергей Карташев (Elisy) 24.02.15 12:50
(2) kostyaomsk,
В чем получается практическое преимущество в отличие от стандартного механизма хранилища?

Преимущества GitHub по сравнению с хранилищем конфигураций 1С: ветвления, встроенный багтрэккер, возможность ревизии и обсуждения кода, исправление кода в браузере, отчеты и графики, открытый API.
13. Сергей Иванов (Serg82) 24.02.15 13:41
Идея интересная. Теперь осталось написать open IDE для 1с с кучу плагинами. )
14. Сергей Карташев (Elisy) 24.02.15 15:09
(13) Serg82,
Эта идея идет в комплекте ))), только за основу предлагается взять готовую IDE:
Миниконфигуратор 1С на Visual Studio
http://infostart.ru/public/324382/
15. Василий Казьмин (awk) 24.02.15 15:18
(14) Elisy, Есть другое предложение. Взять эклипс.
16. Сергей Карташев (Elisy) 24.02.15 15:29
(15) awk,
Проект из (14) на уровне фантазий пока. Сейчас в нем нет привязки к конкретной IDE. На вход ему поступает C# csproj-проект. А сам проект не важно в какой IDE сформирован.
17. Сергей Иванов (Serg82) 03.03.15 06:53
http://www.pcweek.ru/business/article/detail.php?ID=164640
«1С» большое внимание уделяет развитию отношений с независимыми разработчиками прикладных решения на базе своей платформы, и здесь важная роль отводится совершенствованию инструментальных средств. Как сообщил руководитель отделения разработки ПО фирмы «1С» Сергей Нуралиев, начата работа по созданию качественно новой версии средств разработки на базе открытой платформы Eclipse с возможностью использования Java-технологий.

Ждем Eclipse)
18. Алексей Лустин (lustin) 04.03.15 08:36
(17) Serg82, около 2-ух месяцев до превью осталось. Вроде как.
19. Сергей Карташев (Elisy) 10.03.15 06:41
Обработка Xml-выгрузки будет доступна здесь после модерации:
http://infostart.ru/public/335018/
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа