diff --git a/.gitignore b/.gitignore index 7e063b2..ef9c152 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ +.vscode/launch.json oscript_modules/ src/cmd/oscript\.cfg 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 d67d1bc..4ab5bd3 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" @@ -22,12 +22,12 @@ ДопустимыеАлиасы = Новый КартаСоответствие; - ДопустимыеАлиасы.Вставить("lts", Версия("lts", Ложь)); - ДопустимыеАлиасы.Вставить("stable", Версия("latest", Ложь)); - ДопустимыеАлиасы.Вставить("dev", Версия("night-build", Истина)); + ДопустимыеАлиасы.Вставить("lts", Версия("lts")); + ДопустимыеАлиасы.Вставить("stable", Версия("latest")); + ДопустимыеАлиасы.Вставить("dev", Версия("night-build")); - ДопустимыеАлиасы.Вставить("preview", Версия("preview", Истина)); - ДопустимыеАлиасы.Вставить("lts-dev", Версия("latest-dev", Ложь)); + ДопустимыеАлиасы.Вставить("preview", Версия("preview")); + ДопустимыеАлиасы.Вставить("lts-dev", Версия("latest-dev")); КонецЕсли; @@ -35,12 +35,11 @@ КонецФункции -Функция Версия(Метка, ЭтоВерсия2) +Функция Версия(Метка) Результат = Новый Структура; Результат.Вставить("Метка", Метка); - Результат.Вставить("ЭтоВерсия2", ЭтоВерсия2); Возврат Результат; @@ -226,13 +225,93 @@ Таймаут ); - ДоступныеВерсии = ТаблицаДоступныхВерсий(); + Возврат ПолучитьВерсииПоAPI(Соединение); - Если Не ПолучитьВерсииПоAPI(Соединение, ДоступныеВерсии) Тогда - ПолучитьВерсииРазборомHTML(Соединение, ДоступныеВерсии); +КонецФункции + +// Возвращает таблицу файлов конкретной версии +// +// Параметры: +// НомерВерсии - Строка - версия для которой получаем файлы. +// +// Возвращаемое значение: +// ТаблицаЗначений - Вид,ИмяФайла,Архитектура,Ссылка +// Вид: vsix,exe,zip,fdd,scd-win,scd-lin,osx-x64,osx-arm64 +// ИмяФайла: имя файла +// Архитектура: x64,x86 +// Ссылка: прямая ссылка на данный файл +// См. также: +// https://oscript.io/api/archive/ - список всех токенов +// https://oscript.io/api/archive/<токен версии> - данная таблица +// +Функция ПолучитьДоступныеВидыДистрибутивовВерсии(Знач НомерВерсии) Экспорт + Таймаут = 10; + Соединение = Новый HTTPСоединение( + ПараметрыOVM.АдресСайтаОСкрипт(), + , + , + , + , + Таймаут + ); + + Запрос = Новый HTTPЗапрос("api/archive?all=true"); + Ответ = Соединение.Получить(Запрос); + HTTP_OK = 200; + Если Ответ.КодСостояния <> HTTP_OK Тогда + ВызватьИсключение СтрШаблон("Не удалось найти версию %1 на сайте: Статус: %2, Ответ: %3", + НомерВерсии, + Ответ.КодСостояния, + Ответ.ПолучитьТелоКакСтроку() + ); + КонецЕсли; + + ЧтениеJSON = Новый ЧтениеJSON(); + ЧтениеJSON.УстановитьСтроку(Ответ.ПолучитьТелоКакСтроку()); + + МассивВерсий = ПрочитатьJSON(ЧтениеJSON, Ложь); + ИскомыйТокенВерсии = Неопределено; + Для Каждого ОписаниеВерсии Из МассивВерсий Цикл + Если НомерВерсии = ОписаниеВерсии.presentation Тогда + ИскомыйТокенВерсии = ОписаниеВерсии.token; + КонецЕсли; + КонецЦикла; + + Если ИскомыйТокенВерсии = Неопределено Тогда + ВызватьИсключение СтрШаблон("Не удалось найти версию %1 на сайте.", НомерВерсии); + КонецЕсли; + + Запрос = Новый HTTPЗапрос("api/archive/" + ИскомыйТокенВерсии); + Ответ = Соединение.Получить(Запрос); + HTTP_OK = 200; + Если Ответ.КодСостояния <> HTTP_OK Тогда + ВызватьИсключение СтрШаблон("Не удалось найти файлы версии %1 на сайте: Статус: %2, Ответ: %3", + НомерВерсии, + Ответ.КодСостояния, + Ответ.ПолучитьТелоКакСтроку() + ); КонецЕсли; + + ТаблицаРезультата = Новый ТаблицаЗначений(); + ТаблицаРезультата.Колонки.Добавить("Вид"); + ТаблицаРезультата.Колонки.Добавить("ИмяФайла"); + ТаблицаРезультата.Колонки.Добавить("Архитектура"); + ТаблицаРезультата.Колонки.Добавить("Ссылка"); + + ЧтениеJSON = Новый ЧтениеJSON(); + ЧтениеJSON.УстановитьСтроку(Ответ.ПолучитьТелоКакСтроку()); - Возврат ДоступныеВерсии; + МассивФайлов = ПрочитатьJSON(ЧтениеJSON, Ложь); + Для Каждого ОписаниеФайла Из МассивФайлов Цикл + СтрокаТаблицы = ТаблицаРезультата.Добавить(); + СтрокаТаблицы.Вид = ОписаниеФайла.id; + СтрокаТаблицы.ИмяФайла = ОписаниеФайла.filename; + СтрокаТаблицы.Архитектура = ОписаниеФайла.arch; + СтрокаТаблицы.Ссылка = ОписаниеФайла.link; + КонецЦикла; + + Возврат ТаблицаРезультата; + КонецФункции // <Описание функции> @@ -320,25 +399,21 @@ КонецФункции -Функция ТаблицаДоступныхВерсий() - ДоступныеВерсии = Новый ТаблицаЗначений; - ДоступныеВерсии.Колонки.Добавить("Алиас"); - ДоступныеВерсии.Колонки.Добавить("Путь"); - - Возврат ДоступныеВерсии; -КонецФункции - -Функция ПолучитьВерсииПоAPI(Знач Соединение, Знач ДоступныеВерсии) +Функция ПолучитьВерсииПоAPI(Знач Соединение) Запрос = Новый HTTPЗапрос("api/archive"); Ответ = Соединение.Получить(Запрос); HTTP_OK = 200; Если Ответ.КодСостояния <> HTTP_OK Тогда - Возврат Ложь; + ВызватьИсключение СтрШаблон("Не удалось получить список версий с сайта. Код ошибки: %1", Ответ.КодСостояния); КонецЕсли; ЧтениеJSON = Новый ЧтениеJSON(); ЧтениеJSON.УстановитьСтроку(Ответ.ПолучитьТелоКакСтроку()); + ДоступныеВерсии = Новый ТаблицаЗначений; + ДоступныеВерсии.Колонки.Добавить("Алиас"); + ДоступныеВерсии.Колонки.Добавить("Путь"); + АдресСайтаОСкрипт = ПараметрыOVM.АдресСайтаОСкрипт(); МассивВерсий = ПрочитатьJSON(ЧтениеJSON, Ложь); Для Каждого ОписаниеВерсии Из МассивВерсий Цикл @@ -353,49 +428,9 @@ ОбеспечитьСтрокуВерсииПоАлиасу(ДоступныеВерсии, Итератор.Следующий(), "Путь"); КонецЦикла; - Возврат Истина; + Возврат ДоступныеВерсии; КонецФункции -Процедура ПолучитьВерсииРазборомHTML(Знач Соединение, Знач ДоступныеВерсии) - Запрос = Новый HTTPЗапрос("downloads"); - - Ответ = Соединение.Получить(Запрос); - HTTP_OK = 200; - Если Ответ.КодСостояния <> HTTP_OK Тогда - ВызватьИсключение Ответ.КодСостояния; - КонецЕсли; - - ТелоСтраницы = Ответ.ПолучитьТелоКакСтроку(); - - РегулярноеВыражение = Новый РегулярноеВыражение( - "(" + ПараметрыOVM.МаскаНомераВерсии() + ")<"); - ИндексГруппыАдрес = 1; - ИндексГруппыВерсия = 2; - - АдресСайтаОСкрипт = ПараметрыOVM.АдресСайтаОСкрипт(); - Совпадения = РегулярноеВыражение.НайтиСовпадения(ТелоСтраницы); - Для Каждого СовпадениеРегулярногоВыражения Из Совпадения Цикл - ГруппаАдрес = СовпадениеРегулярногоВыражения.Группы[ИндексГруппыАдрес]; - ГруппаВерсия = СовпадениеРегулярногоВыражения.Группы[ИндексГруппыВерсия]; - - // TODO: Убрать после решения https://github.com/EvilBeaver/OneScript/issues/667 - Если ГруппаВерсия.Значение = "1.0.9" Тогда - Продолжить; - КонецЕсли; - - ДоступнаяВерсия = ДоступныеВерсии.Добавить(); - ДоступнаяВерсия.Алиас = ГруппаВерсия.Значение; - ДоступнаяВерсия.Путь = АдресСайтаОСкрипт + ГруппаАдрес.Значение; - КонецЦикла; - - Итератор = ДопустимыеАлиасы().Ключи().Итератор(); - - Пока Итератор.ЕстьСледующий() Цикл - ОбеспечитьСтрокуВерсииПоАлиасу(ДоступныеВерсии, Итератор.Следующий(), "Путь"); - КонецЦикла; - -КонецПроцедуры - Процедура ОбеспечитьСтрокуВерсииПоАлиасу(ТаблицаВерсий, Алиас, ИмяРеквизитаПуть = "ПутьСервер") СтрокаВерсии = ТаблицаВерсий.Найти(Алиас, "Алиас"); 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 4f6a8e5..4367ff4 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" @@ -54,13 +54,19 @@ Возврат СистемнаяИнформация.Это64БитнаяОперационнаяСистема; КонецФункции -// Регулярное выражение точного номера версии. +// Регулярное выражение версии по semver // // Возвращаемое значение: // Строка - Регулярное выражение // -Функция МаскаНомераВерсии() Экспорт - Возврат "\d+\.\d+\.\d+(\.rc\d+?)?"; +Функция МаскаНомераВерсииSemver() Экспорт + // https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string + // https://regex101.com/r/vkijKf/1/ + + // BSLLS:LineLength-off + Возврат "^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$"; + // BSLLS:LineLength-on + КонецФункции СистемнаяИнформация = Новый СистемнаяИнформация; 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 865ccc3..199f7e3 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" @@ -304,15 +304,15 @@ КонецПроцедуры -Функция ЭтоТочныйНомерВерсии(ВерсияКУстановке) - РВ = Новый РегулярноеВыражение("^" + ПараметрыOVM.МаскаНомераВерсии() + "$"); +Функция ЭтоДопустимыйНомерВерсии(ВерсияКУстановке) + РВ = Новый РегулярноеВыражение(ПараметрыOVM.МаскаНомераВерсииSemver()); РВ.ИгнорироватьРегистр = Ложь; РВ.МногоСтрочный = Ложь; Возврат РВ.Совпадает(ВерсияКУстановке); КонецФункции Процедура ПроверитьКорректностьПереданнойВерсии(Знач ВерсияКУстановке) - Если НЕ ЭтоТочныйНомерВерсии(ВерсияКУстановке) + Если НЕ ЭтоДопустимыйНомерВерсии(ВерсияКУстановке) И Не ВерсииOneScript.ДопустимыеАлиасы().СодержитКлюч(ВерсияКУстановке) Тогда Лог.Ошибка("Версия имеет некорректный формат"); @@ -323,9 +323,9 @@ Функция ПолучитьПутьКСкачиваниюФайла(Знач ВерсияКУстановке, Знач ИспользоватьХ64, Знач ИспользоватьFDD) - Если ЭтоТочныйНомерВерсии(ВерсияКУстановке) Тогда + Если ЭтоДопустимыйНомерВерсии(ВерсияКУстановке) Тогда - КаталогВерсии = СтрЗаменить(ВерсияКУстановке, ".", "_"); + ИскомаяВерсия = ВерсияКУстановке; ЭтоВерсия2 = СтроковыеФункции.СравнитьВерсии(ВерсияКУстановке, "2.0") >= 0; Иначе @@ -334,30 +334,63 @@ .Получить(ВерсияКУстановке) .ИначеВызватьИсключение("Ошибка получения пути к файлу по версии"); - КаталогВерсии = ДанныеВерсии.Метка; - ЭтоВерсия2 = ДанныеВерсии.ЭтоВерсия2; + ИскомаяВерсия = ДанныеВерсии.Метка; + // Когда v2 выйдет из preview мы не будем знать к какой версии относится алиас stable. + ЭтоВерсия2 = Неопределено; КонецЕсли; - Если ЭтоВерсия2 И ИспользоватьFDD Тогда - ИмяФайла = "fdd"; - ИначеЕсли ЭтоВерсия2 Тогда - ИмяФайла = ТипДистрибутиваТекущейПлатформы(); + Если ЭтоВерсия2 = Истина Тогда + ВидДистрибутива = ?(ИспользоватьFDD, "fdd", ТипДистрибутиваТекущейПлатформы()); + ИначеЕсли ЭтоВерсия2 = Ложь Тогда + ВидДистрибутива = "zip"; + ИначеЕсли ИспользоватьFDD Тогда + ЭтоВерсия2 = Истина; + ВидДистрибутива = "fdd"; Иначе - ИмяФайла = "zip"; + // Это установка по алиасу и мы не знаем, версия 2 это или нет. + // Определим это с двух попыток ниже. + ВидДистрибутива = ТипДистрибутиваТекущейПлатформы(); КонецЕсли; - ЧастиПути = Новый Массив; - ЧастиПути.Добавить("downloads"); - ЧастиПути.Добавить(КаталогВерсии); - Если ИспользоватьХ64 Тогда - ЧастиПути.Добавить("x64"); + ПереченьФайлов = ВерсииOneScript.ПолучитьДоступныеВидыДистрибутивовВерсии(ИскомаяВерсия); + + Возврат НайтиПодходящийДистрибутив(ПереченьФайлов, ВидДистрибутива, ИспользоватьХ64, ЭтоВерсия2 = Неопределено); + +КонецФункции + +Функция НайтиПодходящийДистрибутив(Знач ПереченьФайлов, Знач ВидДистрибутива, Знач ИспользоватьХ64, Знач РежимАлиаса) + КритерийПоиска = Новый Структура; + КритерийПоиска.Вставить("Вид", ВидДистрибутива); + + Если ВидДистрибутива = "scd-win" или ВидДистрибутива = "fdd" или ВидДистрибутива = "zip" Тогда + Если ИспользоватьХ64 Тогда + КритерийПоиска.Вставить("Архитектура", "x64"); + Иначе + КритерийПоиска.Вставить("Архитектура", "x86"); + КонецЕсли; КонецЕсли; - ЧастиПути.Добавить(ИмяФайла); - Ресурс = СтрСоединить(ЧастиПути, "/"); - Возврат Ресурс; + НайденныеСтроки = ПереченьФайлов.НайтиСтроки(КритерийПоиска); + Если НайденныеСтроки.Количество() <> 1 Тогда + // Это может быть установка по алиасу и тогда есть шанс у дистрибутива zip для версии 1 + Если РежимАлиаса Тогда + КритерийПоиска.Вид = "zip"; + КонецЕсли; + + НайденныеСтроки = ПереченьФайлов.НайтиСтроки(КритерийПоиска); + Если НайденныеСтроки.Количество() <> 1 Тогда + ТекстОшибки = СтрШаблон( + "Не найден дистрибутив для критериев: Вид=%1, Архитектура=%2. Найдено файлов: %3", + КритерийПоиска.Вид, + ?(КритерийПоиска.Свойство("Архитектура"), КритерийПоиска.Архитектура, "<любая>"), + НайденныеСтроки.Количество() + ); + ВызватьИсключение ТекстОшибки; + КонецЕсли; + КонецЕсли; + Возврат НайденныеСтроки[0].Ссылка; КонецФункции Функция ТипДистрибутиваТекущейПлатформы()