異動した

先日病気をしてからの体調面のこと、幸いに受け入れてもらえるチームがあったこと、などいろいろあって異動することにした。

以前の部署では、休んでた期間を除いて一年強と短い期間ではあるが、複数チームが関わる大きなプロダクトに携われたことは、とても良い経験になった。

今日からはスモールチームでやっていく。規模感は前とは全然違うが、その分自分が関われる範囲は広いだろう。それに自分の実力が成果に直結することになるので、今まで以上にちゃんとしてないと。

とはいえあまり意識高い感じでこじらせるとしんどいんで、良い感じでパフォーマンス出せるようにがんばろう。

zshでGitのリモートリポジトリのホスト名を表示する

zshではvcs_infoを使用して作業中のリポジトリの情報を表示することができる。「zsh vcs_info」でググるといろいろと出てくるが、私は以下の記事をベースに設定を行って、少しずつアップデートしている。

zsh の vcs_info に独自の処理を追加して stash 数とか push していない件数とか何でも表示する(記事は4年ほど前のものだが、zsh自体がそんなにアップデートしているわけでもないので、今でも十分通用する)

最近になってgithub.comgitlab.comのどちらも使用するようにしたので、リモートリポジトリを間違えないようにホスト名を表示できるように修正した。

リモートリポジトリのホスト名を取得する

git ls-remote --get-urlでリモートリポジトリのURLを取得できる。このURLは.git/configに記載されているものが表示されるようになっている。たぶんgit remote add origin REMOTE_REPOSITORYで設定したものと同じになるはず。リモートが複数設定されている場合にどうなるか未確認だが自分のユースケースではそれはあまりないので、気にせず使っている。

git@github.com:kawaken/dotfilesという構成になっている場合が多いので、:@で分割してホスト名に該当しそうな箇所を拾っている。

hostname=$(git ls-remote --get-url | cut -d: -f1 | cut -d@ -f2)

プロンプトに表示する

自分の場合はhook_com[branch]の中に混ぜ込むようにしている。 https://github.com/kawaken/dotfiles/blob/master/zsh/vcs_info#L54

-    echo "%f${arrow}%F{cyan}${remote}%f${(j:/:)gitstatus}"
+    echo "%f${arrow}%F{cyan}${remote}(${hostname})%f${(j:/:)gitstatus}"

最終的にはこんな感じで表示される。

f:id:kentaro_kawano:20180926234632p:plain

出力結果が長い

ホスト名が出るのは良いが、ちょっと長いので短くしたい。ここで以前書いたホスト名を短くする手法を使う。SSH_CONFIGを使用してgitのリポジトリURLを短縮する

# gh = git@github.com
git remote rm origin
git remote add origin gh:kawaken/dotfiles
git branch -u origin/master

f:id:kentaro_kawano:20180926234611p:plain

シンプルな表示になった。

GitLabCIの結果をGitHubにコミットする

hugoで生成したHTMLをコミットしたかったのでやってみた。

SSHのキーペアを作成する

既存のものは使い回したくないんで、新規に作成する。

$ ssh-keygen -f id_rsa_gl2gh

作った鍵は以下のように使用する。

  • 公開鍵 -> GitHubのDeploy keyとして設定する
  • 秘密鍵 -> GitLab CIのVariableに設定する

GitHubでのDeploy keyの設定

コミットしたいリポジトリの設定から、作成した公開鍵をDeploy keyに追加する。 追加したあと、SSHで接続の確認をする。

$ ssh -i id_rsa_gl2gh git@github.com
PTY allocation request failed on channel 0
Hi kawaken/kawaken.me! You've successfully authenticated, but GitHub does not provide shell access.
Connection to github.com closed.

普段使っている鍵と違い、ユーザ名と特定のリポジトリ名が表示されている。

GitLabCIのVariableの設定

GitLabCIでは実行中の環境変数を外部から設定できるようになっている。プロジェクトのSettings -> CI/CDのVariableの設定に、Key/Valueの組み合わせを登録する。

Key名をSSH_PRIVATE_KEYにして、秘密鍵を登録する。

UI上は短い一行の値しか入力できないように見えるが、複数行の内容でも問題なく設定できる。

GitLab CIの設定

Using SSH keys with GitLab CI/CD | GitLab におおまかな手順は載っているが、ちょっと修正が必要になる。

自分は以下のような設定になった。

before_script:
# SSH用のディレクトリ作成
  - mkdir -p ~/.ssh
  - chmod 700 ~/.ssh
# github.comのSSH host keysを保存する
  - apt-get update -y && apt-get install openssh-client -y
  - ssh-keyscan -t rsa github.com >> ~/.ssh/known_hosts
# ssh-agentの設定
  - eval $(ssh-agent -s)
  - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - > /dev/null
# git のユーザ情報設定
  - git config --global user.email "user@example.com"
  - git config --global user.name "Kentaro Kawano"

to_github:
  stage: build
  script:
    - rm -fr public
    - git clone git@github.com:kawaken/kawaken.me.git public
    - hugo
    - cd public
    - export MESSAGE="update $(date +'%F %T')"
    - git add -A .
    - git status
    - git commit -m "${MESSAGE}"
    - git push origin master

  only:
    - master

更新対象のリポジトリをhugoの出力ディレクトリとし、変更をすべてコミット&プッシュするようにした。

git statusを途中で実行しているのは、何が対象となったかをGitLabのJobのログに残したいため。

SSH_CONFIGを使用してgitのリポジトリURLを短縮する

gitのリポジトリSSHでアクセスするときに限るがSSH_CONFIGを使用することでホスト名を簡略化でき、リポジトリURLを短縮することができる。

SSH_CONFIGでの設定

例えば以下のようにする。

Host gh
  User git
  Hostname github.com

cloneする

GitHubでのリポジトリURLが以下のような場合、

git@github.com:kawaken/repositry.git

短縮して、

gh:kawaken/repositry.git

となる。さらに最後の.gitは無くてもいいので、最終的にコマンドは以下のようになる。

git clone gh:kawaken/repositry

ちょっとだけ便利。

ちなみにSVNでもこのテクニックは使える。

DynamoDB Local(Amazon公式)のDockerイメージを使う

先日の8月22日に、Amazonから公式にDynamoDBのDockerイメージが公開された。

ググっても野良のイメージしか出てこないのでまだあまり認知されてないっぽい。

ちょうどDynamoDB Localを利用していたところだったので、早速試してみた。

とりあえず立ち上げる

$ docker run --rm amazon/dymamodb-local
Initializing DynamoDB Local with the following configuration:
Port:   8000
InMemory:   true
DbPath: null
SharedDb:   false
shouldDelayTransientStatuses:   false
CorsParams: *

jarで配布されていたものと同じっぽい。

オプションを使用したい

とりあえず開発時のテストとはいえ、データを永続化したい。

jar版では起動時の引数で設定することができたので、Dockerイメージにおいても引数を渡せれば設定できるはず。 Dockerfileは見当たらないので、とりあえずinspectしてみる。

$ docker inspect amazon/dynamodb-local:latest
(snip)
        "Config": {
            "Hostname": "",
            "Domainname": "",
            "User": "dynamodblocal",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "ExposedPorts": {
                "8000/tcp": {}
            },
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
            ],
            "Cmd": [
                "-jar",
                "DynamoDBLocal.jar",
                "-inMemory"
            ],
            "ArgsEscaped": true,
            "Image": "sha256:6901b80d033a1d94e1283711be031f2657d90edf0768118bb22c952feba780bd",
            "Volumes": null,
            "WorkingDir": "/home/dynamodblocal",
            "Entrypoint": [
                "java"
            ],
            "OnBuild": null,
            "Labels": {
                "aws.java.sdk.version": "1.11.119"
            }
        },
(snip)
  • Entrypoint: java
  • Cmd: -jar DynamoDBLocal.jar -inMemory

となっているので、docker runの際に javaのオプションとなる部分をすべて指定することで設定を変えられそう。

データを永続化する

dbPathでパスを指定することができるので、Volumeを指定してそこにデータを置くようにする。 ひとまずフォアグラウンドで起動する。

$ docker run --rm -p 8000:8000 -v ~/dynamodb-data:/home/dynamodblocal/data \
amazon/dynamodb-local -jar DynamoDBLocal.jar -dbPath /home/dynamodblocal/data
Initializing DynamoDB Local with the following configuration:
Port:   8000
InMemory:   false
DbPath: /home/dynamodblocal/data
SharedDb:   false
shouldDelayTransientStatuses:   false
CorsParams: *

別のターミナルからawsコマンドを使用し、テーブルを作成してみる。

$ aws dynamodb create-table --table-name Clients \
    --attribute-definitions AttributeName=id,AttributeType=S \
    --key-schema AttributeName=id,KeyType=HASH \
    --provisioned-throughput ReadCapacityUnits=1,WriteCapacityUnits=1 \
    --endpoint-url http://localhost:8000
{
    "TableDescription": {
        "TableArn": "arn:aws:dynamodb:ddblocal:000000000000:table/Clients",
(snip)
    }
}

一覧で取得できるか確認。

$ aws dynamodb list-tables --endpoint-url http://localhost:8000
{
    "TableNames": [
        "Clients"
    ]
}

ホスト側のデータ保存先に指定した場所を確認してみる。

$ ls ~/dynamodb-data
AKIAIOSFODNN7EXAMPLE_ap-northeast-1.db

この中にデータが入ってそう。

まとめ

DockerイメージでのDynamoDB Localの動作確認ができた。

Javaの環境を用意しなくても動作ができるので、気楽に利用できるようになった。ありがたい。

rmdirの使い方

rmdirは対象のディレクトリが空の時だけ削除できる。そのため、中身は問わずディレクトリ消したいときは、rm -frを使用していた。Linuxを使い始めてから長いことそうしていて、rmdirを使うことはほとんどなかった。

確実に空のディレクトリだけを削除できる

この1年くらいコードの整理をする機会が増えたため、確実に空のディレクトリだけ削除したいということが増えた。最初はfindなどで中身が空か確認してから削除するようにしていた。しかしfind -> rm -frというのも手間なので、rmdirを使用するようになった。

rm -rでいいのでは?とも思ったが、rm -frとついつい誤って打ってしまうことがありコマンド自体を使い分けることにした。

rmdirの対象が空ではない場合、

  1. rmdirで失敗する
  2. 中身を確認する
  3. 残っているファイルを処理する(だいたいrmする)
  4. 改めてrmdirを実行

というフローを踏むようになった。たまに本当に消してはいけない何かがあることがあり、誤って消してしまうような致命的なミスは避けられるようになった。

ちょっと便利なオプション

rmdirにも当然オプションがあり、とりあえず空のディレクトリをガサッと消すぞ!みたいなときに使える。

--ignore-fail-on-non-empty: 対象が空のディレクトリではなく、削除できなかった時にfailしない。forやxargsと組み合わせて削除していく際に、このオプションを付与したりする。

-p: 対象のディレクトリの親も削除する。mkdir -pの逆の動作をする。manには以下のように書いてある。

'rmdir -p a/b/c' is similar to 'rmdir a/b/c a/b a'

とりあえず雑に以下のような使い方をする。

$ find target_dir -type d | xargs rmdir --ignore-fail-on-non-empty -p

あまり嬉しくないのは、どのディレクトリを消したか教えてくれるオプションがないこと。なので、その辺を確認したいときはあらかじめfindで一覧を残しておく。

あとrmdir.を渡すとrmdir: failed to remove '.': Invalid argumentとして怒られる。

おしまい

iPhone/Macで使えるMarkdownエディタを検討する

ブログの執筆を前提にしたエディタを評価してみた。

あるといい機能

  • ファイル名を指定せずに書き始めることができる
    • 先頭行がタイトルとなる
    • メモ一覧でもタイトルが表示される
  • iPhone/Macの同期がスムーズにできる
    • Dropboxなどオンラインストレージがいらない
    • iCloudでも良い
    • 明示的に「同期」アクションをしなくてもよい
  • iPhoneでは、Markdown用のキーボードがあるとよい
    • 使用できるマークアップがカスタマイズできるとよい
    • 自分の使用頻度の高いものが使いやすい位置にあるとよい
  • Macでは、独立した編集/プレビューのモードがある
    • Split表示嫌いなんで
    • 編集モードであってもヘッダーやリストなどはスタイルが変わるとうれしい
  • iPhoneではプレビューが容易だとうれしい
  • タグ付けができるとよい

ちなみに、この辺り全部満たしてる感じのやつはなかった。

bear

最終的にこれを使うことにした。iPhone/Macで同期を行う機能は有料で年間1500円。やすっ。

Bear - Notes for iPhone, iPad and Mac

いいところ

  • 編集中でもスタイルが変わるのでわかりやすい
  • ファイル名を指定せずに書き始めることができる
  • データの同期がすごいスムーズ
    • 別の端末でアプリを開いた際の待ち時間を感じたことがない

おしいところ

  • 逆にプレビューモードがない
    • iPhoneでは、HTMLに出力する機能がプレビューの代替として使えるがやや手間
  • リストが完全にリストになってしまうので、ちょっとインデントの編集で手間取ることがある
    • MacだとTabで変更可能
  • 自分が頻繁に使用するマークアップへのアクセスが良くない(iPhone)
  • タグ付けできるが、文章内に#tagという感じで書かないといけない
  • TODOというドキュメントの種類があるが、文章中に- [ ]を含んでいるだけでは該当しない
    • タスク数などが簡単に確認できるわけでもない

MWeb

ちょっと同期周りがめんどくさい気がした。ちゃんと試してない。

MWeb - Pro Markdown writing, note taking and static blog generator App - MWeb

いいところ

おしいところ

  • ファイル名を指定しないと書き始めることができない

Inkdrop

作者の人、すごいなーと思って試してみた。

Note-taking App with Robust Markdown Editor - Inkdrop

いいところ

  • タグ付けとステータスの管理ができる
    • Completeとかにするとデフォルトのメモ一覧から表示されない
  • TODOが含まれているとカウントされる
  • ファイル名指定せずに書き始めることができる
  • メモ一覧の情報量と視認性がとてもいい

おしいところ

  • Macではなんか全体的にもっさりする
  • iPhoneでメモ一覧からスライドして削除できないのがちょっと…

Mac版の方はすごく良かった。しばらくしたらもっと使いやすくなっているかもしれないので、たまに試してみたい。

Boostnote

会社では使ってるけど、iPhoneアプリが非公開になっているらしく、候補から外れた。

1つ気になるのが、編集モードからフォーカスが外れるとプレービューモードに切り替わってしまうのが好きではなくて、Snippetをもっぱら使用している。

Issueも上がっているけど、しばらく進展してないっぽい。

Disable preview? · Issue #1767 · BoostIO/Boostnote