forked from vanessa-opensource/ovm
-
Notifications
You must be signed in to change notification settings - Fork 9
feat: команда completions через autumn-cli + &ПоставщикДополнения #54
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
Draft
Copilot
wants to merge
15
commits into
develop
Choose a base branch
from
copilot/add-completions-command
base: develop
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from 6 commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
5fe9c29
add completions command with bash support
Copilot 217fbfe
address review: use Russian naming conventions
Copilot 080f005
generate bash completions dynamically from registered commands via au…
Copilot f7ca444
include subcommands in bash completions via nested case statements
Copilot 491dd4b
Use DI injection for КомандаПриложения beans and СборщикОпций for Опи…
Copilot 807b8f5
Add error handling for ОписаниеКоманды call in ПолучитьОпцииКоманды
Copilot e8a4bdc
Remove СборщикОпций, use КонсольноеПриложение injection and CLI libra…
Copilot e588683
Fix spacing inconsistency in assignment operators
Copilot d8404c6
Fix КомандаCompletions: avoid DI cycle and use valid multi-line strin…
nixel2007 5a53682
Bump autumn-logos from 1.2.0 to 1.3.1
nixel2007 cd4e354
Smart completions for 'ovm use' and 'ovm install' version aliases
nixel2007 54711e8
Extend smart completions to 'uninstall', 'which', 'run'
nixel2007 932167e
feat: use completions from autumn-cli, switch install to declarative …
nfedkin 4a06e32
chore: синхронизация оверлея autumn-cli (генераторы-желуди)
nfedkin 0d04c38
refactor(completions): lightweight version-alias getter + fix indenta…
nixel2007 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| #language: ru | ||
|
|
||
| Функциональность: Генерация скрипта автодополнения | ||
|
|
||
| Как пользователь ovm | ||
| Я хочу получить скрипт автодополнения для моей оболочки | ||
| Чтобы удобно использовать ovm в терминале | ||
|
|
||
| Контекст: | ||
| Допустим Я устанавливаю переменной среды "OVM_INSTALL_PATH" значение "./temp/ovm" | ||
|
|
||
| Сценарий: Генерация completions для bash | ||
| Когда Я выполняю команду "oscript ./src/cmd/ovm.os completions --shell bash" | ||
| Тогда я вижу в консоли вывод "_ovm_completions" | ||
| И я вижу в консоли вывод "complete -F _ovm_completions ovm" | ||
|
|
||
| Сценарий: Генерация completions для bash с коротким флагом | ||
| Когда Я выполняю команду "oscript ./src/cmd/ovm.os completions -s bash" | ||
| Тогда я вижу в консоли вывод "_ovm_completions" | ||
| И я вижу в консоли вывод "complete -F _ovm_completions ovm" | ||
|
|
||
| Сценарий: Ошибка при указании неподдерживаемой оболочки | ||
| Когда Я выполняю команду "oscript ./src/cmd/ovm.os completions --shell zsh" | ||
| Тогда я вижу в консоли вывод "не поддерживается" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,240 @@ | ||
| #Использовать annotations | ||
|
|
||
| &ЛогOVM | ||
| Перем Лог; | ||
|
|
||
| &Пластилин(Тип = "ТаблицаЗначений", Значение = "КомандаПриложения") | ||
| Перем КомандыПриложения; | ||
|
|
||
| Перем Рефлектор; | ||
|
|
||
| &Опция(Имя = "shell s", Описание = "Тип оболочки для генерации автодополнения (поддерживается: bash)") | ||
| &ТСтрока | ||
| &ПоУмолчанию("bash") | ||
| &ВОкружении("OVM_COMPLETIONS_SHELL") | ||
| Перем ТипОболочки; | ||
|
|
||
| &КомандаПриложения(Имя = "completions", Описание = "Вывести скрипт автодополнения команд для выбранной оболочки") | ||
| Процедура ПриСозданииОбъекта() | ||
| Рефлектор = Новый Рефлектор(); | ||
| КонецПроцедуры | ||
|
|
||
| &ВыполнениеКоманды | ||
| Процедура ВыполнениеКоманды() Экспорт | ||
|
|
||
| Если НРег(ТипОболочки) = "bash" Тогда | ||
| Лог.Информация(СкриптАвтодополненияBash()); | ||
| Иначе | ||
| ВызватьИсключение СтрШаблон("Оболочка ""%1"" не поддерживается. Поддерживаемые оболочки: bash", ТипОболочки); | ||
| КонецЕсли; | ||
|
|
||
| КонецПроцедуры | ||
|
|
||
| Функция СкриптАвтодополненияBash() | ||
|
|
||
| ДеревоКоманд = ПолучитьДеревоКоманд(); | ||
|
|
||
| МассивИменВсехКоманд = Новый Массив(); | ||
| СтрокиCase = Новый Массив(); | ||
|
|
||
| Для Каждого ОписаниеКоманды Из ДеревоКоманд Цикл | ||
| Для Каждого ИмяКоманды Из ОписаниеКоманды.Имена Цикл | ||
| МассивИменВсехКоманд.Добавить(ИмяКоманды); | ||
| КонецЦикла; | ||
|
|
||
| ПаттернCase = СтрСоединить(ОписаниеКоманды.Имена, "|"); | ||
|
|
||
| Если ОписаниеКоманды.Подкоманды.Количество() > 0 Тогда | ||
| МассивИменПодкоманд = Новый Массив(); | ||
| МассивПодкомандCase = Новый Массив(); | ||
|
|
||
| Для Каждого ОписаниеПодкоманды Из ОписаниеКоманды.Подкоманды Цикл | ||
| Для Каждого ИмяПодкоманды Из ОписаниеПодкоманды.Имена Цикл | ||
| МассивИменПодкоманд.Добавить(ИмяПодкоманды); | ||
| КонецЦикла; | ||
|
|
||
| ПаттернПодкомандCase = СтрСоединить(ОписаниеПодкоманды.Имена, "|"); | ||
| СтрокаОпцийПодкоманды = СтрСоединить(ОписаниеПодкоманды.Опции, " "); | ||
|
|
||
| МассивПодкомандCase.Добавить(" " + ПаттернПодкомандCase + ")"); | ||
| МассивПодкомандCase.Добавить(" COMPREPLY=($(compgen -W """ + СтрокаОпцийПодкоманды + """ -- ""$cur""))"); | ||
| МассивПодкомандCase.Добавить(" ;;"); | ||
| КонецЦикла; | ||
|
|
||
| ИменаПодкоманд = СтрСоединить(МассивИменПодкоманд, " "); | ||
| СтрокаОпцийРодителя = СтрСоединить(ОписаниеКоманды.Опции, " "); | ||
| ТелоПодкомандCase = СтрСоединить(МассивПодкомандCase, Символы.ПС); | ||
|
|
||
| СтрокиCase.Добавить(" " + ПаттернCase + ")"); | ||
| СтрокиCase.Добавить(" if [ $cword -eq 2 ]; then"); | ||
| СтрокиCase.Добавить(" COMPREPLY=($(compgen -W """ + ИменаПодкоманд + " " + СтрокаОпцийРодителя + """ -- ""$cur""))"); | ||
| СтрокиCase.Добавить(" else"); | ||
| СтрокиCase.Добавить(" local subcommand=""${words[2]}"""); | ||
| СтрокиCase.Добавить(" case ""$subcommand"" in"); | ||
| СтрокиCase.Добавить(ТелоПодкомандCase); | ||
| СтрокиCase.Добавить(" esac"); | ||
| СтрокиCase.Добавить(" fi"); | ||
| СтрокиCase.Добавить(" ;;"); | ||
| Иначе | ||
| СтрокаОпций = СтрСоединить(ОписаниеКоманды.Опции, " "); | ||
|
|
||
| СтрокиCase.Добавить(" " + ПаттернCase + ")"); | ||
| СтрокиCase.Добавить(" COMPREPLY=($(compgen -W """ + СтрокаОпций + """ -- ""$cur""))"); | ||
| СтрокиCase.Добавить(" ;;"); | ||
| КонецЕсли; | ||
| КонецЦикла; | ||
|
|
||
| ВсеКоманды = СтрСоединить(МассивИменВсехКоманд, " "); | ||
| ТелоCase = СтрСоединить(СтрокиCase, Символы.ПС); | ||
|
|
||
| Скрипт = | ||
| "# ovm bash completions | ||
| # Добавьте строку ниже в ~/.bashrc для активации автодополнения: | ||
| # source <(ovm completions --shell bash) | ||
|
|
||
| _ovm_completions() { | ||
| local cur prev words cword | ||
| _init_completion 2>/dev/null || { | ||
| COMPREPLY=() | ||
| cur=""${COMP_WORDS[COMP_CWORD]}"" | ||
| prev=""${COMP_WORDS[COMP_CWORD-1]}"" | ||
| words=(""${COMP_WORDS[@]}"") | ||
| cword=$COMP_CWORD | ||
| } | ||
|
|
||
| local commands=""" + ВсеКоманды + """ | ||
|
|
||
| if [ $cword -eq 1 ]; then | ||
| COMPREPLY=($(compgen -W ""$commands"" -- ""$cur"")) | ||
| return 0 | ||
| fi | ||
|
|
||
| local command=""${words[1]}"" | ||
|
|
||
| case ""$command"" in | ||
| " + ТелоCase + " | ||
| *) | ||
| ;; | ||
| esac | ||
|
|
||
| return 0 | ||
| } | ||
|
|
||
| complete -F _ovm_completions ovm"; | ||
|
|
||
| Возврат Скрипт; | ||
|
|
||
| КонецФункции | ||
|
|
||
| Функция ПолучитьДеревоКоманд() | ||
|
|
||
| // Первый проход: собрать все команды с их именами желудей и родителями | ||
| ВсеИнфо = Новый Соответствие(); | ||
|
|
||
| Для Каждого ДанныеЖелудя Из КомандыПриложения Цикл | ||
| ИмяЖелудя = ДанныеЖелудя.Имя; | ||
| ОпределениеЖелудя = ДанныеЖелудя.ОпределениеЖелудя; | ||
| Желудь = ДанныеЖелудя.Желудь; | ||
| Конструктор = ОпределениеЖелудя.Завязь().ДанныеМетода(); | ||
|
|
||
| АннотацияКоманды = РаботаСАннотациями.НайтиАннотацию(Конструктор.Аннотации, "КомандаПриложения"); | ||
| Если АннотацияКоманды = Неопределено Тогда | ||
| Продолжить; | ||
| КонецЕсли; | ||
|
|
||
| ИмяКоманды = РаботаСАннотациями.ПолучитьЗначениеПараметраАннотации(АннотацияКоманды, "Имя"); | ||
| Если НЕ ЗначениеЗаполнено(ИмяКоманды) Тогда | ||
| Продолжить; | ||
| КонецЕсли; | ||
|
|
||
| Родитель = РаботаСАннотациями.ПолучитьЗначениеПараметраАннотации(АннотацияКоманды, "Родитель", ""); | ||
|
|
||
| ИнфоКоманды = Новый Структура("ИмяЖелудя, Родитель, Имена, Опции"); | ||
| ИнфоКоманды.ИмяЖелудя = ИмяЖелудя; | ||
| ИнфоКоманды.Родитель = Родитель; | ||
| ИнфоКоманды.Имена = СтрРазделить(ИмяКоманды, " "); | ||
| ИнфоКоманды.Опции = ПолучитьОпцииКоманды(Желудь, ОпределениеЖелудя); | ||
|
|
||
| ВсеИнфо.Вставить(ИмяЖелудя, ИнфоКоманды); | ||
| КонецЦикла; | ||
|
|
||
| // Второй проход: собрать дерево — верхнеуровневые команды со своими подкомандами | ||
| Результат = Новый Массив(); | ||
|
|
||
| Для Каждого КлючЗначение Из ВсеИнфо Цикл | ||
| ИнфоКоманды = КлючЗначение.Значение; | ||
|
|
||
| Если ЗначениеЗаполнено(ИнфоКоманды.Родитель) Тогда | ||
| Продолжить; | ||
| КонецЕсли; | ||
|
|
||
| Подкоманды = НайтиПодкоманды(ИнфоКоманды.ИмяЖелудя, ВсеИнфо); | ||
|
|
||
| ОписаниеКоманды = Новый Структура("Имена, Опции, Подкоманды"); | ||
| ОписаниеКоманды.Имена = ИнфоКоманды.Имена; | ||
| ОписаниеКоманды.Опции = ИнфоКоманды.Опции; | ||
| ОписаниеКоманды.Подкоманды = Подкоманды; | ||
|
|
||
| Результат.Добавить(ОписаниеКоманды); | ||
| КонецЦикла; | ||
|
|
||
| Возврат Результат; | ||
|
|
||
| КонецФункции | ||
|
|
||
| Функция НайтиПодкоманды(ИмяРодителя, ВсеИнфо) | ||
|
|
||
| Результат = Новый Массив(); | ||
|
|
||
| Для Каждого КлючЗначение Из ВсеИнфо Цикл | ||
| ИнфоКоманды = КлючЗначение.Значение; | ||
|
|
||
| Если НРег(ИнфоКоманды.Родитель) = НРег(ИмяРодителя) Тогда | ||
| ОписаниеПодкоманды = Новый Структура("Имена, Опции"); | ||
| ОписаниеПодкоманды.Имена = ИнфоКоманды.Имена; | ||
| ОписаниеПодкоманды.Опции = ИнфоКоманды.Опции; | ||
| Результат.Добавить(ОписаниеПодкоманды); | ||
| КонецЕсли; | ||
| КонецЦикла; | ||
|
|
||
| Возврат Результат; | ||
|
|
||
| КонецФункции | ||
|
|
||
| Функция ПолучитьОпцииКоманды(Желудь, ОпределениеЖелудя) | ||
|
|
||
| Опции = Новый Массив(); | ||
| Опции.Добавить("--help"); | ||
|
|
||
| Если Рефлектор.МетодСуществует(Желудь, "ОписаниеКоманды") Тогда | ||
| Попытка | ||
| Сборщик = Новый СборщикОпций(); | ||
| Желудь.ОписаниеКоманды(Сборщик); | ||
| Для Каждого ИмяОпции Из Сборщик.ПолучитьОпции() Цикл | ||
| Опции.Добавить(ИмяОпции); | ||
| КонецЦикла; | ||
| Исключение | ||
| Лог.Предупреждение("Не удалось получить опции команды через ОписаниеКоманды: %1", ОписаниеОшибки()); | ||
| КонецПопытки; | ||
| Иначе | ||
| Свойства = ОпределениеЖелудя.Свойства(); | ||
| Для Каждого Свойство Из Свойства Цикл | ||
| АннотацияОпции = РаботаСАннотациями.ПолучитьАннотацию(Свойство, "Опция"); | ||
| Если АннотацияОпции = Неопределено Тогда | ||
| Продолжить; | ||
| КонецЕсли; | ||
|
|
||
| ИмяОпции = РаботаСАннотациями.ПолучитьЗначениеПараметраАннотации(АннотацияОпции, "Имя"); | ||
| Для Каждого ЧастьОпции Из СтрРазделить(ИмяОпции, " ") Цикл | ||
| Если СтрДлина(ЧастьОпции) = 1 Тогда | ||
| Опции.Добавить("-" + ЧастьОпции); | ||
| Иначе | ||
| Опции.Добавить("--" + ЧастьОпции); | ||
| КонецЕсли; | ||
| КонецЦикла; | ||
| КонецЦикла; | ||
| КонецЕсли; | ||
|
|
||
| Возврат Опции; | ||
|
|
||
| КонецФункции | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,110 @@ | ||
| // Вспомогательный класс для сбора имён опций команды. | ||
| // Используется как заглушка вместо КомандаПриложения при вызове ОписаниеКоманды(), | ||
| // чтобы получить зарегистрированные опции без запуска команды. | ||
|
|
||
| Перем Опции; // Массив - собранные имена опций | ||
|
|
||
| Процедура ПриСозданииОбъекта() | ||
|
nixel2007 marked this conversation as resolved.
Outdated
|
||
| Опции = Новый Массив(); | ||
| КонецПроцедуры | ||
|
|
||
| // Перехватывает регистрацию опции и возвращает себя для поддержки цепочек вызовов. | ||
| // | ||
| // Параметры: | ||
| // Имя - Строка - имя опции (может включать синонимы через пробел, например "clean c") | ||
| // Значение - Произвольный - значение по умолчанию (не используется) | ||
| // Описание - Строка - описание (не используется) | ||
| // | ||
| // Возвращаемое значение: | ||
| // СборщикОпций - ЭтотОбъект для цепочки вызовов | ||
| Функция Опция(Имя, Значение = "", Описание = "") Экспорт | ||
|
|
||
| Для Каждого ЧастьИмени Из СтрРазделить(Имя, " ", Ложь) Цикл | ||
| Если СтрДлина(ЧастьИмени) = 1 Тогда | ||
| Опции.Добавить("-" + ЧастьИмени); | ||
| Иначе | ||
| Опции.Добавить("--" + ЧастьИмени); | ||
| КонецЕсли; | ||
| КонецЦикла; | ||
|
|
||
| Возврат ЭтотОбъект; | ||
|
|
||
| КонецФункции | ||
|
|
||
| // Игнорирует регистрацию аргумента (позиционные аргументы не нужны для автодополнения опций). | ||
| // | ||
| // Возвращаемое значение: | ||
| // СборщикОпций - ЭтотОбъект для цепочки вызовов | ||
| Функция Аргумент(Имя, Значение = "", Описание = "") Экспорт | ||
| Возврат ЭтотОбъект; | ||
| КонецФункции | ||
|
|
||
| // Методы цепочки вызовов — возвращают ЭтотОбъект, не выполняя реальных действий. | ||
|
|
||
| Функция ТСтрока() Экспорт | ||
| Возврат ЭтотОбъект; | ||
| КонецФункции | ||
|
|
||
| Функция ТЧисло() Экспорт | ||
| Возврат ЭтотОбъект; | ||
| КонецФункции | ||
|
|
||
| Функция ТБулево() Экспорт | ||
| Возврат ЭтотОбъект; | ||
| КонецФункции | ||
|
|
||
| Функция ТДата(ФорматДаты = "") Экспорт | ||
| Возврат ЭтотОбъект; | ||
| КонецФункции | ||
|
|
||
| Функция ТМассивСтрок() Экспорт | ||
| Возврат ЭтотОбъект; | ||
| КонецФункции | ||
|
|
||
| Функция ТМассивЧисел() Экспорт | ||
| Возврат ЭтотОбъект; | ||
| КонецФункции | ||
|
|
||
| Функция ТМассивДат() Экспорт | ||
| Возврат ЭтотОбъект; | ||
| КонецФункции | ||
|
|
||
| Функция ВОкружении(Переменная) Экспорт | ||
| Возврат ЭтотОбъект; | ||
| КонецФункции | ||
|
|
||
| Функция Флаговый() Экспорт | ||
| Возврат ЭтотОбъект; | ||
| КонецФункции | ||
|
|
||
| Функция Флаг() Экспорт | ||
| Возврат ЭтотОбъект; | ||
| КонецФункции | ||
|
|
||
| Функция СкрытьВСправке() Экспорт | ||
| Возврат ЭтотОбъект; | ||
| КонецФункции | ||
|
|
||
| Функция ПоУмолчанию(Значение) Экспорт | ||
| Возврат ЭтотОбъект; | ||
| КонецФункции | ||
|
|
||
| Функция Обязательный(Признак = Истина) Экспорт | ||
| Возврат ЭтотОбъект; | ||
| КонецФункции | ||
|
|
||
| Функция ПодробноеОписание(Описание) Экспорт | ||
| Возврат ЭтотОбъект; | ||
| КонецФункции | ||
|
|
||
| Функция Псевдоним(Имя) Экспорт | ||
| Возврат ЭтотОбъект; | ||
| КонецФункции | ||
|
|
||
| // Возвращает собранные имена опций. | ||
| // | ||
| // Возвращаемое значение: | ||
| // Массив - список строк вида "--name" и "-n" | ||
| Функция ПолучитьОпции() Экспорт | ||
| Возврат Опции; | ||
| КонецФункции | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.