post Image
Realize が Go 1.11 の Modules で使えない

去年、 [Go] Realizeが便利なので、もう少し仲良くなってみる という記事を公開してから今でもたまにいいねしていただけるのですが、ホットリロードツールとしては本当に realize は使いやすいですよね。

※ もうこの時点で 「いや、こっちのツールのほうがいいよ」 などありましたら、ぜひコメントで教えていただけると泣いて喜びます :pray:

しかし、 Go 1.11 から組み込まれた Modules を使おうとすると realize は動かなくなってしまいます。
本記事では、この原因を探しにいった旅行記になります。

発生した問題

realize init コマンドを打つと、 .realize.yaml というファイルが生成されます。
このファイルを元に、監視するファイルの絞り込みや、変更されたときに Before/After で行うコマンドの指定など、さまざまなオプションを指定することができます。

例えば、.go のファイルを監視して変更がされた場合に、再度 go run ... をさせたい場合は、以下のように設定します(一部抜粋)。

...
schema:
  watcher:
    extensions:
    - go
  commands:
    run:
      status: true
...

ところが、 GO111MODULE=on では realize の起動ができなくなってしまいます。

$ realize start
[09:38:37][MYAPP] : Watching 0 file/s 0 folder/s
[09:38:37][MYAPP] : Build started
[09:38:37][MYAPP] : Build
 exec: not started

この原因を探っていきます。

Issue はあるのか

Go module support

とりあえず、Gopkg.toml を go.mod と go.sum に置き換えたら?

んーそうじゃないんだよな…

Cannot do --run with go1.11 using go mod under windows.

Windows に限った話ではなく、 Mac / Linux でも起きてるよー、とのこと。
ただ、根本的な原因が見えなかったので、直接コードを見ることにしました。

コードを読む

realize.go

とりあえず main パッケージから読み始めます。

まずは realize start してる部分を探します。
CLI パッケージは gopkg.in/urfave/cli.v2 を使ってるみたいですね。

Commands: []*cli.Command{
    {
        Name:   "start",
        ...
        Action: start,
    },

プライベート関数 start を呼んでるので、次はそちら。
いろいろ書かれていますが、最後の return r.Start() の先にありそうですね。

cli.go

見る限り、gorutine で複数のプロジェクトを監視できるようにしてるみたいですね。
複数プロジェクトをまたいだ開発や、そもそも設定でプロジェクトのパスを設定できるため、リポジトリ内には .realize.yaml を含めない、みたいなことも可能だそうです。

// Start realize workflow
func (r *Realize) Start() error {
    if len(r.Schema.Projects) > 0 {
        var wg sync.WaitGroup
        wg.Add(len(r.Schema.Projects))
        for k := range r.Schema.Projects {
            r.Schema.Projects[k].exit = make(chan os.Signal, 1)
            signal.Notify(r.Schema.Projects[k].exit, os.Interrupt)
            r.Schema.Projects[k].parent = r
            go r.Schema.Projects[k].Watch(&wg)
        }
        wg.Wait()
    } else {
        return errors.New("there are no projects")
    }
    return nil
}

次は、 r.Schema.Projects[k].Watch(&wg) 関数を辿ってみます。

projects.go

// Watch a project
func (p *Project) Watch(wg *sync.WaitGroup) {
    ...
    // before start checks
    p.Before()
    // start watcher
    go p.Reload("", p.stop)
    ...

コメントがありがたいですね。 p.Before() この辺が怪しそうです。

func (p *Project) Before() {
    ...
    if hasGoMod(Wdir()) {
        p.Tools.vgo = true
    }
    ...
    // setup go tools
    p.Tools.Setup()
    // global commands before
    p.cmd(p.stop, "before", true)
    // indexing files and dirs
    for _, dir := range p.Watcher.Paths {
        base, _ := filepath.Abs(p.Path)
    ...

hasGoMod(Wdir())p.Tools.vgo が True になっている。
Go1.11 なら go mod ... で良いんじゃなかったっけ…?

Wdir() は Working ディレクトリを返します。
では、 hasGoMod() は?

utils.go

func hasGoMod(dir string) bool {
    filename := path.Join(dir, "go.mod")
    if _, err := os.Stat(filename); os.IsNotExist(err) {
        return false
    }

    return true
}

ははーん。 go.mod があると、 vgo は True になるんですね。
もしや…

tools.go

ありました。
projects.goBefore() 内にある Setup() で以下のように書かれていました。

// Setup go tools
func (t *Tools) Setup() {
    var gocmd string
    if t.vgo {
        gocmd = "vgo"
    } else {
        gocmd = "go"
    }
    ...

    t.Install.name = "Install"
    t.Install.cmd = replace([]string{gocmd, "install"}, t.Install.Method)
    t.Install.Args = split([]string{}, t.Install.Args)
    ...

つまり Go Modules には対応していない みたいです。

まとめ

「お、これは PR チャンスなのでは?」
「いや、そもそもここまで書いてるんだったら、PR 出してマージされましたーぐらいまで話もってこいや」

と思われる方もいらっしゃるでしょう。

しかし、Cannot do --run with go1.11 using go mod under windows. や、他のいくつかの Issue をご覧になった方はすでに把握していると思うんですが、数日前のコメントで

thanks for the support and for the reports, in the last months we had some company changes but in the first trimester 2019 we will release a new version

レポーティングありがとー。2019年の第一期に新しいバージョン出すね。

とのこと。
1.12 から GO111MODULE=on の挙動が標準になるらしい点も踏まえると、もうちょっと待ってみてもいいかな…それでもだめなら他のツールか、もしくは自作してみるのもありかもしれない。

明らかに間違っている情報などありましたら、コメント等でいただけますと幸いです。


『 Go 』Article List
Category List

Eye Catch Image
Read More

Androidに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

AWSに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Bitcoinに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

CentOSに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

dockerに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

GitHubに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Goに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Javaに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

JavaScriptに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Laravelに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Pythonに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Rubyに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Scalaに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Swiftに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Unityに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Vue.jsに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Wordpressに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

機械学習に関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。