Комментарии 10
В вашем примере с app pipeline pull --fetch commit -m "fix" push run вы объявляете и run, и --fetch параметром. Непонятно, как оно делит поток на команды и их аргументы, и что будет делать в случае неоднозначности (например, если объявить [ArgsPipelineCommand("run")], то оно воспримется как отдельная команда или как параметр в ExecConfig?
Всё, что между командами, является их параметрами. На push команды заканчиваются и дальше может быть что угодно. В данном случае это поле корневого класса. В случае неоднозначности будет ошибка. Нельзя сделать и команду, и поле run. Но у разных команд параметры могут повторяться.
Чем мне нравится экосистема dotnet это тем, что дефолтные решения существуют неплохого качества и закрывают топ потребностей разработчика. Если они этого не делают, то ваша тема или супернишевая, или вам "захотелось странного". Это я к тому что есть System.CommandLine и Spectre, они максимально гибкие, первый является стандартом для внутренних разработок ms, наример, используется в dotnet core tools, и из статьи не понятно в чем преимущество стороннего решения. Таблица не помогает, и к тому же требует проверки. Где вот этот наглядный импрув, чтобы читатель сразу сказал, ну да это однозначно надо звезду поставить и плюсик в карму ?
Лично я бы не стал пользоваться. Минимальная гибкость, смешение ответственности, глобальные статические коллбеки.. отсутствие контекстной конфигурации или стратегий, возможности подкинуть свой сериализатор, а еще все обмазано рефлексей вместо кодогенерации.. список можно и дальше продолжать.
Мне не нравится, когда мы описываем каждую команду через пачку кода. Мне хотелось сделать максимально компактное решение. Плюсом оно сразу проверяет порядок аргументов, повторяемость, некоторую логику (определённый аргумент можно указать только после другого или только один из множества). А в случае ошибки получаем ещё и позицию аргумента, где она возникла.
Если же мы выполняем аргументы сразу по мере их чтения, то это очень плохая идея. Мы можем что-то выполнить (удалить файл, например), а потом узнать, что у нас ошибка в аргументах. На мой взгляд, надо сначала прочитать все аргументы, провалидировать их, а потом уже работать. Моя библиотека решает первый шаг целиком и второй частично (какая-то сложная валидация остаётся на пользователя).
Мне не нравится, когда мы описываем каждую команду через пачку кода
Пишем свой кодогенератор для System.CommandLine, или берем из nuget.. или смотрим что там написали до нас и пишем свой более легковесный, не принципиально. Вы потратите столько же строк если не меньше.
Плюсом оно сразу проверяет порядок аргументов, повторяемость, некоторую логику (определённый аргумент можно указать только после другого или только один из множества). А в случае ошибки получаем ещё и позицию аргумента, где она возникла.
И все это умеет System.CommandLine, вам только следует описать обертку если вы хотите модно использовать дженерики. Главное, что вы берете готовый активно поддерживаемый инструмент с перспективами. Долгосрочная же поддержка ваших велосипедов объективно сомнительна. Не воспринимайте как личную обиду, но это же opensource, даже если проект выстрелил и стал хитом сейчас, это не гарантирует его поддержку.. а включение в тулинг ms - да.
Если же мы выполняем аргументы сразу по мере их чтения, то это очень плохая идея. Мы можем что-то выполнить (удалить файл, например), а потом узнать, что у нас ошибка в аргументах
Мне из текста не понятна ситуация, где аргументы "выполняются" сразу после чтения. Для чего? Понимаете кто пишет такой код? Вы исправляли баги за пьяным орангутаном который это написал, и в процессе сделали решение которое делать было не надо.
Вот жалко, что в таблице нет Native AOT compability. Да в принципе я уже вижу, что у вас примерно всё на рефлекшене, а значит в native aot работать не будет.
Жаль. Как раз сейчас мне нужен парсинг команд cli для native aot приложения.

Arguments to Config — простая и мощная библиотека для парсинга аргументов в CLI-приложении на C#