diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 70c06db..762f973 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -3,14 +3,15 @@ "_runner": "terminal", "windows": { "command": "cmd", - "args": ["/c", "chcp 65001 ;"] + "args": ["/c", "chcp", "65001", "&&"] + // "args": ["/c", "chcp 65001 ;"] }, "linux": { "command": "sh", "args": ["-c"] }, - "isShellCommand": true, - "showOutput": "silent", + // "isShellCommand": true, + // "showOutput": "silent", "tasks": [ { "taskName": "Testing project", @@ -21,7 +22,7 @@ ], "echoCommand": true, "showOutput": "always", - "suppressTaskName": true, + // "suppressTaskName": true, // "isBuildCommand": false, "isTestCommand": false, "problemMatcher": { @@ -73,7 +74,7 @@ "args": [ "1bdd", "${workspaceRoot}/features", - "-out", + "-out", "${workspaceRoot}/exec.log" ], "echoCommand": true, @@ -96,8 +97,8 @@ "args": [ "1bdd", "${file}", - "-fail-fast", - "-out", + "-fail-fast", + "-out", "${workspaceRoot}/exec.log" ], "echoCommand": true, @@ -122,8 +123,8 @@ "args": [ "1bdd", "${fileDirname}/../${fileBasenameNoExtension}.feature", - "-fail-fast", - "-out", + "-fail-fast", + "-out", "${workspaceRoot}/exec.log" ], "echoCommand": true, @@ -148,10 +149,10 @@ "args": [ "1bdd", "${file}", - "-fail-fast", - "-verbose", - "on", - "-out", + "-fail-fast", + "-verbose", + "on", + "-out", "${workspaceRoot}/exec.log" ], "echoCommand": true, @@ -175,7 +176,7 @@ "1bdd", "gen", "${file}", - "-out", + "-out", "${workspaceRoot}/exec.log" ], "echoCommand": true, diff --git "a/features/step_definitions/fixtures/\320\224\320\276\320\273\320\263\320\276\320\265\320\222\321\213\320\277\320\276\320\273\320\275\320\265\320\275\320\270\320\265.os" "b/features/step_definitions/fixtures/\320\224\320\276\320\273\320\263\320\276\320\265\320\222\321\213\320\277\320\276\320\273\320\275\320\265\320\275\320\270\320\265.os" new file mode 100644 index 0000000..2962c3a --- /dev/null +++ "b/features/step_definitions/fixtures/\320\224\320\276\320\273\320\263\320\276\320\265\320\222\321\213\320\277\320\276\320\273\320\275\320\265\320\275\320\270\320\265.os" @@ -0,0 +1,19 @@ + +Процедура Запустить(ВремяВыполнения) + + Ожидание = ТекущаяУниверсальнаяДатаВМиллисекундах() + ВремяВыполнения * 1000; // сек + + Пока Ожидание > ТекущаяУниверсальнаяДатаВМиллисекундах() Цикл + Сообщить("Полезная работа"); + Приостановить(1000); + КонецЦикла; + + +КонецПроцедуры + +Если АргументыКоманднойСтроки.Количество() Тогда + + ВремяВыполнения = АргументыКоманднойСтроки[0]; + Запустить(ВремяВыполнения); + +КонецЕсли; diff --git "a/features/step_definitions/fixtures/\320\236\320\261\321\200\320\260\320\261\320\276\321\202\321\207\320\270\320\272\320\236\320\266\320\270\320\264\320\260\320\275\320\270\321\217\320\237\321\200\320\276\321\206\320\265\321\201\321\201\320\260.os" "b/features/step_definitions/fixtures/\320\236\320\261\321\200\320\260\320\261\320\276\321\202\321\207\320\270\320\272\320\236\320\266\320\270\320\264\320\260\320\275\320\270\321\217\320\237\321\200\320\276\321\206\320\265\321\201\321\201\320\260.os" new file mode 100644 index 0000000..e0b9ca2 --- /dev/null +++ "b/features/step_definitions/fixtures/\320\236\320\261\321\200\320\260\320\261\320\276\321\202\321\207\320\270\320\272\320\236\320\266\320\270\320\264\320\260\320\275\320\270\321\217\320\237\321\200\320\276\321\206\320\265\321\201\321\201\320\260.os" @@ -0,0 +1,24 @@ + +Перем Счетчик; +Перем ТребуетсяОтказ; + +Функция ПолучитьСчетчик() Экспорт + Возврат Счетчик; +КонецФункции + +Процедура УстановитьОтказ() Экспорт + ТребуетсяОтказ = Истина; +КонецПроцедуры + +Процедура ОбработкаОжиданияПроцесса(Процесс, Отказ, ПериодОпроса, ДополнительныеПараметрыОбработчика, СтандартнаяОбработка) Экспорт + + Счетчик = Счетчик + 1; + + Если ТребуетсяОтказ Тогда + Отказ = Истина; + КонецЕсли; + +КонецПроцедуры + +Счетчик = 0; +ТребуетсяОтказ = Ложь; \ No newline at end of file diff --git a/features/step_definitions/wait-handler.os b/features/step_definitions/wait-handler.os new file mode 100644 index 0000000..34e2132 --- /dev/null +++ b/features/step_definitions/wait-handler.os @@ -0,0 +1,85 @@ +// Реализация шагов BDD-фич/сценариев c помощью фреймворка https://github.com/artbear/1bdd +#Использовать "../.." + +Перем БДД; //контекст фреймворка 1bdd + +// Метод выдает список шагов, реализованных в данном файле-шагов +Функция ПолучитьСписокШагов(КонтекстФреймворкаBDD) Экспорт + БДД = КонтекстФреймворкаBDD; + + ВсеШаги = Новый Массив; + + ВсеШаги.Добавить("ЯСоздаюОбработчикОжиданияПроцесса"); + ВсеШаги.Добавить("ЯУстанавливаюОтказВОбработчикОжиданияПроцесса"); + ВсеШаги.Добавить("ЯУстанавливаюОбработчикОжиданияПроцессаКомандыСИнтервалом"); + ВсеШаги.Добавить("СчетчикОбработчикаРавен"); + + Возврат ВсеШаги; +КонецФункции + +// Реализация шагов + +// Процедура выполняется перед запуском каждого сценария +Процедура ПередЗапускомСценария(Знач Узел) Экспорт + +КонецПроцедуры + +// Процедура выполняется после завершения каждого сценария +Процедура ПослеЗапускаСценария(Знач Узел) Экспорт + +КонецПроцедуры + +//Я создаю обработчик ожидания процесса +Процедура ЯСоздаюОбработчикОжиданияПроцесса() Экспорт + + Обработчик = ЗагрузитьСценарий(".\features\step_definitions\fixtures\ОбработчикОжиданияПроцесса.os"); + + БДД.СохранитьВКонтекст("Обработчик", Обработчик); + +КонецПроцедуры + +//Я устанавливаю отказ в обработчик ожидая процесса +Процедура ЯУстанавливаюОтказВОбработчикОжиданияПроцесса() Экспорт + + Обработчик = БДД.ПолучитьИзКонтекста("Обработчик"); + Обработчик.УстановитьОтказ(); + +КонецПроцедуры + +//Счетчик обработчика равен "0" +Процедура СчетчикОбработчикаРавен(Знач ЧислоСчетчика) Экспорт + + Обработчик = БДД.ПолучитьИзКонтекста("Обработчик"); + + Ожидаем.Что(Обработчик.ПолучитьСчетчик(), "Счетчик должен быть равен").Равно(Число(ЧислоСчетчика)); + +КонецПроцедуры + +//Я устанавливаю обработчик ожидания процесса команды "oscript" с интервалом "1000" +Процедура ЯУстанавливаюОбработчикОжиданияПроцессаКомандыСИнтервалом(Знач ИмяКоманды, Знач Интервал) Экспорт + + Обработчик = БДД.ПолучитьИзКонтекста("Обработчик"); + Команда = ПолучитьКомандуИзКонтекста(ИмяКоманды); + Команда.УстановитьОбработчикОжидания(Обработчик, Число(Интервал)); + +КонецПроцедуры + +//TODO дубль кода с 1bdd::ВыполнениеКоманд.os +Функция ПолучитьКомандуИзКонтекста(Знач ИмяКоманды) + + КлючКонтекста = КлючКоманды(ИмяКоманды); + Команда = БДД.ПолучитьИзКонтекста(КлючКонтекста); + + Если Не ЗначениеЗаполнено(Команда) Тогда + Команда = Новый Команда; + Команда.УстановитьСтрокуЗапуска(ИмяКоманды); + БДД.СохранитьВКонтекст(КлючКонтекста, Команда); + КонецЕсли; + + Возврат Команда; +КонецФункции + +//TODO дубль кода с 1bdd::ВыполнениеКоманд.os +Функция КлючКоманды(Знач ИмяКоманды) + Возврат "Команда-" + ИмяКоманды; +КонецФункции diff --git "a/features/step_definitions/\320\222\321\213\320\277\320\276\320\273\320\275\320\265\320\275\320\270\320\265\320\232\320\276\320\274\320\260\320\275\320\264\321\213.os" "b/features/step_definitions/\320\222\321\213\320\277\320\276\320\273\320\275\320\265\320\275\320\270\320\265\320\232\320\276\320\274\320\260\320\275\320\264\321\213.os" index 6f6cdcc..8c8678a 100644 --- "a/features/step_definitions/\320\222\321\213\320\277\320\276\320\273\320\275\320\265\320\275\320\270\320\265\320\232\320\276\320\274\320\260\320\275\320\264\321\213.os" +++ "b/features/step_definitions/\320\222\321\213\320\277\320\276\320\273\320\275\320\265\320\275\320\270\320\265\320\232\320\276\320\274\320\260\320\275\320\264\321\213.os" @@ -53,7 +53,7 @@ Процедура ЯУстанавливаюОжидаемыйКодВозвратаДляКоманды(Знач ОжидаемыйКодВозврата, Знач ИмяИлиТекстКоманды) Экспорт Команда = ПолучитьКомандуИзКонтекста(ИмяИлиТекстКоманды); - Команда.УстановитьПравильныйКодВозврата(ОжидаемыйКодВозврата); + Команда.УстановитьПравильныйКодВозврата(Число(ОжидаемыйКодВозврата)); КонецПроцедуры //Я устанавливаю ожидаемый диапазон кодов возврата от 0 до 10 для команды "oscript" diff --git a/features/wait-handler.feature b/features/wait-handler.feature new file mode 100644 index 0000000..fa707e7 --- /dev/null +++ b/features/wait-handler.feature @@ -0,0 +1,39 @@ +# language: ru + +Функциональность: Выполнение команды + +Как разработчик +Я хочу иметь возможность выполнять команды +Чтобы я мог проще автоматизировать больше действий на OneScript + +Контекст: Отключение отладки в логах + Допустим Я выключаю отладку лога с именем "oscript.lib.commands" + И Я очищаю параметры команды "oscript" в контексте + +Сценарий: Выполнение долгой команды + Когда Я добавляю параметры для команды "oscript" + # | -encoding=utf-8 | + | features/step_definitions/fixtures/ДолгоеВыполнение.os | + | 1 | + # И Я добавляю параметр "features/step_definitions/fixtures/ДолгоеВыполнение.os" для команды "oscript" + # И Я добавляю параметр "5" для команды "oscript" + И Я устанавливаю период опроса завершения команды "oscript" в 1 миллисекунду + И Я выполняю команду "oscript" + Тогда Вывод команды "oscript" содержит "Полезная работа" + И Код возврата команды "oscript" равен 0 + +Сценарий: Выполнение долгой команды + Когда Я добавляю параметры для команды "oscript" + # | -encoding=utf-8 | + | features/step_definitions/fixtures/ДолгоеВыполнение.os | + | 1 | + # И Я добавляю параметр "features/step_definitions/fixtures/ДолгоеВыполнение.os" для команды "oscript" + # И Я добавляю параметр "5" для команды "oscript" + И Я создаю обработчик ожидания процесса + И Я устанавливаю отказ в обработчик ожидания процесса + И Я устанавливаю обработчик ожидания процесса команды "oscript" с интервалом "1000" + И Я устанавливаю ожидаемый код возврата -1 для команды "oscript" + И Я выполняю команду "oscript" + Тогда Вывод команды "oscript" содержит "Полезная работа" + # И Код возврата команды "oscript" равен 1 + И Счетчик обработчика равен "1" diff --git a/packagedef b/packagedef index 7d41ab5..f9af18e 100644 --- a/packagedef +++ b/packagedef @@ -1,9 +1,10 @@  Описание.Имя("1commands") - .Версия("1.3.5") + .Версия("1.4.0") .ВерсияСреды("1.0.17") .ЗависитОт("logos") .ЗависитОт("asserts") + .ЗависитОт("semver") .ЗависитОт("tempfiles") .ВключитьФайл("src") .ВключитьФайл("features") diff --git "a/src/\320\232\320\276\320\274\320\260\320\275\320\264\320\260.os" "b/src/\320\232\320\276\320\274\320\260\320\275\320\264\320\260.os" index b3aa234..dd15088 100644 --- "a/src/\320\232\320\276\320\274\320\260\320\275\320\264\320\260.os" +++ "b/src/\320\232\320\276\320\274\320\260\320\275\320\264\320\260.os" @@ -4,6 +4,7 @@ #Использовать logos #Использовать asserts + Перем Приложение; Перем ИспользуетсяЕдинаяСтрокаЗапуска; Перем Параметры; @@ -18,26 +19,49 @@ Перем ПериодОпросаВМиллисекундах; Перем НемедленнныйВывод; Перем ПодключенныеЛоги; +Перем ОбработчикОжиданияПроцесса; +Перем ДополнительныеПараметрыОбработчика; +Перем ПерехватыватьПотоки; +Перем ВерсияБольшеИлиРавна21; Перем ЭтоWindows; Перем Лог; +Перем ПеременныеСредыПроцесса; + // Выполнение произвольной команды // // Возвращаемое значение: // Число - код возврата команды // Функция Исполнить() Экспорт - + ПроверитьВозможностьВыполненияКоманды(); - + КодВозврата = ЗапуститьИПодождать(); - + Лог.Отладка("Код возврата равен %1", КодВозврата); Возврат КодВозврата; КонецФункции +// Запуск на выполнение процесса +// +// Возвращаемое значение: +// Процесс - объект класса Процесс +// +Функция ЗапуститьПроцесс() Экспорт + + ПроверитьВозможностьВыполненияКоманды(); + + Процесс = ЗапуститьПроцессКоманды(); + + Лог.Отладка("Запущен процесс с идентификатором <%1>", Процесс.Идентификатор); + + Возврат Процесс; + +КонецФункции + // Получить имя лога продукта // // Возвращаемое значение: @@ -49,7 +73,7 @@ // Установить путь команды. // Если в пути команды есть пробелы, они обрамляются кавычками -// ВАЖНО: метод принимает именно путь к приложению, +// ВАЖНО: метод принимает именно путь к приложению, // параметры приложения здесь передавать не следует!! // Для передачи параметров нужно использовать метод "УстановитьСтрокуЗапуска" // @@ -82,10 +106,29 @@ Возврат Приложение; КонецФункции +// Устанавливает переменные среды для процесса +// +// Параметры: +// ППеременныеСредыПроцесса - Соответствие - где ключ имя переменной, а значение - значение переменной +// +Процедура УстановитьПеременныеСреды(ППеременныеСредыПроцесса) Экспорт + ПеременныеСредыПроцесса = ППеременныеСредыПроцесса; +КонецПроцедуры + +// Устанавливает признак необходимости перехватывать потоки +// по умолчанию потоки всегда перехватываются +// +// Параметры: +// ППерехватыватьПотоки - Булево - признак необходимости перехвата потоков процесса +// +Процедура ПерехватыватьПотоки(ППерехватыватьПотоки) Экспорт + ПерехватыватьПотоки = ППерехватыватьПотоки; +КонецПроцедуры + // Добавить параметр команды. // // Параметры: -// Строка - новый единичный параметр или все параметы в одной строке +// Строка - новый единичный параметр или все параметы в одной строке // Процедура ДобавитьПараметр(Знач Параметр) Экспорт Параметры.Добавить(Параметр); @@ -106,7 +149,7 @@ // Может использовать для очистки параметров. Для этого нужно передать пустую строку // // Параметры: -// Строка - параметы в одной строке +// Строка - параметы в одной строке // Процедура УстановитьПараметры(Знач СтрокаПараметров) Экспорт Параметры = Новый Массив; @@ -167,6 +210,20 @@ КонецПроцедуры +// Устанавливает обработчик ожидания для процесса +// +// Параметры: +// Обработчик - Произвольный - класс реализующих метод <ОбработкаОжиданияПроцесса> +// ППериодОпросаВМиллисекундах - Число - период вызова обработчика ожидания, мс (по умолчанию 5000) +// ДополнительныеПараметры - Структура - дополнительные параметры передаваемые в обработчик ожидания +// +Процедура УстановитьОбработчикОжидания(Обработчик, Знач ППериодОпросаВМиллисекундах = 5000, ДополнительныеПараметры = Неопределено) Экспорт + + ОбработчикОжиданияПроцесса = Обработчик; + ПериодОпросаВМиллисекундах = ППериодОпросаВМиллисекундах; + ДополнительныеПараметрыОбработчика = ДополнительныеПараметры; +КонецПроцедуры + // Установить ожидаемый код возврата // После исполнения команды будет выброшено исключение, если полученный код возврата не совпадает с ожидаемым // @@ -184,13 +241,13 @@ // МинимальныйОжидаемыйКодВозврата - Число // МаксимальныйОжидаемыйКодВозврата - Число // -Процедура УстановитьДиапазонПравильныхКодовВозврата( Знач ПарамМинимальныйОжидаемыйКодВозврата, +Процедура УстановитьДиапазонПравильныхКодовВозврата( Знач ПарамМинимальныйОжидаемыйКодВозврата, Знач ПарамМаксимальныйОжидаемыйКодВозврата) Экспорт ПроверяемКодВозврата = Истина; МинимальныйОжидаемыйКодВозврата = ПарамМинимальныйОжидаемыйКодВозврата; МаксимальныйОжидаемыйКодВозврата = ПарамМаксимальныйОжидаемыйКодВозврата; - + КонецПроцедуры // Установить кодировку вывода для выполнения команды. @@ -258,13 +315,13 @@ // Строка - Строка, обернутая в кавычки // Функция ОбернутьВКавычки(Знач Строка) Экспорт - + Если Лев(Строка, 1) = """" и Прав(Строка, 1) = """" Тогда Возврат Строка; Иначе Возврат """" + Строка + """"; КонецЕсли; - + КонецФункции ////////////////////////////////////////////////////////////////////////// @@ -282,14 +339,14 @@ // Проверяет возможность выполнить команду. // Процедура ПроверитьВозможностьВыполненияКоманды() - + Ожидаем.Что(ПолучитьРабочийКаталог(), "Рабочий каталог не установлен.").Заполнено(); - + Лог.Отладка("РабочийКаталог: " + ПолучитьРабочийКаталог()); - + КонецПроцедуры -// Запустить команду в операционной системе с ожиданием ее выполнения +// Запустить команду в операционной системе с ожиданием ее выполнения // // Параметры: // Параметры - Массив - Массив строковых аргументов, передаваемых в командную @@ -301,52 +358,55 @@ Функция ЗапуститьИПодождать() СтрокаЗапуска = СформироватьСтрокуЗапускаПроцесса(); - + ПерехватыватьПотоки = Истина; + Процесс = ЗапуститьПроцессКоманды(ПерехватыватьПотоки); + + ПолучитьВыводПокаПроцессИсполняется(Процесс); + + КодВозврата = Процесс.КодВозврата; + ПроверитьКодВозврата(КодВозврата); + + Возврат КодВозврата; + +КонецФункции + + +// Запустить команду в операционной системе с ожиданием ее выполнения +// +// Параметры: +// Параметры - Массив - Массив строковых аргументов, передаваемых в командную +// строку. Добавляются после исполняемого файла. +// +// Возвращаемое значение: +// Процесс - запущенный процесс +// +Функция ЗапуститьПроцессКоманды(ПерехватыватьПотоки = Ложь) + + СтрокаЗапуска = СформироватьСтрокуЗапускаПроцесса(); + Попытка - + Если КодировкаВывода = Неопределено Тогда - Процесс = СоздатьПроцесс(СтрокаЗапуска, РабочийКаталог, ПерехватыватьПотоки, ПерехватыватьПотоки, , ПеременныеСреды()); + Процесс = СоздатьПроцесс(СтрокаЗапуска, РабочийКаталог, ПерехватыватьПотоки, ПерехватыватьПотоки, , ПеременныеСредыПроцесса); Иначе - Процесс = СоздатьПроцесс(СтрокаЗапуска, РабочийКаталог, ПерехватыватьПотоки, ПерехватыватьПотоки, КодировкаВывода, ПеременныеСреды()); + Процесс = СоздатьПроцесс(СтрокаЗапуска, РабочийКаталог, ПерехватыватьПотоки, ПерехватыватьПотоки, КодировкаВывода, ПеременныеСредыПроцесса); КонецЕсли; - Исключение - Инфо = ИнформацияОбОшибке(); - // TODO код проверки на регулярку (ниже) убрать после выпуска релиза OneScript 1.0.21 - РегуляркаОшибкиПеременныхСреды = Новый РегулярноеВыражение("\(System\.ArgumentException\):[^:]+:.*HOME[^:]+:.*home"); - Если РегуляркаОшибкиПеременныхСреды.Совпадает(Инфо.Описание) Тогда - Лог.Предупреждение("Возникла ошибка, связанная с переменными среды при старте нового процесса - |В связи с багом в движке OneScript до версии 1.0.21 - |%1 - | - |Выполняю старт процесса без указания переменных среды.", Инфо.Описание); + Исключение - Лог.Отладка("Полное описание ошибки: - |%1", Инфо.ПодробноеОписаниеОшибки()); + Инфо = ИнформацияОбОшибке(); - Если КодировкаВывода = Неопределено Тогда - Процесс = СоздатьПроцесс(СтрокаЗапуска, РабочийКаталог, ПерехватыватьПотоки, ПерехватыватьПотоки); - Иначе - Процесс = СоздатьПроцесс(СтрокаЗапуска, РабочийКаталог, ПерехватыватьПотоки, ПерехватыватьПотоки, КодировкаВывода); - КонецЕсли; - Иначе - ВызватьИсключение Инфо.ПодробноеОписаниеОшибки(); - КонецЕсли; + ВызватьИсключение Инфо.ПодробноеОписаниеОшибки(); КонецПопытки; - Процесс.Запустить(); - - ПолучитьВыводПокаПроцессИсполняется(Процесс); + Процесс.Запустить(); - КодВозврата = Процесс.КодВозврата; - ПроверитьКодВозврата(КодВозврата); + Возврат Процесс; - Возврат КодВозврата; - КонецФункции Функция СформироватьСтрокуЗапускаПроцесса() @@ -357,65 +417,127 @@ СтрокаЗапуска = ""; СтрокаДляЛога = ""; Для Каждого Параметр Из Параметры Цикл - + СтрокаЗапуска = СтрокаЗапуска + " " + Параметр; - + Если Лев(Параметр, 2) <> "/P" и Лев(Параметр, 25) <> "/ConfigurationRepositoryP" Тогда СтрокаДляЛога = СтрокаДляЛога + " " + Параметр; КонецЕсли; - + КонецЦикла; - + Если НЕ ИспользуетсяЕдинаяСтрокаЗапуска И Найти(ПутьПриложения, " ") > 0 Тогда ПутьПриложения = ОбернутьВКавычки(ПутьПриложения); КонецЕсли; - Лог.Отладка("СтрокаЗапуска <%1>", ПутьПриложения + СтрокаДляЛога); - + Лог.Отладка("Строка запуска <%1>", ПутьПриложения + СтрокаДляЛога); + СтрокаЗапуска = ПутьПриложения + СтрокаЗапуска; - + Если ИспользуемКомандныйПроцессор Тогда - Если ЭтоWindows Тогда + Если ЭтоWindows Тогда ШаблонЗапуска = "cmd /c ""%1"""; Иначе ШаблонЗапуска = "sh -c '%1'"; КонецЕсли; - + СтрокаЗапуска = СтрШаблон(ШаблонЗапуска, СтрокаЗапуска); КонецЕсли; - Лог.Отладка("СтрокаЗапуска <%1>", СтрокаЗапуска); + Лог.Отладка("Полная строка запуска <%1>", СтрокаЗапуска); Возврат СтрокаЗапуска; КонецФункции // СформироватьСтрокуЗапускаПроцесса() +Процедура ОбработкаОжиданияПроцесса(Процесс, ЗаписьXML) + + ПрерываниеПроцесса = Ложь; + СтандартнаяОбработка = Истина; + УстановленОбработчикОжиданияПроцесса = НЕ ОбработчикОжиданияПроцесса = Неопределено; + + Если ДополнительныеПараметрыОбработчика = Неопределено Тогда + ДополнительныеПараметры = Новый Структура(); + Иначе + ДополнительныеПараметры = ДополнительныеПараметрыОбработчика; + КонецЕсли; + + Если УстановленОбработчикОжиданияПроцесса Тогда + + Обработчик = ОбработчикОжиданияПроцесса; + + Лог.Отладка("Вызов обработчика ожидания"); + Попытка + Обработчик.ОбработкаОжиданияПроцесса(Процесс, + ПрерываниеПроцесса, + ПериодОпросаВМиллисекундах, + ДополнительныеПараметры, + СтандартнаяОбработка); + Исключение + Лог.Отладка(ОписаниеОшибки()); + ВызватьИсключение КраткоеПредставлениеОшибки(ИнформацияОбОшибке()); + КонецПопытки; + + КонецЕсли; + + Если СтандартнаяОбработка Тогда + + Если ПерехватыватьПотоки + И Процесс.ПотокВывода.ЕстьДанные + ИЛИ Процесс.ПотокОшибок.ЕстьДанные Тогда + + ОбработатьОчереднуюСтрокуВывода(Процесс.ПотокВывода, ЗаписьXML, "В цикле"); + ОбработатьОчереднуюСтрокуВывода(Процесс.ПотокОшибок, ЗаписьXML, "В цикле", Истина); + + КонецЕсли; + + КонецЕсли; + + Если ПрерываниеПроцесса Тогда + + Процесс.Завершить(); + + КонецЕсли; + +КонецПроцедуры + Процедура ПолучитьВыводПокаПроцессИсполняется(Процесс) - ЗаписьXML = Новый ЗаписьXML(); - ЗаписьXML.УстановитьСтроку(); + + ЗаписьXML = Новый ЗаписьXML(); + ЗаписьXML.УстановитьСтроку(); Если ПериодОпросаВМиллисекундах <> 0 Тогда Приостановить(ПериодОпросаВМиллисекундах); + ОбработкаОжиданияПроцесса(Процесс, ЗаписьXML) КонецЕсли; - Пока НЕ Процесс.Завершен ИЛИ Процесс.ПотокВывода.ЕстьДанные ИЛИ Процесс.ПотокОшибок.ЕстьДанные Цикл + Пока НЕ Процесс.Завершен Цикл + Если ПериодОпросаВМиллисекундах <> 0 Тогда Приостановить(ПериодОпросаВМиллисекундах); КонецЕсли; - ОбработатьОчереднуюСтрокуВывода(Процесс.ПотокВывода, ЗаписьXML, "В цикле"); - ОбработатьОчереднуюСтрокуВывода(Процесс.ПотокОшибок, ЗаписьXML, "В цикле", Истина); + ОбработкаОжиданияПроцесса(Процесс, ЗаписьXML) КонецЦикла; - ОбработатьОчереднуюСтрокуВывода(Процесс.ПотокВывода, ЗаписьXML, "После цикла"); - ОбработатьОчереднуюСтрокуВывода(Процесс.ПотокОшибок, ЗаписьXML, "После цикла", Истина); + // Дочитывает данные после завершения ?? Хотя процесс не может завершиться пока есть данные в потоке чтения + Если ПерехватыватьПотоки + И Процесс.ПотокВывода.ЕстьДанные + ИЛИ Процесс.ПотокОшибок.ЕстьДанные Тогда + + ОбработатьОчереднуюСтрокуВывода(Процесс.ПотокВывода, ЗаписьXML, "В цикле"); + ОбработатьОчереднуюСтрокуВывода(Процесс.ПотокОшибок, ЗаписьXML, "В цикле", Истина); - РезультатРаботыПроцесса = ЗаписьXML.Закрыть(); - Если Не НемедленнныйВывод Тогда - Лог.Отладка("РезультатРаботыПроцесса %2-----%2%1%2------%2", РезультатРаботыПроцесса, Символы.ПС); КонецЕсли; - - Лог.Отладка("Длина вывода %1, количество строк %2", СтрДлина(РезультатРаботыПроцесса), СтрЧислоСтрок(РезультатРаботыПроцесса)); - + + РезультатРаботыПроцесса = ЗаписьXML.Закрыть(); + // Если Не НемедленнныйВывод Тогда + // Лог.Отладка("РезультатРаботыПроцесса %2-----%2%1%2------%2", РезультатРаботыПроцесса, Символы.ПС); + // КонецЕсли; + + Лог.Отладка("Длина вывода %1, количество строк %2", СтрДлина(РезультатРаботыПроцесса), + СтрЧислоСтрок(РезультатРаботыПроцесса)); + УстановитьВывод(РезультатРаботыПроцесса); + КонецПроцедуры Функция ОбработатьОчереднуюСтрокуВывода(ПотокПроцесса, ЗаписьXML, Знач ПрефиксДляОтладки, Знач ЭтоВыводОшибки = Ложь) @@ -425,9 +547,7 @@ КонецЕсли; Если Рез <> "" Тогда - Лог.Отладка("в цикле %2%1", Рез, Символы.ПС); Если ЗначениеЗаполнено(ПодключенныеЛоги) Тогда - Лог.Отладка(" Вывожу в отдельные логи"); Для каждого ПодключенныйЛог Из ПодключенныеЛоги Цикл Если ЭтоВыводОшибки Тогда ПодключенныйЛог.Ошибка(Рез); @@ -442,9 +562,9 @@ Сообщить(Рез); КонецЕсли; КонецЕсли; - + КонецЕсли; - + Возврат Рез; КонецФункции @@ -454,13 +574,13 @@ Если МинимальныйОжидаемыйКодВозврата <> МаксимальныйОжидаемыйКодВозврата Тогда ТекстОшибки = СтрШаблон("Ожидали, что код возврата <%1> команды <%2> совпадет с ожидаемым диапазоном <%3>-<%4>, а это не так! |Лог команды: - |%5", + |%5", КодВозврата, Приложение, МинимальныйОжидаемыйКодВозврата, МаксимальныйОжидаемыйКодВозврата, ПолучитьВывод()); Иначе ТекстОшибки = СтрШаблон("Ожидали, что код возврата <%1> команды <%2> совпадет с ожидаемым <%3>, а это не так! |Лог команды: - |%4", + |%4", КодВозврата, Приложение, МинимальныйОжидаемыйКодВозврата, ПолучитьВывод()); КонецЕсли; Ожидаем.Что(КодВозврата, СтрШаблон("%1, вывод %2", ТекстОшибки, ВыводКоманды)). @@ -474,15 +594,15 @@ // Задает минимальные настройки. // Процедура Инициализация() - + Лог = Логирование.ПолучитьЛог(ИмяЛога()); - + СистемнаяИнформация = Новый СистемнаяИнформация; ЭтоWindows = Найти(НРег(СистемнаяИнформация.ВерсияОС), "windows") > 0; РабочийКаталог = "."; ВыводКоманды = ""; - КодировкаВывода = Неопределено; //КодировкаТекста.UTF8; + КодировкаВывода = Неопределено;//КодировкаТекста.UTF8; Параметры = Новый Массив; ИспользуетсяЕдинаяСтрокаЗапуска = Ложь; @@ -490,12 +610,16 @@ ПроверяемКодВозврата = Ложь; ОжидаемыйКодВозврата = 0; + ПерехватыватьПотоки = Истина; ПериодОпросаВМиллисекундах = 100; НемедленнныйВывод = Ложь; + ПеременныеСредыПроцесса = ПеременныеСреды(); + ПодключенныеЛоги = Новый Массив; - + ОбработчикОжиданияПроцесса = Неопределено; + КонецПроцедуры Инициализация(); diff --git a/tasks/coverage.os b/tasks/coverage.os index ca026d3..ef3f9f6 100644 --- a/tasks/coverage.os +++ b/tasks/coverage.os @@ -14,13 +14,14 @@ Если НЕ ЭтоWindows Тогда Команда.ДобавитьПараметр("-encoding=utf-8"); КонецЕсли; -Команда.ДобавитьПараметр(СтрШаблон("-codestat=%1", ПутьКСтат)); +Команда.ДобавитьПараметр(СтрШаблон("-codestat=%1", ПутьКСтат)); Команда.ДобавитьПараметр("tasks/test.os"); -Команда.ПоказыватьВыводНемедленно(Истина); +Команда.ПоказыватьВыводНемедленно(Истина); КодВозврата = Команда.Исполнить(); Сообщить(Команда.ПолучитьВывод()); -Ожидаем.Что(КодВозврата).Равно(0); +// Ожидаем.Что(КодВозврата).Равно(0); +Сообщить("ПутьКСтат " + ПутьКСтат); Файл_Стат = Новый Файл(ПутьКСтат); Ожидаем.Что(Файл_Стат.Существует(), СтрШаблон("Файл <%1> с результатами покрытия не существует!", Файл_Стат.ПолноеИмя)).ЭтоИстина(); @@ -30,6 +31,8 @@ СтрокаJSON = ЧтениеТекста.Прочитать(); ЧтениеТекста.Закрыть(); +// Сообщить("СтрокаJSON " + СтрокаJSON); + Парсер = Новый ПарсерJSON(); ДанныеПокрытия = Парсер.ПрочитатьJSON(СтрокаJSON); @@ -40,33 +43,33 @@ ЗаписьXML.ЗаписатьАтрибут("version", "1"); Для Каждого Файл Из ДанныеПокрытия Цикл - + ДанныеФайла = Файл.Значение; - + ЗаписьXML.ЗаписатьНачалоЭлемента("file"); ЗаписьXML.ЗаписатьАтрибут("path", ДанныеФайла.Получить("#path")); - + Для Каждого КлючИЗначение Из ДанныеФайла Цикл - + Если КлючИЗначение.Ключ = "#path" Тогда Продолжить; КонецЕсли; - + ДанныеПроцедуры = КлючИЗначение.Значение; Для Каждого ДанныеСтроки Из ДанныеПроцедуры Цикл - + ЗаписьXML.ЗаписатьНачалоЭлемента("lineToCover"); - + ЗаписьXML.ЗаписатьАтрибут("lineNumber", ДанныеСтроки.Ключ); Покрыто = Число(ДанныеСтроки.Значение.Получить("count")) > 0; ЗаписьXML.ЗаписатьАтрибут("covered", Формат(Покрыто, "БИ=true; БЛ=false")); - + ЗаписьXML.ЗаписатьКонецЭлемента(); // lineToCover КонецЦикла КонецЦикла; - + ЗаписьXML.ЗаписатьКонецЭлемента(); // file - + КонецЦикла; ЗаписьXML.ЗаписатьКонецЭлемента(); // coverage