Go 및 Cobra를 사용하여 CLI 툴을 구축하는 방법

27396 단어 tutorialcligocobra
최초 출시 시점divrhino.com
Go는 서비스를 구축하고 생산성을 높이는 도구에 매우 유용하다.CLI 툴은 매우 강력합니다.그들은 다양한 일상 임무를 자동화하는 위대한 방식이다.누가 하루에 적어도 한 번은 아버지의 농담을 할 필요가 없겠는가?작은 CLI 도구를 만드는 법을 배울 것입니다. icanhazdadjokeapi를 사용하여 무작위 아빠 농담을 할 것입니다.

선결 조건


이 자습서를 계속 공부하려면 Go 및 Cobra를 설치해야 합니다.
설치 가이드:
  • Go
  • Cobra generator
  • 프로젝트 초기화


    터미널에서, 우리는 먼저 우리의 프로젝트를 위해 새 디렉터리를 만들 수 있다.그리고 새 디렉터리로 전환해서 새 프로그램을 만들고 패키지 이름을 줄 수 있습니다.보통 가방 하나가 당신의 URL입니다.
    이 예에서, 우리는 그것을 github 환매라고 명명했다.example를 Github 사용자 이름으로 변경할 수 있습니다.
    cd Sites
    mkdir dadjoke
    cd dadjoke
    cobra init --pkg-name github.com/example/dadjoke
    
    터미널에서 ls 명령을 실행하면 cobra init 명령이 만든 파일을 볼 수 있습니다.
    ls
    
    현재 허가증 하나, cmd 폴더 하나,main 하나가 있습니다.분류하여 보존하다
  • 라이센스
  • 폴더cmd 1개
  • 파일main.go 1개
  • Cobra는 main.go 파일을 엔트리 포인트로만 사용합니다.우리는 어떤 CLI application 코드도 여기에 두지 않을 것이다.반면, 우리의 대부분의 코드는 cmd 폴더에 저장될 것이다.
    우리는 또한 프로젝트에서 Go modules를 사용하여 의존 관계를 처리하기를 희망한다.우리는 터미널에서 go mod init 명령을 실행하여 초기화할 것이다Go modules.여기서 우리가 사용하는 패키지 이름은 이전에 cobra 프로그램을 만들 때 사용했던 이름과 같다.
    go mod init github.com/example/dadjoke
    
    이것은 의존 관계를 관리하는 데 도움을 줄 go.mod 파일을 만들 것입니다.

    생성 명령


    터미널에서 처음 실행 go run main.go 하면 모든 의존항이 설치되고 go.sum 파일도 생성됩니다.이것은 하나lock file로 여겨질 수 있다.이것은 의존 항목의 checksum 변경이 없는지 확인하는 데 사용됩니다.
    CLI에 대한 설명, 사용법 및 사용 가능한 명령과 같은 출력도 볼 수 있습니다.지금 우리는 help명령밖에 없다.
    go run main.go
    
    Cobra는 어플리케이션의 기능 설명을 포함한 샘플 컨텐츠를 제공합니다.우리가 구축하고 있는dadjoke 프로그램에 대한 설명을 더 잘 설명하기 위해 업데이트를 해야 할 수도 있습니다
    새로 만든 cmd/root.go 명령에 대한 설명을 업데이트하기 위해 root 파일을 엽니다.기본 내용을 사용자 고유ShortLong 설명으로 바꿉니다.
    var rootCmd = &cobra.Command{
        Use:   "dadjoke",
        Short: "Get random dad jokes in your terminal",
        Long:  `Dadjoke CLI is a tool that gives you a random dad joke`,
    }
    
    만약 우리가 지금 응용 프로그램 go run main.go 을 실행하고 있다면, 우리는 방금 쓴 설명을 볼 수 있을 것이다.현재, 우리 프로그램에는 사용할 수 있는 명령 목록이 없습니다.
    이제 random 명령을 만듭니다.코브라는 우리에게 add 명령을 제공하여 우리가 이 일을 쉽게 완성할 수 있도록 했다.터미널에서 프로젝트 루트 디렉토리에 있는지 확인하고 다음 명령을 실행합니다.
    cobra add random
    
    add 명령은 새 cmd/random.go 파일을 생성합니다.
    따라서, 만약 우리가 실행 go run main.go 한다면, 우리는 random 현재 우리가 사용할 수 있는 명령 중의 하나임을 보게 될 것이다.이게 얼마나 멋있어요?
    go run main.go
    
    만약 우리가 지금 random 명령을 실행한다면, 우리는 이전에 보았던 루트 명령과 같은 샘플 설명을 볼 수 있을 것이다.우리도 이 설명을 갱신하기를 바란다.cmd/random.go 파일에 들어가서 ShortLong 설명을 추가합니다.
    var randomCmd = &cobra.Command{
        Use:   "random",
        Short: "Get a random dad joke",
        Long:  `This command fetches a random dad joke from the icanhazdadjoke api`,
        Run: func(cmd *cobra.Command, args []string) {
            ...
        },
    }
    

    API-curl


    사용할 API에 대한 설명서를 살펴보겠습니다.우리는 무료icanhazdadjoke API를 사용할 것이다.이 API는 인증할 필요가 없습니다.창작자가 좋으니 공짜로 사용하자.그들이 유일하게 요구하는 것은 우리가 사용자 정의 User-Agent 제목을 추가하는 것이다.우리는 절대로 할 수 있다.

    끝점으로 스크롤하면 cURL 명령을 볼 수 있습니다.우리 터미널에서 그것을 운행해서 우리가 무엇을 얻었는지 봅시다.
    curl -H "Accept: application/json" https://icanhazdadjoke.com/
    
    여기에서 우리는 그것이 하나ID, 하나joke와 하나status로 되돌아오는 것을 보았다.우리가 계속하기 전에 코드에서 이 점을 신속하게 표시합시다.cmd/random.go 내부에 새 type Joke struct:
    package cmd
    
    import (
        "fmt"
    
        "github.com/spf13/cobra"
    )
    
    var randomCmd = &cobra.Command{
        Use:   "random",
        Short: "Get a random dad joke",
        Long:  `This command fetches a random dad joke from the icanhazdadjoke api`,
        Run: func(cmd *cobra.Command, args []string) {
            ...
        },
    }
    
    func init() {
        rootCmd.AddCommand(randomCmd)
    }
    
    type Joke struct {
        ID     string `json:"id"`
        Joke   string `json:"joke"`
        Status int    `json:"status"`
    }
    

    Go에서 요청 받기


    이제 API 호출을 시작합니다.
    우리는 random.go 문서에서 대부분의 일을 완성할 것이다.현재, 우리의 Run 함수는 단지 메시지를 인쇄할 뿐입니다.getRandomJoke라는 함수를 만듭니다.우리는 Run 방법에서 이 함수를 호출할 것이다.이제 메시지가 유효한지 프린트해 봅시다.random.go 파일에 새 getRandomJoke() 방법을 추가하고 내부 Run에서 호출합니다.
    package cmd
    
    import (
        "fmt"
    
        "github.com/spf13/cobra"
    )
    
    var randomCmd = &cobra.Command{
        Use:   "random",
        Short: "Get a random dad joke",
        Long:  `This command fetches a random dad joke from the icanhazdadjoke api`,
        Run: func(cmd *cobra.Command, args []string) {
            getRandomJoke()
        },
    }
    
    func init() {
        rootCmd.AddCommand(randomCmd)
    }
    
    type Joke struct {
        ID     string `json:"id"`
        Joke   string `json:"joke"`
        Status int    `json:"status"`
    }
    
    func getRandomJoke() {
        fmt.Println("Get random dad joke :P")
    }
    
    만약 우리가 지금 터미널에서 random 명령을 실행하고 있다면, 우리는 25줄에서 Println 메시지를 볼 것이다
    go run main.go random
    

    http 패키지 보기


    그런 다음 API 끝점에 GET 요청을 보내는 함수를 생성합니다.우리는 그것으로 무작위 우스갯소리 데이터를 얻을 것이다.우리는 net/http 패키지를 사용하여 이 점을 실현할 수 있다.
    우선, 우리는 net/http 문서를 방문하여 그것을 어떻게 사용하는지 더욱 잘 이해하도록 하자.우리는 방문https://golang.org/pkg/net/http/과 검색func Get을 할 수 있다.우리가 GET 청구하고 싶은 것을 알고 있기 때문이다.여기서 우리는 이 선을 보고 말했다

    To make a request with custom headers, use NewRequest and DefaultClient.Do.


    만약 당신이 기억하고 있다면, API 관리자는 우리가 응용 프로그램에 사용자 정의 헤더를 추가하기를 원하기 때문에 이것이 바로 우리가 찾는 것입니다.

    getJokeData() 방법


    icanhazdadjoke API endpoint에 요청하는 함수를 만들 것입니다 GET
    package cmd
    
    import (
        "fmt"
    
        "github.com/spf13/cobra"
    )
    
    var randomCmd = &cobra.Command{
        Use:   "random",
        Short: "Get a random dad joke",
        Long:  `This command fetches a random dad joke from the icanhazdadjoke api`,
        Run: func(cmd *cobra.Command, args []string) {
            getRandomJoke()
        },
    }
    
    func init() {
        rootCmd.AddCommand(randomCmd)
    }
    
    type Joke struct {
        ID     string `json:"id"`
        Joke   string `json:"joke"`
        Status int    `json:"status"`
    }
    
    func getRandomJoke() {
        fmt.Println("Get random dad joke :P")
    }
    
    func getJokeData(baseAPI string) []byte {}
    
    getJokeData() 함수체에서 NewRequest() 패키지의 net/http 방법으로 새 요청을 만들 것입니다
    package cmd
    
    import (
        "fmt"
        "net/http"
        "io/ioutil"
    
        "github.com/spf13/cobra"
    )
    
    var randomCmd = &cobra.Command{
        Use:   "random",
        Short: "Get a random dad joke",
        Long:  `This command fetches a random dad joke from the icanhazdadjoke api`,
        Run: func(cmd *cobra.Command, args []string) {
            getRandomJoke()
        },
    }
    
    func init() {
        rootCmd.AddCommand(randomCmd)
    }
    
    type Joke struct {
        ID     string `json:"id"`
        Joke   string `json:"joke"`
        Status int    `json:"status"`
    }
    
    func getRandomJoke() {
        fmt.Println("Get random dad joke :P")
    }
    
    func getJokeData(baseAPI string) []byte {
        request, err := http.NewRequest(
            http.MethodGet, //method
            baseAPI,        //url
            nil,            //body
        )
    
        if err != nil {
            log.Printf("Could not request a dadjoke. %v", err)
        }
    
        request.Header.Add("Accept", "application/json")
        request.Header.Add("User-Agent", "Dadjoke CLI (https://github.com/example/dadjoke)")
    }
    
    새 코드 설명:
  • 행 5
  • 수입net/http포장
  • 6행
  • 수입io/ioutil포장
  • 35행
  • 사용 http.NewRequest() 방법으로 새 요청 만들기
  • 36행
  • 첫 번째 매개 변수는 HTTP 방법
  • 이다.
  • 37행
  • 두 번째 파라미터는url
  • 제38행
  • 세 번째 매개 변수는 요청 주체다.끝의 쉼표를 기억해라.
  • 41-43행
  • 에서 반환된 오류 처리
  • 45행
  • API가 데이터를 http.NewRequest()로 되돌려 주기를 원한다는 제목을 추가합니다.
  • 46행
  • API 관리자에게 API를 어떻게 사용하는지 알려주는 사용자 정의JSON 헤드 추가
  • 완료User-Agent 방법:
    func getJokeData(baseAPI string) []byte {
        request, err := http.NewRequest(
            http.MethodGet, //method
            baseAPI,        //url
            nil,            //body
        )
    
        if err != nil {
            log.Printf("Could not request a dadjoke. %v", err)
        }
    
        request.Header.Add("Accept", "application/json")
        request.Header.Add("User-Agent", "Dadjoke CLI (https://github.com/example/dadjoke)")
    
        response, err := http.DefaultClient.Do(request)
        if err != nil {
            log.Printf("Could not make a request. %v", err)
        }
    
        responseBytes, err := ioutil.ReadAll(response.Body)
        if err != nil {
            log.Printf("Could not read response body. %v", err)
        }
    
        return responseBytes
    }
    
    새 코드 설명:
  • 48행
  • getJokeData()request에 전달하는 방법http.DefaultClient.Do()으로 획득response
  • 제49-51행
  • 메서드http.DefaultClient.Do()에서 반환된 오류 처리
  • 53행
  • resonseBodyioutil.ReadAll()에 전달하여 읽기bytes
  • 54-56행
  • 메서드ioutil.ReadAll()에서 반환된 오류 처리
  • 58행
  • 바이트로 응답
  • 반환

    getRandomJoke() 메서드 완료

    getRandomJoke 메서드에 다시 액세스하여 getJokeData 메서드를 사용할 수 있습니다.
    func getRandomJoke() {
        url := "https://icanhazdadjoke.com/"
        responseBytes := getJokeData(url)
        joke := Joke{}
    
        if err := json.Unmarshal(responseBytes, &joke); err != nil {
            fmt.Printf("Could not unmarshal reponseBytes. %v", err)
        }
    
        fmt.Println(string(joke.Joke))
    }
    
    새 코드 설명:
  • 행 2
  • API URL을 url 변수
  • 에 저장
  • 세 번째 행
  • urlgetJokeData() 방법에 전달하고 되돌아오는 응답 바이트를 변수
  • 에 저장한다.
  • 4행
  • 새로운 우스갯소리 구조를 만듭니다.그룹 해제 응답
  • 시 데이터를 여기에 저장합니다
  • 6-8행
  • 해제 응답, responseBytesurl를 매개 변수
  • http.Unmarshal에 전달
  • 반환된 오류도 처리
  • 열 번째 행
  • joke.Joke를 문자열로 변환하여 터미널에 인쇄
  • 터미널로 돌아가서 명령을 실행하여 무작위 농담을 얻습니다.
    go run main.go
    

    결론


    이 자습서에서는 Go 및 Cobra를 사용하여 명령행 응용 프로그램을 만드는 방법에 대해 설명합니다.두 번째 부분에서 우리는 무작위 명령을 위한 표지를 어떻게 실현하는지 배울 것이다.
    만약 당신이 이 글을 좋아하고 더 많은 것을 원한다면 다음과 같은 내용을 고려할 수 있다.
    축하해, 잘했어.끊임없이 공부하고, 끊임없이 인코딩하다.안녕히 계세요.

    디프리노 / 아버지의 농담


    Go 및 Cobra를 사용하여 기본적인 CLI 도구를 구축합니다.동영상 튜토리얼은 Div Rhino 유튜브 채널에서 이용할 수 있다.


    DADCLI 도구

  • 텍스트 자습서: https://divrhino.com/articles/build-command-line-tool-go-cobra/
  • 비디오 자습서:
  • View on GitHub

    좋은 웹페이지 즐겨찾기