CLI приложения #2. Ручной парсинг аргументов

Поскольку все необходимые данные CLI приложения получают на входе, эти самые данные нужно как-то получить и обработать. Предлагаю сперва прочувствовать, каково это парсить строки руками. Маленький пример, который должен работать.

myapp --name Иван --count 3 --verbose
myapp -n Иван -c 3 -v
myapp --name=Иван

По большому счету, тут три одинаковые записи. Почти одинаковые. Никакой фантастики, всё кратко и очевидно.

myapp -> название приложения (на самом деле это главная команда),
--name Иван -> передаем имя
--count 3 -> передаем количество повторений приветствия
--verbose -> просим приложение выполнять действия с выводом подробной информации в консоль

И теперь код, который заставит это работать:


static int Main(string[] args)
{
    string? name = null;
    int count = 1;
    bool verbose = false;

    for (int i = 0; i < args.Length; i++)
    {
        var arg = args[i];

        if (arg == "--name" || arg == "-n")
        {
            if (i + 1 >= args.Length)
            {
                Console.Error.WriteLine("Ошибка: --name требует значение");
                return 1;
            }
            name = args[++i];
        }
        else if (arg.StartsWith("--name="))
        {
            name = arg["--name=".Length..];
        }
        else if (arg == "--count" || arg == "-c")
        {
            if (i + 1 >= args.Length || !int.TryParse(args[i + 1], out count))
            {
                Console.Error.WriteLine("Ошибка: --count требует число");
                return 1;
            }
            i++;
        }
        else if (arg == "--verbose" || arg == "-v")
        {
            verbose = true;
        }
        else
        {
            Console.Error.WriteLine($"Неизвестный аргумент: {arg}");
            return 1;
        }
    }

    if (name is null)
    {
        Console.Error.WriteLine("Ошибка: не указан --name");
        return 1;
    }

    for (int i = 0; i < count; i++)
        Console.WriteLine($"Привет, {name}!");

    if (verbose)
        Console.WriteLine($"Готово, повторов: {count}");

    return 0;
}

Сколько тут строк получилось? Вооот, а это только самый минимум и приложение ничего не делает.

Из папки с проектом можно выполнить команду и проверить результат

dotnet run -- --name Иван --count 3 -v

Для того, чтобы наше изделие можно было назвать CLI приложением, нужно добавить еще:

  • опцию --help (используется во всех CLI приложениях, это справка по командам и аргументам)
  • команда --count=3 не работает в принципе, такая конструкция сейчас доступна только для name
  • подкоманды вида myapp config set ключ значение + значения по умолчанию в справке и проверки значений.

Для всего этого нужно написать еще множество строк кода и по итогу для небольшого приложения получим огромное полотно кода. Это еще тестов не касались.

Так что, ручной парсинг - это техника, которой хорошо владеть, понимать, как это работает, но для реальных приложений используют библиотеки. В нашем случае это System.CommandLine.
А как будет выглядеть код с использованием этой библиотеки мы посмотрим уже в следующем посте.