20220115のGoに関する記事は4件です。

【Go(Gin)✕Docker✕delve✕vsCodeでデバッグできるようにする最小構成】

ディレクトリ構成 Goアプリケーションはapplicationディレクトリ以下にある。 *(アスタリスク)で囲んでいるファイルがポイント。 . ├── .vscode │   └── **launch.json** ├── README.md ├── application │   ├── **Dockerfile** │   ├── controllers │   ├── db │   ├── go.mod │   ├── go.sum │   ├── main.go │   ├── models │   ├── server │   ├── services │   ├── **start.sh** │   ├── tests │   ├── tmp │   └── vendor ├── **docker-compose.yml** └── tmp docker-compose 8080:8080はもともとあったアプリケーション用のport。 2345:2345をデバッガ用のportとして追記。 version: '3' services: api: ports: - 8080:8080 - 2345:2345 Dockerfile FROM golang:1.16 WORKDIR /go/src/app/application COPY go.mod ./ COPY go.sum ./ RUN go mod download COPY . . EXPOSE 8080 COPY start.sh /usr/local/bin/start.sh RUN chmod 775 /usr/local/bin/start.sh CMD ["start.sh"] start.sh DEBUG=dap DEBUG_PORT=2345 docker compose up -d このコマンドでデバッグのためのコマンドを実行してくれる。 (環境変数によって処理を分岐) コマンドの詳しい意味は参考記事を閲覧してください。 #!/bin/bash # DEBUG=dap DEBUG_PORT=2345 docker compose up -d でリモート接続用コマンドを実行できる if [ "${DEBUG}" = "dap" ];then go build -gcflags='all=-N -l' -o app dlv dap -l 0.0.0.0:${DEBUG_PORT} --log --check-go-version=false elif [ "${DEBUG}" = "rpc" ]; then dlv debug --continue --check-go-version=false --accept-multiclient --headless -l 0.0.0.0:${DEBUG_PORT} main.go else go run main.go fi launch.json 参考にした記事ほど複雑な設定をせずともデバッグを開始できました。 { "version": "0.2.0", "configurations": [ { "name": "Launch Package", "type": "go", "request": "launch", "mode": "auto", "program": "${fileDirname}" } ] } コンテナがしっかり立ち上がるまで待たないとビルドエラーみたいなのがでて混乱するので、コンテナ立ち上がり後はしっかり待つようにしたほうがいいです。(せっかちなので困惑しました) 参考記事
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

GOLANDでGOプロジェクトをインストールしたら最初にやる設定

1.Go Modulesを有効にする Go Modules=>Enable GO Modules integrationにチェック 2.ルートディレクトリにモジュール群をインストール cd paht/to/root-dir go mod vendor これでコードジャンプも効くようになる。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

requirements.txtを作るだけのアプリ

よくrequirements.txtを書くのを忘れる自分のために「requirements.txt Generator」を作った。 デモ 機能 Windows, Mac, Linux対応 言語選択 フォルダ検索 フォルダの複数選択 フォルダ詳細表示 パッケージ選択 バージョン選択 説明 主にFlaskで作り、PyFladeskなるものを使うと簡単にFlaskのアプリをデスクトップアプリにできるので、それをpyinstallerで.exeなり.appにした。フォルダ構造を表示するJavaScriptでは、jstreeを使用。 対応している言語は Python Python(ipynb) Julia Julia((ipynb) Go で、PythonとJuliaのみバージョンを記載するかどうかを選ぶことができる。 Pythonでパッケージをインストールするには $ pip install -r requirements.txt だが、Juliaではそういった機能なく? install.jl using Pkg; Pkg.add(open(f->readlines(f), "./requirements.txt")) このinstall.jlというファイルを作った上で $ julia install.jl とするのが良いと思う。もちろんREPLでも。 $ julia julia> using Pkg julia> Pkg.add(open(f->readlines(f), "./requirements.txt")) Goに対応させているのは、単純にパッケージをインストールすることがあるからというだけで、requirements.txtにまとめる必要はないのと思うが、一応追加しておいた。 settings.pyのデフォルトパスになっているDesktopを好きなフォルダ名に変更すれば、その直下のデータのjsonファイルが作成される。デスクトップに大量のデータがある人は、ちゃんと動作しない可能性があるが、作成されるjsonファイルの行数が10万行でも動いていたので、おそらく大丈夫だと思う。 今後 Githubには、それぞれのOSに対応したダウンロードリンクが張ってあるが、Windowsに関してはWindowsDefenderでブロックされ、Macでは破損しているとか何とかで、ダウンロードしたものは使えなかったのでどうにかしたい。 今後はコマンドで実行できるようにしたり、Webでも利用できるようにしたい。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

GolangでS3からZipダウンロードする時の中身のタイムスタンプの設定

概要 S3にあるファイルを一つにまとめてZipダウンロードする際の中身のファイルのタイムスタンプを引き継ぐ方法について解説する。 zip化の流れ tmpフォルダにzipファイルを配備する S3から該当ファイルを複数取得する 取得したファイルをZipファイルに書き込む <- この中身のタイムスタンプの設定 zipファイルをS3にアップロードする tmpフォルダのzipファイルを削除し、S3へのzipパスを返却する 対象モジュール archive/zip ※標準パッケージ Goのバージョン 1.17.2 zip内のファイルの更新日時が1979/11/30になってしまう zip書き込みを以下のようにそのまま実施してしまうとS3に登録した更新日時が適用されずに1979/11/30になってしまう問題がある。参考記事 write_zip.go func writeZip(zipFilePath string, zipWriter *zip.Writer, srcBody []byte) error { writer, err := zipWriter.Create(zipFilePath) if err != nil { return err } if _, err := writer.Write(srcBody); err != nil { return err } return nil } ※writer.Writeをio.Copyに置き換えた場合も同様  zipの中身 解決方法 writerを作成する前ファイルヘッダを書き換え、それを読み込ませることで変更日時を設定することができる。 ただ、zipWriter.CreateHeaderにセットするためのos.FileInfoが必要になり、そのためにはos.Fileが必要になるため、S3で取得したbyteデータを一度ファイル生成したのちに、os.FileInfoを取得する方法をとった。 現在日時としてzip化する方法 func writeZip(zipFilePath string, srcBody []byte, zipWriter *zip.Writer) error { // ユニークなtmpファイル名にする fw, err := os.CreateTemp("tmp/s3_zip", "zip_item_*") if err != nil { return err } defer os.Remove(fw.Name()) // tmp作成したファイルは忘れず消しておく defer fw.Close() _, err = fw.Write(srcBody) if err != nil { return err } fileInfo, err := fw.Stat() if err != nil { return err } fileHeader, _ := zip.FileInfoHeader(fileInfo) // Headerの場合、zipに含めるファイル名の指定が必要(sampleフォルダにsample1.jpgを配備したい場合はsample/sample1.jpgを設定する) fileHeader.Name = zipFilePath writer, err := zipWriter.CreateHeader(fileHeader) if err != nil { return err } if _, err := writer.Write(srcBody); err != nil { return err } return nil } この場合はtmpにS3ファイルを作成した時間がセットされるため現在日時(≒zipダウンロードしたタイミング)で取得することなる。  zipの中身 要件上、現在日時で問題ない場合は上記で解決だが、ファイルごとのS3への変更日時で取得したい場合はもう一手間必要になる。 その場合、S3パッケージのGetObject時にS3の変更日時(s3.GetObjectOutput.LastModified)を受け取り、それをos.Chtimesにセットすることで変更日時を変更することができる。こちらはファイルのatimeとmtimeを更新することができる。 ※atime:アクセス日時、mtime:変更日時 byteデータを一度Writeしてからos.Chtimesをコールしないと反映されないので注意する S3の変更日時としてzip化する方法 func writeZip(zipFilePath string, srcBody []byte, zipWriter *zip.Writer, srcLastModifiedAt time.Time) error { // ユニークなtmpファイル名にする fw, err := os.CreateTemp("tmp/s3_zip", "zip_item_*") if err != nil { return err } defer os.Remove(fw.Name()) defer fw.Close() _, err = fw.Write(srcBody) if err != nil { return err } // --ここだけ追加-- err = os.Chtimes(fw.Name(), srcLastModifiedAt, srcLastModifiedAt) if err != nil { return err } // ---- fileInfo, err := fw.Stat() if err != nil { return err } fileHeader, _ := zip.FileInfoHeader(fileInfo) // Headerの場合、zipに含めるファイル名の指定が必要(sampleフォルダにsample1.jpgを配備したい場合はsample/sample1.jpgを設定する) fileHeader.Name = zipFilePath writer, err := zipWriter.CreateHeader(fileHeader) if err != nil { return err } if _, err := writer.Write(srcBody); err != nil { return err } return nil } // S3から中身のファイルと最終更新日時を取得する func (s *S3Handler) getObject(bucket string, path string) ([]byte, *time.Time, error) { obj, err := s.Client.GetObject(&s3.GetObjectInput{ Bucket: aws.String(bucket), Key: &path, }) if err != nil { return []byte{}, nil, err } defer obj.Body.Close() buf := new(bytes.Buffer) // buffer Response Body buf.ReadFrom(obj.Body) return buf.Bytes(), obj.LastModified, nil }  zipの中身 まとめ S3ではなくzip化する環境で読み取れるファイルの場合はそのままファイルを読み込み、ヘッダーにセットするだけで期待通りの変更日時が設定されていたと思いますが、S3のように一度ダウンロードしてファイル生成する場合には、os.Chtimesのような一手間が必要になるかと思います。 ご参考になれば幸いですm(_ _)m 参考
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む