GO: Запустите команду cli с неверными аргументами - PullRequest
0 голосов
/ 05 ноября 2018

Я использую кобру, чтобы создать инструмент командной строки CLI. все выглядит нормально, кроме обработки ошибок

что я хочу, чтобы, если команда была отправлена ​​по ошибке (неверные аргументы или неправильный ввод), верните std.err вместо std.out

, чтобы упростить секнарио, которое я создал, которое демонстрирует мой вариант использования

package main

import (
    "errors"
    "fmt"
    "os"

    "github.com/spf13/cobra"
)

var (
    RootCmd = &cobra.Command{
        Use: "myApp",
        Run: func(cmd *cobra.Command, args []string) {
            fmt.Printf("ROOT verbose = %d, args = %v\n", args)
        },
    }

    provideCmd = &cobra.Command{
        Use: "provide",
        Run: nil,
    }

    appCmd = &cobra.Command{
        Use: "apps",
        RunE: func(cmd *cobra.Command, args []string) error {
            name := args[0]
            if name != "myapp" {
                err := errors.New("app name doesnt exist")
                return err
            }
            return nil
        },
        SilenceUsage:               true,
    }


)

func init() {
    // Add the application command to app command
    provideCmd.AddCommand(appCmd)
    //  add provide command to root command
    RootCmd.AddCommand(provideCmd)
}

func main() {
    if err := RootCmd.Execute(); err != nil {
        fmt.Println(err)
        os.Exit(-1)
    }
}

Теперь, если я компилирую двоичный файл и запускаю exec.Command для двоичного файла, все работает как положено. но если я хочу проверить сценарий ошибки, как mycli provide apps apps1 Я хочу видеть, что вернулся в std.err, а не в std.out

Когда я выполняю mycli provide apps myapp все должно быть в порядке

но если я запускаю mycli provide apps myapp2 я хочу получить std.err, а не std.out, что здесь не так ... что мне здесь не хватает?

https://play.golang.org/p/B00z4eZ7Sj-

1 Ответ

0 голосов
/ 05 ноября 2018

Ваш образец уже печатает ошибку как stdout и stderr.

По умолчанию пакет cobra печатает все ошибки, с которыми он сталкивается, до stderr, если вы специально не измените это.

Так работает ./main provide apps something 2> ./stderr.txt создает текстовый файл со следующим содержимым (это то, что кобра пишет в stderr без вашего вмешательства):

Error: app name doesnt exist

И работает ./main provide apps something > ./stdout.txt - создает текстовый файл со следующим содержимым (вы напечатали это самостоятельно с помощью fmt.Println(err), вторая строка снизу в вашем коде):

app name doesnt exist

Что означает поведение по умолчанию печатает ошибки как stdout и stderr.

Как вам советовал Девин, изменив последнюю строку на os.Stderr.WriteString(err) или fmt.Fprintln(os.Stderr, err) (тот, который я бы использовал) заставит ваш проект напечатать все до stderr only , что означает ошибки печати дважды:

Error: app name doesnt exist
app name doesnt exist

Может быть полезно знать, что кобра позволяет вам контролировать поведение при печати ошибок. Например, вы можете указать команде кобры, в какой поток печатать:

command.SetOutput(os.Stdout)     // Defaults to os.Stderr

Вы также можете предотвратить печать ошибок:

command.SilenceErrors = true

или запретить печать текста использования:

command.SilenceUsage = true
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...