Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/cmd/opm.os
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@
Приложение.ДобавитьКоманду("test", НСтр("ru='Выполнить тестирование проекта';en='Run project testing'"), Новый КомандаOpm_Test);
Приложение.ДобавитьКоманду("u update", НСтр("ru='Обновить пакет';en='Update package'"), Новый КомандаOpm_Update);
Приложение.ДобавитьКоманду("version", НСтр("ru='Вывести версию продукта';en='show application version'"), Новый КомандаOpm_Version);
Приложение.ДобавитьКоманду("dl download",
НСтр("ru='Скачать файл пакета и файлы зависимостей';
|en='Download package and dependencies'"),
Новый КомандаOpm_Download);

Приложение.Запустить(АргументыКоманднойСтроки);

Expand Down
137 changes: 137 additions & 0 deletions src/cmd/Классы/КомандаOpm_Download.os
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
///////////////////////////////////////////////////////////////////////////////////////////////////
// Прикладной интерфейс

Процедура ОписаниеКоманды(Знач КомандаПриложения) Экспорт

КомандаПриложения.Опция("a all", Ложь, "Установить все пакеты, зарегистрированные в хабе");
КомандаПриложения.Опция("f file", "", "Указать файл из которого нужно установить пакет. Поддерживает указание маски файла для пакетной установки");
КомандаПриложения.Опция("u url", "", "Указать прямую интернет-ссылку на файл *.ospx из которого нужно установить пакет");

КомандаПриложения.Опция("dev", Ложь, "Признак установки пакетов для разработки");
КомандаПриложения.Опция("s skip-install-deps", Ложь, "признак пропуска установки зависимых пакетов");
КомандаПриложения.Опция("d dest", "", "Целевой каталог");

ОпцияЗеркала = КомандаПриложения.Опция("m mirror", "", "Указать имя сервера, с которого необходимо ставить пакеты.
| Доступные сервера прописываются в конфигурационном файле opm.cfg, параметр 'СервераПакетов'.")
.ВОкружении("OPM_HUB_MIRROR")
.ТПеречисление();

МенеджерПолучения = Новый МенеджерПолученияПакетов();
Для Каждого ДоступноеЗеркало Из МенеджерПолучения.ИменаДоступныхСерверов() Цикл
ОпцияЗеркала.Перечисление(ДоступноеЗеркало, ДоступноеЗеркало, "Сервер '" + ДоступноеЗеркало + "'");
КонецЦикла;

КомандаПриложения.Аргумент("PACKAGE", "", "Имя пакета в хабе. Чтобы установить конкретную версию, используйте ИмяПакета@ВерсияПакета")
.ТМассивСтрок()
.Обязательный(Ложь);

// КомандаПриложения.Спек = "(-a | --all | -l | --local | -d | --dest )";

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

Процедура ВыполнитьКоманду(Знач КомандаПриложения) Экспорт

УстановкаПакетовРазработчика = КомандаПриложения.ЗначениеОпции("dev");
УстановкаВсехПакетов = КомандаПриложения.ЗначениеОпции("all");
КаталогУстановки = КомандаПриложения.ЗначениеОпции("dest");
ФайлПакетаУстановки = КомандаПриложения.ЗначениеОпции("file");
ИнтернетСсылкаНаПакет = КомандаПриложения.ЗначениеОпции("url");
МассивПакетовКУстановке = КомандаПриложения.ЗначениеАргумента("PACKAGE");

НеобходимоУстановитьЗависимости = Не КомандаПриложения.ЗначениеОпции("skip-install-deps");
ИмяСервера = КомандаПриложения.ЗначениеОпции("mirror");

РежимУстановки = РежимУстановкиПакетов.Скачивание;

Если Не ПустаяСтрока(КаталогУстановки) Тогда
ЦелевойКаталог = КаталогУстановки;
Иначе
ЦелевойКаталог = ТекущийКаталог();
КонецЕсли;
Лог = Логирование.ПолучитьЛог(ПараметрыПриложенияOpm.ИмяЛогаСистемы());

Лог.Отладка("УстановкаПакетовРазработчика: %1", УстановкаПакетовРазработчика);
Лог.Отладка("УстановкаВсехПакетов: %1", УстановкаВсехПакетов);
Лог.Отладка("КаталогУстановки: %1", КаталогУстановки);
Лог.Отладка("ФайлПакетаУстановки: %1", ФайлПакетаУстановки);
Лог.Отладка("ИнтернетСсылкаНаПакет: %1", ИнтернетСсылкаНаПакет);
Лог.Отладка("МассивПакетовКУстановке: %1", МассивПакетовКУстановке.Количество());
Лог.Отладка("НеобходимоУстановитьЗависимости: %1", НеобходимоУстановитьЗависимости);

НастройкаУстановки = РаботаСПакетами.ПолучитьНастройкуУстановки();
НастройкаУстановки.УстанавливатьЗависимости = НеобходимоУстановитьЗависимости;
НастройкаУстановки.УстанавливатьЗависимостиРазработчика = УстановкаПакетовРазработчика;
НастройкаУстановки.СоздаватьФайлыЗапуска = Ложь;
НастройкаУстановки.ИмяСервера = ИмяСервера;

Если УстановкаВсехПакетов Тогда
РаботаСПакетами.УстановитьВсеПакетыИзОблака(РежимУстановки, ЦелевойКаталог, НастройкаУстановки);
ИначеЕсли ПустаяСтрока(ФайлПакетаУстановки) И ПустаяСтрока(ИнтернетСсылкаНаПакет) И МассивПакетовКУстановке.Количество() = 0 Тогда
РаботаСПакетами.УстановитьПакетыПоОписаниюПакета(РежимУстановки, ЦелевойКаталог, НастройкаУстановки);
ИначеЕсли НЕ ПустаяСтрока(ФайлПакетаУстановки) Тогда

РазобранныйАдрес = СтрРазделить(ФайлПакетаУстановки, ПолучитьРазделительПути());
Путь = ".";
Маска = ФайлПакетаУстановки;
Если РазобранныйАдрес.Количество() > 1 Тогда // отделим последнюю секцию как имя файла, а остальное опять соберем в строку пути

Маска = РазобранныйАдрес[РазобранныйАдрес.Количество() - 1];
РазобранныйАдрес.Удалить(РазобранныйАдрес.Количество() - 1);
Путь = СтрСоединить(РазобранныйАдрес, ПолучитьРазделительПути());

КонецЕсли;

ФайлыПоМаске = НайтиФайлы(Путь, Маска);
Для Каждого ФайлПакета Из ФайлыПоМаске Цикл

РаботаСПакетами.УстановитьПакетИзФайла(ФайлПакета.ПолноеИмя, РежимУстановки, ЦелевойКаталог, НастройкаУстановки);

КонецЦикла;

ИначеЕсли НЕ ПустаяСтрока(ИнтернетСсылкаНаПакет) Тогда

позСервер = СтрНайти(ИнтернетСсылкаНаПакет, "/", , , 3);
Сервер = Лев(ИнтернетСсылкаНаПакет, позСервер-1);
Адрес = Сред(ИнтернетСсылкаНаПакет, позСервер);
Если Нрег(Лев(Сервер, 5)) = "https" Тогда
Порт = 443;
Иначе
Порт = 80;
КонецЕсли;

Соединение = Новый HTTPСоединение(Сервер, Порт);
Запрос = Новый HTTPЗапрос(Адрес);
Ответ = Соединение.Получить(Запрос);
ДД = Ответ.ПолучитьТелоКакДвоичныеДанные();
ИмяВременногоФайла = ПолучитьИмяВременногоФайла("ospx");
ДД.Записать(ИмяВременногоФайла);

РаботаСПакетами.УстановитьПакетИзФайла(ИмяВременногоФайла, РежимУстановки, ЦелевойКаталог, НастройкаУстановки);

УдалитьФайлы(ИмяВременногоФайла);

Иначе

Для каждого ИмяПакета Из МассивПакетовКУстановке Цикл

Если ЭтоФайлПакета(ИмяПакета) Тогда

РаботаСПакетами.УстановитьПакетИзФайла(ИмяПакета, РежимУстановки, ЦелевойКаталог, НастройкаУстановки);

Иначе

РаботаСПакетами.УстановитьПакетИзОблака(ИмяПакета, РежимУстановки, ЦелевойКаталог, НастройкаУстановки);

КонецЕсли;

КонецЦикла;

КонецЕсли;

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

Функция ЭтоФайлПакета(Знач ИмяПакета)

Возврат СтрЗаканчиваетсяНа(НРег(ИмяПакета), ".ospx");

КонецФункции
147 changes: 147 additions & 0 deletions src/core/Классы/КэшСкачанныхПакетов.os
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@

#Использовать fs
#Использовать logos
#Использовать semver

Перем Лог;

Перем КаталогПоискаБиблиотек;

Перем УстановленныеПакеты;

Функция ПакетУстановлен(Знач ОписаниеЗависимости, Знач КаталогПоискаБиблиотек = "") Экспорт

Перем УстановленныеПакеты;
УстановленныеПакеты = ПолучитьУстановленныеПакеты();

ДанныеПакета = УстановленныеПакеты.Получить(ОписаниеЗависимости.ИмяПакета);
ПакетУстановлен = ДанныеПакета <> Неопределено;
Если ПакетУстановлен И НЕ ПустаяСтрока(КаталогПоискаБиблиотек) Тогда
КаталогБиблиотекПакета = Новый Файл(ОбъединитьПути(ДанныеПакета.КаталогПакета, "..")).ПолноеИмя;
ПакетУстановлен = ФС.ПутиРавны(КаталогБиблиотекПакета, КаталогПоискаБиблиотек);
КонецЕсли;

ПутьКФайлуМетаданных = ПолучитьПутьКФайлуМетаданныхБиблиотеки(ОписаниеЗависимости.ИмяПакета);

ФайлМетаданных = Новый Файл(ПутьКФайлуМетаданных);
Если ФайлМетаданных.Существует() Тогда
МетаОписаниеПакета = ПрочитатьМетаданныеПакета(ПутьКФайлуМетаданных);
УстановленнаяВерсия = МетаОписаниеПакета.Свойства().Версия;
Иначе
// @deprecated
УстановленнаяВерсия = "0";
КонецЕсли;
Лог.Отладка("ПакетУстановлен: Перед вызовом СравнитьВерсии(ЭтаВерсия = <%1>, БольшеЧемВерсия = <%2>)", УстановленнаяВерсия, ОписаниеЗависимости.МинимальнаяВерсия);

ВерсияSNAPSHOT = "SNAPSHOT";
Если ОписаниеЗависимости.МинимальнаяВерсия = ВерсияSNAPSHOT И УстановленнаяВерсия = ВерсияSNAPSHOT Тогда
УстановленаКорректнаяВерсия = Истина;
ИначеЕсли ОписаниеЗависимости.МинимальнаяВерсия = ВерсияSNAPSHOT И УстановленнаяВерсия <> ВерсияSNAPSHOT Тогда
УстановленаКорректнаяВерсия = Ложь;
Иначе
УстановленаКорректнаяВерсия = ОписаниеЗависимости.МинимальнаяВерсия = Неопределено
ИЛИ Версии.СравнитьВерсии(УстановленнаяВерсия, ОписаниеЗависимости.МинимальнаяВерсия) >= 0;
КонецЕсли;

Лог.Отладка("Пакет установлен: " + ПакетУстановлен);
Лог.Отладка("Установлена корректная версия: " + УстановленаКорректнаяВерсия);
Возврат ПакетУстановлен И УстановленаКорректнаяВерсия;

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

Процедура Обновить() Экспорт

УстановленныеПакеты = Новый Соответствие;
НайденныеФайлы = НайтиФайлы(КаталогПоискаБиблиотек, ПолучитьМаскуВсеФайлы());

Для Каждого ФайлКаталога Из НайденныеФайлы Цикл
Если ФайлКаталога.ЭтоКаталог() Тогда

// ДобавитьУстановленныйПакет заменит уже добавленный пакет при совпадении имён
// Соответственно, более поздние каталоги будут иметь приоритет
ДобавитьУстановленныйПакет(ФайлКаталога);

КонецЕсли;
КонецЦикла;

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

Функция ПолучитьУстановленныеПакеты() Экспорт

Если УстановленныеПакеты = Неопределено Тогда
Обновить();
КонецЕсли;

Возврат УстановленныеПакеты;

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

// Добавляет каталог в список, по которому выполняется поиск библиотек
Процедура ДобавитьКаталогБиблиотек(Знач Каталог) Экспорт

//МассивКаталоговПоискаБиблиотек.Добавить(Каталог);

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

Процедура ДобавитьУстановленныйПакет(Знач ФайлКаталога)

ПутьКФайлуМетаданных = ОбъединитьПути(ФайлКаталога.ПолноеИмя, КонстантыOpm.ИмяФайлаМетаданныхПакета);
ФайлМетаданных = Новый Файл(ПутьКФайлуМетаданных);
Если ФайлМетаданных.Существует() Тогда
МетаОписаниеПакета = ПрочитатьМетаданныеПакета(ПутьКФайлуМетаданных);
Иначе
// @deprecated
МетаОписаниеПакета = Истина;
КонецЕсли;

СтруктураДанных = Новый Структура();
СтруктураДанных.Вставить("МетаданныеПакета", МетаОписаниеПакета);
СтруктураДанных.Вставить("КаталогПакета", ФайлКаталога.ПолноеИмя);

УстановленныеПакеты.Вставить(ФайлКаталога.Имя, СтруктураДанных);

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

Функция ПрочитатьМетаданныеПакета(Знач ПутьКФайлуМетаданных)

Перем Метаданные;
Попытка
Чтение = Новый ЧтениеXML;
Чтение.ОткрытьФайл(ПутьКФайлуМетаданных);
Сериализатор = Новый СериализацияМетаданныхПакета;
Метаданные = Сериализатор.ПрочитатьXML(Чтение);

Чтение.Закрыть();
Исключение
Чтение.Закрыть();
ВызватьИсключение;
КонецПопытки;

Возврат Метаданные;

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

Функция ПолучитьПутьКФайлуМетаданныхБиблиотеки(ИмяПакета) Экспорт

ПутьКФайлуМетаданных = "";
ВремПутьКФайлуМетаданных = ОбъединитьПути(
КаталогПоискаБиблиотек,
ИмяПакета,
КонстантыOpm.ИмяФайлаМетаданныхПакета
);

Лог.Отладка(Новый Файл(ВремПутьКФайлуМетаданных).ПолноеИмя);
Если ФС.ФайлСуществует(ВремПутьКФайлуМетаданных) Тогда
ПутьКФайлуМетаданных = ВремПутьКФайлуМетаданных;
КонецЕсли;

Возврат ПутьКФайлуМетаданных;

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

Процедура ПриСозданииОбъекта(Знач ЦелевойКаталогСкачиванияБиблиотек)

Лог = Логирование.ПолучитьЛог("oscript.app.opm");
КаталогПоискаБиблиотек = ЦелевойКаталогСкачиванияБиблиотек;

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