5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

学生LTAdvent Calendar 2018

Day 12

[Qiita] Bash用のLibrary manager作っている -- blib

Last updated at Posted at 2018-12-11

この投稿は学生LT Advent Calendar 2018の12日目の記事です。

学生LTについて、公式Discordから引用させていただきますと

学生LTコミュニティへようこそ!
ここは技術に関心のある学生と様々な交流が出来る場所となっております。

主にはDiscordでの交流、LT会の企画運営参加?などをしています。
Youtube等を使ったオンラインLT会もあるので遠方の方でも参加できます!(みんな割とバラバラな地域の人で構成されています)

学生LT公式HP: https://student-lt.tech/


まだbeta段階ですがちょうどいい機会なので、今作っているbash用ライブラリマネージャー、Cj-bc/blibを紹介します

  • 前半: 使い方
  • 後半: 技術的な話

軽く使い方。

Installation

homebrewに対応しています

$ brew install Cj-bc/blib/blib

また、(個人的には)初の試みとしてMakefileを使ってみたのでそちらでもいけます(いけるはず)

$ git clone https://github.com/Cj-bc/blib
$ cd blib
$ make install

その他対応予定

  • bpkg

使い方

ライブラリのインストール

  1. 該当ライブラリ用のformulaレポジトリが存在することを確認します
  2. blib install <user>/<repo>でインストールできます

この時、<user>/<repo>そのformulaレポジトリの/であることに注意してください。
また、<repo>blib-のプレフィックスを除いた状態で記載してください。

例:

$ blib install Cj-bc/libtar

インストール済みライブラリの一覧取得

$ blib list

bash-oo-frameworklibblibはデフォルトで表示されます(blibで使用するため)

blibライブラリを使用してスクリプトを書くには

たった1行付け足すだけで対応できます

source "$(blib --prefix)/bash-oo-framework/lib/oo-bootstrap.sh"

これでblibのライブラリをimportできるようになりました(勿論、bash-oo-frameworkの各種ライブラリも使用可能です)

blibでインストールされたライブラリをimportする際は、prefix: blib:をつけてください

import blib:libtar

ここから後半

動機

  • コードスニペットを共有して使いたかった
  • source時にパスを考えなければならなかったりして少し面倒
  • 純粋に、同じコードは同じ場所から呼び出したい
  • パッケージマネージャーがあるのにライブラリマネージャーがないのが納得いかん
  • だって楽しそうじゃん

ちなみに、bash用のパッケージマネージャーは幾つか存在します

主な仕様

現状

  • Homebrewライクなライブラリ管理システム。formulaを作成することでライブラリとして認識できるようになる
    • これにより、他者のコードを使うこともできますね!やったね!
  • bash-oo-frameworkimport文を使用してライブラリ読み込み
    • bash-oo-frameworkは標準で使用可能になります。importするだけでお手軽。
  • 内部的にはファイルをsourceしているだけのため、bash-oo-frameworkを用いているものもそうでないものも管理可能
  • 管理者権限のいらないパスにライブラリを保存
  • どの場所からでもblibさえあれば動く!!

現状のコマンド群

$ blib --prefix # ライブラリの格納先
/usr/local/etc/blib/lib
$ blib list # install済みライブラリの一覧
bash-oo-framework libblib
$ blib install <user>/<repo> # github上の<user>/<repo>レポジトリのformulaを探してインストール
$ blib uninstall <library_name> # <library_name>をアンインストール(Cellarからは消えない)

追加予定の仕様

  • ライブラリ情報の表示コマンド
  • バージョン管理
  • ライブラリのドキュメント表示機能
  • blib対応バージョンのbash-oo-frameworkをいつか本家にPR出したい

追加予定のコマンド群

$ blib cleanup # `Cellar`内に残っているcacheを削除する
$ blib switch <library_name> <version> # ライブラリのバージョン切り替え
$ blib init # 冒頭に必要になる文字列を簡略化する(詳細はissueを参照)

実装

おそらくこのツールの実装面の一番の特徴はshellscriptで書かれていること、bash-oo-frameworkを使っていることだと思います。
今回の実装では、以下の機能を使って書かれています:

ライブラリ名 説明
util/class オブジェクト指向で書けるようにする
util/log ロガーの追加
util/tryCatch try-Catch構文を追加
util/exception 例外を追加
UI/Console 標準エラー出力への一律のアクセス
UI/Color 色エイリアスの追加 util/logでエラーが出るため追加

大雑把な実装

大雑把に実装の流れを書いておきます。
その後、実装に際して詰まった部分を書いていきます。

1. blibクラスを作成

静的クラスとしてblibクラスを作成します。
(高速化したい場合、個別に関数を作成した方が良いです)
(この場合、どちらの書き方でも速度以外の違いはありません。多分。)

class:blib() {
  # クラスメゾットを追加します
}

Type::InitializeStatic blib

2. クラスメゾットをいくつか作成

機能ごとにクラスメゾットを追加します(当たり前)
とりあえず必要なものをリストアップ

class:blib() {
  # オプションを取り扱う
  blib::option() {
    :
  }

  # インストール用処理
  blib::install() {
    :
  }

  # アンインストール処理
  blib::uninstall() {
    :
  }

  # インストールされたライブラリの一覧表示
  blib::list() {
    :
  }

  # manコマンド(未実装)
  blib::man() {
    :
  }

  # infoコマンド(未実装)
  blib::info() {
    :
  }
}

Type::InitializeStatic blib

3. 内容に応じて必要なライブラリを開発

本来、blibクラス自体も分けるべきなのですがまだ分けてません(気づいたのが後だった)
blibの依存ライブラリはlibblibにまとめられています。
いずれ汎用性を上げたのち、別途ライブラリを分ける予定でいます。
今回使っているライブラリは二つです

ライブラリ名 説明
formula formulaの検証等するライブラリ
user Githubのユーザーの検証等するライブラリ

4. main関数を書く

別に名前はなんでもいいのですが他に倣ってmain関数を書き、それを実行することにしました。

main() {
  # この中からblibを呼ぶ
  :
}

main $@

これはshellscriptとしてはどうなものかといったものですが、オブジェクト指向的、ということでスルーします。
とりあえずこれで大雑把な流れは終了

困ったところ、詰まったところ、etc

今後の人のリファレンスになればいいなぁというのも思っているので一問一答形式で書いていきます

1. ライブラリインストール先 [WIP]

これに関してはまだあまり詰められてません
今は暫定的なものとなっていますがより良いものがあれば知りたいです。

2. ライブラリはレポジトリごと置いておくか否か

結論: Yes

ライブラリをレポジトリごとおくことにより、バージョン管理が楽になります(git checkoutで行えるので)
(尚、この記事を書いていてタグによるバージョン管理を思いついたので、細部は現状の仕様とは異なります)
(現状の仕様: バージョンごとにディレクトリを分けてクローン)

3. 完全なアンインストール処理にrm -rfを使って良いか否か

結論: 使う

(ここでの「完全なアンインストール」というのは、blib cleanupとして実装予定の機能で、Cellar内も消去します)
ライブラリがgitレポジトリである以上、.gitを消去しないといけなくなるため、結局強制的にrm -rf`を使うことになります。
なので元から使ってしまおうということです。

4. classからの例外が捕捉できない [BUG]

これは明確なバグです
正確には、classから例外が返ってきていないようです。
bash-oo-framework本家にもissueが上がっています。
* niieani/bash-oo-framework
鋭意捜査中ですがまだ治ってません。

5. mainから存在しないはずの例外が返ってくる [BUG]

結論: おそらく4.のバグ
対処: main呼び出し元もtryCatchで囲む。

6. mainをtryCatchで囲むと、main関数の戻り値(=プログラムの戻り値)が戻らず、常に0になってしまう

対処: main呼び出し元を囲むtryCatchにて、mainの戻り値を例外として投げる

main関数からの例外は基本的に存在しないはずなため、緊急策としてmainの戻り値を変数に格納して例外として送出、それをそのままプログラムの戻り値として設定。

[2018-12-12]@ Qiita 学生LT Advent Calendar参加日

[2018-12-02 08:45]

5
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?