From b6ed3df8007004e44c3a3189387d7ec55722800e Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 2 Sep 2026 21:58:25 +0000 Subject: [PATCH 1/5] =?UTF-8?q?=D0=A3=D1=81=D1=82=D0=B0=D0=BD=D0=BE=D0=B2?= =?UTF-8?q?=D0=BA=D0=B0=20=D1=81=D0=B1=D0=BE=D1=80=D0=BE=D0=BA=20=D0=B2?= =?UTF-8?q?=D0=B5=D1=82=D0=BE=D0=BA=20=D0=B8=20=D0=BF=D1=83=D0=BB-=D1=80?= =?UTF-8?q?=D0=B5=D0=BA=D0=B2=D0=B5=D1=81=D1=82=D0=BE=D0=B2=20=D1=81=20bui?= =?UTF-8?q?ld.oscript.io?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Добавлена возможность устанавливать OneScript из сборок сервера сборок (Jenkins), а не только релизы с сайта oscript.io. Версия задается префиксом branch: или pr:, конкретная сборка - через решетку: ovm install branch:develop ovm install branch:feature/my-branch ovm install pr:1731 ovm install branch:develop#777 ovm use --install pr:1731 Алиасом установки по умолчанию становится имя ветки или пул-реквеста (косая черта заменяется дефисом, номер сборки дописывается через дефис). Список доступных к установке сборок выводится командой ovm ls --builds. Адрес сервера сборок и имя задания настраиваются параметрами build.server и build.job. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01MrVzeYybDtYzaPov6zw4Zk --- README.md | 60 +++- features/list-builds.feature | 19 ++ packagedef | 2 +- ...320\260\320\275\320\264\320\260Install.os" | 19 +- ...74\320\260\320\275\320\264\320\260List.os" | 26 +- ...274\320\260\320\275\320\264\320\260Use.os" | 2 +- ...0\260\321\202\320\276\321\200OneScript.os" | 24 +- ...1\200\321\201\320\270\320\270OneScript.os" | 159 ++++++++++ ...274\320\265\321\202\321\200\321\213OVM.os" | 26 ++ ...20\266\320\265\320\275\320\270\321\217.os" | 2 +- ...20\261\320\276\321\200\320\272\320\270.os" | 296 ++++++++++++++++++ ...0\262\321\211\320\270\320\272OneScript.os" | 99 ++++-- ...20\275\320\265\320\275\320\270\321\217.os" | 16 +- tests/buildServerTests.os | 242 ++++++++++++++ 14 files changed, 949 insertions(+), 43 deletions(-) create mode 100644 features/list-builds.feature create mode 100644 "src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\237\321\200\320\276\320\262\320\260\320\271\320\264\320\265\321\200\320\224\320\270\321\201\321\202\321\200\320\270\320\261\321\203\321\202\320\270\320\262\320\276\320\262\320\241\320\261\320\276\321\200\320\272\320\270.os" create mode 100644 tests/buildServerTests.os diff --git a/README.md b/README.md index 8f498c6..6e9806a 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ ovm - утилита, предназначенная для установки, ## Пререквизиты * Установленный `.Net Framework >=4.5.2` либо `Mono >=4.6` -* Работающий интернет +* Работающий интернет (доступ к [oscript.io](https://oscript.io), а для установки сборок веток и пул-реквестов - к [build.oscript.io](https://build.oscript.io)) ## Установка @@ -103,6 +103,44 @@ ovm install dev stable 1.0.19 # Установить стабильную, но ovm use --install dev # Активировать ночную сборку и установить, если ее нет ``` +### Установка сборок с сервера сборок + +Помимо релизов с сайта OneScript, ovm умеет ставить сборки веток и пул-реквестов с сервера сборок [build.oscript.io](https://build.oscript.io/job/1Script/). Это удобно, чтобы проверить свою библиотеку с еще не вышедшими изменениями движка. + +Версия задается с префиксом `branch:` (ветка) либо `pr:` (пул-реквест): + +```sh +ovm install branch:develop # Последняя успешная сборка ветки develop +ovm install branch:feature/my-branch # Ветка с косой чертой в имени +ovm install pr:1731 # Последняя успешная сборка пул-реквеста 1731 + +ovm use --install pr:1731 # Установить (если ее нет) и активировать сборку пул-реквеста +``` + +По умолчанию берется последняя успешная сборка. Конкретную сборку можно указать через решетку: + +```sh +ovm install branch:develop#777 # Сборка №777 ветки develop +``` + +Каталогом установки (алиасом) по умолчанию становится имя ветки или пул-реквеста, косая черта заменяется на дефис, номер сборки дописывается через дефис: + +|Версия|Алиас| +|-|- +|`branch:develop`|`develop` +|`branch:feature/my-branch`|`feature-my-branch` +|`pr:1731`|`PR-1731` +|`branch:develop#777`|`develop-777` + +Как и для обычных версий, алиас можно задать явно опцией `--name`: + +```sh +ovm install --name test_pr pr:1731 +ovm use test_pr +``` + +Список веток и пул-реквестов, доступных к установке, выводится командой `ovm ls --builds` (см. [Вывод установленных версий OneScript](#вывод-установленных-версий-onescript)). + ### Активация OneScript Для запуска `oscript` и прочих утилит без указания путей к ним необходимо произвести активацию версии OneScript. При этом в каталоге данных `ovm` создастся специальная символическая ссылка `current`, ведущая на активированную версию. @@ -135,6 +173,14 @@ $ ovm ls --remote # Вывод версий, доступных к устано 1.0.18 (http://oscript.io/downloads/archive/1_0_18) ``` +```sh +$ ovm ls --builds # Вывод сборок веток и пул-реквестов, доступных к установке с сервера сборок + +pr:1731 (https://build.oscript.io/job/1Script/job/PR-1731/) +branch:develop (https://build.oscript.io/job/1Script/job/develop/) +branch:feature/async (https://build.oscript.io/job/1Script/job/feature%252Fasync/) +``` + ```sh $ ovm ls --all # Вывод всех версий - установленных и доступных @@ -202,6 +248,18 @@ $ ovm config <имя параметра> <значение> $ ovm config oscript.server https://internal.oscript.io ``` +### Настройка сервера сборок + +```sh +$ ovm config build.server https://internal.build.oscript.io +$ ovm config build.job 1Script +``` + +|Параметр|Значение по умолчанию|Пояснение +|-|-|- +|build.server|https://build.oscript.io|Адрес сервера сборок (Jenkins), с которого ставятся версии `branch:` и `pr:` +|build.job|1Script|Имя многоветочного задания сборки OneScript на сервере сборок + ### Настройка прокси-сервера При работе за корпоративным прокси-сервером может потребоваться указание настроек прокси. diff --git a/features/list-builds.feature b/features/list-builds.feature new file mode 100644 index 0000000..1d368fa --- /dev/null +++ b/features/list-builds.feature @@ -0,0 +1,19 @@ +#language: ru + +Функциональность: Просмотр сборок с сервера сборок + +Как разработчик OneScript +Я хочу просматривать список сборок веток и пул-реквестов +Чтобы устанавливать движок из конкретной ветки или пул-реквеста + +Контекст: + Допустим Я устанавливаю переменной среды "OVM_INSTALL_PATH" значение "./temp/ovm" + +Сценарий: Вывод списка доступных сборок + Когда Я выполняю команду "oscript ./src/cmd/ovm.os ls --builds" + Тогда я вижу в консоли строку подобно "^branch:develop\s\(http.*\)" + И я вижу в консоли строку подобно "^pr:\d+\s\(http.*\)" + +Сценарий: Вывод списка доступных сборок в тихом режиме + Когда Я выполняю команду "oscript ./src/cmd/ovm.os ls --builds --quiet" + Тогда я вижу в консоли строку подобно "^branch:develop$" diff --git a/packagedef b/packagedef index 9685fa6..b05644d 100644 --- a/packagedef +++ b/packagedef @@ -1,5 +1,5 @@ Описание.Имя("ovm") - .Версия("1.6.2") + .Версия("1.7.0") .Автор("Nikita Fedkin") .АдресАвтора("nixel2007@gmail.com") .Описание("OneScript Version Manager") diff --git "a/src/cmd/\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\260Install.os" "b/src/cmd/\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\260Install.os" index e72bf04..f1b5043 100644 --- "a/src/cmd/\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\260Install.os" +++ "b/src/cmd/\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\260Install.os" @@ -6,6 +6,9 @@ &Пластилин Перем УстановщикOneScript; +&Пластилин +Перем ВерсииOneScript; + &Пластилин("ДетекторОкружения") Перем Окружение; @@ -38,9 +41,12 @@ КомандаПриложения.Аргумент( "VERSION", , - "Устанавливаемая версия (версии) OneScript. " + + "Устанавливаемая версия (версии) OneScript. " + "Допустимо использовать трехномерные версии (1.0.17, 1.0.18), " + - "lts, stable, dev, preview, lts-dev " + + "lts, stable, dev, preview, lts-dev, " + + "а также сборки веток и пул-реквестов с сервера сборок " + + "(branch:develop, branch:feature/my-branch, pr:1731). " + + "Конкретную сборку можно указать через решетку: branch:develop#777. " + "Может быть передано несколько значений") .ТМассивСтрок() .ВОкружении("OVM_INSTALL_VERSION"); @@ -78,10 +84,17 @@ КонецЦикла; Если МассивВерсийКУстановке.Количество() > 0 Тогда + + Если НЕ ЗначениеЗаполнено(АлиасВерсии) Тогда + АлиасВерсии = ВерсииOneScript.АлиасПоУмолчанию( + МассивВерсийКУстановке[МассивВерсийКУстановке.ВГраница()] + ); + КонецЕсли; + Лог.Информация( "Для начала использования версии OneScript, выполните команду: |ovm use %1", - ?(ЗначениеЗаполнено(АлиасВерсии), АлиасВерсии, МассивВерсийКУстановке[МассивВерсийКУстановке.ВГраница()]) + АлиасВерсии ); КонецЕсли; diff --git "a/src/cmd/\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\260List.os" "b/src/cmd/\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\260List.os" index 411b1f6..5f290ae 100644 --- "a/src/cmd/\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\260List.os" +++ "b/src/cmd/\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\260List.os" @@ -15,6 +15,12 @@ &ПоУмолчанию(Ложь) Перем ВыводитьСписокВерсийНаСайте; +&Опция(Имя = "builds b", Описание = "Вывести список сборок веток и пул-реквестов, доступных к установке с сервера сборок") +&ВОкружении("OVM_LIST_BUILDS") +&ТБулево +&ПоУмолчанию(Ложь) +Перем ВыводитьСписокСборок; + &Опция(Имя = "all a", Описание = "Вывести список всех версий: установленных и доступных на сайте") &ВОкружении("OVM_LIST_ALL") &ТБулево @@ -34,7 +40,9 @@ &ВыполнениеКоманды Процедура ВыполнениеКоманды() Экспорт - Если ВыводитьВсеВерсии Тогда + Если ВыводитьСписокСборок Тогда + ВывестиСписокДоступныхКУстановкеСборок(); + ИначеЕсли ВыводитьВсеВерсии Тогда ВывестиВсеВерсии(); ИначеЕсли ВыводитьСписокВерсийНаСайте Тогда ВывестиСписокДоступныхКУстановкеВерсий(); @@ -110,8 +118,22 @@ КонецЦикла; КонецПроцедуры +Процедура ВывестиСписокДоступныхКУстановкеСборок() + + СписокДоступныхСборок = ВерсииOneScript.ПолучитьСписокДоступныхКУстановкеСборок(); + Для Каждого ДоступнаяСборка Из СписокДоступныхСборок Цикл + Если ТихийРежим Тогда + Сообщение = ДоступнаяСборка.Алиас; + Иначе + Сообщение = СтрШаблон("%1 (%2)", ДоступнаяСборка.Алиас, ДоступнаяСборка.Путь); + КонецЕсли; + Лог.Информация(Сообщение); + КонецЦикла; + +КонецПроцедуры + Процедура ВывестиСписокДоступныхКУстановкеВерсий() - + СписокДоступныВерсий = ВерсииOneScript.ПолучитьСписокДоступныхКУстановкеВерсий(); Для Каждого ДоступнаяВерсия Из СписокДоступныВерсий Цикл Если ТихийРежим Тогда diff --git "a/src/cmd/\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\260Use.os" "b/src/cmd/\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\260Use.os" index a4f67c8..be83cdc 100644 --- "a/src/cmd/\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\260Use.os" +++ "b/src/cmd/\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\260Use.os" @@ -1,7 +1,7 @@ &Пластилин Перем АктиваторOneScript; -&Аргумент(Имя = "VERSION", Описание = "Используемая версия OneScript. Допустимо использовать трехномерные версии (1.0.17, 1.0.18), stable, dev") +&Аргумент(Имя = "VERSION", Описание = "Используемая версия OneScript. Допустимо использовать трехномерные версии (1.0.17, 1.0.18), stable, dev, а совместно с опцией --install - и сборки с сервера сборок (branch:develop, pr:1731)") &ВОкружении("OVM_USE_VERSION") &ТСтрока Перем ИспользуемаяВерсия; diff --git "a/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\220\320\272\321\202\320\270\320\262\320\260\321\202\320\276\321\200OneScript.os" "b/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\220\320\272\321\202\320\270\320\262\320\260\321\202\320\276\321\200OneScript.os" index 2f5826a..14b0080 100644 --- "a/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\220\320\272\321\202\320\270\320\262\320\260\321\202\320\276\321\200OneScript.os" +++ "b/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\220\320\272\321\202\320\270\320\262\320\260\321\202\320\276\321\200OneScript.os" @@ -29,11 +29,18 @@ // алиас не установлен // Процедура ИспользоватьВерсиюOneScript(Знач ИспользуемаяВерсия, Знач ВыполнятьУстановкуПриНеобходимости = Ложь) Экспорт - + + ВерсияКУстановке = ИспользуемаяВерсия; + ИспользуемаяВерсия = ВерсииOneScript.АлиасПоУмолчанию(ИспользуемаяВерсия); + Лог.Информация("Активация версии OneScript %1", ИспользуемаяВерсия); - ПроверитьНаличиеИспользуемойВерсии(ИспользуемаяВерсия, ВыполнятьУстановкуПриНеобходимости); - + ПроверитьНаличиеИспользуемойВерсии( + ИспользуемаяВерсия, + ВерсияКУстановке, + ВыполнятьУстановкуПриНеобходимости + ); + КаталогУстановки = ПараметрыOVM.КаталогУстановкиПоУмолчанию(); КаталогУстановкиВерсии = ОбъединитьПути(КаталогУстановки, ИспользуемаяВерсия); @@ -253,17 +260,20 @@ КонецПроцедуры -Процедура ПроверитьНаличиеИспользуемойВерсии(Знач ИспользуемаяВерсия, Знач ВыполнятьУстановкуПриНеобходимости) - +Процедура ПроверитьНаличиеИспользуемойВерсии( + Знач ИспользуемаяВерсия, + Знач ВерсияКУстановке, + Знач ВыполнятьУстановкуПриНеобходимости) + Если ВерсииOneScript.ВерсияУстановлена(ИспользуемаяВерсия) Тогда Возврат; КонецЕсли; - + Если ВыполнятьУстановкуПриНеобходимости Тогда ДополнительныеПараметры = УстановщикOneScript.ДополнительныеПараметрыУстановки(); ДополнительныеПараметры.ИспользоватьХ64 = Окружение.ЭтоX64(); - УстановщикOneScript.УстановитьOneScript(ИспользуемаяВерсия, , ДополнительныеПараметры); + УстановщикOneScript.УстановитьOneScript(ВерсияКУстановке, , ДополнительныеПараметры); Иначе ВызватьИсключение СтрШаблон("Не обнаружена требуемая версия <%1>", ИспользуемаяВерсия); КонецЕсли; diff --git "a/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\222\320\265\321\200\321\201\320\270\320\270OneScript.os" "b/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\222\320\265\321\200\321\201\320\270\320\270OneScript.os" index c562ffe..e24711c 100644 --- "a/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\222\320\265\321\200\321\201\320\270\320\270OneScript.os" +++ "b/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\222\320\265\321\200\321\201\320\270\320\270OneScript.os" @@ -12,6 +12,9 @@ &Пластилин Перем ПровайдерДистрибутивовВерсии; +&Пластилин +Перем ПровайдерДистрибутивовСборки; + Перем ДопустимыеАлиасы; // Кеш коллекции допустимых алиасов &Пластилин("ДетекторОкружения") @@ -253,6 +256,162 @@ Возврат ПровайдерДистрибутивовВерсии.ПолучитьДоступныеВидыДистрибутивовВерсии(НомерВерсии); КонецФункции +// Возвращает таблицу файлов сборки ветки или пул-реквеста с сервера сборок +// +// Параметры: +// ИмяСборки - Строка - Имя ветки или пул-реквеста на сервере сборок (develop, PR-1731, feature/my-branch) +// НомерСборки - Строка - Номер сборки. Если не указан, используется последняя успешная сборка +// +// Возвращаемое значение: +// ТаблицаЗначений - Вид,ИмяФайла,Архитектура,Ссылка +// +Функция ПолучитьДоступныеВидыДистрибутивовСборки(Знач ИмяСборки, Знач НомерСборки = "") Экспорт + Возврат ПровайдерДистрибутивовСборки.ПолучитьДоступныеВидыДистрибутивовСборки(ИмяСборки, НомерСборки); +КонецФункции + +// Получить информацию о сборках веток и пул-реквестов, доступных к установке +// +// Возвращаемое значение: +// ТаблицаЗначений - Информация о доступных сборках: +// * Алиас - Строка - Спецификация сборки для команды install (branch:develop, pr:1731) +// * Путь - Строка - Полный адрес задания сборки на сервере сборок +// +Функция ПолучитьСписокДоступныхКУстановкеСборок() Экспорт + Возврат ПровайдерДистрибутивовСборки.ПолучитьСписокДоступныхКУстановкеСборок(); +КонецФункции + +// Префикс версии, обозначающий установку сборки пул-реквеста с сервера сборок +// +// Возвращаемое значение: +// Строка - Префикс версии +// +Функция ПрефиксПулРеквеста() Экспорт + Возврат "pr:"; +КонецФункции + +// Префикс версии, обозначающий установку сборки ветки с сервера сборок +// +// Возвращаемое значение: +// Строка - Префикс версии +// +Функция ПрефиксВетки() Экспорт + Возврат "branch:"; +КонецФункции + +// Проверить, что переданная версия описывает сборку с сервера сборок +// +// Параметры: +// ПроверяемаяВерсия - Строка - Проверяемая версия +// +// Возвращаемое значение: +// Булево - Версия описывает сборку с сервера сборок +// +Функция ЭтоСборкаСервераСборок(Знач ПроверяемаяВерсия) Экспорт + + ВерсияВНижнемРегистре = НРег(Строка(ПроверяемаяВерсия)); + + Возврат СтрНачинаетсяС(ВерсияВНижнемРегистре, ПрефиксПулРеквеста()) + Или СтрНачинаетсяС(ВерсияВНижнемРегистре, ПрефиксВетки()); + +КонецФункции + +// Разобрать спецификацию сборки на имя задания и номер сборки +// +// Параметры: +// ВерсияКУстановке - Строка - Спецификация сборки вида branch:develop, pr:1731 или branch:develop#777 +// +// Возвращаемое значение: +// Структура - Параметры сборки: +// * ИмяСборки - Строка - Имя задания ветки или пул-реквеста на сервере сборок +// * НомерСборки - Строка - Номер сборки. Пустая строка означает последнюю успешную сборку +// +Функция ПараметрыСборки(Знач ВерсияКУстановке) Экспорт + + Если НЕ ЭтоСборкаСервераСборок(ВерсияКУстановке) Тогда + ВызватьИсключение СтрШаблон("Версия <%1> не является сборкой сервера сборок", ВерсияКУстановке); + КонецЕсли; + + ЭтоПулРеквест = СтрНачинаетсяС(НРег(ВерсияКУстановке), ПрефиксПулРеквеста()); + ДлинаПрефикса = СтрДлина(?(ЭтоПулРеквест, ПрефиксПулРеквеста(), ПрефиксВетки())); + + Результат = ОтделитьНомерСборки(СокрЛП(Сред(ВерсияКУстановке, ДлинаПрефикса + 1))); + + Если ЭтоПулРеквест Тогда + Результат.ИмяСборки = "PR-" + УдалитьПрефиксПулРеквеста(Результат.ИмяСборки); + КонецЕсли; + + Возврат Результат; + +КонецФункции + +// Получить алиас (имя каталога установки) по умолчанию для указанной версии +// +// Параметры: +// ВерсияКУстановке - Строка - Устанавливаемая версия или спецификация сборки +// +// Возвращаемое значение: +// Строка - Алиас версии +// +Функция АлиасПоУмолчанию(Знач ВерсияКУстановке) Экспорт + + Если НЕ ЭтоСборкаСервераСборок(ВерсияКУстановке) Тогда + Возврат ВерсияКУстановке; + КонецЕсли; + + ПараметрыСборки = ПараметрыСборки(ВерсияКУстановке); + + Алиас = СтрЗаменить(ПараметрыСборки.ИмяСборки, "/", "-"); + Если ЗначениеЗаполнено(ПараметрыСборки.НомерСборки) Тогда + Алиас = Алиас + "-" + ПараметрыСборки.НомерСборки; + КонецЕсли; + + Возврат Алиас; + +КонецФункции + +Функция ОтделитьНомерСборки(Знач Спецификация) + + Результат = Новый Структура("ИмяСборки, НомерСборки", Спецификация, ""); + + ПозицияРазделителя = СтрНайти(Спецификация, "#", НаправлениеПоиска.СКонца); + Если ПозицияРазделителя = 0 Тогда + Возврат Результат; + КонецЕсли; + + НомерСборки = Сред(Спецификация, ПозицияРазделителя + 1); + + // Решетка может быть частью имени ветки, номером сборки считаем только число после нее + Если НЕ ЭтоЦелоеЧисло(НомерСборки) Тогда + Возврат Результат; + КонецЕсли; + + Результат.ИмяСборки = Лев(Спецификация, ПозицияРазделителя - 1); + Результат.НомерСборки = НомерСборки; + + Возврат Результат; + +КонецФункции + +Функция ЭтоЦелоеЧисло(Знач ПроверяемаяСтрока) + + РегулярноеВыражение = Новый РегулярноеВыражение("^\d+$"); + РегулярноеВыражение.МногоСтрочный = Ложь; + + Возврат РегулярноеВыражение.Совпадает(ПроверяемаяСтрока); + +КонецФункции + +Функция УдалитьПрефиксПулРеквеста(Знач ИмяСборки) + + // Допускаем как pr:1731, так и pr:PR-1731 + Если СтрНачинаетсяС(НРег(ИмяСборки), "pr-") Тогда + Возврат Сред(ИмяСборки, СтрДлина("pr-") + 1); + КонецЕсли; + + Возврат ИмяСборки; + +КонецФункции + // <Описание функции> // // Возвращаемое значение: diff --git "a/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213OVM.os" "b/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213OVM.os" index 878f2cd..bf5e9be 100644 --- "a/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213OVM.os" +++ "b/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213OVM.os" @@ -3,6 +3,12 @@ &Деталька(Значение = "oscript.server", ЗначениеПоУмолчанию = "https://oscript.io") Перем АдресСайтаОСкрипт; +&Деталька(Значение = "build.server", ЗначениеПоУмолчанию = "https://build.oscript.io") +Перем АдресСервераСборок; + +&Деталька(Значение = "build.job", ЗначениеПоУмолчанию = "1Script") +Перем ЗаданиеСервераСборок; + &Пластилин("ДетекторОкружения") Перем Окружение; @@ -40,6 +46,26 @@ Возврат АдресСайтаОСкрипт; КонецФункции +// Адрес сервера сборок OneScript (build.oscript.io) +// +// Возвращаемое значение: +// Строка - Адрес сервера сборок +// +&Завязь(Тип = "Строка") +Функция АдресСервераСборок() Экспорт + Возврат АдресСервераСборок; +КонецФункции + +// Имя многоветочного задания сборки OneScript на сервере сборок +// +// Возвращаемое значение: +// Строка - Имя задания сборки +// +&Завязь(Тип = "Строка") +Функция ЗаданиеСервераСборок() Экспорт + Возврат ЗаданиеСервераСборок; +КонецФункции + // Полный адрес к каталогу дистрибутивов OneScript // // Возвращаемое значение: diff --git "a/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213\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\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213\320\237\321\200\320\270\320\273\320\276\320\266\320\265\320\275\320\270\321\217.os" index 74f5392..5b03725 100644 --- "a/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213\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\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213\320\237\321\200\320\270\320\273\320\276\320\266\320\265\320\275\320\270\321\217.os" @@ -12,5 +12,5 @@ КонецФункции Функция ВерсияПриложения() Экспорт - Возврат "1.6.2"; + Возврат "1.7.0"; КонецФункции diff --git "a/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\237\321\200\320\276\320\262\320\260\320\271\320\264\320\265\321\200\320\224\320\270\321\201\321\202\321\200\320\270\320\261\321\203\321\202\320\270\320\262\320\276\320\262\320\241\320\261\320\276\321\200\320\272\320\270.os" "b/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\237\321\200\320\276\320\262\320\260\320\271\320\264\320\265\321\200\320\224\320\270\321\201\321\202\321\200\320\270\320\261\321\203\321\202\320\270\320\262\320\276\320\262\320\241\320\261\320\276\321\200\320\272\320\270.os" new file mode 100644 index 0000000..d72ee98 --- /dev/null +++ "b/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\237\321\200\320\276\320\262\320\260\320\271\320\264\320\265\321\200\320\224\320\270\321\201\321\202\321\200\320\270\320\261\321\203\321\202\320\270\320\262\320\276\320\262\320\241\320\261\320\276\321\200\320\272\320\270.os" @@ -0,0 +1,296 @@ +&ЛогOVM +Перем Лог; + +&Пластилин +Перем ФабрикаИнтернетСоединения; + +&Пластилин +Перем АдресСервераСборок; + +&Пластилин +Перем ЗаданиеСервераСборок; + +&Желудь +Процедура ПриСозданииОбъекта() +КонецПроцедуры + +// Возвращает таблицу файлов дистрибутивов сборки ветки или пул-реквеста +// +// Параметры: +// ИмяСборки - Строка - Имя ветки или пул-реквеста на сервере сборок (develop, PR-1731, feature/my-branch) +// НомерСборки - Строка - Номер сборки. Если не указан, используется последняя успешная сборка +// +// Возвращаемое значение: +// ТаблицаЗначений - Вид,ИмяФайла,Архитектура,Ссылка +// Вид: fdd,scd-win,scd-lin,osx-x64,osx-arm64 +// ИмяФайла: имя файла +// Архитектура: x64,x86 +// Ссылка: ссылка на файл относительно адреса сервера сборок +// См. также: +// https://build.oscript.io/job/1Script/ - список веток и пул-реквестов +// +Функция ПолучитьДоступныеВидыДистрибутивовСборки(Знач ИмяСборки, Знач НомерСборки = "") Экспорт + + АдресСборки = АдресСборки(ЗаданиеСервераСборок, ИмяСборки, НомерСборки); + Ресурс = АдресСборки + "/api/json?tree=artifacts%5BfileName,relativePath%5D"; + + Лог.Отладка("Сервер: %1. Ресурс: %2", АдресСервераСборок, Ресурс); + + Соединение = ФабрикаИнтернетСоединения.Создать(АдресСервераСборок); + Ответ = Соединение.Получить(Новый HTTPЗапрос(Ресурс)); + + HTTP_OK = 200; + Если Ответ.КодСостояния <> HTTP_OK Тогда + ВызватьИсключение СтрШаблон( + "Не удалось найти сборку <%1> на сервере сборок %2: Статус: %3", + ПредставлениеСборки(ИмяСборки, НомерСборки), + АдресСервераСборок, + Ответ.КодСостояния + ); + КонецЕсли; + + ПереченьФайлов = ДистрибутивыИзОписанияАртефактов( + Ответ.ПолучитьТелоКакСтроку(), + АдресСборки + "/artifact" + ); + + Если ПереченьФайлов.Количество() = 0 Тогда + ВызватьИсключение СтрШаблон( + "Сборка <%1> на сервере сборок %2 не содержит дистрибутивов OneScript", + ПредставлениеСборки(ИмяСборки, НомерСборки), + АдресСервераСборок + ); + КонецЕсли; + + Возврат ПереченьФайлов; + +КонецФункции + +// Получить информацию о сборках веток и пул-реквестов, доступных к установке +// +// Возвращаемое значение: +// ТаблицаЗначений - Информация о доступных сборках: +// * Алиас - Строка - Спецификация сборки для команды install (branch:develop, pr:1731) +// * Путь - Строка - Полный адрес задания сборки на сервере сборок +// +Функция ПолучитьСписокДоступныхКУстановкеСборок() Экспорт + + Ресурс = СтрШаблон( + "job/%1/api/json?tree=jobs%%5Bname,url,lastSuccessfulBuild%%5Bnumber%%5D%%5D", + ЗаданиеСервераСборок + ); + + Лог.Отладка("Сервер: %1. Ресурс: %2", АдресСервераСборок, Ресурс); + + Соединение = ФабрикаИнтернетСоединения.Создать(АдресСервераСборок); + Ответ = Соединение.Получить(Новый HTTPЗапрос(Ресурс)); + + HTTP_OK = 200; + Если Ответ.КодСостояния <> HTTP_OK Тогда + ВызватьИсключение СтрШаблон( + "Не удалось получить список сборок с сервера сборок %1. Код ошибки: %2", + АдресСервераСборок, + Ответ.КодСостояния + ); + КонецЕсли; + + Возврат СборкиИзОписанияЗаданий(Ответ.ПолучитьТелоКакСтроку()); + +КонецФункции + +// Отбирает сборки, доступные к установке, из ответа сервера сборок со списком заданий +// +// Параметры: +// ТелоОтвета - Строка - Тело ответа api/json многоветочного задания со списком заданий веток +// +// Возвращаемое значение: +// ТаблицаЗначений - Алиас,Путь +// +Функция СборкиИзОписанияЗаданий(Знач ТелоОтвета) Экспорт + + ДоступныеСборки = Новый ТаблицаЗначений; + ДоступныеСборки.Колонки.Добавить("Алиас"); + ДоступныеСборки.Колонки.Добавить("Путь"); + + ЧтениеJSON = Новый ЧтениеJSON(); + ЧтениеJSON.УстановитьСтроку(ТелоОтвета); + + ОписаниеЗадания = ПрочитатьJSON(ЧтениеJSON, Истина); + Задания = ОписаниеЗадания.Получить("jobs"); + + Если Задания = Неопределено Тогда + Возврат ДоступныеСборки; + КонецЕсли; + + Для Каждого Задание Из Задания Цикл + + // Задание без успешных сборок установить нельзя + Если Не ЗначениеЗаполнено(Задание.Получить("lastSuccessfulBuild")) Тогда + Продолжить; + КонецЕсли; + + // Jenkins отдает "/" в именах веток закодированным как %2F + ИмяСборки = РаскодироватьСтроку(Задание.Получить("name"), СпособКодированияСтроки.КодировкаURL); + + ДоступнаяСборка = ДоступныеСборки.Добавить(); + ДоступнаяСборка.Алиас = СпецификацияСборки(ИмяСборки); + ДоступнаяСборка.Путь = Задание.Получить("url"); + + КонецЦикла; + + Возврат ДоступныеСборки; + +КонецФункции + +// Относительный адрес сборки ветки или пул-реквеста на сервере сборок +// +// Параметры: +// ИмяЗадания - Строка - Имя многоветочного задания сборки (например, 1Script) +// ИмяСборки - Строка - Имя ветки или пул-реквеста (например, develop или PR-1731) +// НомерСборки - Строка - Номер сборки. Если не указан, используется последняя успешная сборка +// +// Возвращаемое значение: +// Строка - Относительный адрес сборки +// +Функция АдресСборки(Знач ИмяЗадания, Знач ИмяСборки, Знач НомерСборки = "") Экспорт + + // Jenkins хранит "/" в именах веток закодированным как %2F, + // поэтому в адресе задания он должен быть закодирован дважды. + ЗакодированноеИмяСборки = СтрЗаменить( + КодироватьСтроку(ИмяСборки, СпособКодированияСтроки.КодировкаURL), + "%2F", + "%252F" + ); + + Возврат СтрШаблон( + "job/%1/job/%2/%3", + ИмяЗадания, + ЗакодированноеИмяСборки, + ?(ЗначениеЗаполнено(НомерСборки), НомерСборки, "lastSuccessfulBuild") + ); + +КонецФункции + +Функция СпецификацияСборки(Знач ИмяСборки) + + РегулярноеВыражение = Новый РегулярноеВыражение("^PR-(\d+)$"); + РегулярноеВыражение.ИгнорироватьРегистр = Ложь; + РегулярноеВыражение.МногоСтрочный = Ложь; + + Совпадения = РегулярноеВыражение.НайтиСовпадения(ИмяСборки); + Если Совпадения.Количество() = 1 Тогда + Возврат "pr:" + Совпадения[0].Группы[1].Значение; + КонецЕсли; + + Возврат "branch:" + ИмяСборки; + +КонецФункции + +Функция ПредставлениеСборки(Знач ИмяСборки, Знач НомерСборки) + + Если Не ЗначениеЗаполнено(НомерСборки) Тогда + Возврат ИмяСборки; + КонецЕсли; + + Возврат ИмяСборки + "#" + НомерСборки; + +КонецФункции + +// Отбирает дистрибутивы OneScript из ответа сервера сборок со списком артефактов +// +// Параметры: +// ТелоОтвета - Строка - Тело ответа api/json сборки со списком артефактов +// АдресАртефактов - Строка - Адрес каталога артефактов сборки, к которому дописывается путь файла +// +// Возвращаемое значение: +// ТаблицаЗначений - Вид,ИмяФайла,Архитектура,Ссылка +// +Функция ДистрибутивыИзОписанияАртефактов(Знач ТелоОтвета, Знач АдресАртефактов) Экспорт + + ТаблицаРезультата = Новый ТаблицаЗначений(); + ТаблицаРезультата.Колонки.Добавить("Вид"); + ТаблицаРезультата.Колонки.Добавить("ИмяФайла"); + ТаблицаРезультата.Колонки.Добавить("Архитектура"); + ТаблицаРезультата.Колонки.Добавить("Ссылка"); + + ЧтениеJSON = Новый ЧтениеJSON(); + ЧтениеJSON.УстановитьСтроку(ТелоОтвета); + + ОписаниеСборки = ПрочитатьJSON(ЧтениеJSON, Истина); + Артефакты = ОписаниеСборки.Получить("artifacts"); + + Если Артефакты = Неопределено Тогда + Возврат ТаблицаРезультата; + КонецЕсли; + + Для Каждого Артефакт Из Артефакты Цикл + + ИмяФайла = Артефакт.Получить("fileName"); + ОписаниеДистрибутива = ОписаниеДистрибутиваПоИмениФайла(ИмяФайла); + + Если ОписаниеДистрибутива = Неопределено Тогда + Продолжить; + КонецЕсли; + + СтрокаТаблицы = ТаблицаРезультата.Добавить(); + СтрокаТаблицы.Вид = ОписаниеДистрибутива.Вид; + СтрокаТаблицы.Архитектура = ОписаниеДистрибутива.Архитектура; + СтрокаТаблицы.ИмяФайла = ИмяФайла; + СтрокаТаблицы.Ссылка = АдресАртефактов + "/" + Артефакт.Получить("relativePath"); + + КонецЦикла; + + Возврат ТаблицаРезультата; + +КонецФункции + +// Определяет вид и архитектуру дистрибутива OneScript по имени файла артефакта +// +// Параметры: +// ИмяФайла - Строка - Имя файла артефакта сборки +// +// Возвращаемое значение: +// Структура, Неопределено - Неопределено, если файл не является дистрибутивом OneScript: +// * Вид - Строка - Вид дистрибутива (fdd, scd-win, scd-lin, osx-x64, osx-arm64) +// * Архитектура - Строка - Разрядность дистрибутива (x86, x64) +// +Функция ОписаниеДистрибутиваПоИмениФайла(Знач ИмяФайла) Экспорт + + РегулярноеВыражение = Новый РегулярноеВыражение("^OneScript-.+-(fdd|win|linux|osx)-(x86|x64|arm64)\.zip$"); + РегулярноеВыражение.ИгнорироватьРегистр = Ложь; + РегулярноеВыражение.МногоСтрочный = Ложь; + + Совпадения = РегулярноеВыражение.НайтиСовпадения(ИмяФайла); + Если Совпадения.Количество() <> 1 Тогда + Возврат Неопределено; + КонецЕсли; + + Платформа = Совпадения[0].Группы[1].Значение; + Разрядность = Совпадения[0].Группы[2].Значение; + + Результат = Новый Структура("Вид, Архитектура"); + + Если Платформа = "osx" Тогда + Результат.Вид = "osx-" + Разрядность; + // Дистрибутивы для macOS на сайте OneScript помечены архитектурой x64 независимо от вида + Результат.Архитектура = "x64"; + Иначе + Результат.Вид = ВидДистрибутиваПоПлатформе(Платформа); + Результат.Архитектура = Разрядность; + КонецЕсли; + + Возврат Результат; + +КонецФункции + +Функция ВидДистрибутиваПоПлатформе(Знач Платформа) + + Если Платформа = "win" Тогда + Возврат "scd-win"; + ИначеЕсли Платформа = "linux" Тогда + Возврат "scd-lin"; + Иначе + Возврат Платформа; + КонецЕсли; + +КонецФункции diff --git "a/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\243\321\201\321\202\320\260\320\275\320\276\320\262\321\211\320\270\320\272OneScript.os" "b/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\243\321\201\321\202\320\260\320\275\320\276\320\262\321\211\320\270\320\272OneScript.os" index 73a9999..246c90c 100644 --- "a/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\243\321\201\321\202\320\260\320\275\320\276\320\262\321\211\320\270\320\272OneScript.os" +++ "b/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\243\321\201\321\202\320\260\320\275\320\276\320\262\321\211\320\270\320\272OneScript.os" @@ -47,7 +47,8 @@ КонецФункции // Установка указанной версии OneScript. -// Допустимо использовать трех-разрядные номера версий и шорткаты dev и stable +// Допустимо использовать трех-разрядные номера версий, шорткаты dev и stable, +// а также сборки с сервера сборок в формате build:<ветка или пул-реквест> // // Параметры: // ВерсияКУстановке - Строка - Имя версии, которую необходимо установить @@ -68,17 +69,17 @@ ИспользоватьХ64 = ДополнительныеПараметры.ИспользоватьХ64; ИспользоватьFDD = ДополнительныеПараметры.ИспользоватьFDD; + ПроверитьКорректностьПереданнойВерсии(ВерсияКУстановке); + Если ИспользоватьХ64 Тогда ИспользоватьХ64 = ПроверитьВозможностьУстановкиX64(ВерсияКУстановке); КонецЕсли; Лог.Информация("Установка OneScript %1...", ВерсияКУстановке); - + Если НЕ ЗначениеЗаполнено(АлиасВерсии) Тогда - АлиасВерсии = ВерсияКУстановке; + АлиасВерсии = ВерсииOneScript.АлиасПоУмолчанию(ВерсияКУстановке); КонецЕсли; - - ПроверитьКорректностьПереданнойВерсии(ВерсияКУстановке); КаталогУстановки = ПараметрыOVM.КаталогУстановкиПоУмолчанию(); КаталогУстановкиВерсии = ОбъединитьПути(КаталогУстановки, АлиасВерсии); @@ -115,12 +116,14 @@ Лог.Информация("Скачиваю установщик версии %1%2...", ВерсияКУстановке, ?(ИспользоватьХ64, "-x64", "")); ПутьКСохраняемомуФайлу = ВременныеФайлы.НовоеИмяФайла("zip"); - - Соединение = ФабрикаИнтернетСоединения.Создать(); - - Ресурс = ПолучитьПутьКСкачиваниюФайла(ВерсияКУстановке, ИспользоватьХ64, ИспользоватьFDD); + + ПараметрыСкачивания = ПолучитьПараметрыСкачиванияФайла(ВерсияКУстановке, ИспользоватьХ64, ИспользоватьFDD); + + Соединение = ФабрикаИнтернетСоединения.Создать(ПараметрыСкачивания.Сервер); + + Ресурс = ПараметрыСкачивания.Ресурс; Запрос = Новый HTTPЗапрос(Ресурс); - + Лог.Отладка("Сервер: %1. Ресурс: %2", Соединение.Сервер, Ресурс); Ответ = Соединение.Получить(Запрос, ПутьКСохраняемомуФайлу); @@ -260,44 +263,90 @@ Процедура ПроверитьКорректностьПереданнойВерсии(Знач ВерсияКУстановке) Если НЕ ЭтоДопустимыйНомерВерсии(ВерсияКУстановке) - И Не ВерсииOneScript.ДопустимыеАлиасы().СодержитКлюч(ВерсияКУстановке) Тогда - + И Не ВерсииOneScript.ДопустимыеАлиасы().СодержитКлюч(ВерсияКУстановке) + И Не ЭтоКорректнаяСпецификацияСборки(ВерсияКУстановке) Тогда + Лог.Ошибка("Версия имеет некорректный формат"); ВызватьИсключение ВерсияКУстановке; КонецЕсли; КонецПроцедуры -Функция ПолучитьПутьКСкачиваниюФайла(Знач ВерсияКУстановке, Знач ИспользоватьХ64, Знач ИспользоватьFDD) +Функция ЭтоКорректнаяСпецификацияСборки(Знач ВерсияКУстановке) + + Возврат ВерсииOneScript.ЭтоСборкаСервераСборок(ВерсияКУстановке) + И ЗначениеЗаполнено(ВерсииOneScript.ПараметрыСборки(ВерсияКУстановке).ИмяСборки); + +КонецФункции + +// Определяет сервер и ресурс, с которых необходимо скачать дистрибутив версии +// +// Параметры: +// ВерсияКУстановке - Строка - Устанавливаемая версия или спецификация сборки +// ИспользоватьХ64 - Булево - Устанавливать версию x64 +// ИспользоватьFDD - Булево - Устанавливать fdd дистрибутив +// +// Возвращаемое значение: +// Структура - Параметры скачивания дистрибутива: +// * Сервер - Строка - Адрес сервера, с которого скачивается дистрибутив +// * Ресурс - Строка - Адрес файла дистрибутива относительно адреса сервера +// +Функция ПолучитьПараметрыСкачиванияФайла(Знач ВерсияКУстановке, Знач ИспользоватьХ64, Знач ИспользоватьFDD) ОпределительДистрибутива = КоробочкаСОпределителями.Достать() .ИспользоватьХ64(ИспользоватьХ64) .ИспользоватьFDD(ИспользоватьFDD); - Если ЭтоДопустимыйНомерВерсии(ВерсияКУстановке) Тогда + Если ВерсииOneScript.ЭтоСборкаСервераСборок(ВерсияКУстановке) Тогда - ИскомаяВерсия = ВерсияКУстановке; - ОпределительДистрибутива.ЭтоДистрибутивНеткор(СтроковыеФункции.СравнитьВерсии(ВерсияКУстановке, "2.0") >= 0); + // Сервер сборок собирает только дистрибутивы OneScript 2.x + ОпределительДистрибутива.ЭтоДистрибутивНеткор(Истина); + + ПараметрыСборки = ВерсииOneScript.ПараметрыСборки(ВерсияКУстановке); + ПереченьФайлов = ВерсииOneScript.ПолучитьДоступныеВидыДистрибутивовСборки( + ПараметрыСборки.ИмяСборки, + ПараметрыСборки.НомерСборки + ); + + АдресСервера = ПараметрыOVM.АдресСервераСборок(); Иначе - ДанныеВерсии = ВерсииOneScript.ДопустимыеАлиасы() - .Получить(ВерсияКУстановке) - .ИначеВызватьИсключение("Ошибка получения пути к файлу по версии"); + Если ЭтоДопустимыйНомерВерсии(ВерсияКУстановке) Тогда - ИскомаяВерсия = ДанныеВерсии.Метка; + ИскомаяВерсия = ВерсияКУстановке; + ОпределительДистрибутива.ЭтоДистрибутивНеткор( + СтроковыеФункции.СравнитьВерсии(ВерсияКУстановке, "2.0") >= 0 + ); - КонецЕсли; + Иначе + + ДанныеВерсии = ВерсииOneScript.ДопустимыеАлиасы() + .Получить(ВерсияКУстановке) + .ИначеВызватьИсключение("Ошибка получения пути к файлу по версии"); - ПереченьФайлов = ВерсииOneScript.ПолучитьДоступныеВидыДистрибутивовВерсии(ИскомаяВерсия); + ИскомаяВерсия = ДанныеВерсии.Метка; - Возврат ОпределительДистрибутива.Выбрать(ПереченьФайлов); + КонецЕсли; + + ПереченьФайлов = ВерсииOneScript.ПолучитьДоступныеВидыДистрибутивовВерсии(ИскомаяВерсия); + + АдресСервера = ПараметрыOVM.АдресСайтаОСкрипт(); + + КонецЕсли; + + Возврат Новый Структура( + "Сервер, Ресурс", + АдресСервера, + ОпределительДистрибутива.Выбрать(ПереченьФайлов) + ); КонецФункции Функция ПроверитьВозможностьУстановкиX64(ВерсияКУстановке) - - Возврат ВерсииOneScript.ДопустимыеАлиасы().СодержитКлюч(ВерсияКУстановке) + + Возврат ВерсииOneScript.ЭтоСборкаСервераСборок(ВерсияКУстановке) + Или ВерсииOneScript.ДопустимыеАлиасы().СодержитКлюч(ВерсияКУстановке) Или СтроковыеФункции.СравнитьВерсии(ВерсияКУстановке, "1.2.0") >= 0; КонецФункции diff --git "a/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\244\320\260\320\261\321\200\320\270\320\272\320\260\320\230\320\275\321\202\320\265\321\200\320\275\320\265\321\202\320\241\320\276\320\265\320\264\320\270\320\275\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\244\320\260\320\261\321\200\320\270\320\272\320\260\320\230\320\275\321\202\320\265\321\200\320\275\320\265\321\202\320\241\320\276\320\265\320\264\320\270\320\275\320\265\320\275\320\270\321\217.os" index 6733265..8ee4b8e 100644 --- "a/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\244\320\260\320\261\321\200\320\270\320\272\320\260\320\230\320\275\321\202\320\265\321\200\320\275\320\265\321\202\320\241\320\276\320\265\320\264\320\270\320\275\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\244\320\260\320\261\321\200\320\270\320\272\320\260\320\230\320\275\321\202\320\265\321\200\320\275\320\265\321\202\320\241\320\276\320\265\320\264\320\270\320\275\320\265\320\275\320\270\321\217.os" @@ -26,7 +26,19 @@ Процедура ПриСозданииОбъекта() КонецПроцедуры -Функция Создать() Экспорт +// Создать соединение с указанным сервером +// +// Параметры: +// АдресСервера - Строка - Адрес сервера. По умолчанию используется адрес сайта OneScript +// +// Возвращаемое значение: +// HTTPСоединение - Соединение с сервером +// +Функция Создать(Знач АдресСервера = "") Экспорт + Если Не ЗначениеЗаполнено(АдресСервера) Тогда + АдресСервера = АдресСайтаОСкрипт; + КонецЕсли; + Если ИспользоватьПрокси = "true" Тогда Если Не ЗначениеЗаполнено(ПроксиСервер) Тогда @@ -63,7 +75,7 @@ Таймаут = 10; Соединение = Новый HTTPСоединение( - АдресСайтаОСкрипт, + АдресСервера, , , , diff --git a/tests/buildServerTests.os b/tests/buildServerTests.os new file mode 100644 index 0000000..dd89046 --- /dev/null +++ b/tests/buildServerTests.os @@ -0,0 +1,242 @@ +///////////////////////////////////////////////////// +// Тесты установки сборок с сервера сборок (build.oscript.io) +///////////////////////////////////////////////////// + +#Использовать "../src/core" + +Перем Версии; +Перем Провайдер; + +// BSLLS:DuplicateStringLiteral-off + +#Область РазборСпецификацииСборки + +&ПараметризованныйТест +&ИсточникЗначение("branch:develop", Истина) +&ИсточникЗначение("branch:feature/my-branch", Истина) +&ИсточникЗначение("BRANCH:develop", Истина) +&ИсточникЗначение("pr:1731", Истина) +&ИсточникЗначение("PR:1731", Истина) +&ИсточникЗначение("branch:develop#777", Истина) +&ИсточникЗначение("1.9.2", Ложь) +&ИсточникЗначение("dev", Ложь) +&ИсточникЗначение("", Ложь) +Процедура ОпределяетЧтоВерсияЯвляетсяСборкойСервераСборок(Знач Версия, Знач Ожидание) Экспорт + + Ожидаем.Что(Версии.ЭтоСборкаСервераСборок(Версия), Версия).Равно(Ожидание); + +КонецПроцедуры + +&ПараметризованныйТест +&ИсточникЗначение("branch:develop", "develop", "") +&ИсточникЗначение("branch:feature/my-branch", "feature/my-branch", "") +&ИсточникЗначение("BRANCH: develop ", "develop", "") +&ИсточникЗначение("pr:1731", "PR-1731", "") +&ИсточникЗначение("pr:PR-1731", "PR-1731", "") +&ИсточникЗначение("branch:develop#777", "develop", "777") +&ИсточникЗначение("pr:1731#3", "PR-1731", "3") +Процедура РазбираетСпецификациюСборкиНаИмяИНомер(Знач Версия, Знач ИмяСборки, Знач НомерСборки) Экспорт + + ПараметрыСборки = Версии.ПараметрыСборки(Версия); + + Ожидаем.Что(ПараметрыСборки.ИмяСборки, Версия).Равно(ИмяСборки); + Ожидаем.Что(ПараметрыСборки.НомерСборки, Версия).Равно(НомерСборки); + +КонецПроцедуры + +&Тест +Процедура СчитаетРешеткуЧастьюИмениВеткиЕслиЗаНейНеНомер() Экспорт + + ПараметрыСборки = Версии.ПараметрыСборки("branch:feature/issue#42-fix"); + + Ожидаем.Что(ПараметрыСборки.ИмяСборки).Равно("feature/issue#42-fix"); + Ожидаем.Что(ПараметрыСборки.НомерСборки).Равно(""); + +КонецПроцедуры + +&Тест +Процедура ВыбрасываетИсключениеПриРазбореОбычнойВерсииКакСборки() Экспорт + + ПараметрыДействия = Новый Массив; + ПараметрыДействия.Добавить("1.9.2"); + + Ожидаем.Что(Версии).Метод("ПараметрыСборки", ПараметрыДействия) + .ВыбрасываетИсключение("Версия <1.9.2> не является сборкой сервера сборок"); + +КонецПроцедуры + +&ПараметризованныйТест +&ИсточникЗначение("branch:develop", "develop") +&ИсточникЗначение("branch:feature/my-branch", "feature-my-branch") +&ИсточникЗначение("pr:1731", "PR-1731") +&ИсточникЗначение("branch:develop#777", "develop-777") +&ИсточникЗначение("pr:1731#3", "PR-1731-3") +&ИсточникЗначение("1.9.2", "1.9.2") +&ИсточникЗначение("dev", "dev") +Процедура ВозвращаетАлиасУстановкиПоУмолчанию(Знач Версия, Знач Ожидание) Экспорт + + Ожидаем.Что(Версии.АлиасПоУмолчанию(Версия), Версия).Равно(Ожидание); + +КонецПроцедуры + +#КонецОбласти + +#Область АдресаСборок + +&ПараметризованныйТест +&ИсточникЗначение("develop", "", "job/1Script/job/develop/lastSuccessfulBuild") +&ИсточникЗначение("PR-1731", "", "job/1Script/job/PR-1731/lastSuccessfulBuild") +&ИсточникЗначение("feature/my-branch", "", "job/1Script/job/feature%252Fmy-branch/lastSuccessfulBuild") +&ИсточникЗначение("develop", "777", "job/1Script/job/develop/777") +&ИсточникЗначение("PR-1731", "3", "job/1Script/job/PR-1731/3") +Процедура ФормируетАдресСборки(Знач ИмяСборки, Знач НомерСборки, Знач Ожидание) Экспорт + + Ожидаем.Что(Провайдер.АдресСборки("1Script", ИмяСборки, НомерСборки), ИмяСборки).Равно(Ожидание); + +КонецПроцедуры + +#КонецОбласти + +#Область ОпределениеВидаДистрибутива + +&ПараметризованныйТест +&ИсточникЗначение("OneScript-2.2.0-dev+777-fdd-x86.zip", "fdd", "x86") +&ИсточникЗначение("OneScript-2.2.0-dev+777-fdd-x64.zip", "fdd", "x64") +&ИсточникЗначение("OneScript-2.2.0-dev+777-win-x86.zip", "scd-win", "x86") +&ИсточникЗначение("OneScript-2.2.0-dev+777-win-x64.zip", "scd-win", "x64") +&ИсточникЗначение("OneScript-2.2.0-dev+777-linux-x64.zip", "scd-lin", "x64") +&ИсточникЗначение("OneScript-2.2.0-dev+777-osx-x64.zip", "osx-x64", "x64") +&ИсточникЗначение("OneScript-2.2.0-dev+777-osx-arm64.zip", "osx-arm64", "x64") +&ИсточникЗначение("OneScript-2.1.0-linux-x64.zip", "scd-lin", "x64") +Процедура ОпределяетВидДистрибутиваПоИмениФайла(Знач ИмяФайла, Знач Вид, Знач Архитектура) Экспорт + + ОписаниеДистрибутива = Провайдер.ОписаниеДистрибутиваПоИмениФайла(ИмяФайла); + + Ожидаем.Что(ОписаниеДистрибутива, ИмяФайла).Существует(); + Ожидаем.Что(ОписаниеДистрибутива.Вид, ИмяФайла).Равно(Вид); + Ожидаем.Что(ОписаниеДистрибутива.Архитектура, ИмяФайла).Равно(Архитектура); + +КонецПроцедуры + +&ПараметризованныйТест +&ИсточникЗначение("oscript-debug-1.1.0.vsix") +&ИсточникЗначение("syntax-helper.json") +&ИсточникЗначение("OneScript.2.2.0-dev.nupkg") +&ИсточникЗначение("tests.xml") +Процедура НеОпределяетВидДистрибутиваДляПостороннихАртефактов(Знач ИмяФайла) Экспорт + + Ожидаем.Что(Провайдер.ОписаниеДистрибутиваПоИмениФайла(ИмяФайла), ИмяФайла).ЭтоНеопределено(); + +КонецПроцедуры + +#КонецОбласти + +#Область РазборСпискаАртефактов + +&Тест +Процедура ОтбираетДистрибутивыИзСпискаАртефактовСборки() Экспорт + + ПереченьФайлов = Провайдер.ДистрибутивыИзОписанияАртефактов( + ОтветСоСпискомАртефактов(), + "job/1Script/job/develop/lastSuccessfulBuild/artifact" + ); + + Ожидаем.Что(ПереченьФайлов.Количество()).Равно(7); + + КритерийПоиска = Новый Структура("Вид, Архитектура", "scd-lin", "x64"); + НайденныеСтроки = ПереченьФайлов.НайтиСтроки(КритерийПоиска); + + Ожидаем.Что(НайденныеСтроки.Количество()).Равно(1); + Ожидаем.Что(НайденныеСтроки[0].ИмяФайла).Равно("OneScript-2.2.0-dev+777-linux-x64.zip"); + Ожидаем.Что(НайденныеСтроки[0].Ссылка).Равно( + "job/1Script/job/develop/lastSuccessfulBuild/artifact/built/OneScript-2.2.0-dev+777-linux-x64.zip" + ); + +КонецПроцедуры + +&Тест +Процедура ВозвращаетПустойПереченьФайловДляСборкиБезАртефактов() Экспорт + + ПереченьФайлов = Провайдер.ДистрибутивыИзОписанияАртефактов("{""artifacts"": []}", "artifact"); + + Ожидаем.Что(ПереченьФайлов.Количество()).Равно(0); + +КонецПроцедуры + +#КонецОбласти + +#Область РазборСпискаСборок + +&Тест +Процедура ОтбираетДоступныеСборкиИзСпискаЗаданий() Экспорт + + ДоступныеСборки = Провайдер.СборкиИзОписанияЗаданий(ОтветСоСпискомЗаданий()); + + // Задания без успешных сборок в список не попадают + Ожидаем.Что(ДоступныеСборки.Количество()).Равно(3); + + Ожидаем.Что(ДоступныеСборки[0].Алиас).Равно("pr:1555"); + Ожидаем.Что(ДоступныеСборки[0].Путь).Равно("https://build.oscript.io/job/1Script/job/PR-1555/"); + + Ожидаем.Что(ДоступныеСборки[1].Алиас).Равно("branch:develop"); + + // Косая черта в имени ветки приходит от Jenkins в закодированном виде + Ожидаем.Что(ДоступныеСборки[2].Алиас).Равно("branch:copilot/fix-debug-attach-issue"); + +КонецПроцедуры + +#КонецОбласти + +Функция ОтветСоСпискомАртефактов() + + Возврат "{ + | ""_class"": ""org.jenkinsci.plugins.workflow.job.WorkflowRun"", + | ""artifacts"": [ + | {""fileName"": ""syntax-helper.json"", ""relativePath"": ""built/docs/json/syntax-helper.json""}, + | {""fileName"": ""OneScript.2.2.0-dev.nupkg"", ""relativePath"": ""built/nuget/OneScript.2.2.0-dev.nupkg""}, + | {""fileName"": ""OneScript-2.2.0-dev+777-fdd-x64.zip"", ""relativePath"": ""built/OneScript-2.2.0-dev+777-fdd-x64.zip""}, + | {""fileName"": ""OneScript-2.2.0-dev+777-fdd-x86.zip"", ""relativePath"": ""built/OneScript-2.2.0-dev+777-fdd-x86.zip""}, + | {""fileName"": ""OneScript-2.2.0-dev+777-linux-x64.zip"", ""relativePath"": ""built/OneScript-2.2.0-dev+777-linux-x64.zip""}, + | {""fileName"": ""OneScript-2.2.0-dev+777-osx-arm64.zip"", ""relativePath"": ""built/OneScript-2.2.0-dev+777-osx-arm64.zip""}, + | {""fileName"": ""OneScript-2.2.0-dev+777-osx-x64.zip"", ""relativePath"": ""built/OneScript-2.2.0-dev+777-osx-x64.zip""}, + | {""fileName"": ""OneScript-2.2.0-dev+777-win-x64.zip"", ""relativePath"": ""built/OneScript-2.2.0-dev+777-win-x64.zip""}, + | {""fileName"": ""OneScript-2.2.0-dev+777-win-x86.zip"", ""relativePath"": ""built/OneScript-2.2.0-dev+777-win-x86.zip""}, + | {""fileName"": ""oscript-debug-1.1.0.vsix"", ""relativePath"": ""built/vscode/oscript-debug-1.1.0.vsix""} + | ] + |}"; + +КонецФункции + +Функция ОтветСоСпискомЗаданий() + + Возврат "{ + | ""_class"": ""org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject"", + | ""jobs"": [ + | { + | ""name"": ""PR-1555"", + | ""url"": ""https://build.oscript.io/job/1Script/job/PR-1555/"", + | ""lastSuccessfulBuild"": {""number"": 7} + | }, + | { + | ""name"": ""PR-1566"", + | ""url"": ""https://build.oscript.io/job/1Script/job/PR-1566/"", + | ""lastSuccessfulBuild"": null + | }, + | { + | ""name"": ""develop"", + | ""url"": ""https://build.oscript.io/job/1Script/job/develop/"", + | ""lastSuccessfulBuild"": {""number"": 777} + | }, + | { + | ""name"": ""copilot%2Ffix-debug-attach-issue"", + | ""url"": ""https://build.oscript.io/job/1Script/job/copilot%252Ffix-debug-attach-issue/"", + | ""lastSuccessfulBuild"": {""number"": 1} + | } + | ] + |}"; + +КонецФункции + +/////////////////////////// +Версии = Новый ВерсииOneScript; +Провайдер = Новый ПровайдерДистрибутивовСборки; From 48de0ab9845817915baf5f710045a9faacb1107e Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 2 Sep 2026 22:03:09 +0000 Subject: [PATCH 2/5] =?UTF-8?q?=D0=90=D0=BA=D1=82=D1=83=D0=B0=D0=BB=D0=B8?= =?UTF-8?q?=D0=B7=D0=B0=D1=86=D0=B8=D1=8F=20lib.config?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Манифест ссылался на src/core/Модули/ВерсииOneScript.os и src/core/Модули/ПараметрыOVM.os, которых нет с тех пор, как эти модули стали классами autumn. Из-за этого подключение ovm как библиотеки (#Использовать ovm) падало с ошибкой "Не найден файл ..., указанный в манифесте". В манифест добавлены все фактически существующие классы из src/core/Классы и src/cmd/Классы, включая новый ПровайдерДистрибутивовСборки. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01MrVzeYybDtYzaPov6zw4Zk --- lib.config | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/lib.config b/lib.config index e213981..3ed1b65 100644 --- a/lib.config +++ b/lib.config @@ -1,7 +1,26 @@ - + + + + + + + + + + + - - \ No newline at end of file + + + + + + + + + + + From 45077a7bdb9c66ee1b5eb406ae1c77d2efcbe94b Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 2 Sep 2026 22:07:40 +0000 Subject: [PATCH 3/5] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BF=D0=B0=D0=B4=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D1=8F=20BDD-=D1=81=D1=86=D0=B5=D0=BD=D0=B0=D1=80=D0=B8=D1=8F?= =?UTF-8?q?=20=D0=BD=D0=B0=20Windows?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Шаг проверял вывод регулярным выражением "^branch:develop$". На Windows строки вывода команды разделены CRLF, и "$" в многострочном режиме стоит перед "\n", то есть после "\r" - совпадения не находилось, и job test (default, 1testrunner) / build (windows-latest) падал. Якорь заменен на "\s*$": он съедает перевод каретки на Windows и остается пустым на Linux. Проверка при этом не ослабла - в нетихом режиме, где после алиаса идет адрес сборки, выражение по-прежнему не совпадает. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01MrVzeYybDtYzaPov6zw4Zk --- features/list-builds.feature | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/features/list-builds.feature b/features/list-builds.feature index 1d368fa..c459fdc 100644 --- a/features/list-builds.feature +++ b/features/list-builds.feature @@ -16,4 +16,5 @@ Сценарий: Вывод списка доступных сборок в тихом режиме Когда Я выполняю команду "oscript ./src/cmd/ovm.os ls --builds --quiet" - Тогда я вижу в консоли строку подобно "^branch:develop$" + # \s* перед $ - это перевод каретки в конце строки на Windows + Тогда я вижу в консоли строку подобно "^branch:develop\s*$" From d3e4f038ed4b1e62951a1f9117eadeee9f7bbc4f Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 2 Sep 2026 22:15:48 +0000 Subject: [PATCH 4/5] =?UTF-8?q?=D0=92=D0=B0=D0=BB=D0=B8=D0=B4=D0=B0=D1=86?= =?UTF-8?q?=D0=B8=D1=8F=20=D0=BD=D0=BE=D0=BC=D0=B5=D1=80=D0=B0=20=D0=BF?= =?UTF-8?q?=D1=83=D0=BB-=D1=80=D0=B5=D0=BA=D0=B2=D0=B5=D1=81=D1=82=D0=B0?= =?UTF-8?q?=20=D0=B8=20=D0=BF=D1=80=D0=B0=D0=B2=D0=BA=D0=B8=20=D0=BE=D0=BF?= =?UTF-8?q?=D0=B8=D1=81=D0=B0=D0=BD=D0=B8=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit По замечаниям ревью: - pr:abc и pr:PR-abc проходили проверку формата версии и уходили запросом на сервер сборок, где падали с 404 вместо внятной ошибки формата. Добавлена ВерсииOneScript.ЭтоКорректнаяСпецификацияСборки: для префикса pr: имя задания обязано быть PR-<число>. Установщик теперь использует ее вместо локальной проверки на заполненность имени. - В комментарии к УстановитьOneScript остался формат build:<...> из ранней версии, хотя код принимает только branch: и pr:. - В справке ovm use не было спецификаций с номером сборки, хотя при --install они поддерживаются. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01MrVzeYybDtYzaPov6zw4Zk --- ...274\320\260\320\275\320\264\320\260Use.os" | 2 +- ...1\200\321\201\320\270\320\270OneScript.os" | 25 +++++++++++++++++++ ...0\262\321\211\320\270\320\272OneScript.os" | 12 +++------ tests/buildServerTests.os | 20 +++++++++++++++ 4 files changed, 49 insertions(+), 10 deletions(-) diff --git "a/src/cmd/\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\260Use.os" "b/src/cmd/\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\260Use.os" index be83cdc..4a79db0 100644 --- "a/src/cmd/\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\260Use.os" +++ "b/src/cmd/\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\260Use.os" @@ -1,7 +1,7 @@ &Пластилин Перем АктиваторOneScript; -&Аргумент(Имя = "VERSION", Описание = "Используемая версия OneScript. Допустимо использовать трехномерные версии (1.0.17, 1.0.18), stable, dev, а совместно с опцией --install - и сборки с сервера сборок (branch:develop, pr:1731)") +&Аргумент(Имя = "VERSION", Описание = "Используемая версия OneScript. Допустимо использовать трехномерные версии (1.0.17, 1.0.18), stable, dev, а совместно с опцией --install - и сборки с сервера сборок (branch:develop, branch:develop#777, pr:1731, pr:1731#3)") &ВОкружении("OVM_USE_VERSION") &ТСтрока Перем ИспользуемаяВерсия; diff --git "a/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\222\320\265\321\200\321\201\320\270\320\270OneScript.os" "b/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\222\320\265\321\200\321\201\320\270\320\270OneScript.os" index e24711c..6a0e3e8 100644 --- "a/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\222\320\265\321\200\321\201\320\270\320\270OneScript.os" +++ "b/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\222\320\265\321\200\321\201\320\270\320\270OneScript.os" @@ -344,6 +344,31 @@ КонецФункции +// Проверить, что переданная версия является корректной спецификацией сборки +// +// Параметры: +// ПроверяемаяВерсия - Строка - Проверяемая версия +// +// Возвращаемое значение: +// Булево - Версия является корректной спецификацией сборки +// +Функция ЭтоКорректнаяСпецификацияСборки(Знач ПроверяемаяВерсия) Экспорт + + Если НЕ ЭтоСборкаСервераСборок(ПроверяемаяВерсия) Тогда + Возврат Ложь; + КонецЕсли; + + ИмяСборки = ПараметрыСборки(ПроверяемаяВерсия).ИмяСборки; + + Если СтрНачинаетсяС(НРег(ПроверяемаяВерсия), ПрефиксПулРеквеста()) Тогда + // Имя задания пул-реквеста на сервере сборок всегда PR-<номер> + Возврат ЭтоЦелоеЧисло(Сред(ИмяСборки, СтрДлина("PR-") + 1)); + КонецЕсли; + + Возврат ЗначениеЗаполнено(ИмяСборки); + +КонецФункции + // Получить алиас (имя каталога установки) по умолчанию для указанной версии // // Параметры: diff --git "a/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\243\321\201\321\202\320\260\320\275\320\276\320\262\321\211\320\270\320\272OneScript.os" "b/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\243\321\201\321\202\320\260\320\275\320\276\320\262\321\211\320\270\320\272OneScript.os" index 246c90c..1d8ebe3 100644 --- "a/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\243\321\201\321\202\320\260\320\275\320\276\320\262\321\211\320\270\320\272OneScript.os" +++ "b/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\243\321\201\321\202\320\260\320\275\320\276\320\262\321\211\320\270\320\272OneScript.os" @@ -48,7 +48,8 @@ // Установка указанной версии OneScript. // Допустимо использовать трех-разрядные номера версий, шорткаты dev и stable, -// а также сборки с сервера сборок в формате build:<ветка или пул-реквест> +// а также сборки с сервера сборок в формате branch:<ветка> или pr:<номер>, +// с необязательным номером сборки через решетку: branch:develop#777 // // Параметры: // ВерсияКУстановке - Строка - Имя версии, которую необходимо установить @@ -264,7 +265,7 @@ Процедура ПроверитьКорректностьПереданнойВерсии(Знач ВерсияКУстановке) Если НЕ ЭтоДопустимыйНомерВерсии(ВерсияКУстановке) И Не ВерсииOneScript.ДопустимыеАлиасы().СодержитКлюч(ВерсияКУстановке) - И Не ЭтоКорректнаяСпецификацияСборки(ВерсияКУстановке) Тогда + И Не ВерсииOneScript.ЭтоКорректнаяСпецификацияСборки(ВерсияКУстановке) Тогда Лог.Ошибка("Версия имеет некорректный формат"); @@ -272,13 +273,6 @@ КонецЕсли; КонецПроцедуры -Функция ЭтоКорректнаяСпецификацияСборки(Знач ВерсияКУстановке) - - Возврат ВерсииOneScript.ЭтоСборкаСервераСборок(ВерсияКУстановке) - И ЗначениеЗаполнено(ВерсииOneScript.ПараметрыСборки(ВерсияКУстановке).ИмяСборки); - -КонецФункции - // Определяет сервер и ресурс, с которых необходимо скачать дистрибутив версии // // Параметры: diff --git a/tests/buildServerTests.os b/tests/buildServerTests.os index dd89046..1680f27 100644 --- a/tests/buildServerTests.os +++ b/tests/buildServerTests.os @@ -65,6 +65,26 @@ КонецПроцедуры +&ПараметризованныйТест +&ИсточникЗначение("branch:develop", Истина) +&ИсточникЗначение("branch:feature/my-branch", Истина) +&ИсточникЗначение("branch:develop#777", Истина) +&ИсточникЗначение("pr:1731", Истина) +&ИсточникЗначение("pr:PR-1731", Истина) +&ИсточникЗначение("pr:1731#3", Истина) +// Имя задания пул-реквеста на сервере сборок всегда PR-<номер> +&ИсточникЗначение("pr:abc", Ложь) +&ИсточникЗначение("pr:PR-abc", Ложь) +&ИсточникЗначение("pr:", Ложь) +&ИсточникЗначение("branch:", Ложь) +&ИсточникЗначение("1.9.2", Ложь) +&ИсточникЗначение("dev", Ложь) +Процедура ПроверяетКорректностьСпецификацииСборки(Знач Версия, Знач Ожидание) Экспорт + + Ожидаем.Что(Версии.ЭтоКорректнаяСпецификацияСборки(Версия), Версия).Равно(Ожидание); + +КонецПроцедуры + &ПараметризованныйТест &ИсточникЗначение("branch:develop", "develop") &ИсточникЗначение("branch:feature/my-branch", "feature-my-branch") From e9a26b6d5b1da6e8a42f03426999995c089fdf47 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 2 Sep 2026 22:29:45 +0000 Subject: [PATCH 5/5] =?UTF-8?q?=D0=A3=D1=81=D1=82=D1=80=D0=B0=D0=BD=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=B7=D0=B0=D0=BC=D0=B5=D1=87=D0=B0=D0=BD?= =?UTF-8?q?=D0=B8=D0=B9=20=D1=81=D1=82=D0=B0=D1=82=D0=B8=D1=87=D0=B5=D1=81?= =?UTF-8?q?=D0=BA=D0=BE=D0=B3=D0=BE=20=D0=B0=D0=BD=D0=B0=D0=BB=D0=B8=D0=B7?= =?UTF-8?q?=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Quality Gate падал на 40 новых замечаниях BSL LS и покрытии 78.1% при пороге 80%. Стиль (27 замечаний): - IncorrectLineBreak: закрывающая скобка вызова не должна стоять на отдельной строке, а оператор конкатенации переносится в начало следующей строки. - MissingVariablesDescription: добавлены описания переменных в стиле репозитория - комментарием в конце строки объявления. - LineLength: описания аргумента use и опции ls --builds превышали 120 символов. Аннотации не допускают конкатенацию, поэтому описание аргумента use оформлено многострочным литералом. Покрытие: - Добавлены тесты на защитные ветки разбора ответов сервера сборок, когда в JSON нет ключа artifacts или jobs. - ПредставлениеСборки участвует в тексте ошибок, видимых пользователю, поэтому вынесено в контракт класса и покрыто тестом. Непокрытыми остаются только методы, обращающиеся к серверу сборок по HTTP. Всего тестов 110. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01MrVzeYybDtYzaPov6zw4Zk --- ...320\260\320\275\320\264\320\260Install.os" | 19 +++++---- ...74\320\260\320\275\320\264\320\260List.os" | 6 ++- ...274\320\260\320\275\320\264\320\260Use.os" | 6 ++- ...0\260\321\202\320\276\321\200OneScript.os" | 3 +- ...1\200\321\201\320\270\320\270OneScript.os" | 2 +- ...274\320\265\321\202\321\200\321\213OVM.os" | 4 +- ...20\261\320\276\321\200\320\272\320\270.os" | 40 ++++++++++--------- ...0\262\321\211\320\270\320\272OneScript.os" | 9 ++--- tests/buildServerTests.os | 28 +++++++++++++ 9 files changed, 74 insertions(+), 43 deletions(-) diff --git "a/src/cmd/\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\260Install.os" "b/src/cmd/\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\260Install.os" index f1b5043..30bfbe6 100644 --- "a/src/cmd/\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\260Install.os" +++ "b/src/cmd/\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\260Install.os" @@ -7,7 +7,7 @@ Перем УстановщикOneScript; &Пластилин -Перем ВерсииOneScript; +Перем ВерсииOneScript; // Работа с версиями OneScript &Пластилин("ДетекторОкружения") Перем Окружение; @@ -41,13 +41,13 @@ КомандаПриложения.Аргумент( "VERSION", , - "Устанавливаемая версия (версии) OneScript. " + - "Допустимо использовать трехномерные версии (1.0.17, 1.0.18), " + - "lts, stable, dev, preview, lts-dev, " + - "а также сборки веток и пул-реквестов с сервера сборок " + - "(branch:develop, branch:feature/my-branch, pr:1731). " + - "Конкретную сборку можно указать через решетку: branch:develop#777. " + - "Может быть передано несколько значений") + "Устанавливаемая версия (версии) OneScript. " + + "Допустимо использовать трехномерные версии (1.0.17, 1.0.18), " + + "lts, stable, dev, preview, lts-dev, " + + "а также сборки веток и пул-реквестов с сервера сборок " + + "(branch:develop, branch:feature/my-branch, pr:1731). " + + "Конкретную сборку можно указать через решетку: branch:develop#777. " + + "Может быть передано несколько значений") .ТМассивСтрок() .ВОкружении("OVM_INSTALL_VERSION"); @@ -87,8 +87,7 @@ Если НЕ ЗначениеЗаполнено(АлиасВерсии) Тогда АлиасВерсии = ВерсииOneScript.АлиасПоУмолчанию( - МассивВерсийКУстановке[МассивВерсийКУстановке.ВГраница()] - ); + МассивВерсийКУстановке[МассивВерсийКУстановке.ВГраница()]); КонецЕсли; Лог.Информация( diff --git "a/src/cmd/\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\260List.os" "b/src/cmd/\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\260List.os" index 5f290ae..0db561e 100644 --- "a/src/cmd/\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\260List.os" +++ "b/src/cmd/\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\260List.os" @@ -15,11 +15,13 @@ &ПоУмолчанию(Ложь) Перем ВыводитьСписокВерсийНаСайте; -&Опция(Имя = "builds b", Описание = "Вывести список сборок веток и пул-реквестов, доступных к установке с сервера сборок") +&Опция( + Имя = "builds b", + Описание = "Вывести список сборок веток и пул-реквестов, доступных к установке с сервера сборок") &ВОкружении("OVM_LIST_BUILDS") &ТБулево &ПоУмолчанию(Ложь) -Перем ВыводитьСписокСборок; +Перем ВыводитьСписокСборок; // Признак вывода списка сборок с сервера сборок &Опция(Имя = "all a", Описание = "Вывести список всех версий: установленных и доступных на сайте") &ВОкружении("OVM_LIST_ALL") diff --git "a/src/cmd/\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\260Use.os" "b/src/cmd/\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\260Use.os" index 4a79db0..78a201b 100644 --- "a/src/cmd/\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\260Use.os" +++ "b/src/cmd/\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\260Use.os" @@ -1,7 +1,11 @@ &Пластилин Перем АктиваторOneScript; -&Аргумент(Имя = "VERSION", Описание = "Используемая версия OneScript. Допустимо использовать трехномерные версии (1.0.17, 1.0.18), stable, dev, а совместно с опцией --install - и сборки с сервера сборок (branch:develop, branch:develop#777, pr:1731, pr:1731#3)") +&Аргумент( + Имя = "VERSION", + Описание = "Используемая версия OneScript. Допустимо использовать трехномерные версии + |(1.0.17, 1.0.18), stable, dev, а совместно с опцией --install - и сборки с сервера + |сборок (branch:develop, branch:develop#777, pr:1731, pr:1731#3)") &ВОкружении("OVM_USE_VERSION") &ТСтрока Перем ИспользуемаяВерсия; diff --git "a/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\220\320\272\321\202\320\270\320\262\320\260\321\202\320\276\321\200OneScript.os" "b/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\220\320\272\321\202\320\270\320\262\320\260\321\202\320\276\321\200OneScript.os" index 14b0080..b4cb8b8 100644 --- "a/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\220\320\272\321\202\320\270\320\262\320\260\321\202\320\276\321\200OneScript.os" +++ "b/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\220\320\272\321\202\320\270\320\262\320\260\321\202\320\276\321\200OneScript.os" @@ -38,8 +38,7 @@ ПроверитьНаличиеИспользуемойВерсии( ИспользуемаяВерсия, ВерсияКУстановке, - ВыполнятьУстановкуПриНеобходимости - ); + ВыполнятьУстановкуПриНеобходимости); КаталогУстановки = ПараметрыOVM.КаталогУстановкиПоУмолчанию(); КаталогУстановкиВерсии = ОбъединитьПути(КаталогУстановки, ИспользуемаяВерсия); diff --git "a/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\222\320\265\321\200\321\201\320\270\320\270OneScript.os" "b/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\222\320\265\321\200\321\201\320\270\320\270OneScript.os" index 6a0e3e8..55bfef3 100644 --- "a/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\222\320\265\321\200\321\201\320\270\320\270OneScript.os" +++ "b/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\222\320\265\321\200\321\201\320\270\320\270OneScript.os" @@ -13,7 +13,7 @@ Перем ПровайдерДистрибутивовВерсии; &Пластилин -Перем ПровайдерДистрибутивовСборки; +Перем ПровайдерДистрибутивовСборки; // Провайдер дистрибутивов сборок сервера сборок Перем ДопустимыеАлиасы; // Кеш коллекции допустимых алиасов diff --git "a/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213OVM.os" "b/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213OVM.os" index bf5e9be..1c73c9f 100644 --- "a/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213OVM.os" +++ "b/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\213OVM.os" @@ -4,10 +4,10 @@ Перем АдресСайтаОСкрипт; &Деталька(Значение = "build.server", ЗначениеПоУмолчанию = "https://build.oscript.io") -Перем АдресСервераСборок; +Перем АдресСервераСборок; // Адрес сервера сборок &Деталька(Значение = "build.job", ЗначениеПоУмолчанию = "1Script") -Перем ЗаданиеСервераСборок; +Перем ЗаданиеСервераСборок; // Имя многоветочного задания сборки OneScript &Пластилин("ДетекторОкружения") Перем Окружение; diff --git "a/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\237\321\200\320\276\320\262\320\260\320\271\320\264\320\265\321\200\320\224\320\270\321\201\321\202\321\200\320\270\320\261\321\203\321\202\320\270\320\262\320\276\320\262\320\241\320\261\320\276\321\200\320\272\320\270.os" "b/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\237\321\200\320\276\320\262\320\260\320\271\320\264\320\265\321\200\320\224\320\270\321\201\321\202\321\200\320\270\320\261\321\203\321\202\320\270\320\262\320\276\320\262\320\241\320\261\320\276\321\200\320\272\320\270.os" index d72ee98..44cef26 100644 --- "a/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\237\321\200\320\276\320\262\320\260\320\271\320\264\320\265\321\200\320\224\320\270\321\201\321\202\321\200\320\270\320\261\321\203\321\202\320\270\320\262\320\276\320\262\320\241\320\261\320\276\321\200\320\272\320\270.os" +++ "b/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\237\321\200\320\276\320\262\320\260\320\271\320\264\320\265\321\200\320\224\320\270\321\201\321\202\321\200\320\270\320\261\321\203\321\202\320\270\320\262\320\276\320\262\320\241\320\261\320\276\321\200\320\272\320\270.os" @@ -1,14 +1,14 @@ &ЛогOVM -Перем Лог; +Перем Лог; // Лог приложения &Пластилин -Перем ФабрикаИнтернетСоединения; +Перем ФабрикаИнтернетСоединения; // Фабрика соединений с сервером сборок &Пластилин -Перем АдресСервераСборок; +Перем АдресСервераСборок; // Адрес сервера сборок &Пластилин -Перем ЗаданиеСервераСборок; +Перем ЗаданиеСервераСборок; // Имя многоветочного задания сборки OneScript &Желудь Процедура ПриСозданииОбъекта() @@ -45,21 +45,18 @@ "Не удалось найти сборку <%1> на сервере сборок %2: Статус: %3", ПредставлениеСборки(ИмяСборки, НомерСборки), АдресСервераСборок, - Ответ.КодСостояния - ); + Ответ.КодСостояния); КонецЕсли; ПереченьФайлов = ДистрибутивыИзОписанияАртефактов( Ответ.ПолучитьТелоКакСтроку(), - АдресСборки + "/artifact" - ); + АдресСборки + "/artifact"); Если ПереченьФайлов.Количество() = 0 Тогда ВызватьИсключение СтрШаблон( "Сборка <%1> на сервере сборок %2 не содержит дистрибутивов OneScript", ПредставлениеСборки(ИмяСборки, НомерСборки), - АдресСервераСборок - ); + АдресСервераСборок); КонецЕсли; Возврат ПереченьФайлов; @@ -77,8 +74,7 @@ Ресурс = СтрШаблон( "job/%1/api/json?tree=jobs%%5Bname,url,lastSuccessfulBuild%%5Bnumber%%5D%%5D", - ЗаданиеСервераСборок - ); + ЗаданиеСервераСборок); Лог.Отладка("Сервер: %1. Ресурс: %2", АдресСервераСборок, Ресурс); @@ -90,8 +86,7 @@ ВызватьИсключение СтрШаблон( "Не удалось получить список сборок с сервера сборок %1. Код ошибки: %2", АдресСервераСборок, - Ответ.КодСостояния - ); + Ответ.КодСостояния); КонецЕсли; Возврат СборкиИзОписанияЗаданий(Ответ.ПолучитьТелоКакСтроку()); @@ -159,15 +154,13 @@ ЗакодированноеИмяСборки = СтрЗаменить( КодироватьСтроку(ИмяСборки, СпособКодированияСтроки.КодировкаURL), "%2F", - "%252F" - ); + "%252F"); Возврат СтрШаблон( "job/%1/job/%2/%3", ИмяЗадания, ЗакодированноеИмяСборки, - ?(ЗначениеЗаполнено(НомерСборки), НомерСборки, "lastSuccessfulBuild") - ); + ?(ЗначениеЗаполнено(НомерСборки), НомерСборки, "lastSuccessfulBuild")); КонецФункции @@ -186,7 +179,16 @@ КонецФункции -Функция ПредставлениеСборки(Знач ИмяСборки, Знач НомерСборки) +// Представление сборки для сообщений пользователю +// +// Параметры: +// ИмяСборки - Строка - Имя ветки или пул-реквеста на сервере сборок +// НомерСборки - Строка - Номер сборки. Если не указан, подразумевается последняя успешная сборка +// +// Возвращаемое значение: +// Строка - Представление сборки +// +Функция ПредставлениеСборки(Знач ИмяСборки, Знач НомерСборки = "") Экспорт Если Не ЗначениеЗаполнено(НомерСборки) Тогда Возврат ИмяСборки; diff --git "a/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\243\321\201\321\202\320\260\320\275\320\276\320\262\321\211\320\270\320\272OneScript.os" "b/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\243\321\201\321\202\320\260\320\275\320\276\320\262\321\211\320\270\320\272OneScript.os" index 1d8ebe3..e6e9541 100644 --- "a/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\243\321\201\321\202\320\260\320\275\320\276\320\262\321\211\320\270\320\272OneScript.os" +++ "b/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\243\321\201\321\202\320\260\320\275\320\276\320\262\321\211\320\270\320\272OneScript.os" @@ -299,8 +299,7 @@ ПараметрыСборки = ВерсииOneScript.ПараметрыСборки(ВерсияКУстановке); ПереченьФайлов = ВерсииOneScript.ПолучитьДоступныеВидыДистрибутивовСборки( ПараметрыСборки.ИмяСборки, - ПараметрыСборки.НомерСборки - ); + ПараметрыСборки.НомерСборки); АдресСервера = ПараметрыOVM.АдресСервераСборок(); @@ -310,8 +309,7 @@ ИскомаяВерсия = ВерсияКУстановке; ОпределительДистрибутива.ЭтоДистрибутивНеткор( - СтроковыеФункции.СравнитьВерсии(ВерсияКУстановке, "2.0") >= 0 - ); + СтроковыеФункции.СравнитьВерсии(ВерсияКУстановке, "2.0") >= 0); Иначе @@ -332,8 +330,7 @@ Возврат Новый Структура( "Сервер, Ресурс", АдресСервера, - ОпределительДистрибутива.Выбрать(ПереченьФайлов) - ); + ОпределительДистрибутива.Выбрать(ПереченьФайлов)); КонецФункции diff --git a/tests/buildServerTests.os b/tests/buildServerTests.os index 1680f27..edae3c4 100644 --- a/tests/buildServerTests.os +++ b/tests/buildServerTests.os @@ -115,6 +115,16 @@ КонецПроцедуры +&ПараметризованныйТест +&ИсточникЗначение("develop", "", "develop") +&ИсточникЗначение("develop", "777", "develop#777") +&ИсточникЗначение("PR-1731", "3", "PR-1731#3") +Процедура ФормируетПредставлениеСборкиДляСообщений(Знач ИмяСборки, Знач НомерСборки, Знач Ожидание) Экспорт + + Ожидаем.Что(Провайдер.ПредставлениеСборки(ИмяСборки, НомерСборки), ИмяСборки).Равно(Ожидание); + +КонецПроцедуры + #КонецОбласти #Область ОпределениеВидаДистрибутива @@ -183,6 +193,15 @@ КонецПроцедуры +&Тест +Процедура ВозвращаетПустойПереченьФайловЕслиОтветБезКлючаАртефактов() Экспорт + + ПереченьФайлов = Провайдер.ДистрибутивыИзОписанияАртефактов("{""number"": 777}", "artifact"); + + Ожидаем.Что(ПереченьФайлов.Количество()).Равно(0); + +КонецПроцедуры + #КонецОбласти #Область РазборСпискаСборок @@ -205,6 +224,15 @@ КонецПроцедуры +&Тест +Процедура ВозвращаетПустойСписокСборокЕслиОтветБезКлючаЗаданий() Экспорт + + ДоступныеСборки = Провайдер.СборкиИзОписанияЗаданий("{""_class"": ""WorkflowMultiBranchProject""}"); + + Ожидаем.Что(ДоступныеСборки.Количество()).Равно(0); + +КонецПроцедуры + #КонецОбласти Функция ОтветСоСпискомАртефактов()