Help us understand the problem. What is going on with this article?

はじめての Go 言語 (on Windows) その9

More than 3 years have passed since last update.

これまでの記事の目次。同ページのブックマークも参考にどうぞ)

このシリーズではしばらくぶり。今回は gb を使ってプロジェクト・ベースで Golang のソースを管理してみる。

gb の導入

gb の導入は go get コマンド一発である(go get コマンドの使い方は「その3」をどうぞ)。

C:>go get -v github.com/constabulary/gb/...
github.com/constabulary/gb (download)
github.com/constabulary/gb
github.com/constabulary/gb/cmd
github.com/constabulary/gb/cmd/gb-vendor/vendor
github.com/constabulary/gb/cmd/gb
github.com/constabulary/gb/cmd/gb-vendor

環境変数 GOPATH で指定するフォルダ配下の bin フォルダに gb.exe および gb-vendor.exe が生成される。このフォルダに PATH を通しておく。

プロジェクトの構築とビルド

ソースコードの配置

プロジェクト・フォルダを C:\path\to\project とし,ソース・ファイル用のフォルダを作成する。

C:\path\to\project>mkdir src\gbdemo
C:\path\to\project>tree . /A
C:\PATH\TO\PROJECT
└─src
    └─gbdemo

更に C:\path\to\project\src\gbdemo フォルダにソース・ファイルを作成する。今回は「その6」で最後に作ったファイルを流用する。

gbdemo/main.go
package main

import (
    "flag"
    "fmt"
    "github.com/spiegel-im-spiegel/astrocalc/modjulian"
    "strconv"
    "time"
)

func main() {
    //引数のチェック
    flag.Parse()
    argsStr := flag.Args()
    if len(argsStr) < 3 {
        fmt.Printf("年月日を指定してください")
        return
    }
    args := make([]int, 3)
    for i := 0; i < 3; i++ {
        num, err := strconv.Atoi(argsStr[i])
        if err != nil {
            if enum, ok := err.(*strconv.NumError); ok {
                switch enum.Err {
                case strconv.ErrRange:
                    fmt.Printf("Bad Range Error")
                case strconv.ErrSyntax:
                    fmt.Printf("Syntax Error")
                }
            }
            return
        } else {
            args[i] = num
        }
    }
    tm := time.Date(args[0], time.Month(args[1]), args[2], 0, 0, 0, 0, time.UTC)
    fmt.Printf("%v\n", tm)
    fmt.Printf("MJD = %d日\n", modjulian.DayNumber(tm))
}

あとは gb build コマンドでビルドすればいいのだが,ここで github.com/spiegel-im-spiegel/astrocalc/modjulian パッケージがないとエラーを吐いてしまう。

C:\path\to\project>gb build
FATAL command "build" failed: failed to resolve import path "gbdemo": cannot find package "github.com/spiegel-im-spiegel/astrocalc/modjulian" in any of:
        C:\Go\src\github.com\spiegel-im-spiegel\astrocalc\modjulian (from $GOROOT)
        C:\path\to\project\src\github.com\spiegel-im-spiegel\astrocalc\modjulian (from $GOPATH)
        C:\path\to\project\vendor\src\github.com\spiegel-im-spiegel\astrocalc\modjulian

GOPATH にプロジェクト・フォルダが設定されていることにお気づきだろうか。 gb では既存の GOPATH 設定は使わないようだ。

外部パッケージの導入

外部パッケージを導入するには gb vendor fetch コマンドを使う。

C:\path\to\project>gb vendor fetch github.com/spiegel-im-spiegel/astrocalc/modjulian
C:\path\to\project>tree . /A
C:\PATH\TO\PROJECT
├─src
│  └─gbdemo
│          main.go
│
└─vendor
    │  manifest
    │
    └─src
        └─github.com
            └─spiegel-im-spiegel
                └─astrocalc
                    └─modjulian
                            example_test.go
                            modjulian.go
                            modjulian_test.go

プロジェクト・フォルダ以下に vendor フォルダが作成され,パッケージのソースファイルが展開できているのがお分かりだろうか。ちなみに今回 gb vendor fetch で取得したパッケージは GitHub のリポジトリから取ってきたものだが, clone されたものではなく,(少なくとも見た目は)単純に export してきたもののようである(プロジェクト・フォルダ全体をソースコード管理する場合に vendor フォルダ以下に別(システム)のリポジトリがあると管理が面倒臭くなるからかな?)。

ちなみに外部パッケージをアップデートする場合は gb vendor update コマンドを使う。

C:\path\to\project>gb vendor update github.com/spiegel-im-spiegel/astrocalc/modjulian

または

C:\path\to\project>gb vendor update -all

プロジェクトのビルド

では,この状態でもう一回ビルドしてみる。

C:\path\to\project>gb build
github.com/spiegel-im-spiegel/astrocalc/modjulian
gbdemo

C:\path\to\project>tree . /A
C:\PATH\TO\PROJECT
├─bin
│      gbdemo.exe
│
├─pkg
│  └─windows
│      └─amd64
│          └─github.com
│              └─spiegel-im-spiegel
│                  └─astrocalc
│                          modjulian.a
│
├─src
│  └─gbdemo
│          main.go
│
└─vendor
    │  manifest
    │
    └─src
        └─github.com
            └─spiegel-im-spiegel
                └─astrocalc
                    └─modjulian
                            example_test.go
                            modjulian.go
                            modjulian_test.go

C:\path\to\project>bin\gbdemo 2015 1 1
2015-01-01 00:00:00 +0000 UTC
MJD = 57023日

今度は上手くいったようだ。

ちなみに gb build コマンドのオプションは以下の通り。

C:\path\to\project>gb help build
usage: gb build [build flags] [packages]

Build compiles the packages named by the import paths, along with their dependencies.

The build flags are

        -f
                ignore cached packages if present, new packages built will overwrite any cached packages.
                This effectively disables incremental compilation.
        -F
                do not cache packages, cached packages will still be used for in cremental compilation.
                -f -F is advised to disable the package caching system.
        -q
                decreases verbosity, effectively raising the output level to ERROR.
                In a successful build, no output will be displayed.
        -R
                sets the base of the project root search path from the current working directory to the value supplied.
                Effectively gb changes working directory to this path before searching for the project root.
        -v
                increases verbosity, effectively lowering the output level from INFO to DEBUG.
        -ldflags 'flag list'
                arguments to pass on each linker invocation.
        -gcflags 'arg list'
                arguments to pass on each go tool compile invocation.

The list flags accept a space-separated list of strings. To embed spaces in an element in the list, surround it with either single or double quotes.

For more about specifying packages, see 'gb help packages'. For more about where packages and binaries are installed, run 'gb help project'.

-ldflags-gcflags が使えるのはありがたいかな。

複数パッケージを含めたプロジェクト管理

いくつかのパッケージを含んだプロジェクト管理を行いたい場合もある。例えば以下のような構成を考えてみる。

C:\path\to\project>tree . /A
C:\PATH\TO\PROJECT
└─src
    └─gbdemo
            main.go

C:\path\to\project>pushd src
C:\path\to\project\src>mkdir github.com\spiegel-im-spiegel
C:\path\to\project\src>cd github.com\spiegel-im-spiegel
C:\path\to\project\src\github.com\spiegel-im-spiegel>git clone git@github.com:spiegel-im-spiegel/astrocalc.git
Cloning into 'astrocalc'...
remote: Counting objects: 35, done.
remote: Total 35 (delta 0), reused 0 (delta 0), pack-reused 34
Unpacking objects: 100% (35/35), done.
Checking connectivity... done.

C:\path\to\project\src\github.com\spiegel-im-spiegel>popd
C:\path\to\project>tree . /A
C:\PATH\TO\PROJECT
└─src
    ├─gbdemo
    │      main.go
    │
    └─github.com
        └─spiegel-im-spiegel
            └─astrocalc
                │  .gitignore
                │  .travis.yml
                │  LICENSE
                │  README.md
                │
                └─modjulian
                        example_test.go
                        modjulian.go
                        modjulian_test.go

この状態でビルドを実行してみる。

C:\path\to\project>gb build
github.com/spiegel-im-spiegel/astrocalc/modjulian
gbdemo

C:\path\to\project>tree . /A
C:\PATH\TO\PROJECT
├─bin
│      gbdemo.exe
│
├─pkg
│  └─windows
│      └─amd64
│          └─github.com
│              └─spiegel-im-spiegel
│                  └─astrocalc
│                          modjulian.a
│
└─src
    ├─gbdemo
    │      main.go
    │
    └─github.com
        └─spiegel-im-spiegel
            └─astrocalc
                │  .gitignore
                │  .travis.yml
                │  LICENSE
                │  README.md
                │
                └─modjulian
                        example_test.go
                        modjulian.go
                        modjulian_test.go

C:\path\to\project>bin\gbdemo 2015 1 1
2015-01-01 00:00:00 +0000 UTC
MJD = 57023日

さらにテストもできる(テストの書き方は「その7」をどうぞ)。

C:\path\to\project>gb test
github.com/spiegel-im-spiegel/astrocalc/modjulian
testing: warning: no tests to run
PASS
PASS

(ワーニングが出るのは gbdemo パッケージにテストがないため)

ブックマーク

spiegel-im-spiegel
職業エンジニアは無期休業中。
https://baldanders.info/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした