Skip to content
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@

.vscode/launch.json
oscript_modules/

src/cmd/oscript\.cfg
Expand Down
159 changes: 97 additions & 62 deletions src/core/Классы/ВерсииOneScript.os
Original file line number Diff line number Diff line change
Expand Up @@ -22,25 +22,24 @@

ДопустимыеАлиасы = Новый КартаСоответствие;

ДопустимыеАлиасы.Вставить("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"));

КонецЕсли;

Возврат ДопустимыеАлиасы;

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

Функция Версия(Метка, ЭтоВерсия2)
Функция Версия(Метка)

Результат = Новый Структура;

Результат.Вставить("Метка", Метка);
Результат.Вставить("ЭтоВерсия2", ЭтоВерсия2);

Возврат Результат;

Expand Down Expand Up @@ -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.АдресСайтаОСкрипт(),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Кандидат на распил в детальки, кстати...

,
,
,
,
Таймаут
);

Запрос = Новый HTTPЗапрос("api/archive?all=true");
Ответ = Соединение.Получить(Запрос);
HTTP_OK = 200;
Если Ответ.КодСостояния <> HTTP_OK Тогда
ВызватьИсключение СтрШаблон("Не удалось найти версию %1 на сайте: Статус: %2, Ответ: %3",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Вся функция в целом ищет версию на сайте. Текст исключения относится к ней (может это только мне так кажется...)

НомерВерсии,
Ответ.КодСостояния,
Ответ.ПолучитьТелоКакСтроку()
);
КонецЕсли;

ЧтениеJSON = Новый ЧтениеJSON();
ЧтениеJSON.УстановитьСтроку(Ответ.ПолучитьТелоКакСтроку());

МассивВерсий = ПрочитатьJSON(ЧтениеJSON, Ложь);
ИскомыйТокенВерсии = Неопределено;
Для Каждого ОписаниеВерсии Из МассивВерсий Цикл
Если НомерВерсии = ОписаниеВерсии.presentation Тогда
ИскомыйТокенВерсии = ОписаниеВерсии.token;
КонецЕсли;
КонецЦикла;

Если ИскомыйТокенВерсии = Неопределено Тогда
ВызватьИсключение СтрШаблон("Не удалось найти версию %1 на сайте.", НомерВерсии);
КонецЕсли;

Запрос = Новый HTTPЗапрос("api/archive/" + ИскомыйТокенВерсии);
Ответ = Соединение.Получить(Запрос);
HTTP_OK = 200;
Если Ответ.КодСостояния <> HTTP_OK Тогда
ВызватьИсключение СтрШаблон("Не удалось найти файлы версии %1 на сайте: Статус: %2, Ответ: %3",
НомерВерсии,
Ответ.КодСостояния,
Ответ.ПолучитьТелоКакСтроку()
);
КонецЕсли;

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

ЧтениеJSON = Новый ЧтениеJSON();
ЧтениеJSON.УстановитьСтроку(Ответ.ПолучитьТелоКакСтроку());

Возврат ДоступныеВерсии;
МассивФайлов = ПрочитатьJSON(ЧтениеJSON, Ложь);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Не обязательно в этот пр, но задумываюсь над тем, чтобы сюда 1connector затянуть

Для Каждого ОписаниеФайла Из МассивФайлов Цикл
СтрокаТаблицы = ТаблицаРезультата.Добавить();
СтрокаТаблицы.Вид = ОписаниеФайла.id;
СтрокаТаблицы.ИмяФайла = ОписаниеФайла.filename;
СтрокаТаблицы.Архитектура = ОписаниеФайла.arch;
СтрокаТаблицы.Ссылка = ОписаниеФайла.link;
КонецЦикла;

Возврат ТаблицаРезультата;

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

// <Описание функции>
Expand Down Expand Up @@ -320,25 +399,21 @@

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

Функция ТаблицаДоступныхВерсий()
ДоступныеВерсии = Новый ТаблицаЗначений;
ДоступныеВерсии.Колонки.Добавить("Алиас");
ДоступныеВерсии.Колонки.Добавить("Путь");

Возврат ДоступныеВерсии;
КонецФункции

Функция ПолучитьВерсииПоAPI(Знач Соединение, Знач ДоступныеВерсии)
Функция ПолучитьВерсииПоAPI(Знач Соединение)
Запрос = Новый HTTPЗапрос("api/archive");
Ответ = Соединение.Получить(Запрос);
HTTP_OK = 200;
Если Ответ.КодСостояния <> HTTP_OK Тогда
Возврат Ложь;
ВызватьИсключение СтрШаблон("Не удалось получить список версий с сайта. Код ошибки: %1", Ответ.КодСостояния);
КонецЕсли;

ЧтениеJSON = Новый ЧтениеJSON();
ЧтениеJSON.УстановитьСтроку(Ответ.ПолучитьТелоКакСтроку());

ДоступныеВерсии = Новый ТаблицаЗначений;
ДоступныеВерсии.Колонки.Добавить("Алиас");
ДоступныеВерсии.Колонки.Добавить("Путь");

АдресСайтаОСкрипт = ПараметрыOVM.АдресСайтаОСкрипт();
МассивВерсий = ПрочитатьJSON(ЧтениеJSON, Ложь);
Для Каждого ОписаниеВерсии Из МассивВерсий Цикл
Expand All @@ -353,49 +428,9 @@
ОбеспечитьСтрокуВерсииПоАлиасу(ДоступныеВерсии, Итератор.Следующий(), "Путь");
КонецЦикла;

Возврат Истина;
Возврат ДоступныеВерсии;
КонецФункции

Процедура ПолучитьВерсииРазборомHTML(Знач Соединение, Знач ДоступныеВерсии)
Запрос = Новый HTTPЗапрос("downloads");

Ответ = Соединение.Получить(Запрос);
HTTP_OK = 200;
Если Ответ.КодСостояния <> HTTP_OK Тогда
ВызватьИсключение Ответ.КодСостояния;
КонецЕсли;

ТелоСтраницы = Ответ.ПолучитьТелоКакСтроку();

РегулярноеВыражение = Новый РегулярноеВыражение(
"<a href=""(\/downloads\/[^""]+)"">(" + ПараметрыOVM.МаскаНомераВерсии() + ")<");
ИндексГруппыАдрес = 1;
ИндексГруппыВерсия = 2;

АдресСайтаОСкрипт = ПараметрыOVM.АдресСайтаОСкрипт();
Совпадения = РегулярноеВыражение.НайтиСовпадения(ТелоСтраницы);
Для Каждого СовпадениеРегулярногоВыражения Из Совпадения Цикл
ГруппаАдрес = СовпадениеРегулярногоВыражения.Группы[ИндексГруппыАдрес];
ГруппаВерсия = СовпадениеРегулярногоВыражения.Группы[ИндексГруппыВерсия];

// TODO: Убрать после решения https://github.com/EvilBeaver/OneScript/issues/667
Если ГруппаВерсия.Значение = "1.0.9" Тогда
Продолжить;
КонецЕсли;

ДоступнаяВерсия = ДоступныеВерсии.Добавить();
ДоступнаяВерсия.Алиас = ГруппаВерсия.Значение;
ДоступнаяВерсия.Путь = АдресСайтаОСкрипт + ГруппаАдрес.Значение;
КонецЦикла;

Итератор = ДопустимыеАлиасы().Ключи().Итератор();

Пока Итератор.ЕстьСледующий() Цикл
ОбеспечитьСтрокуВерсииПоАлиасу(ДоступныеВерсии, Итератор.Следующий(), "Путь");
КонецЦикла;

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

Процедура ОбеспечитьСтрокуВерсииПоАлиасу(ТаблицаВерсий, Алиас, ИмяРеквизитаПуть = "ПутьСервер")

СтрокаВерсии = ТаблицаВерсий.Найти(Алиас, "Алиас");
Expand Down
12 changes: 9 additions & 3 deletions src/core/Классы/ПараметрыOVM.os
Original file line number Diff line number Diff line change
Expand Up @@ -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

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

СистемнаяИнформация = Новый СистемнаяИнформация;
73 changes: 53 additions & 20 deletions src/core/Классы/УстановщикOneScript.os
Original file line number Diff line number Diff line change
Expand Up @@ -304,15 +304,15 @@

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

Функция ЭтоТочныйНомерВерсии(ВерсияКУстановке)
РВ = Новый РегулярноеВыражение("^" + ПараметрыOVM.МаскаНомераВерсии() + "$");
Функция ЭтоДопустимыйНомерВерсии(ВерсияКУстановке)
РВ = Новый РегулярноеВыражение(ПараметрыOVM.МаскаНомераВерсииSemver());
РВ.ИгнорироватьРегистр = Ложь;
РВ.МногоСтрочный = Ложь;
Возврат РВ.Совпадает(ВерсияКУстановке);
КонецФункции

Процедура ПроверитьКорректностьПереданнойВерсии(Знач ВерсияКУстановке)
Если НЕ ЭтоТочныйНомерВерсии(ВерсияКУстановке)
Если НЕ ЭтоДопустимыйНомерВерсии(ВерсияКУстановке)
И Не ВерсииOneScript.ДопустимыеАлиасы().СодержитКлюч(ВерсияКУстановке) Тогда

Лог.Ошибка("Версия имеет некорректный формат");
Expand All @@ -323,9 +323,9 @@

Функция ПолучитьПутьКСкачиваниюФайла(Знач ВерсияКУстановке, Знач ИспользоватьХ64, Знач ИспользоватьFDD)

Если ЭтоТочныйНомерВерсии(ВерсияКУстановке) Тогда
Если ЭтоДопустимыйНомерВерсии(ВерсияКУстановке) Тогда

КаталогВерсии = СтрЗаменить(ВерсияКУстановке, ".", "_");
ИскомаяВерсия = ВерсияКУстановке;
ЭтоВерсия2 = СтроковыеФункции.СравнитьВерсии(ВерсияКУстановке, "2.0") >= 0;

Иначе
Expand All @@ -334,30 +334,63 @@
.Получить(ВерсияКУстановке)
.ИначеВызватьИсключение("Ошибка получения пути к файлу по версии");

КаталогВерсии = ДанныеВерсии.Метка;
ЭтоВерсия2 = ДанныеВерсии.ЭтоВерсия2;
ИскомаяВерсия = ДанныеВерсии.Метка;
// Когда v2 выйдет из preview мы не будем знать к какой версии относится алиас stable.
ЭтоВерсия2 = Неопределено;

КонецЕсли;

Если ЭтоВерсия2 И ИспользоватьFDD Тогда
ИмяФайла = "fdd";
ИначеЕсли ЭтоВерсия2 Тогда
ИмяФайла = ТипДистрибутиваТекущейПлатформы();
Если ЭтоВерсия2 = Истина Тогда
ВидДистрибутива = ?(ИспользоватьFDD, "fdd", ТипДистрибутиваТекущейПлатформы());
ИначеЕсли ЭтоВерсия2 = Ложь Тогда
ВидДистрибутива = "zip";
ИначеЕсли ИспользоватьFDD Тогда
ЭтоВерсия2 = Истина;
ВидДистрибутива = "fdd";
Иначе
ИмяФайла = "zip";
// Это установка по алиасу и мы не знаем, версия 2 это или нет.
// Определим это с двух попыток ниже.
ВидДистрибутива = ТипДистрибутиваТекущейПлатформы();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Кажется мы в этом случае при установке ovm i dev --fdd поставим таки scd а не fdd, потому что флаг мы обрабатываем только для "номерных" версий

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Да, исправил.

КонецЕсли;

ЧастиПути = Новый Массив;
ЧастиПути.Добавить("downloads");
ЧастиПути.Добавить(КаталогВерсии);
Если ИспользоватьХ64 Тогда
ЧастиПути.Добавить("x64");
ПереченьФайлов = ВерсииOneScript.ПолучитьДоступныеВидыДистрибутивовВерсии(ИскомаяВерсия);

Возврат НайтиПодходящийДистрибутив(ПереченьФайлов, ВидДистрибутива, ИспользоватьХ64, ЭтоВерсия2 = Неопределено);

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

Функция НайтиПодходящийДистрибутив(Знач ПереченьФайлов, Знач ВидДистрибутива, Знач ИспользоватьХ64, Знач РежимАлиаса)
КритерийПоиска = Новый Структура;
КритерийПоиска.Вставить("Вид", ВидДистрибутива);

Если ВидДистрибутива = "scd-win" или ВидДистрибутива = "fdd" или ВидДистрибутива = "zip" Тогда
Если ИспользоватьХ64 Тогда
КритерийПоиска.Вставить("Архитектура", "x64");
Иначе
КритерийПоиска.Вставить("Архитектура", "x86");
КонецЕсли;
КонецЕсли;
ЧастиПути.Добавить(ИмяФайла);

Ресурс = СтрСоединить(ЧастиПути, "/");
Возврат Ресурс;
НайденныеСтроки = ПереченьФайлов.НайтиСтроки(КритерийПоиска);
Если НайденныеСтроки.Количество() <> 1 Тогда
// Это может быть установка по алиасу и тогда есть шанс у дистрибутива zip для версии 1
Если РежимАлиаса Тогда
КритерийПоиска.Вид = "zip";
КонецЕсли;

НайденныеСтроки = ПереченьФайлов.НайтиСтроки(КритерийПоиска);
Если НайденныеСтроки.Количество() <> 1 Тогда
ТекстОшибки = СтрШаблон(
"Не найден дистрибутив для критериев: Вид=%1, Архитектура=%2. Найдено файлов: %3",
КритерийПоиска.Вид,
?(КритерийПоиска.Свойство("Архитектура"), КритерийПоиска.Архитектура, "<любая>"),
НайденныеСтроки.Количество()
);
ВызватьИсключение ТекстОшибки;
КонецЕсли;
КонецЕсли;

Возврат НайденныеСтроки[0].Ссылка;
КонецФункции

Функция ТипДистрибутиваТекущейПлатформы()
Expand Down