robert-min / handson-go

Go-lang hands on guide
0 stars 0 forks source link

Chapter2. Sub command #4

Open robert-min opened 1 year ago

robert-min commented 1 year ago

서브커맨드 구현

robert-min commented 1 year ago

Sub Command Example

import ( "flag" "fmt" "io" "os" )

func handleCmdA(w io.Writer, args []string) error { var v string fs := flag.NewFlagSet("cmd-a", flag.ContinueOnError) fs.SetOutput(w) fs.StringVar(&v, "verb", "argument-value", "Argument 1") err := fs.Parse(args) if err != nil { return nil } fmt.Fprintf(w, "Executing command A") return nil }

func handleCmdB(w io.Writer, args []string) error { var v string fs := flag.NewFlagSet("cmd-b", flag.ContinueOnError) fs.SetOutput(w) fs.StringVar(&v, "verb", "argument-value", "Argument 1") err := fs.Parse(args) if err != nil { return err } fmt.Fprintf(w, "Executing command B") return nil }

func printUsage(w io.Writer) { fmt.Fprintf(w, "Usage: %s [cmd-a|cmd-b] -h\n", os.Args[0]) handleCmdA(w, []string{"-h"}) handleCmdB(w, []string{"-h"}) }

func main() { var err error if len(os.Args) < 2 { printUsage(os.Stdout) os.Exit(1) } switch os.Args[1] { case "cmd-a": err = handleCmdA(os.Stdout, os.Args[2:]) case "cmd-b": err = handleCmdB(os.Stdout, os.Args[2:]) default: printUsage(os.Stdout) }

if err != nil {
    fmt.Fprint(os.Stdout, err)
    os.Exit(1)
}

}

robert-min commented 1 year ago

서브커맨드 주도 어플리케이션 아키텍쳐

robert-min commented 1 year ago

main package

package main

import (
    "errors"
    "fmt"
    "io"
    "os"

    "github.com/handson-go/chap2/sub-cmd-arch/cmd"
)

var errInvalidSubCommand = errors.New("Invalid sub-command specified")

// Print usage
func printUsage(w io.Writer) {
    fmt.Fprintf(w, "Usage: mync [http|grpc] -h\n")
    cmd.HandleHttp(w, []string{"-h"})
    cmd.HandleGrpc(w, []string{"-h"})
}

// Handling command
func handleCommand(w io.Writer, args []string) error {
    var err error

    if len(args) < 1 {
        err = errInvalidSubCommand
    } else {
        switch args[0] {
        case "http":
            err = cmd.HandleHttp(w, args[1:])
        case "grpc":
            err = cmd.HandleGrpc(w, args[1:])
        case "-h":
            printUsage(w)
        case "-help":
            printUsage(w)
        default:
            err = errInvalidSubCommand
        }
    }

    if errors.Is(err, cmd.ErrNoServerSpecified) || errors.Is(err, errInvalidSubCommand) {
        fmt.Fprintln(w, err)
        printUsage(w)
    }
    return err

}

func main() {
    err := handleCommand(os.Stdout, os.Args[1:])
    if err != nil {
        os.Exit(1)
    }
}
robert-min commented 1 year ago

cmd/httpCmd.go

package cmd

import (
    "flag"
    "fmt"
    "io"
)

type httpConfig struct {
    url  string
    verb string
}

func HandleHttp(w io.Writer, args []string) error {
    var v string

    fs := flag.NewFlagSet("http", flag.ContinueOnError)
    fs.SetOutput(w)
    fs.StringVar(&v, "verb", "GET", "HTTP method")

    fs.Usage = func() {
        var usageString = `
http: A HTTP client.

http: <options> server`
        fmt.Fprintf(w, usageString)

        fmt.Fprintln(w)
        fmt.Fprintln(w)
        fmt.Fprintln(w, "Options: ")
        fs.PrintDefaults()
    }

    err := fs.Parse(args)
    if err != nil {
        return err
    }

    if fs.NArg() != 1 {
        return ErrNoServerSpecified
    }

    c := httpConfig{verb: v}
    c.url = fs.Arg(0)
    fmt.Fprintln(w, "Executing http command")
    return nil
}