Golden Road

好きだという熱こそが最低限で最高の希望

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のインストールでエラーが出る人はお試しあれ。

『ボトルメール』というLINE Botを作っていた話。 #BOTawards

inabaです。

忙しくてブログにまとめるのが遅れていまいましたが、2月末にLINE Botを作ってLINE BOT AWARDSにエントリーしてました。

bottle-mail.178inaba.com

ボトルメールといいます。
Botと友達になってメッセージを送るとBotと友達になっている人の中でランダムにメッセージが飛び、その人と会話できるBotです。
「おわり」とメッセージを送って返ってきた確認ダイアログで「終了」を押すか、1時間メッセージが飛んでいないと会話が終了になります。

2月26日に作り始めて、半ば徹夜のような形で作っていたため告知できませんでした(=_=)
(開発自体は2月28日までに終わってましたよ!マジで!!)
このBot自体の友達が多くないと意味が無いので多分賞に選ばれることは無いと思いますw
まぁ勉強だと思って作りましたので、よかったら友だちになってやってください!

https://qr-official.line.me/M/S3fUYbyDh8.png

LINE BOT AWARDSの結果でた後くらいにはソースを整理してGitHubに上げようと思ってます。

何かあればコメントやツイッターにでもご意見頂ければうれしいです。

よろしくどうぞ〜