本日は
TerminalGat.jl の紹介です gat という Go で実装された cat コマンドの代替ツールを Julia の REPL から使えるようにしました.gat の本家は以下のリンクから行けます.
less の対応物に相当する gess コマンドも使えるようになっています.
gess という名前は実は私が思いついたものを gat の著者が実現してくださったという背景が実はありました.普段から使っててこれを REPL で動かしたら便利だよなぁーっと思って数ヶ月経ちました.重い腰を上げてようやく General レジストリに登録することができました.
Install
Julia の REPL を開いて下記のように実行します.
julia> using Pkg; Pkg.add("TerminalGat")
ユーザは gat コマンド自身はインストールは不要です.
使い方
Go 実装の README.md を読みましょう.
それで心が踊ったら Julia 版を試してみましょう.
julia> using TerminalGat
julia> gat("file.jl") # ファイルを表示,色は Monokai テーマで表示される
julia> gess("longfile.jl") # less longfile.jl のカラフル版
julia> gat("README.md") # markdown ファイルをレンダリングする
julia> gat(@doc sin) # Julia の Markdown.MD オブジェクトも表示可能
julia> gat("image.png") # Sixel サポートしている
julia> gat("image.jpg") # PNG と JPEG は対応
TerminalGat.jl のソースコードは以下にあります.
gat コマンドが事前にインストール不要な理由
TerminalGαt.jl をインストールすると Julia パッケージとして gat_jll.jl というのがインストールされます.この gat_jll.jl がビルド済み gat コマンドをインストールしてくれます.つまり Julia 以外の実行形式をあたかも Julia のパッケージをインストールするように利用することができるのです.この仕組みを持っているのが Julia の強みの一つでありいます.
gat_jll.jl が提供する gat はどこからくるの?
gat_jll.jl は下記のリンクにあるレシピファイル(Juliaスクリプト)をもとに作られます.
using BinaryBuilder
name = "gat"
version = v"0.19.1"
# Collection of sources required to complete build
sources = [
GitSource("https://github.com/koki-develop/gat.git", "173737297556cbcdf6c1e3145ae8baa1c4a68bdf")
]
# Bash recipe for building across all platforms
script = raw"""
cd ${WORKSPACE}/srcdir/gat
go build -o "${bindir}/gat${exeext}"
"""
# These are the platforms we will build for by default, unless further
# platforms are passed in on the command line
platforms = supported_platforms()
# The products that we will ensure are always built
products = [
ExecutableProduct("gat", :gat)
]
# Dependencies that must be installed before this package can be built
dependencies = Dependency[
]
# Build the tarballs, and possibly a `build.jl` as well.
build_tarballs(ARGS, name, version, sources, script, platforms, products, dependencies; julia_compat="1.6", compilers = [:go, :c])
やっていることは次のとおりです.
-
sourcesで指定したソースコードを入手(gatをビルドするためのソースコードを入手) -
scriptに基づいてgatプロジェクトをビルド.これにより実行形式としてのgatを作ることができます.この時ビルドする環境は Docker のコンテナ内で行われるのでローカル環境でデバッグする際はホストマシンはJuliaとDockerさえあればOKです. - Windows, macOS, Linux の幅広いプラットフォームで
gatをビルドしてくれます.(platforms = supported_platforms()) -
gat_jll.jlはgatコマンドを提供します.productsに対応, - ソースコードをビルドするためにもちろん Go が必要なので
compilers = [:go, :c]を指定します.
Go に限らず Rust のコンパイラも利用できるので Rust で作られた便利なCLIツールやライブラリの共有ライブラリがあればそれをレシピファイルとしてプルリクを出せば Julia の人は喜びます.
Yggdrasil および BinaryBuilderは apt-get install ..., brew install, winget install ... のようなパッケージマネージャの Julia に相当するものです.Yggdrasil はレシピの集まり,BinaryBuilderはレシピから生成物を作成する仕組みを持っています.OS,プラットフォームごとに異なる事前準備を踏まず,「Pkg.add すれば必要なものが降ってきて Julia のパッケージを利用できる!」ということが可能になっています.
gat_jll.jl を作った流れ
「Pkg.add すれば必要なものが降ってきて Julia のパッケージを利用できる!」と言いましたが,レシピはJulia コミュニティの方がコントリビューションしています.gat_jll は元からある訳ではなかったので自分で作る必要がありました.
ローカルで確かめる
PR を出す前に BinaryBuilder v0.5 系をインストールして前述のレシピファイルを build_tarballs.jl という名前で保存します.
julia build_tarballs.jl
これでまずビルドができるかを試行錯誤します
レシピファイルを追加する
レシピファイルを追加するプルリクエストを作成します.
gat 自体は MIT ライセンスで公開されてるものですが Yggdrasil にレシピを登録するのは初めてだったので,一応念の為, gat 側の Issue を立てて Julia のコミュニティのエコシステムに取り入れる許可をもらいました.他のPRを見てると Deno v2.0 を入れてたりするので(ライセンスの許す範囲で)思ったよりも好き勝手に突っ込んでる印象があります.
いくつか細かい suggestion をもらいましたが,とりあえず言われるまま,suggestion を受け入れて細かい変更のやり取りがありました,が,ほぼ一瞬で終わりました.
導入の背景を書いておくとレビューワはすんなり通してくれる印象があります.
Yggdrasil でのPRがマージされると
ここからは General というリポジトリに自動的にPRが発行されます.
これはほぼ形式的なもので Pkg.add("gat_jll") が可能になるための仕組みとして General というレジストリがあり,そこに登録する儀式を行ってると理解すればOKです.
20分のサイクルで自動的にマージされます.思ったよりもシンプルでびっくりしました.
TerminalGat.jl の登録
(みんなにも使ってもらいたい価値があるものであると信じて) General レジストリに登録をします.
の説明文を読んで登録作業をします.GitHub App からボットを使って命令するか JuliaHub のページから手動で登録の手順を行う二通りの方法があります.ソースコードがGitHubで登録されていれば GitHub App の方が簡単です.
ここからは人間は何もする必要はありません.事前にローカルのテストが通っている,README.md にパッケージの概要が書いてある,ネーミングのガイドラインを守っているなどなどをしていれば特に言われることはないです.
3日間待ちます.3日間待つのは,その間に人間のレビューワーが「このパッケージはなんだろう,このパッケージはマトモなものか?,README.md がなかったら流石にまずいだろ,説明ぐらいつけろ」という判断のための待機時間です.この期間はひたすら待ちます.寝ましょう.
この記事が出ていることには Pkg.add("TerminalGat") で利用できるようになるはずです.ぜひ使ってくださいね.Go,Rust 系のCLIツールで有用なものがあれば(ライセンスの許す範囲で)登録していくのもありかなと感じました.
ちなみに gh_jll.jl というのもあり gh コマンドが使えるようになります.これで gh auth login を Julia のスクリプトとして実行・GitHub API を gh コマンドで使う操作をJuliaスクリプトとして行うといったことができるようになります.最初はやや違和感があると思いますが,Julia というのを高級なシェルスクリプトとして割り切ればまぁ,そういうのもあるよな・みっけたラッキーぐらいの気持ちになっていくと思います.
最後に
gat 作っていただきありがとうございました.
結構面白いものを作っていらっしゃるので皆さんも眺めてみてください.