Publish 1C configuration on GitHub

  • Tutorial
The article shows how to prepare 1C configuration for publication in versioning systems other than 1C configuration storage. The operation involved .Net framework and C #, which allows you to accurately distribute the 1C project into folders.

An example of publishing a configuration based on old BSP updates four years ago (from 1.0.7.5 to 1.1.3.1) can be found at https://github.com/elisy/ssl . In the same way, it is theoretically possible to publish configurations to other versioning systems. But, the experience of publishing a large number of modified files in SVN was unsuccessful: the SVN client crashed while viewing the log through Tortoise SVN.

Stage 1: uploading the 1C 8.3 configuration to XML files


Starting with version 8.3, 1C can upload the configuration in the form of XML files.

This is done through Configuration - Upload configuration to files ... You need to specify the directory and click OK. The configuration will be uploaded to the xml, txt, html fileset.

Using the command line, you can upload files with the / DumpConfigToFiles parameter the upload directory, where the upload directory is the directory into which the configuration will be downloaded.

This could finish the preparation of the configuration for publication, but there is one problem. All configuration files will be in the same directory. For example, for UT 11.0.7 files there will be about 10,000 (ten thousand) in size of approximately 430 MB. It would be more convenient to have these files laid out in directories, where each folder is responsible for files of the same type.

A specially written program will help to decompose files into directories. In this case, in C #.

Stage 2: distributing XML files into folders


The essence of placing files in directories is as follows: based on the name of the file decomposed with the dot separator, its full path with the same extension is obtained. So the first word to the point defines the catalog of the type of the object, the next word defines the catalog of the name of the object inside the type. And so on - every word after point - a new catalog.

There are exceptions: forms, layouts and help. To them, xml is additionally transferred to the directory with the definition of the form / layout or help from the parent directory. Subsystems differ in that within subsystems there are definitions of subordinate subsystems. Files starting with “Configuration.” are placed in the root.

The code for obtaining the relative path will be as follows:

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 pathParts = new List();
        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 pathParts = new List();
        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 pathParts = new List();
        pathParts.AddRange(nameParts.Take(nameParts.Length - 1));
        pathParts.Add(nameParts[nameParts.Length - 1] + Path.GetExtension(id));
        newPath = Path.Combine(pathParts.ToArray());
    }
    return newPath;
}


Copying the file is accompanied by checking for the presence of the directory where it is copied (if there is no directory, it is created) and checking for the presence of the final file (if the file is there, it is deleted before copying).

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);


Step 3: Publish on GitHub


After registering on GitHub, you need to create a repository. In this case, the repository is called ssl.

To synchronize the local directory with the GitHub website, you need to download the Windows client from the github.com website. After installing the application, the GitHub.exe file is launched.

Through the settings (plus the top left of the application), the local directory must be associated with the repository. After that, the running GitHub.exe client will begin to track directory changes automatically. Will output added or modified files.

Sending changes to the server or receiving modified files is performed through the Sync command - the button on the top right of the application.

conclusions


There have been examples in the history of publishing configurations unloaded from cf files. But the presentation of files in the internal 1C format does not have clarity. The XML format is more attractive, the unloading of which appeared only in 1C 8.3.

The experience of publishing the configuration on GitHub added another powerful tool to the 1C arsenal of tools. The advantages of GitHub compared to the storage of 1C configurations are obvious: branching, built-in bug tracker, the ability to revise and discuss code, correcting code in a browser, reports and graphs, an open API.

Despite the apparent attractiveness, only the practice of work will be able to prove the viability of the methodology. Storage 1C, despite the criticism, somehow works for years. What difficulties hides the transition to other versioning systems you can only guess. Perhaps, in versions it may be inconvenient to track changes in XML files due to the specifics of this format ( see layout ).

Also popular now: