Technology Engineering

178inaba の技術ブログ

ブログ再始動

お久しぶりです。

178inabaです。

久しぶりにブログを書いています。

最近、技術書典で技術書を販売した方のブログを見ました。

shu223.hatenablog.com

このブログを見て

(自分もいつかは本が書けたら楽しいだろうな)
(沢山の人が来場していて交流できるし、報酬も得られる!)

などと思い、

でも本を出すにはまず、休止状態のブログを再始動して技術的な記事とか書くべきだろうと思いこのブログを書いています。

Kyash始めてみた

Kyashは同僚と食事に行った時に割り勘代金を渡すために入れてみたのですが便利です。

上の技術書典のブログを読んだときに、KyashのAndroidエンジニアのこにふぁーさんのブログを思い出しました。

konifar.hatenablog.com

このこにふぁーさんのブログには投げ銭の話が書いてあって、上の技術書典の話と 『技術情報の発信で報酬を得る』 という所で通ずるなと思いました。

なので真似してKyashのIDとQRコードを貼ってみます。

kyash_id: 178inaba

f:id:i178inaba:20181012005104j:plain

今後

今後は定期的に技術情報をブログに書いていけたらと思います。
よろしくです!

GitHub Gistにファイルをアップロードするコマンドをgolangで作った

Gistを作る時、毎回catでファイル内容を表示してコピーして、GistのWeb画面にペーストしてたんだけど、
これが地味にめんどくなってきたので、ファイルを渡すとGistを作ってくれるコマンドをgolangで作った。

github.com

使い方

  • target.goをGistにアップロードする場合。
$ gistup target.go
  • 複数ファイルをGistにアップロードする場合。
$ gistup target.go target_test.go target_linux.go
  • 標準入力をGistにアップロードする場合。
$ stdin | gistup

アップロードが成功するとブラウザで作成されたGistのページを開きます。
(開けなかった場合はURLを表示。)

デフォルトでは最初にユーザ名とパスワードでログインを求められます。
(後述のオプションで匿名を選択すればログイン不要。)

また、デフォルトでは非公開のGistとして作成されます。
(こちらもオプションで公開のGistとして作成することも可能です。)

オプション

  • -a
    • 匿名のGistを投稿します。
  • -d <description>
    • Gistの説明を追加します。
  • -n <file_name>
    • 標準入力からGistにアップロードする場合のファイル名を設定します。
    • 指定しない場合はGistのデフォルトgistfile1.txtになります。
  • -p
    • パブリック(公開)のGistを投稿します。

所感など

入力時のコンテキストキャンセル検知

ユーザ名、パスワード入力は下記のようにコンテキストのキャンセルを検知できるようにしている。

func readString(ctx context.Context, hint string, readFunc func(t *tty.TTY) (string, error), t *tty.TTY) (string, error) {
    fmt.Printf("%s: ", hint)
    ch := make(chan string)
    errCh := make(chan error)
    go func() {
        s, err := readFunc(t)
        if err != nil {
            errCh <- err
        }
        ch <- s
    }()
    var s string
    select {
    case <-ctx.Done():
        return "", ctx.Err()
    case s = <-ch:
    case err := <-errCh:
        return "", err
    }
    return s, nil
}

理由はgistupはInterruptシグナル(Ctrl+C)を受けてコンテキストをキャンセルする仕組み(下記参照)になっているのだが、

sigCh := make(chan os.Signal, 1)
signal.Notify(sigCh, os.Interrupt)
ctx, cancel := context.WithCancel(context.Background())
go func() {
    <-sigCh
    cancel()
}()

これだと、入力中にCtrl+Cを押しても終わらない。
なので、ゴルーチンで入力処理を実行して、コンテキストのキャンセルと、入力終了をselectで同時に待つようにした。

結果、入力中にCtrl+Cを押すと終了するようにできた。

ユーザ名、パスワードの入力はTTYを使用

gistupではユーザ名とパスワードの入力にTTYを使用している。

理由は、最初、標準入力からユーザ名とパスワードを取得していたけど、
標準入力をGistにアップロードする箇所を実装してる時にユーザ名、パスワードの取得ができなくなる事に気づいた。

いろいろ調べたけど引き続き標準入力からユーザ名、パスワードを取得するのは難しそうで、調べて出てきたのはperlの質問でTTYを使っているやつだった。

stackoverflow.com

「goでTTYって確かmattnさんが作ってたよな」と探したらあって、

github.com

ただ、パスワードを読むメソッドしか無かったのでReadStringメソッドをプルリクエストした。
その後、速攻でマージして頂けたのでユーザ名の入力にはReadStringを使用。

結果、ユーザ名、パスワードを入力しつつ、標準入力から取得した文字列をGistにアップロードすることができた。

まとめ

これでコピペせずにGistにアップロードできるようになった。

またなんか作ったら書きます。

あと、PR大歓迎です😆

Raspberry Piで使うSDカードをコマンドラインで作る

新しいRaspberry Piを買ったので起動SDを作るコマンドをメモしておきます。
使用するOSはRaspbianです。

# ダウンロード
$ wget https://downloads.raspberrypi.org/raspbian_lite_latest -O raspbian.zip

# zip解凍
$ unzip raspbian.zip

# SDカードのマウント箇所を確認
$ diskutil list
...
/dev/disk2 (internal, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:     FDisk_partition_scheme                        *2.0 GB     disk2
...

# SDカードのマウントを解除
$ diskutil unmountDisk /dev/disk2

# SDカードにイメージを書き込む
$ sudo dd bs=1m if=2017-03-02-raspbian-jessie-lite.img of=/dev/rdisk2

イメージを書き込むのが結構時間かかります。

マウント箇所(上記だとdisk2)はPCによって異なります。
イメージファイル名(上記だと2017-03-02-raspbian-jessie-lite.img)もRaspbianがアップデートされると変わります。

参考:

www.raspberrypi.org

Raspberry Pi(Raspbian)の更新

新しいRaspberry Piを買ったので、ついでに以前GitLabを入れたRaspberry Piの更新をした。

# パッケージリスト更新
$ sudo apt-get update

# パッケージ更新
$ sudo apt-get dist-upgrade

# ダウンロードしたパッケージの削除
$ sudo apt-get clean

sudo apt-get dist-upgradeは結構時間かかる。

GitLabもRaspbian版は長らくバージョン8.7.9で止まっていたのだが、最近更新されてバージョン9.0.2が使えるようになっていた。
Dockerレジストリも使えるようになった。

参考:

www.raspberrypi.org

gitlab.com

Herokuアプリとgitからcloneしたアプリの紐付け

Herokuアプリを1から作る時はheroku createだけど、既に存在するHerokuアプリとgitからcloneしたアプリを紐付ける方法がわからなかったので調べた。

$ heroku git:remote -a app_name

これでリモートにherokuが追加される。

$ git remote -v
heroku  https://git.heroku.com/app_name.git (fetch)
heroku  https://git.heroku.com/app_name.git (push)
...

参考:

stackoverflow.com

別環境で作ったRailsプロジェクトを新しい環境に持ってきたときの環境構築

今日は近くの公民館の自習室でRailsチュートリアルをしてました。

帰ってきてからRails環境が無いPCで続きやろうとしてgit cloneの後、ちょっと躓いたのでその時の事をメモとして残しておきます。

Rails環境構築

macOSRailsの環境構築してローカルサーバ起動するまで。

# Rubyをbrewでインストール
$ brew install ruby

# NokogiriのGemをインストール
$ gem update --system
$ xcode-select --install
$ gem install nokogiri

# RailsのGemをインストール
$ gem install rails

# Railsプロジェクトをクローン
$ git clone https://github.com/user/rails-project.git

# プロジェクト固有のGemをインストール
$ cd rails-project/
$ bundle install

# DB構築
$ bin/rails db:migrate

# ローカルサーバ起動
$ bin/rails server

Gemfile.lockがあったらbundle installすると覚えておけば良い。
bundleコマンドはgem install railsRailsの依存Gemとしてインストールされる。

bin/rails db:migrateも意外と忘れがちなので注意。

Railsのインストールでエラーが出たらNokogiriを先にインストールしよう

Railsのチュートリアルをやっているのですが、Railsのインストールで躓きました。

$ gem install rails
...
xmlIO.c:1450:52: error: use of undeclared identifier 'LZMA_OK'
...

Nokogiriのインストールでエラーです。

issueも立っていました。

github.com

解決法

NokogiriのmacOS用のインストール手順に従って

$ gem update --system
$ xcode-select --install
$ gem install nokogiri

とするとNokogiriがうまくインストールされます。

Nokogiriがインストールされた後にRailsをインストールするとエラーも出ません。

$ gem install rails

Railsのインストールでエラーが出る人はお試しあれ。