Screaming Loud

日々是精進

2020年読んだ本まとめ

2020年に読んだ本は22冊でした。

f:id:yuutookun:20210103212517p:plain
読書メーターのstats

mocyutoさんの2020年読書まとめ - 読書メーター

今まで通勤中に結構読んでたのですが、2020年はリモートワークで読む時間が減って読む量が減った気がします。 ただ、実際カウントしてみると2019年と1冊差でしたね。

個別ピックアップ

以下は読んだ本のピックアップです。

これとかは意外に知らなかった歴史の背景などが知ることができたので面白かったですね。

bookmeter.com

あとは話題になった本です。 とりあえず読んだことがないのであれば、さらっと読んでみてもいいかもしれないですねー

bookmeter.com

こちらをきっかけに The Last of Us というゲームをやるに至りました。

bookmeter.com

去年のまとめ

yuutookun.hatenablog.com

GitHub Actionでtagを打った際にgit-pr-releaseみたいなリリースノートを作る

今年はコロナで出かけていないので、ちょっとGitHub Actionいじってます。

やりたいこと

タイトル通りですが、やりたいことは「GitHub Actionでタグを打ったときに、git-pr-releaseみたいな前のタグからのPRのリストをリリースノートに乗せたい」です。

f:id:yuutookun:20210102163926p:plain
実際の自動で生成したリリースノート

やりかた

これを実施するにあたり、git-pr-releaseと違ってメインブランチとサブブランチを決めてそのPRを取るという手法が使えないので以下のようにする必要があります

  • 前のタグからの今のタグへの全コミット取得
  • PRのコミット取得
  • 対象のPRを取得
  • リリースノートに反映

前のタグからの今のタグへの全コミット取得

これはGitHubAPIからは取れなかったので、Git操作で取得します。 git log を使えば、あるタグから別のタグまでのコミットログを取れます。 また通常のログだといろいろな情報が乗ってくるので、formatしてあげて必要な情報に絞る必要があります。 今回はコミットハッシュだけがほしいので %H だけを使います。 コマンドで示すと以下です。

$ git log v0.10.0...v0.10.1 --pretty=format:"%H"

それとは別にtag一覧を取って、最新と一つ前を取る必要があります。 sortを使うとタグのバージョンを考慮してsortしてくれるので使わない手はありません。 コマンドでは以下になります。

$ git tag  --sort=-v:refname

これのsortでは v0.1.0. v0.8.0, v0.10.0 をちゃんと並べてくれます

これをGitHubActionでやる必要があるので、実施には actions/github-script@v3 を使います. github-scriptを使うとjsで操作を記述できる上に、GitHub APIが簡単に叩けます。

では特定タグ間のコミットログのハッシュ取得部分です。 jsの simple-git というライブラリを使ってGit操作を行っています。

const simpleGit = require('simple-git');
const git = simpleGit(path); // pathは操作するリポジトリの絶対パス
const logs = await git.tags({ '--sort': '-v:refname' })
    .then((t) => {
        const tags = t.all.slice(0, 2);
        return git.log({ 'from': tags[0], 'to': tags[1] })
    });

slice(0,2) と指定しているのは、sortされているので最新とその次を取るためです。 (一番最初のタグのときは考慮してないので、もしやる場合は考慮させましょう)

PRのコミットを取得

ここに関してはGitHub APIを叩いて取得します。

    const { data } = await github.pulls.list({
        owner: 'mocyuto',
        repo: 'ec2-search',
        base: 'master',
        state: 'closed',
    })

これだけでmasterに向けたmege済みのPRを取得できます。

他にも操作する場合は、以下のoctokitのページを見るといろいろわかります。 localで試したい場合は、以下を参考に試してみるといいと思います。 localの場合は octokit を使い、github-scriptの中では github を使えば動きます。

octokit.github.io

あとはjsでfilterするだけです。

リリースノートに反映

自分は action-gh-release を使っていたので、これをベースに説明します。

ほぼREADMEに書いてあることを実施すればいいのですが、一点リリースノートを追記する際、 bodyを記載した際は追記になるので、matrixで複数リリースノートへ書き込みを行うと同じ文言がmatrix分だけ乗ってしまいます。

ですので、matrixを利用している場合はjobをわけたほうがよいです。

実際のソースコード

以下がワークフローの記述部分です simpe-git を使うためにnpm installしています。 あとactions/checkout@v2 はデフォルトでdepth=1なので0を指定して全部取ってきましょう。

https://github.com/mocyuto/ec2-search/blob/v0.10.1/.github/workflows/release.yml#L77-L99

そして、呼び出しているスクリプトは以下です。

https://github.com/mocyuto/ec2-search/blob/v0.10.1/.github/script/prs.js

まとめ

最初は割と面倒かなと思ったのですが、github-scriptとsimple-gitのおかげでラップしてくれたので、以外に簡単にできました。 tag打ちのときの面倒の手助けになれば。

2020年振り返り

去年の振り返りはこちら

yuutookun.hatenablog.com

仕事

今年はKubernetesにどっぷり浸かった1年でした。 kubernetesの流れが大きくなっていく中で、がっつり触れたのはよい機会だったなと。

以下会社ブログで書いたやつです

tech.gunosy.io

tech.gunosy.io

また、2019年に作った新規サービスをクローズした1年でもありました。 うまく売上が立たず、事業の立ち上げの難しさを感じました。

コロナによって在宅勤務になり環境は大きく変わりましたが、仕事としての違いに関しては元々オフライン時にもオンラインツールを使っていたのであまり感じませんでした。

オンライン化はプラスとして通勤がなくなったことですが、 マイナスとして他部署の人との接点が今まで飲み会とかだったので、 それが無くなりチーム外との雑談は減ってしまったので、そこは今後カイゼンされればいいなと。

あとは、去年掲げていたリードエンジニアとして組織を良くするにはどうすればいいかみたいなことを実行に移しました。

yuutookun.hatenablog.com

ここらへんは実際に実行に移してみたもののそれがまだいい影響を与えているのかはわからないので、 しっかりフィードバックをもらいつつカイゼンを回していかなければなと思っています。

プライベート

会社ではなかったスタンディングデスクを導入することで立ち仕事が増えたので、このコロナ禍の中で健康面ではむしろ向上してたようです。 健康診断で体脂肪率が17.9%から12.4%に減っていました。 去年から引き続きテニスをやっているのが功を奏したのかもしれません。 テニスに関しては昨年に比べて相当上達したと感じています。

対して人間ドックで初の再検査に引っかかりました。来年再検査ですが、何もないことを祈りますw

あと、膝も負傷しましたね。 運動するときサポートをつけていないとゆるくなってしまって、踏み込めなくなってしまいました。 脱臼したりアキレス腱切ったり、故障はとにかく多い人生ですね。。

そういえば今年見た映画は全部アニメなのですが、全部泣いてしまいました。 最近涙腺がゆるくなってるのかな

まとめ

去年に比べてコロナのせいか1年があっという間でした。 来年はコロナの対策が進むことで情勢は変わるかなと思うので、来年は打破できればよいなと思います。

Rustのstructoptで作ったCLIにシェル補完をつける

引き続きCLIシリーズの紹介です

cliを作ったはいいものの、やはりコマンドのシェル補完はないと厳しいですよね。

structoptで作ったCLIでも簡単に補完のスクリプトを生成できるようになっています。 structoptのベースであるclap側にその機能があり、それをstructoptで呼び出すという感じです。

structopt

早速コードを見ていきましょう。 以下はec2-searchのコードを一部省いて載せています。

use std::io;
use structopt::clap::Shell;
use structopt::StructOpt;

#[derive(Debug, StructOpt)]
struct Cli {
    #[structopt(subcommand)]
    cmd: Command,
}

#[derive(Debug, StructOpt)]
enum Command {
    #[structopt(about = "Prints version information")]
    Version,
    #[structopt(about = "Prints Completion")]
    Completion(CompletionOpt),
}
#[derive(Debug, StructOpt)]
enum CompletionOpt {
    Zsh,
    Bash,
    Fish,
}

#[tokio::main]
async fn main() {
    match Cli::from_args().cmd {
        Command::Version => version(),
        Command::Completion(opt) => match opt {
            CompletionOpt::Bash => completion(Shell::Bash),
            CompletionOpt::Zsh => completion(Shell::Zsh),
            CompletionOpt::Fish => completion(Shell::Fish),
        },
    }
}

fn version() {
    println!("ec2-search {}", env!("CARGO_PKG_VERSION"))
}

fn completion(s: Shell) {
    Cli::clap().gen_completions_to(env!("CARGO_BIN_NAME"), s, &mut io::stdout())
}

Cli::clap() でclapの関数を呼べるようになっているので、これで補完スクリプトを生成する gen_completions_to を呼び出します。 生成したものを標準出力に出したいので、stdoutに吐いています。

実際のコードは以下リンク先です。

github.com

homebrewに対応

brewでインストールさせている場合、tapのスクリプトに以下を設定することでインストール時にシェルのcompletionの設定ができます

 def install
    bin.install 'ec2s'

    # bash completion
    output = Utils.safe_popen_read("#{bin}/ec2s", 'completion', 'bash')
    (bash_completion / 'ec2s').write output
    # zsh completion
    output = Utils.safe_popen_read("#{bin}/ec2s", 'completion', 'zsh')
    (zsh_completion / '_ec2s').write output
  end

この記述は何をしているかというとbashzshの補完スクリプトを各シェルの補完用ディレクトリに保存しています。 実際には以下のようなコマンドを実行しているのと等価です。

bashの場合

$ ec2s completion bash >  /usr/local/etc/bash_completion.d/ec2s

zshの場合

$ ec2s completion zsh >  /usr/local/share/zsh/site-functions/_ec2s

実際のコードは以下リンクです

homebrew-tap/ec2-search.rb at cd8f5e4dc0201a0a670d737a3dde5007ba7ba726 · mocyuto/homebrew-tap · GitHub

ハマったところ

clapには conflicts_with というオプションを複数指定した場合に使っていないオプションを指定していると以下のような実行時エラーが発生します。

$ cargo run completion zsh
   Compiling ec2-search v0.9.1 (/Users/yuto/GitHub/ec2-search)
    Finished dev [unoptimized + debuginfo] target(s) in 26.67s
     Running `target/debug/ec2s completion zsh`
thread 'main' panicked at 'Fatal internal error. Please consider filing a bug report at https://github.com/clap-rs/clap/issues', /Users/yuto/.cargo/registry/src/github.com-1ecc6299db9ec823/clap-2.33.3/src/completions/zsh.rs:346:29
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

denoでも同じようなバグが発生しているので、 conflicts_with を使う場合気をつけましょう。

github.com

以下のように生成部分をテストに含めて壊れないかチェックしておくとよいでしょう。 https://github.com/mocyuto/ec2-search/blob/v0.9.1/src/main.rs#L56-L61