From 6467330f7a0881d9cbf2df43f417eac2246f38f2 Mon Sep 17 00:00:00 2001 From: ivan ivanov Date: Thu, 30 Jul 2026 13:21:41 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9E=D0=BF=D1=86=D0=B8=D0=B8=20=D0=BF=D0=BE?= =?UTF-8?q?=D1=81=D0=BB=D0=B5=20=D0=BF=D0=BE=D0=B7=D0=B8=D1=86=D0=B8=D0=BE?= =?UTF-8?q?=D0=BD=D0=BD=D1=8B=D1=85=20=D0=B0=D1=80=D0=B3=D1=83=D0=BC=D0=B5?= =?UTF-8?q?=D0=BD=D1=82=D0=BE=D0=B2=20+=20=D0=B4=D0=B8=D0=B0=D0=B3=D0=BD?= =?UTF-8?q?=D0=BE=D1=81=D1=82=D0=B8=D0=BA=D0=B0=20=D0=BE=D1=88=D0=B8=D0=B1?= =?UTF-8?q?=D0=BA=D0=B8=20=D1=80=D0=B0=D0=B7=D0=B1=D0=BE=D1=80=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Парсер прерывал поиск опций на первом позиционном аргументе, из-за чего вызовы вида 'app ARG --opt значение' завершались ошибкой чтения параметров. Теперь позиционные аргументы пропускаются при сканировании, и опции можно указывать как до, так и после них. Семантика '--' (конец опций) сохранена. В сообщение 'Ошибка чтения параметров команды' добавлен список аргументов, которые не удалось разобрать. Co-Authored-By: Claude Fable 5 --- ...21\200\321\201\320\265\321\200\320\260.os" | 5 ++-- ...20\266\320\265\320\275\320\270\321\217.os" | 6 +++-- ...6\320\265\320\275\320\270\321\217_test.os" | 27 ++++++++++++++++++- 3 files changed, 33 insertions(+), 5 deletions(-) diff --git "a/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/internal/parser/\320\232\320\273\320\260\321\201\321\201\321\213/\320\236\320\277\321\206\320\270\321\217\320\237\320\260\321\200\321\201\320\265\321\200\320\260.os" "b/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/internal/parser/\320\232\320\273\320\260\321\201\321\201\321\213/\320\236\320\277\321\206\320\270\321\217\320\237\320\260\321\200\321\201\320\265\321\200\320\260.os" index 78246e5..05f55be 100644 --- "a/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/internal/parser/\320\232\320\273\320\260\321\201\321\201\321\213/\320\236\320\277\321\206\320\270\321\217\320\237\320\260\321\200\321\201\320\265\321\200\320\260.os" +++ "b/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/internal/parser/\320\232\320\273\320\260\321\201\321\201\321\213/\320\236\320\277\321\206\320\270\321\217\320\237\320\260\321\200\321\201\320\265\321\200\320\260.os" @@ -92,8 +92,9 @@ Индекс = Индекс + РезультатПоискаКороткойОпции.ПрибавочныйИндекс; Иначе - Результат.РезультатПоиска = Опция.УстановленаИзПеременнойОкружения; - Возврат Результат; + // Позиционный аргумент - пропускаем и продолжаем поиск опции правее. + // Так опции можно указывать и до, и после позиционных аргументов. + Индекс = Индекс + 1; КонецЕсли; КонецЦикла; diff --git "a/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\274\320\260\320\275\320\264\320\260\320\237\321\200\320\270\320\273\320\276\320\266\320\265\320\275\320\270\321\217.os" "b/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\274\320\260\320\275\320\264\320\260\320\237\321\200\320\270\320\273\320\276\320\266\320\265\320\275\320\270\321\217.os" index 20ee546..80f09a3 100644 --- "a/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\274\320\260\320\275\320\264\320\260\320\237\321\200\320\270\320\273\320\276\320\266\320\265\320\275\320\270\321\217.os" +++ "b/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\274\320\260\320\275\320\264\320\260\320\237\321\200\320\270\320\273\320\276\320\266\320\265\320\275\320\270\321\217.os" @@ -400,9 +400,11 @@ ОшибкаЧтения = Не НачальноеСостояние.Прочитать(МассивАргументовКПарсингу); Если ОшибкаЧтения Тогда - Лог.КритичнаяОшибка("Ошибка чтения параметров команды"); + ОписаниеОшибкиЧтения = СтрШаблон("Ошибка чтения параметров команды: %1", + СтрСоединить(МассивАргументовКПарсингу, " ")); + Лог.КритичнаяОшибка(ОписаниеОшибкиЧтения); ВывестиСправку(); - ВызватьИсключение "Ошибка чтения параметров команды"; + ВызватьИсключение ОписаниеОшибкиЧтения; КонецЕсли; ВыполнитьДействиеКоманды("ПередВыполнениемКоманды"); diff --git "a/tests/\320\232\320\276\320\274\320\260\320\275\320\264\320\260\320\237\321\200\320\270\320\273\320\276\320\266\320\265\320\275\320\270\321\217_test.os" "b/tests/\320\232\320\276\320\274\320\260\320\275\320\264\320\260\320\237\321\200\320\270\320\273\320\276\320\266\320\265\320\275\320\270\321\217_test.os" index 8b6c10c..37d8b92 100644 --- "a/tests/\320\232\320\276\320\274\320\260\320\275\320\264\320\260\320\237\321\200\320\270\320\273\320\276\320\266\320\265\320\275\320\270\321\217_test.os" +++ "b/tests/\320\232\320\276\320\274\320\260\320\275\320\264\320\260\320\237\321\200\320\270\320\273\320\276\320\266\320\265\320\275\320\270\321\217_test.os" @@ -34,6 +34,7 @@ // ИменаТестов.Добавить("ТестДолжен_ПроверитьРаботуСОднимТиреВАргументах"); ИменаТестов.Добавить("ТестДолжен_ПроверитьСбросОпцийПередАргументами"); + ИменаТестов.Добавить("ТестДолжен_ПроверитьОпцииПослеПозиционногоАргумента"); // ИменаТестов.Добавить("ТестДолжен_ПроверитьСбросМножественныхОпций"); ИменаТестов.Добавить("ТестДолжен_СтандартнуюСтрокуИспользования"); @@ -395,7 +396,31 @@ КонецПроцедуры -Функция ПодготовитьТестовуюКоманду(Спек = "") +Процедура ТестДолжен_ПроверитьОпцииПослеПозиционногоАргумента() Экспорт + + Команда = ПодготовитьТестовуюКоманду(); + + ОпцияОтчет = Команда.Опция("r report", "", "Тестовая опция со значением"); + ОпцияФлаг = Команда.Опция("f force", Ложь, "Тестовый флаг").Флаг(); + ARG1 = Команда.Аргумент("ARG1", "", "Тестовый аргумент").Обязательный(Ложь); + + Аргументы = Новый Массив; + + Аргументы.Добавить("ЗначениеАргумента"); + Аргументы.Добавить("--report"); + Аргументы.Добавить("build/junit.xml"); + Аргументы.Добавить("-f"); + + РезультатВыполнения = ВыполнитьКомандуПриложения(Команда, Аргументы); + + Утверждения.ПроверитьИстину(РезультатВыполнения, "Команда с опциями после позиционного аргумента должна выполниться"); + Утверждения.ПроверитьРавенство(ОпцияОтчет.Значение, "build/junit.xml", "Значение опции после аргумента должно быть прочитано"); + Утверждения.ПроверитьРавенство(ОпцияФлаг.Значение, Истина, "Флаг после аргумента должен быть прочитан"); + Утверждения.ПроверитьРавенство(ARG1.Значение, "ЗначениеАргумента", "Значение аргумента должно быть прочитано"); + +КонецПроцедуры + +Функция ПодготовитьТестовуюКоманду(Спек = "") Команда = Новый КомандаПриложения("testapp", "Тестовое приложения", ЭтотОбъект);