datastoreに依存したテストはStronglyConsistentDatastoreをtrueにする

Goを書き始めた頃、テストで下記のようにcontextを生成していた。

ctx, done, e := aetest.NewContext()
if e != nil {
    t.Fatal(e)
}
defer done()

// 1. Putする

// 2. 1でPutしたデータをGetする

このコードには、datastoreにPutした直後にGetするとデータを取得できずテストが落ちるという問題があった。
これを解決するには aetest.Options{StronglyConsistentDatastore: true} Instance生成時の引数に渡してあげればいい。
しかし、aetest.NewContext には引数でoptionを渡すことはできない。 github.com

aetest.NewInstance にoptionを渡せるメソッドを作り、datastoreが絡むテストはこのメソッドを使うようにしている。

func NewContext(option aetest.Options) (context.Context, func(), error) {
    inst, err := aetest.NewInstance(&option)
    if err != nil {
        return nil, nil, err
    }
    req, err := inst.NewRequest("GET", "/", nil)
    if err != nil {
        inst.Close()
        return nil, nil, err
    }
    ctx := appengine.NewContext(req)
    return ctx, func() {
        inst.Close()
    }, nil
}

呼び出し側

option := aetest.Options{StronglyConsistentDatastore: true}
ctx, done, e := NewContext(option)
if e != nil {
    t.Fatal(e)
}
defer done()

このようにすれば、Putしてdatastoreに反映したものをGetできるようになる。

ブログに残しておこうと思っていたのにいつの間にか数ヶ月経っていてよくないな。。

hatebu: はてブのホットエントリーを表示するCLIツールを作った

最近Goを書いているので、勉強がてらCLIツールを作ってみた。

作ったもの

はてブのホットエントリー(テクノロジー)の一覧を表示するCLIツール hatebu を作った。

github.com

学生の頃からはてブが好きで、2014年頃はホットエントリーを収集して過去のホットエントリーをまとめて見れるようなサービスを作ったりしていた。
CLIツールを作りにあたり、普段よく使うものがよかったので、ホットエントリーを表示するものにした。 今はテクノロジーしか取得していないが、将来的に他のもサブコマンドで指定できるようにしたい。

今回、CLIパッケージは spf13/cobra を使ってみた。元Dockerの中の人で、今はGoogleで働いているらしい。

github.com

サブコマンドは個別にファイル作れば追加できるので拡張性がよさそう。

ホットエントリー一覧を表示するCLIツールは既に作っている人がいて、実装する上で大変参考にさせていただきました。ありがとうございます。
github.com

fish shellでgvmを使う

gvmを使うとGoをバージョン指定してインストールできる。
https://github.com/moovweb/gvm

以下、Macにインストールするのを前提とする。

依存ツールのインストー

➤ brew update
➤ brew install mercurial 

gvmのインストールは

bash < <(curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer)

または

zsh < <(curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer)

なんだけど、このままではfishではエラーになり使えない。

そこでこのIssueを見ると解決方法が書いてあった。
https://github.com/moovweb/gvm/issues/137

fishermanというfishのプラグインマネージャーを使ってbassプラグインをインストールすれば解決できるらしい。

fishermanインストー

➤ curl -Lo ~/.config/fish/functions/fisher.fish --create-dirs git.io/fisher

bassをインストー

➤ fisher edc/bass

gvmをインストー

bashに切り替えて

➤ bash
bash-3.2$ bash < <(curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer)

source /Users/username/.gvm/scripts/gvm 実行し、
config.fishに以下を追記して設定反映すれば、gvmコマンドを使うことができる。

function gvm
  bass source ~/.gvm/scripts/gvm ';' gvm $argv
end

Go1.6をインストー

本当は1.8を使いたいところだけど、1.6をインストー

➤ gvm install go1.6
ERROR: Failed to compile. Check the logs at /Users/koori/.gvm/logs/go-go1.6-compile.log
ERROR: Failed to use installed version
exit code: 1

1.5からはセルフホスティングされているため、ビルドに1.4以上が必要らしい・・・あんまりこの辺は理解していない。

バイナリからインストー

➤ gvm install go1.4 -B
Installing go1.4 from binary source

➤ gvm use go1.4
➤ set -x GOROOT_BOOTSTRAP GOROOT

Go1.6をインストー

➤ gvm install go1.6 -B
Installing go1.6 from binary source
➤ gvm use go1.6
Now using version go1.6

確認してみる

➤ gvm list

gvm gos (installed)

   go1.4
   go1.6
➤ go version
go version go1.6 darwin/amd64

OK

--allow-emptyで空コミットを作る

プルリクはできるだけ粒度を小さくしレビューをしやすくしていきたい。
そんなとき、空コミットがあると便利。

git commit --allow-empty -m "commit message"

feature/hogeブランチで空コミットを作ってPushしWIPのプルリクを作る。 各作業はfeature/hogeからブランチを切って作業しプルリクを作り、レビューが通ればfeature/hogeにマージ。

雑なブログになってしまった。

nginx + uWSGI + Python3 + bottle でHello Worldまで

雑に動かすところまでやってみたのでメモ。
PythonフレームワークDjangoが有名だけど、シンプルなbottleを使ってみることにした。
「bottle.py」だけでできているので入門に最適らしい。

環境

uWSGIをインストール

$ pip install uwsgi
$ uwsgi --version
2.0.12

インストールできた。

bottleをインストール。

$ pip install bottle

bottleで簡単なプログラムを書く

$ mkdir myapp
$ cd myappp
$ vim index.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-

from bottle import route, run, default_app

@route('/')
def hello():
    return 'Hello World!'

if __name__ == '__main__':
    # コマンドから"python3 index.py"で起動した場合
    run(host='localhost', port=3030)
else:
    # uWSGIから起動した場合
    application = default_app()

nginxの設定

vim /etc/nginx/conf.d/myapp.conf

server {
    listen 80;
    server_name  myapp.com;
    access_log   /var/log/nginx/myapp.com.access.log;

    location / {
        include uwsgi_params;
        uwsgi_pass  unix:/var/run/uwsgi/myapp.com.sock;
    }
}

uWSGIの設定

[uwsgi]
socket       = /var/run/uwsgi/myapp.com.sock
pidfile      = /var/run/uwsgi/myapp.com.pid
daemonize    = /var/log/uwsgi/myapp.com.log
chdir        = /home/vagrant/myapp/
master       = 1
file         = index.py
chmod-socket = 666
uid          = nginx
gid          = nginx
py-autoreload = 1

ディレクトリ作成して、オーナー変更

$ sudo mkdir /var/run/uwsgi/
$ sudo chown nginx /var/run/uwsgi/
$ sudo mkdir /var/log/uwsgi
$ sudo chown nginx /var/log/uwsgi

uwsgiを起動

uwsgi --ini uwsgi.ini

あとはhosts設定してアクセスすると、Hello World!が表示される。

とても参考になったブログあったんだけど、URLなんだったかな。。。

若手おじさん業をはじめた

先日イベントで会った高校生に、プログラミングに関して聞きたいことがあるので会いたいとDMをいただいたので、今日話してきた。
高校生がプログラミングに興味を持っていることがすごいと思ったし、行動的なところも非常にいいなと思った。自分が高校生のときはこんな勇気なかった。

プログラミング始めたてのころは色々なことで詰まるし、自分のスキルのなさに絶望することもあるんだけど、どうか気を落とさないでほしい。みんな同じ道を通ってきているんだと知ってほしい。
また、エンジニアとしてインターンをしてみたいということも話していたので、そこらへんも参考になると思う。
というわけで、定期的に読みたくなる記事を紹介したい。


Evan Priestley 氏がどうやってプログラミングを学んだかを教えてください

Facebookの元エンジニアがどのようにプログラミングを学んだのかという記事。
すごいと言われるエンジニアでも駆け出しの頃はミスもするし、その経験があったからこそ、Facebookで活躍したエンジニアになったんだなと思う。

教養としてではないプログラミング╭( ・ㅂ・)و

この記事にあるスライドだけでも見て欲しい。
初心者のときは誰でもこういう経験あったのでないだろうか。
教える側もインターンや新卒に対しての対応を気をつけたい。。。

不自由なプログラミング

わかる。共感するところが多い。


パッと思い浮かぶのはこれくらいなんだけど、他にもいい記事はたくさんあるはず。
プログラミング楽しいから、少しずつ頑張ろう (僕も頑張る)