[Go] Go 언어 웹 개발 프로젝트 Part2.5 - 젓가락 휴식 시 dep를 통해 포장 관리와 golint 등을 개선하고 Go 코드를 작성하기 -

지난번 줄거리


지난번에 로그인 인증을 최소한으로 개발한 부분입니다.
지난번 보도를 시작한 지 한 달이 지났으니 다음 단계로 넘어갈 때가 많지 않다.오늘부터 지금까지 한 일, 한 달 동안 몇 개의 Go 언어 학습회에 참가한 지견, 그리고 Go 언어의 좋은 코드를 어떻게 하면 좋을지 쓰기 위해 참고 문헌을 많이 조사해서 공유하고 싶습니다.

goose가 yaml 파일을 통해 명령을 실행할 수 있도록 허용(Reject)


현재 제 프로젝트는bitbucketfork의 이쪽 goose를 사용하고 있습니다.
https://github.com/pressly/goose
명령만 지원되므로 YAML을 통해 마이그레이션을 수행할 수 있도록 PR을 만들었습니다.
...결론을 말하면 거절당했다.이유가 여기 있어요.
https://github.com/pressly/goose/pull/118
그러나 이번 PR을 시작으로 포장 관리 도구는 Go언어를 사용하는 공식 팀에서 개발한dep이 앞으로의 선택이기 때문에 포장 관리 도구를 gom에서 dep로 바꾸기로 했다.
dep의 공식 문서는 여기 있습니다 → https://golang.github.io/dep/

dep 설치


환경을 재구성하기 위해 먼저 dep를 설치합니다.
% goenv exec go get -u github.com/golang/dep/cmd/dep 
그리고 프로젝트에 사용되는 패키지의 집중 관리 파일Gopkg.toml, Gopkg.lock 파일을 생성합니다.
Gopkg.toml
# Gopkg.toml example
#
# Refer to https://golang.github.io/dep/docs/Gopkg.toml.html
# for detailed Gopkg.toml documentation.
#
# required = ["github.com/user/thing/cmd/thing"]
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
#
# [[constraint]]
#   name = "github.com/user/project"
#   version = "1.0.0"
#
# [[constraint]]
#   name = "github.com/user/project2"
#   branch = "dev"
#   source = "github.com/myfork/project2"
#
# [[override]]
#   name = "github.com/x/y"
#   version = "2.4.0"
#
# [prune]
#   non-go = false
#   go-tests = true
#   unused-packages = true

required = ["github.com/pressly/goose/cmd/goose"]

[[constraint]]
  name = "github.com/lib/pq"
  version = "1.0.0"

[[constraint]]
  name = "github.com/yosssi/ace"
  version = "0.0.5"

[prune]
  go-tests = true
  unused-packages = true
기본적으로, [[constraint]]에서directdependency(프로젝트 코드에서 직접) 의존 관계를 설명합니다.
이런 상황에서 goose는 그렇지 않기 때문에 required에 필요한 패키지의 원본을 직접 설치합니다.
% dep ensure
그리고 dep ensure로 대량으로 설치합니다.단, depensure는 src만 가져오면 소프트웨어 패키지를 설치할 수 있는 것이 아닙니다.
자세한 내용은 이쪽 → https://dev.classmethod.jp/go/dep/
다음은 자체 방법 주식회사 dep의 보도를 인용합니다
実行ファイルをインストールしたい場合はパッケージのインストールディレクトリ(mainパッケージが置かれているディレクトリ)に移動し(cd vendor/github.com/user/thing/cmd/thing) go install . でインストールする必要があります。
goose를 설치하려면 다음과 같이 하십시오.
% cd vendor/github.com/pressly/goose/cmd
% goenv exec go install .
요약하면 다음과 같이 Dockerfile이 업데이트되었습니다.
Dockerfile
FROM golang:1.11.0

RUN apt update

# PostgreSQLのClientをインストール
RUN apt install -y postgresql-client

WORKDIR /go/src/dairy_report
ADD src/dairy_report/Gopkg.toml Gopkg.toml
ADD src/dairy_report/Gopkg.lock Gopkg.lock
# depだけgo getで取得
RUN go get -u github.com/golang/dep/cmd/dep

RUN dep ensure --vendor-only
WORKDIR /go/src/dairy_report/vendor/github.com/pressly/goose/cmd/goose/
RUN go install .

WORKDIR /go/src/dairy_report
Docker 컨테이너에서 디버깅을 하려면 옵션으로 --vendor-only 을 추가해야 합니다.
자세한 내용은 이쪽 → https://github.com/golang/dep/issues/796
또한docker-compose.yml는 src/부하의 원본 코드를 호스트와 공유하여 불러오고vendor 디렉터리를 용기 전용 볼륨으로 저장하기 때문에 다음과 같이 정의합니다.
docker-compose.yml
version: '3'
volumes:
  vendor:
services:
  web:
    build:
      context: .
      dockerfile: Dockerfile
    command: go run main.go
    volumes:
      - ./src/dairy_report/:/go/src/dairy_report/
      - vendor:/go/src/dairy_report/vendor
(中略)
docker-compose 설정이 끝났습니다.다음은 코드 성형과 평론에 관한 이야기다.

형식 관련 성형 자동 수정


필자는 Rails 경력이 길기 때문에 코드 성형과 프로젝트의 로컬 규칙 등 코드 위반에 따라 rubocop을 이용하여 수정하거나 논평을 남긴다.
사실 포맷도 일치성 코드이기 때문에 개발자는 반드시 스스로 알아차려야 하지만 발견하는 것은 상당히 어렵다. 포맷을 제외하고는 반드시 수정해야 하는 코드도 스스로 알아차린다.그래서 요즘은 코드 수정의 본질이 아니다(?)나의 사상은 가장 좋은 것은 기계적으로 부분을 수정하는 것이다.기계적으로 찾아내면 어느 정도 부담이 줄어들고 비용読み手を意識したコードを書くための修正의 시간이 증가한다(이 근처에서 읽을 수 있는 코드와 프로그래밍 방법을 읽은 후에야 깨달았다).
따라서 형식을 기계적으로 수정하는 도구가 있는지 조사한 결과 Go에 기본gofmt이 존재하고 코드를 먹게 함으로써 자동으로 수정된다.
goenv를 통해 gofmt를 실행합니다.
% goenv exec gofmt -d main.go                                                                                                                                                   (git)-[feature/add_login]
diff -u main.go.orig main.go
--- main.go.orig    2018-11-11 00:22:28.000000000 +0900
+++ main.go 2018-11-11 00:22:28.000000000 +0900
@@ -1,12 +1,12 @@
 package main

 import (
+   "database/sql"
    "fmt"
+   _ "github.com/lib/pq"
+   "github.com/yosssi/ace"
    "log"
    "net/http"
-   "github.com/yosssi/ace"
-   "database/sql"
-   _ "github.com/lib/pq"
 )

 func login_handler(w http.ResponseWriter, r *http.Request) {
@@ -33,7 +33,7 @@
        fmt.Println("username:", r.FormValue("username"))
        fmt.Println("password:", r.FormValue("password"))

-       user := User{ r.FormValue("username"), r.FormValue("password")}
+       user := User{r.FormValue("username"), r.FormValue("password")}
        db, err := sql.Open("postgres", "host=db user=dairy_report password=dairy_report dbname=dairy_report_development sslmode=disable")
        if err != nil {
            fmt.Println(err)
- d 옵션으로 점수를 얻을 수 있습니다.이런 상황에서 표준 출력에만 표시되기 때문에 -w 옵션으로 원본을 직접 바꿀 수 있습니다.
%  goenv exec gofmt -w main.go
% git diff
diff --git a/src/dairy_report/main.go b/src/dairy_report/main.go
index 75bfcc5..35375ca 100644
--- a/src/dairy_report/main.go
+++ b/src/dairy_report/main.go
@@ -1,12 +1,12 @@
 package main

 import (
+       "database/sql"
        "fmt"
+       _ "github.com/lib/pq"
+       "github.com/yosssi/ace"
        "log"
        "net/http"
-       "github.com/yosssi/ace"
-       "database/sql"
-       _ "github.com/lib/pq"
 )

 func login_handler(w http.ResponseWriter, r *http.Request) {
@@ -33,7 +33,7 @@ func login_handler(w http.ResponseWriter, r *http.Request) {
                fmt.Println("username:", r.FormValue("username"))
                fmt.Println("password:", r.FormValue("password"))

-               user := User{ r.FormValue("username"), r.FormValue("password")}
+               user := User{r.FormValue("username"), r.FormValue("password")}
                db, err := sql.Open("postgres", "host=db user=dairy_report password=dairy_report dbname=dairy_report_development sslmode=disable")
                if err != nil {
                        fmt.Println(err)
또한 이곳의 형식 규칙은 다음과 같은 규칙을 바탕으로 한다.
http://go.shibu.jp/effective_go.html

형식 규칙 이외의 규칙에 주석 추가


기계적으로 수정할 수 없는 부분으로 인해 Go 언어의 코드 규칙은 다음과 같습니다.
https://gist.github.com/knsh14/0507b98c6b62959011ba9e4c310cd15d
이 사소한 규칙을 댓글로 남겨 주시길 바라는 파(?)따라서 reviewdog라는 도구를 설치하여 코드 심사를 진행하십시오.
리뷰독 이쪽→https://github.com/haya14busa/reviewdog
Travis CI에 가입할 수 있는 시간이 얼마 남지 않아 가져오기로 결정했습니다.
.travis.yml
env:
  global:
    - REVIEWDOG_VERSION="0.9.11"
sudo: false
language: go
go:
  - 1.11.2
install:
  - go get -u golang.org/x/lint/golint
  - mkdir -p ~/bin/ && export export PATH="~/bin/:$PATH"
  - curl -fSL https://github.com/haya14busa/reviewdog/releases/download/$REVIEWDOG_VERSION/reviewdog_linux_amd64 -o ~/bin/reviewdog && chmod +x ~/bin/reviewdog

script:
  - golint ./... | reviewdog -f=golint -reporter=github-pr-review
Github Token을 다음과 같이 설정합니다.

리뷰독의 견본 예에서travis.yml에 영패를 직접 입력했습니다. 여기 있습니다.travis.yml에 저장합니다.

따라서reviewdog 가져오기에 성공했습니다.

또한 마침 이 작업을 진행하던 중 TypeName.IsAlias undefined method 오류가 발생하여 Go 버전을 1.11.0->1.21.2로 업데이트했습니다.
자세한 내용은 이쪽 → https://github.com/golang/go/issues/28291

총결산


많이 썼지만 프로젝트의 진전이 그다지 순조롭지 못하다
그럼에도 불구하고 최근 다양한 Go언어 학습회에 참가하여 Go언어로 쉽게 개발할 수 있는 지식을 배우게 되었습니다.
다음 기능을 추가하고 싶을 때, 나는 앞으로 끊임없이 코드를 쓸 것이라고 생각한다.
그럼

참고 문헌


https://dev.classmethod.jp/go/dep/
https://github.com/golang/dep/issues/796
Effective Go
https://gist.github.com/knsh14/0507b98c6b62959011ba9e4c310cd15d
https://github.com/haya14busa/reviewdog

시리즈


Part2 ← Part2.5

좋은 웹페이지 즐겨찾기