Skip to content

Поддержка semver в части пререлизов и метаданных билда #7

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 31 commits into from
May 19, 2025
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
74c855f
Finish 0.5.0
khorevaa Dec 24, 2017
5a36bc6
Finish 0.5.1
khorevaa Feb 6, 2018
4b72bd0
Finish 0.5.1
khorevaa Feb 9, 2018
cbc8fa1
Finish 0.5.2
khorevaa Feb 2, 2019
9e38162
Merge remote-tracking branch 'remotes/origin/master' into develop
EvilBeaver Apr 30, 2025
a0450cf
Модули добавлены в игнор
EvilBeaver Apr 30, 2025
2f8ab48
Бамп версии
EvilBeaver Apr 30, 2025
3cedf48
Новый парсер сегментов версии
EvilBeaver May 1, 2025
4b2545f
Отказ от fluent в поиске максимума версий
EvilBeaver May 1, 2025
b104f24
Исправлена ошибка при поиске максимальной версии
sfaqer May 2, 2025
ad99219
Поднята зависимость от движка
sfaqer May 2, 2025
073ede0
Merge branch 'develop'
sfaqer May 2, 2025
a118bb5
Влиты изменения из ствола
EvilBeaver May 2, 2025
9b33f59
Работоспособный парсер семвера
EvilBeaver May 2, 2025
1a9e7c3
Немножко рефакторинга
EvilBeaver May 2, 2025
afae911
Ошибочно вкоммичен launch.json
EvilBeaver May 2, 2025
ef1ade3
Добавил тесты на склейку дефисов и исправил ошибку
EvilBeaver May 4, 2025
655a983
Замечания по ревью
EvilBeaver May 4, 2025
10fc0a0
Красный тест сравнения пререлизов
EvilBeaver May 12, 2025
a678273
Сравнение версий с учетом пререлизов
EvilBeaver May 13, 2025
7ba53eb
Тестирование OneUnit для dev
sfaqer May 19, 2025
882b3d2
ПолучитьСписокТестов -> &Тест
sfaqer May 19, 2025
03cc185
Убран импорт fluent
nixel2007 May 19, 2025
dedad74
Create qa.yaml
nixel2007 May 19, 2025
25d4331
Create sonar-project.properties
nixel2007 May 19, 2025
5dfe792
Потерянный экспорт
nixel2007 May 19, 2025
2ae472e
Зависимость от coverage
sfaqer May 19, 2025
d08cb2e
Update coverage.os
nixel2007 May 19, 2025
40dd5f7
Исправление замечаний кролика
sfaqer May 19, 2025
6dc7e61
Исправлена ошибка сравнения релизной версии и однокомпонентного RC
sfaqer May 19, 2025
e9683ab
Merge branch 'master' into feature/prereleases-2
sfaqer May 19, 2025
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
3 changes: 1 addition & 2 deletions packagedef
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
//

Описание.Имя("semver")
.Версия("0.6.0")
.Версия("1.0.0")
.Автор("Khorev Aleksey")
.АдресАвтора("[email protected]")
.Описание("Эта библиотека облегчает работу с семантическими версиями")
Expand All @@ -14,7 +14,6 @@
.ВключитьФайл("tests")
.ЗависитОт("logos")
.ЗависитОт("strings")
.ЗависитОт("fluent", "0.6.1")
.РазработкаЗависитОт("1testrunner", "1.9.2")
.ОпределяетМодуль("Версии", "src/core/Модули/Версии.os")
.ОпределяетКласс("Версия", "src/core/Классы/Версия.os")
Expand Down
200 changes: 164 additions & 36 deletions src/core/Классы/Версия.os
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
Перем Патч Экспорт; // число

Перем ПреРелиз Экспорт; // Массив
Перем НомерБилда Экспорт; // Массив;
Перем МетаданныеСборки Экспорт; // Массив;
Перем ОшибкаЧтенияВерсии Экспорт;

Процедура ПриСозданииОбъекта(Знач ВерсияСтрокой)
Expand All @@ -17,6 +17,7 @@
Второстепенная = 0;
Патч = 0;
ПреРелиз = Новый Массив;
МетаданныеСборки = Новый Массив;

Прочитать(ВерсияСтрокой);

Expand Down Expand Up @@ -47,6 +48,14 @@
Функция ВСтроку() Экспорт

СтрокаВерсии = СтрШаблон("%1.%2.%3", Строка(Основная), Строка(Второстепенная), Строка(Патч));

Если ПреРелиз.Количество() Тогда
СтрокаВерсии = СтрокаВерсии + "-" + СтрСоединить(ПреРелиз, ".");
КонецЕсли;

Если МетаданныеСборки.Количество() Тогда
СтрокаВерсии = СтрокаВерсии + "+" + СтрСоединить(МетаданныеСборки, ".");
КонецЕсли;

Возврат СтрокаВерсии;

Expand All @@ -64,7 +73,7 @@

Если НЕ Основная = ВходящаяВерсия.Основная Тогда

Возврат ?(Основная > ВходящаяВерсия.Основная,1,-1);
Возврат ?(Основная > ВходящаяВерсия.Основная, 1,-1);

КонецЕсли;

Expand Down Expand Up @@ -173,64 +182,183 @@

ВерсияСтрокой = ПодготовитьКЧтению(ВерсияСтрокой);

МассивСтрокВерсии = СтрРазделить(ВерсияСтрокой, ".");
Парсер = Новый ПарсерВерсии(ВерсияСтрокой);
Парсер.Следующий();

Попытка
ПрочитатьОсновную(Парсер);
ПрочитатьРазделитель(Парсер, ".");
ПрочитатьВторостепенную(Парсер);
ПрочитатьРазделитель(Парсер, ".");
ПрочитатьПатч(Парсер);
ПрочитатьХвостовыеМассивы(Парсер);
Исключение
ОшибкаЧтенияВерсии = ИнформацияОбОшибке().Описание;
КонецПопытки;

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

Процедура ПрочитатьОчереднойРазделитель(Знач Парсер, Знач Разделитель)

ТекущийТокен = Парсер.Следующий();
Если ТекущийТокен.Тип = Парсер.ТипКонецТекста Тогда
Возврат;
КонецЕсли;

Если МассивСтрокВерсии.Количество() < 3 Тогда
ОшибкаЧтенияВерсии = "Не найдены все составляющие версии";
Возврат;
Если ТекущийТокен.Тип = Парсер.ТипРазделитель Тогда
Если Разделитель = ТекущийТокен.Значение Тогда
СледующийТокен = Парсер.Следующий();
Если СледующийТокен.Тип = Парсер.ТипКонецТекста Тогда
ВызватьИсключение СтрШаблон("Неожиданный конец строки версии, нет данных после разделителя <%1>", Разделитель);
КонецЕсли;
Возврат;
КонецЕсли;
КонецЕсли;

СтрокаОсновнаяВерсия = МассивСтрокВерсии[0];
ВызватьИсключение СтрШаблон("Ожидается разделитель <%1>, но получен <%2>", Разделитель, ТекущийТокен.Значение);

Если Не СтроковыеФункции.ТолькоЦифрыВСтроке(СтрокаОсновнаяВерсия) Тогда

ОшибкаЧтенияВерсии = СтрШаблон("Основная версия <%1> должна содержать только цифры",СтрокаОсновнаяВерсия);
Возврат;
КонецПроцедуры

Процедура ПрочитатьРазделитель(Знач Парсер, Знач Разделитель)

ТекущийТокен = Парсер.Текущий();
Если ТекущийТокен.Тип = Парсер.ТипКонецТекста Тогда
Возврат;
КонецЕсли;

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

Основная = Число(СтрокаОсновнаяВерсия);

СтрокаВторостепеннаяВерсия = МассивСтрокВерсии[1];
ВызватьИсключение СтрШаблон("Ожидается разделитель <%1>, но получен <%2>", Разделитель, ТекущийТокен.Значение);

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

Если Не СтроковыеФункции.ТолькоЦифрыВСтроке(СтрокаВторостепеннаяВерсия) Тогда

ОшибкаЧтенияВерсии = СтрШаблон("Второстепенная версия <%1> должна содержать только цифры",СтрокаОсновнаяВерсия);
Возврат;

Процедура ПрочитатьОсновную(Знач Парсер)
Токен = Парсер.Текущий();
Если Токен.Тип = Парсер.ТипКонецТекста Тогда
Возврат;
КонецЕсли;

Второстепенная = Число(СтрокаВторостепеннаяВерсия);
Если Токен.Тип = Парсер.ТипЧисло Тогда
Основная = Число(Токен.Значение);
ИначеЕсли Токен.Тип = Парсер.ТипОшибка Тогда
ВызватьИсключение Токен.Значение;
Иначе
ВызватьИсключение СтрШаблон("Основная версия <%1> должна содержать только цифры", Токен.Значение);
КонецЕсли;

СтрокаПатчаВерсии = МассивСтрокВерсии[2];
Парсер.Следующий();
КонецПроцедуры

Если Не СтроковыеФункции.ТолькоЦифрыВСтроке(СтрокаПатчаВерсии) Тогда

ОшибкаЧтенияВерсии = СтрШаблон("Версия патча <%1> должна содержать только цифры",СтрокаОсновнаяВерсия);
Возврат;

Процедура ПрочитатьВторостепенную(Знач Парсер)
Токен = Парсер.Текущий();
Если Токен.Тип = Парсер.ТипКонецТекста Тогда
Возврат;
КонецЕсли;

Патч = Число(СтрокаПатчаВерсии);
Если Токен.Тип = Парсер.ТипЧисло Тогда
Второстепенная = Число(Токен.Значение);
ИначеЕсли Токен.Тип = Парсер.ТипОшибка Тогда
ВызватьИсключение Токен.Значение;
Иначе
ВызватьИсключение СтрШаблон("Второстепенная версия <%1> должна содержать только цифры", Токен.Значение);
КонецЕсли;

Парсер.Следующий();
КонецПроцедуры

Функция ПодготовитьКЧтению(Знач СтрокаВерсии)

Если СтрНачинаетсяС(СтрокаВерсии, "v") Тогда
СтрокаВерсии = СтрЗаменить(СтрокаВерсии, "v", "");
Процедура ПрочитатьПатч(Знач Парсер)
Токен = Парсер.Текущий();
Если Токен.Тип = Парсер.ТипКонецТекста Тогда
Возврат;
КонецЕсли;

Если Токен.Тип = Парсер.ТипЧисло Тогда
Патч = Число(Токен.Значение);
ИначеЕсли Токен.Тип = Парсер.ТипОшибка Тогда
ВызватьИсключение Токен.Значение;
Иначе
ВызватьИсключение СтрШаблон("Версия патча <%1> должна содержать только цифры", Токен.Значение);
КонецЕсли;

Парсер.Следующий();
КонецПроцедуры

Процедура ПрочитатьХвостовыеМассивы(Знач Парсер)
Токен = Парсер.Текущий();
Если Токен.Тип = Парсер.ТипКонецТекста Тогда
Возврат;
КонецЕсли;

Если Токен.Тип <> Парсер.ТипРазделитель или Токен.Значение = "." Тогда
ВызватьИсключение "Ожидается разделитель пререлизной версии <-> или метаданных сборки <+>, получен <" + Токен.Значение + ">";
КонецЕсли;

ПрочитатьПреРелиз(Парсер);
ПрочитатьМетаданныеСборки(Парсер);

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

Процедура ПрочитатьПреРелиз(Знач Парсер)
Если Парсер.Текущий().Значение = "-" Тогда
Парсер.Следующий();
СобратьМассивИзКомпонентов(Парсер, ПреРелиз, "+");
КонецЕсли;
КонецПроцедуры

Процедура ПрочитатьМетаданныеСборки(Знач Парсер)
Если Парсер.Текущий().Значение = "+" Тогда
Парсер.Следующий();
СобратьМассивИзКомпонентов(Парсер, МетаданныеСборки, "");
КонецЕсли;
КонецПроцедуры

МассивСтрокВерсии = СтрРазделить(СтрокаВерсии, ".");
Процедура СобратьМассивИзКомпонентов(Знач Парсер, Знач МассивКомпонентов, Знач ПрерватьПо)

Пока Истина Цикл
МассивКомпонентов.Добавить(ПрочитатьКомпонент(Парсер));
Если Парсер.Текущий().Значение = ПрерватьПо или Парсер.Текущий().Тип = Парсер.ТипКонецТекста Тогда
Прервать;
КонецЕсли;

КоличествоДобавления = 3 - МассивСтрокВерсии.Количество();
ПрочитатьРазделитель(Парсер, ".");

Для ИИ = 1 ПО КоличествоДобавления Цикл
МассивСтрокВерсии.Добавить(0);
КонецЦикла;

Возврат СтрСоединить(МассивСтрокВерсии, ".");
КонецПроцедуры

Функция ПрочитатьКомпонент(Знач Парсер)
Токен = Парсер.Текущий();
Если Токен.Тип = Парсер.ТипЧисло Тогда
Парсер.Следующий();
Возврат Токен.Значение;
ИначеЕсли Токен.Тип = Парсер.ТипТекст Тогда
Текст = Токен.Значение;
ТекТокен = Парсер.Следующий();
Пока ТекТокен.Тип = Текст или ТекТокен.Значение = "-" Цикл
Текст = Текст + ТекТокен.Значение;
Парсер.Следующий();
КонецЦикла;
Возврат Текст;
Иначе
ВызватьИсключение СтрШаблон("Ожидается компонент версии, но получен <%1>", ?(Токен.Значение = "", "EOF", Токен.Значение));
КонецЕсли;
КонецФункции

Функция ПодготовитьКЧтению(Знач СтрокаВерсии)

Если СтрНачинаетсяС(СтрокаВерсии, "v") Тогда
СтрокаВерсии = Сред(СтрокаВерсии, 2);
КонецЕсли;

Возврат СтрокаВерсии;

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

Expand Down
122 changes: 122 additions & 0 deletions src/core/Классы/ПарсерВерсии.os
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
Перем СтрокаДляРазбора;
Перем Индекс;

Перем ТипКонецТекста Экспорт;
Перем ТипЧисло Экспорт;
Перем ТипТекст Экспорт;
Перем ТипРазделитель Экспорт;
Перем ТипОшибка Экспорт;

Перем ДиапазонЧислоНачало;
Перем ДиапазонЧислоКонец;

Перем ДиапазонЗаглавныеБуквыНачало;
Перем ДиапазонЗаглавныеБуквыКонец;
Перем ДиапазонСтрочныеБуквыНачало;
Перем ДиапазонСтрочныеБуквыКонец;
Перем Дефис;
Перем Плюс;
Перем Точка;

Перем ТекущийТокен;

Процедура ПриСозданииОбъекта(Знач ВерсияСтрокой)
СтрокаДляРазбора = ВерсияСтрокой;
Если ПустаяСтрока(СтрокаДляРазбора) Тогда
Индекс = -1;
Иначе
Индекс = 1;
КонецЕсли;
КонецПроцедуры

Функция Токен(Знач Значение, Знач Тип)
Возврат Новый Структура("Тип, Значение", Тип, Значение);
КонецФункции

Функция Следующий() Экспорт

ТекущийТокен = ПолучитьСледующий();
Возврат ТекущийТокен;

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

Функция Текущий() Экспорт

Возврат ТекущийТокен;
КонецФункции

Функция Индекс() Экспорт

Возврат Индекс;

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

Функция ПолучитьСледующий()
Если Индекс = -1 Тогда
Возврат Токен("", ТипКонецТекста);
КонецЕсли;

ТипТокена = ТипЧисло;
НачалоЗначения = Индекс;
ЧислоСимволов = 0;

Пока Истина Цикл

Символ = Сред(СтрокаДляРазбора, Индекс, 1);
КодСимвола = КодСимвола(Символ);
Если ПустаяСтрока(Символ) Тогда
Если ЧислоСимволов = 0 Тогда
// Это последний прочитанный токен
Индекс = -1;
Возврат Токен("", ТипКонецТекста);
КонецЕсли;
Прервать;
КонецЕсли;

// Инлайн, чтобы было побыстрее и не тратило время на вызов метода
Если (КодСимвола >= ДиапазонЗаглавныеБуквыНачало И КодСимвола <= ДиапазонЗаглавныеБуквыКонец) ИЛИ
(КодСимвола >= ДиапазонСтрочныеБуквыНачало И КодСимвола <= ДиапазонСтрочныеБуквыКонец) Тогда
ТипТокена = ТипТекст;
ИначеЕсли КодСимвола >= ДиапазонЧислоНачало И КодСимвола <= ДиапазонЧислоКонец Тогда
// обработка числа
ИначеЕсли КодСимвола = Точка ИЛИ КодСимвола = Дефис ИЛИ КодСимвола = Плюс Тогда
// разделитель
Прервать;
Иначе
// ошибка
Позиция = Индекс;
Индекс = -1; // блокировка парсера
Возврат Токен(СтрШаблон("Недопустимый символ '%1' в позиции %2", Символ, Позиция), ТипОшибка);
КонецЕсли;

Индекс = Индекс + 1;
ЧислоСимволов = ЧислоСимволов + 1;
КонецЦикла;

Если ЧислоСимволов = 0 Тогда
// Это разделитель
Значение = Сред(СтрокаДляРазбора, Индекс, 1);
Индекс = Индекс + 1;
Возврат Токен(Значение, ТипРазделитель);
КонецЕсли;

Значение = Сред(СтрокаДляРазбора, НачалоЗначения, ЧислоСимволов);

Возврат Токен(Значение, ТипТокена);
КонецФункции

ТипКонецТекста = 0;
ТипЧисло = 1;
ТипТекст = 2;
ТипРазделитель = 3;
ТипОшибка = 4;

ДиапазонЧислоНачало = 48;
ДиапазонЧислоКонец = 57;
ДиапазонЗаглавныеБуквыНачало = 65;
ДиапазонЗаглавныеБуквыКонец = 90;
ДиапазонСтрочныеБуквыНачало = 97;
ДиапазонСтрочныеБуквыКонец = 122;
Дефис = КодСимвола("-");
Плюс = КодСимвола("+");
Точка = КодСимвола(".");
Loading
Loading