Автодокументация модулей: Markdown, Osparser и Docusaurus

17.06.24

Разработка - DevOps и автоматизация разработки

Рассмотрим создание самоформирующейся документации через комментарии и соглашения: как это сделать и зачем, с описанием полного цикла от исходников конфигурации до странички в интернете

DevOps - это весело. А основа любого нестандартного DevOps - это соглашения. У нас в 1С есть одно более-менее часто встречающееся и, при этом, очень классное соглашение - это комментарии-описания методов. Сегодня мы посмотрим, как использовать данное соглашение в полную силу и извлечь из него максимум пользы - автоматизируем процесс создания документации

То, что будет здесь показано - лишь один из вариантов реализации, пусть и достаточно гибкий для изменения под свои нужды. Я буду опираться на формат комментариев из EDT, который несколько отличается от такового в Конфигураторе. Также вы сможете использовать другую, более близкую себе, систему формирования документов вместо той, которая будет здесь рассматриваться (если захотите) - данная реализация этому не препятствует

 

Зачем нужна автодокументация?

 

Наша документация, по итогу, будет представлять из себя набор документов в формате Markdown, которые мы пропустим через Docusaurus - генератор статических (только из файлов) веб-сайтов, который умеет создавать страницы на их основе. Но, раз уж мы делаем документацию из комментариев-описаний, то выходит, что вся информация в ней будет состоять лишь из того, что уже и так есть в модулях. Так зачем она нужна? Причин, на самом деле, довольно много:

  • Системы для работы с документацией, которые и должны стать финальной точкой данного руководства, имеют такие классные вещи, как древовидная структура и глобальный поиск. Это очень сильно помогает в нахождении нужной информации - куда проще, чем шуршать по общим модулям (особенно, если речь о чужом коде)
     
  • Большинство платформ для документации позволяют получать к ней доступ из любого места. В целом, большинство из них, как и Docusaurus, - это генераторы статический веб-сайтов, результат работы которых может быть развернут на любом хостинге
     
  • Скрипт для разбора модулей - вещь гибкая. Здесь вы можете сами определить иерархию разделов, объединять документы по какому-либо принципу, добавлять признаки для последующего поиска по ним - все ограничивается лишь вашей фантазией (и возможностью поддерживать исполнение соглашений о форматах комментариев внутри вашей команды)
     
  • В конце концов, вам не обязательно формировать всю документацию каждый раз с нуля. Достаточно простой проверки на существование файла с созданием нового только при его отсутствии - и документацию можно дополнять вручную. Это уменьшает гибкость и заставляет следить за актуальностью информации в документах при изменении модулей, но зато в сформированном документе вы сможете добавить любую дополнительную информацию: примечания, скриншоты, места использования, номера задач и пр.

 

Опыт организации подобного процесса я приобрел при разработке документации Открытого пакета интеграций - там вы можете посмотреть один из вариантов конечного результата. Суть работы заключается в следующем:

  • Пишется скрипт на OneScript, который при запуске проходит модули конфигурации и вычленяет из них необходимую информацию
     
  • Эта информация по заранее описанному шаблону записывается в MarkDown файлы
     
  • Файлы помещаются в одну из возможных программ для работы с документацией: MkDocs, Docusaurus, Obsidian, миллионы их

 

Следовательно, нам понадобятся:

  • OneScript с библиотекой osparser
  • Docusaurus (я буду показывать на нем) или другая система для работы с MD

 

Начнем с написания скрипта на OneScript


 

Парсим модули

 

Подразумевается, что вы уже знакомы с написанием скриптов на OS в целом

Работать мы, само собой, будем с исходниками конфигурации, выгруженными в файлы. Бегло рассмотрим пример описания методов в 1С, с которым нам предстоит работать в дальнейшем:
 

// Скачать файл
// Скачивает файл с серверов Telegram
// 
// Параметры:
//  Токен   - Строка - Токен                   
//  IDФайла - Строка - ID файла для скачивания
// 
// Возвращаемое значение:
//  ДвоичныеДанные - данные файла
Функция СкачатьФайл(Знач Токен, Знач IDФайла) Экспорт
...

 

Это - стандартный комментарий, который формирует EDT. В данном случае он состоит из строки с названием и строки краткого описания в начале, далее идет стандартный блок Параметры, где каждый параметр состоит из трех "секций": имени, типа данных и описания. Завершается комментарий возвращаемым значением

Что мы можем принять здесь за постоянную? Это строение стандартных блоков Параметры и Возвращаемое значение, взяв за свое соглашение, разве что, запрет на использование знака дефис в описании - его мы будем использовать для разделения секций. Отдельным соглашением можно назвать использование двух первых строк как Названия и Описания метода - у вас это может быть какой-нибудь другой набор, но здесь я буду делить их так

Исходя из этого мы можем начать писать свой скрипт, но для начала нам надо а)найти необходимые файлы в исходниках б)пройти каждый файл по всем его функциям. С этого и начнем

 

#Использовать osparser
#Использовать fs

Перем ПутьКДокументации;

Процедура ПриСозданииОбъекта()

	ФайлыМодулей         = НайтиФайлы("./", "*.bsl", Истина); // Ищем все .bsl файлы
	ПутьКДокументации    = "./docs";                          // Определяем каталог для сохранения документации

	ФС.ОбеспечитьКаталог(ПутьКДокументации);                  // Создаем каталог, если его нет

	Для Каждого Модуль Из ФайлыМодулей Цикл // Обходим каждый модуль

		ИмяМодуля                 = Новый Файл(СтрЗаменить(Модуль.Путь, "Ext\", "")); // Получаем имя модуля
		ИмяМодуля                 = ИмяМодуля.Имя;
		ПутьМодуля                = Модуль.ПолноеИмя;

                // Создаем отдельный каталог под описание методов данного модуля
		КаталогДокументацииМодуля = ФС.ОбъединитьПути(ПутьКДокументации, ИмяМодуля);

		ФС.ОбеспечитьКаталог(КаталогДокументацииМодуля);
		РазобратьМодуль(ПутьМодуля, КаталогДокументацииМодуля);

	КонецЦикла;

КонецПроцедуры

 

Здесь я использую два сторонних пакета:
 

  • osparser - для парсинга модулей (в коде выше еще не используется)
     
  • fs - для упрощения работы с файлами и создания каталогов. Вы можете заменить его созданием каталогов стандартными методами, если вам так больше нравится

Что происходит в коде выше? Мы создаем пустой каталог для документации и ищем в исходниках все файлы .bsl - собственно, модули, в каталоге и подкаталогах. Потом для каждого модуля в основной папке документации создаем каталог с названием, равным его имени. В моем примере структура документации будет следующей:

  • Модуль как основной раздел          - каталог
    • Область как подраздел           - каталог
      • Метод как документ       - .md файл

 

Пока ничего сложного. Теперь необходимо разложить сам текстовый документ модуля - за это будет отвечать процедура РазобратьМодуль, вызываемая в конце каждой итерации цикла:

 

Процедура РазобратьМодуль(ПутьМодуля, КаталогДокументации)

	МассивОбластей       = Новый Массив;
	МассивМетодов        = Новый Массив;
	ДокументМодуля       = Новый ТекстовыйДокумент();

	ДокументМодуля.Прочитать(ПутьМодуля, "UTF-8");   // Читаем файл модуля
	ТекстМодуля = ДокументМодуля.ПолучитьТекст();    // Получаем текст для парсера

	Парсер          = Новый ПарсерВстроенногоЯзыка;  // Разбираем модуль
	СтруктураМодуля = Парсер.Разобрать(ТекстМодуля);
	ТекущиаяОбласть = "";

	//Обходим все объявления методов, областей и пр.
	Для Каждого Объявление Из СтруктураМодуля.Объявления Цикл 

		// Если это объявление метода - разбираем его комментарий и запиываем эта данные в структуру
		Если Объявление.Тип = "ОбъявлениеМетода" Тогда

			СтруктураДанныхМетода = РазобратьМетод(Объявление, ДокументМодуля);	

			Если ЗначениеЗаполнено(СтруктураДанныхМетода) Тогда
				СтруктураДанныхМетода.Вставить("Область", ТекущиаяОбласть);
				МассивМетодов.Добавить(СтруктураДанныхМетода);
			КонецЕсли;
	
		КонецЕсли;

		// Если это область - записываем её, чтобы потом присвоить структуре данных методов
		Если Объявление.Тип = "ИнструкцияПрепроцессораОбласть" Тогда
			ТекущиаяОбласть = Объявление.Имя;
			МассивОбластей.Добавить(ТекущиаяОбласть);
	        КонецЕсли;

		// Возвращаемся к родительской области, если текущая область закончиалсь
		Если Объявление.Тип = "ИнструкцияПрепроцессораКонецОбласти" Тогда
			МассивОбластей.Удалить(МассивОбластей.ВГраница());

			Если Не МассивОбластей.Количество() = 0 Тогда
				ТекущиаяОбласть = МассивОбластей[МассивОбластей.ВГраница()];
			Иначе
				ТекущиаяОбласть = "";
			КонецЕсли;

		КонецЕсли;

	КонецЦикла;

	// Формируем документы на основе разобранных модулей
	СформироватьФайлыДокументации(МассивМетодов, КаталогДокументации);

КонецПроцедуры


В данной процедуре наша задача сформировать массив однотипных структур по всем методам модуля. Само формирование этих данных вынесено в следующую процедуру. Здесь же мы только ищем объявления методов для описания, а также объявления областей для группировки методов в документации.

Отдельно стоит остановится на парсере встроенного языка. Этот объект из пакета osparser разбирает переданный в него текст модуля на составные части, присущие языку: объявления, переменные, аннотации и пр. Примерно вот так будет выглядеть получаемая структура:


 

С этим мы и работаем: в частности нас интересуют номера строк объявлений методов. Перейдем к функции РазобратьМетод

 

Функция РазобратьМетод(Метод, ТекстовыйДокумент)
	
	СтруктураДанных = Новый Структура();
	
	НомерСтроки         = Метод.Начало.НомерСтроки;
	ИмяМетода           = Метод.Сигнатура.Имя;
	Объявление          = "";

        // Получаем строку объявления метода
	Для Н = НомерСтроки По Метод.Конец.НомерСтроки Цикл	

		Часть      = СокрЛП(ТекстовыйДокумент.ПолучитьСтроку(Н));
		Объявление = Объявление + Часть;

		Если Не ЗначениеЗаполнено(Часть) Тогда
			Прервать;
		КонецЕсли;

	КонецЦикла;

	МассивКомментария        = РазобратьКомментарий(ТекстовыйДокумент, НомерСтроки);
	МассивПараметров         = Новый Массив;
	МассивОписанийПараметров = Новый Массив;

	Если МассивКомментария.Количество() = 0 Тогда
		Возврат СтруктураДанных;
	КонецЕсли;

	СформироватьСтруктуруКомментария(МассивКомментария, МассивПараметров, СтруктураДанных);
	СформироватьМассивОписанийПараметров(МассивПараметров, Метод, МассивОписанийПараметров);

	СтруктураДанных.Вставить("ИмяМетода" , ИмяМетода);
	СтруктураДанных.Вставить("Объявление", Объявление);
	СтруктураДанных.Вставить("Параметры" , МассивОписанийПараметров);

	Возврат СтруктураДанных;

КонецФункции

 

В начале мы сразу определяем номер строки в модуле, на которой начинается объявление текущего метода. Мы эту строку записываем для показа в документации, а номер запоминаем

Далее идет последовательная работа трех методов: РазобратьКомментарий, СформироватьСтруктуруКомментария и СформироватьМассивОписанийПараметров. Финальный результат формируется только в последней, а первые две используются для подготовки данных. Разберем их по порядку, начиная с РазобратьКомментарий:

 

Функция РазобратьКомментарий(Знач ТекстовыйДокумент, Знач НомерСтроки)

    ТекущаяСтрока       = ТекстовыйДокумент.ПолучитьСтроку(НомерСтроки - 1);
    ТекстКомментария    = ТекущаяСтрока;
	
    Счетчик	= 1;
    Пока СтрНайти(ТекущаяСтрока, "//") > 0 Цикл  //Начинаем проходить документ от объявления метода вверх

        Счетчик = Счетчик + 1;

        ТекущаяСтрока    = ТекстовыйДокумент.ПолучитьСтроку(НомерСтроки - Счетчик);
        ТекстКомментария = ТекущаяСтрока + Символы.ПС + ТекстКомментария;

    КонецЦикла;

    Если Счетчик = 1 Тогда
        Возврат Новый Массив; // Пропуск, если нет комментария
    КонецЕсли;

    МассивКомментария = СтрРазделить(ТекстКомментария, "//", Ложь);  // Делим комментарий по строкам

    Если МассивКомментария.Количество() = 0 Тогда
        Возврат Новый Массив;
    Иначе
        МассивКомментария.Удалить(0);                                // Удаляем объявление метода
    КонецЕсли;

    Возврат МассивКомментария;

КонецФункции

 

 

В этой функции мы берем за первую обрабатываемую строку объявление метода, после чего начинаем идти назад (вверх) по документу, записывая комментарий-описание. Далее этот комментарий просто разбивается в массив по символам "//"

 

 

 

Следующая процедура делит полученный массив комментария в более удобную для работы структуру: основные данные, вроде описания или возвращаемого значения, записываются уже непосредственно в финальную структуру описания (которая будет использована для формирования документа), а параметры пока просто добавляются построчно в массив (без деления на секции)
 

Процедура СформироватьСтруктуруКомментария(Знач МассивКомментария, МассивПараметров, СтруктураДанных)

	ОписаниеМетода      = "";
	ЗаписыватьПараметры = Ложь;
    ЗаписыватьОписание  = Истина;

	Счетчик = 0;
	Для Каждого СтрокаКомментария Из МассивКомментария Цикл

        Счетчик = Счетчик + 1;

        Если Не ЗначениеЗаполнено(СокрЛП(СтрокаКомментария)) Тогда 
                         
            // Завершение записи описания, если найдена пустая строка
            ЗаписыватьОписание = Ложь;

        КонецЕсли;
            
        Если ЗаписыватьОписание = Истина И Счетчик > 1 Тогда								

            // Записываем описание из начала комментария
            ОписаниеМетода = СокрЛП(ОписаниеМетода) + " " + СокрЛП(СтрокаКомментария);
        КонецЕсли;

        Если СтрНайти(СтрокаКомментария, "Параметры:") > 0 Тогда
						    
            // Начинаем записывать параметры, если найден признак
            ЗаписыватьПараметры = Истина;
            ЗаписыватьОписание  = Ложь;

        ИначеЕсли СтрНайти(СтрокаКомментария, "Возвращаемое значение:") > 0 Тогда			

            // Записываем возвращаемое значение, если найден признак
            СтруктураДанных.Вставить("ВозвращаемоеЗначение", МассивКомментария[Счетчик]);
            Прервать;

        ИначеЕсли ЗаписыватьПараметры = Истина 
            И ЗначениеЗаполнено(СокрЛП(СтрокаКомментария)) 									
            И Не СтрНачинаетсяС(СокрЛП(СтрокаКомментария), "*") = 0 Тогда

            // Записываем параметр, если он есть и это - не описание элемента коллекции            
            МассивПараметров.Добавить(СтрокаКомментария);

        Иначе
            Продолжить;
        КонецЕсли;

    КонецЦикла;

	СтруктураДанных.Вставить("Описание" , ОписаниеМетода);
	СтруктураДанных.Вставить("Заголовок", МассивКомментария[0]);

КонецПроцедуры

 

В последнем методе мы отдельно обрабатываем описания параметров из комментария:

 

Процедура СформироватьМассивОписанийПараметров(Знач МассивПараметров, Знач Метод, МассивОписанийПараметров)

	Разделитель = "-";

	Для Каждого ПараметрМетода Из МассивПараметров Цикл

		МассивЭлементовПараметра = СтрРазделить(ПараметрМетода, Разделитель, Ложь);
		КоличествоЭлементов      = МассивЭлементовПараметра.Количество();
	
		Для Н = 0 По МассивЭлементовПараметра.ВГраница() Цикл
			МассивЭлементовПараметра[Н] = СокрЛП(МассивЭлементовПараметра[Н]);
		КонецЦикла;
	
                Имя1С     = МассивЭлементовПараметра[0];
                Типы      = МассивЭлементовПараметра[1];
		Описание  = МассивЭлементовПараметра[2];
        
		
		СтруктураПараметра = Новый Структура;
		СтруктураПараметра.Вставить("Имя"                , Имя1С);
		СтруктураПараметра.Вставить("Типы"               , Типы);
		СтруктураПараметра.Вставить("Описание"           , Описание);
		СтруктураПараметра.Вставить("ЗначениеПоУмолчанию", ПолучитьЗначениеПараметраПоУмолчанию(Имя1С, Метод));

		МассивОписанийПараметров.Добавить(СтруктураПараметра);
         
    КонецЦикла;

КонецПроцедуры

 

Еще тут есть небольшая функция ПолучитьЗначениеПараметраПоУмолчанию: она лезет в объявление метода и забирает оттуда значение по умолчанию для необязательных параметров:

 

Функция ПолучитьЗначениеПараметраПоУмолчанию(Знач Имя, Знач Метод)

    Значение = "";

    Для Каждого ПараметрМетода Из Метод.Сигнатура.Параметры Цикл

        Если ПараметрМетода.Имя = Имя Тогда

            ЗначениеПараметра = ПараметрМетода.Значение;
            Если ЗначениеЗаполнено(ЗначениеПараметра) Тогда
                Попытка
                    Значение = ЗначениеПараметра["Элементы"][0]["Значение"];
                Исключение 
                    Значение = ЗначениеПараметра.Значение;
                КонецПопытки;
                Значение = ?(ЗначениеЗаполнено(Значение), Значение, "Пустое значение");
            КонецЕсли;

        КонецЕсли;

    КонецЦикла;

    Возврат Значение;

КонецФункции

 

Теперь мы готовы формировать документацию. К этому моменту у нас есть по вот такой коллекции для каждого отдельного модуля конфигурации:

 

 

Осталось лишь сделать шаблон и записать туда эти данные


 

Шаблоны

 

Шаблону нужен нам для формирования конечных документов. Тут уже все зависит от вашей фантазии и того набора информации, которую вы будете получать из модулей вашей конфигурации. У меня этот шаблон выглядит так:

 

# @Заголовок
@Описание

*@Объявление*

  | Параметр | CLI опция | Тип | Назначение |
  |-|-|-|-|
  @ТаблицаПараметров
  
Возвращаемое значение: @ВозвращаемоеЗначение

 

Шаблон довольно простой: есть заголовок, описание, возвращаемое значение, а также таблица с описанием параметров. Заполним документацию по этому шаблону, вернувшись в наш скрипт к процедуре СформироватьФайлыДокументации:

 

Процедура СформироватьФайлыДокументации(Методы, КаталогДокументации)

	ДокументМакета = Новый ТекстовыйДокумент();
	ДокументМакета.Прочитать("./template.md", "UTF-8");

	// Обходим каждый метод модуля
	Для Каждого СтруктураМетода Из Методы Цикл

		КаталогОбласти = ФС.ОбъединитьПути(КаталогДокументации, СтруктураМетода["Область"]);
		ФС.ОбеспечитьКаталог(КаталогОбласти);

		Макет = ДокументМакета.ПолучитьТекст();

		Макет = СтрЗаменить(Макет, "@Заголовок"           , СтруктураМетода["Заголовок"]);
		Макет = СтрЗаменить(Макет, "@Описание"            , СтруктураМетода["Описание"]);
		Макет = СтрЗаменить(Макет, "@Объявление"          , СтруктураМетода["Объявление"]);
		Макет = СтрЗаменить(Макет, "@ВозвращаемоеЗначение", СтруктураМетода["ВозвращаемоеЗначение"]);

		ТаблицаПараметров = "";

		// Формируем таблицу описания параметров
		Для каждого ПараметрМетода Из СтруктураМетода["Параметры"] Цикл
				
			ТаблицаПараметров = ТаблицаПараметров + "  | " 
				+ ПараметрМетода.Имя + " | "
				+ ПараметрМетода.Типы  + " | "
				+ ПараметрМетода.Описание + " |"
				+ Символы.ПС;

		КонецЦикла;

		Макет = СтрЗаменить(Макет, "@ТаблицаПараметров", ТаблицаПараметров);

		НовыйДокумент = Новый ТекстовыйДокумент();
		НовыйДокумент.УстановитьТекст(Макет);
		НовыйДокумент.Записать(КаталогОбласти + "/" + СтруктураМетода["ИмяМетода"] + ".md");

	КонецЦикла;

КонецПроцедуры


В результате работы данной процедуры мы получаем следующую картину:
 

  1. В каталоге документации есть подкаталог для каждого модуля


     
  2. В каталогах модулей есть каталог для каждой области, если в ней есть методы


     
  3. В каталогах областей лежат документы для каждого метода

 

Данные документы уже можно просмотреть в любом визуализаторе для Markdown разметки

 

Но мы пойдем дальше и закинем эту документацию в новый инструмент...


 

Docusaurus

 

Docusaurus - это генератор статических веб-сайтов, который формирует страницы на основе переданного набора MD файлов. Для того, чтобы начать работу с ним, нам потребуется NPM - устанавливается он вместе с node.js, получить который можно тут: Ссылка

 

После установки NPM достаточно выбрать пустой каталог и в командной строке вызвать:
 

npx create-docusaurus@latest my-cool-1c-docs classic

 

Вместо my-cool-1c-docs можно выбрать свое имя проекта. Пути с кириллицей лучше не использовать, особенно если там есть пробелы. В процессе установки Docusaurus спросит, какой язык мы хотим использовать: JavaScript или TypeScript. Для нас это роли не играет - выбираем JavaScript

 

По окончании установки, каталог созданного проекта будет выглядеть так: 

 

В цели данной статьи не входит описание тонкой настройки данного инструмента, поэтому на сегодня ограничимся просто выводом документации. Для этого нам достаточно очистить папку docs - удалять можно все, кроме документа intro.md - и закинуть туда свои MD файлы, сформированные ранее

Теперь проект можно запустить. Для этого достаточно вызвать следующую команду из папки проекта:
 

npx docusaurus start

 

Для сборки же готового сайта используется команда:
 

npx docusaurus build

 

Start используется для отладки, а build создает одноименную папку в каталоге проекта, которую в дальнейшем можно просто целиком зашвырнуть на любой хостинг, чтобы ваша документация была доступна из любого места

Получившаяся документация выглядит так:



 

Она не без проблем: названия областей и модулей выводятся в PascalCase, не настроено имя сайта и пр. Но это уже рабочий вариант, который можно кастомизировать далее как душе угодно: имена чинятся синонимайзером, а про файл настроек мы еще поговорим далее.

 

Вот пример документации ОПИ, все на этом же движке:




 

Поиск

 

Единственное, что я обещал, но не показал - поиск. Поиск добавляется как отдельный плагин в виде строки в правом верхнем углу. Ищет он по всей документации сразу, как в заголовках, так и в тексте документации

 

Чтобы этот поиск добавить, необходимо найти в каталоге проекта файл docusaurus.config.js и между блоками presers и themeConfig вставить следующий код:

  plugins: [
    [ require.resolve('docusaurus-lunr-search'), {
      languages: ['en', 'ru'] // language codes
    }]],

 

 

После чего просто вызвать в каталоге проекта команду
 

npm i docusaurus-lunr-search  --save

 

 

Поиск будет отображаться при при любом запуске проекта, но работать - только в собранной версии (команда build). Протестировать собранную версию локально также можно. Для этого надо после build дополнительно вызвать
 

npx docusaurus serve

 

 

 

 

Отдельно нужно отметить сам файл docusaurus.config.js, в который мы вносили изменения. Это главный файл настроек Docusaurus и основной массив необходимых параметров находится именно там: имя сайта, лого, блоки, адрес и пр. Он достаточно обильно забит комментариями (на английском), так что с базовой настройкой не должно возникнуть проблем

 

В заключении

 

В первую очередь, данный механизм подойдет создателям собственных отдельных решений, однако даже внутри больших типовых конфигураций всегда найдутся отдельные места, подвластные такому способу документирования.

К главным плюсам можно отнести отсутствие необходимости со стороны разработчика отвлекаться на сторонние инструменты во время написания кода: основа будет создана автоматически, достаточно лишь попутного комментария. При этом, уже потом, после создания базовых документов, страницу любого отдельного метода можно дополнить информацией по своему усмотрению (не говоря уже о том, что и в сам комментарий можно напихать что угодно)

 

 
 Полный текст скрипта из статьи
 

 

Спасибо за внимание!

 

 

 Мой GitHub:     https://gitub.com/Bayselonarrend 
 Лицензия MIT:   https://mit-license.org

Вступайте в нашу телеграмм-группу Инфостарт

документация devops onescript docusaurus

Вы можете заказать платную адаптацию этой статьи под ваши задачи на «Бирже заказов».

  • 0% комиссии — оплата напрямую исполнителю;
  • Исполнители любого масштаба — от отдельных специалистов до команд под проект;
  • Прямой обмен контактами между заказчиком и исполнителем;
  • Безопасная сделка — при необходимости;
  • Рейтинги, кейсы и прозрачная система откликов.

См. также

DevOps и автоматизация разработки Групповая разработка (Git, хранилище) Разработчик 1С:Предприятие 8 Россия Бесплатно (free)

Практическое руководство для команд, которые хотят уйти с хранилища конфигурации на git, не переходя на новую среду разработки. Подойдёт разработчикам и тимлидам, которые настраивают командную разработку на типовых и собственных конфигурациях.

02.11.2026    467    vanya_gonchar    2    

5

Файловый обмен (TXT, XML, DBF), FTP DevOps и автоматизация разработки Групповая разработка (Git, хранилище) Системный администратор Разработчик 1С 8.5 Бесплатно (free)

В прошлой статье я выгрузил Бухгалтерию в XML байт в байт и спросил, на чем проверить дальше. Вы ответили: ERP, старые релизы, зарплата. Прогнал пять конфигураций, от клиента ЭДО до ERP на 120 тысяч файлов. Рассказываю, что сломалось после Бухгалтерии, почему эталону платформы нельзя верить на слово, как выгрузить одну конфигурацию в формат трех версий платформы - и почему cf-конвертер становится отдельным продуктом, Разверткой.

02.11.2026    311    oyti    2    

3

DevOps и автоматизация разработки Групповая разработка (Git, хранилище) Файловый обмен (TXT, XML, DBF), FTP Системный администратор Разработчик 1С 8.5 Бесплатно (free)

Выгрузка типовой Бухгалтерии в XML через базу занимает больше четырёх минут. Я написал движок, который читает файл конфигурации напрямую и выгружает его за 35 секунд, совпадая с выгрузкой платформы байт в байт во всех 90 385 файлах. Загрузка обратно тоже работает: круг через платформу совпадает полностью. Рассказываю, как ускоряли, как проверяем и что при загрузке XML теряет сама платформа. А в конце спрашиваю, нужно ли это кому-то, кроме меня, и на какой конфигурации проверить следующей.

27.10.2026    883    oyti    20    

16

Нейросети DevOps и автоматизация разработки Разработчик 1С 8.3 Бесплатно (free)

ИИ пишет код на 1С все быстрее, а разработчик по-прежнему носит вопросы, ответы и статусы между чатом с агентом, аналитиком и архитектором. Показываю другой подход и демо-стенд: задача из Яндекс Трекера сама идет по этапам, ИИ-агент работает в GitLab CI, а люди только утверждают спецификацию, архитектуру, план и код. Живой пример задачи от заявки до merge, честный отказ агента, права агента, время и стоимость: вся задача обошлась в 68 центов.

22.10.2026    717    maxrubtsoff    1    

3

DevOps и автоматизация разработки Разработчик Бесплатно (free)

Как поднять n8n в Docker и выполнить в нём код OneScript. Три сценария: простой, Осень и ветки схемы.

13.10.2026    561    johnnyshut23    7    

4

DevOps и автоматизация разработки Тестирование QA Разработчик 1С 8.3 1С:Бухгалтерия 3.0 Бесплатно (free)

Все говорят про AI-native: агент сам берет задачу, пишет код и приносит готовую ветку. Мы построили такой конвейер для расширений 1С за три дня: gate на каждом commit, 313 тестов перед main, ревью агентами со скептиком и проверки, которые обязаны хоть раз покраснеть. Он сжег токенов на 606 долларов по прайсу API, а польза для заказчика за эти дни вышла нулевой. Рассказываем, как все устроено и что мы бы сделали с первого дня.

12.10.2026    532    oyti    2    

3

Нейросети DevOps и автоматизация разработки Разработчик Руководитель проекта 1С 8.3 1С 8.5 Бесплатно (free)

Полтора месяца ИИ-агенты писали мне коммерческое расширение 1С. Я поднял журналы всех сессий и сложил по прайсу: $13 365, из них 94 % — за то, что агент заново перечитывает уже известное. Разбор счёта, три дыры, правила, которые вчетверо удешевили шаг, и скрипт, чтобы посчитать свой.

08.10.2026    2371    deda    29    

16

Нейросети DevOps и автоматизация разработки Разработчик 1С 8.3 Абонемент ($m)

Запуск MCP-сервера в Docker с --read-only, --cap-drop ALL, сетью none и внутренней сетью только до заглушки 1С. Что показали попытки соединения, записи на диск и чтения окружения, почему сервер падал на журнале и как это исправлено. Прогон на Docker 29.8.0 и mcp 2.2.0, в архиве Dockerfile и скрипт проверки.

1 стартмани

06.10.2026    800    Ninel_S    0    

8
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. Alxby 1161 17.06.24 06:34 Сейчас в теме
Когда-то давно, в эпоху 77, у меня на основе комментариев глобального модуля в (специальном формате) создавался структурированный als-файл, и все описание API появлялось в синтаксис-помощнике...
bayselonarrend; +1 – Ответить
2. check2 413 17.06.24 08:09 Сейчас в теме
Для описания библиотек самое то.
AntonDan; +1 – Ответить
3. MaCCapAkIII 01.08.24 11:48 Сейчас в теме
А как Вы просматриваете структуру итогового AST в процессе работы скрипта? Отладка скрипта в VSCode или...?
4. bayselonarrend 3214 01.08.24 11:51 Сейчас в теме
5. MaCCapAkIII 02.08.24 11:08 Сейчас в теме
Подскажите пожалуйста:
1. В приведенном скрипте (для указанной структуры комментария) строка
МассивКомментария.Удалить(0);
функции РазобратьКомментарий удаляет не объявление метода, а первую строку комментария, то есть имя метода, соответственно некорректно обрабатывается подстановка данных в шаблон;
2. Правильно ли я понимаю, что указанный шаблон (равно как и код скрипта) работает только для функций, то есть методов с блоком Возврат? Так как для процедур без блока возврата скрипт завершается с ошибкой в строке
Макет = СтрЗаменить(Макет, "@ВозвращаемоеЗначение", СтруктураМетода["ВозвращаемоеЗначение"]);
, так как для процедуры в коллекции "СтруктураМетода" отсутствует свойство "ВозвращаемоеЗначение". То есть мне в идеале надо дописать проверку на тип метода (Процедура или функция).
Для отправки сообщения требуется регистрация/авторизация