Gauche:パッケージ管理
(Shiro:2023/12/26 05:30:21 UTC) 遅きに失した感はあるけど、むしろ待ったおかげでシンプルになった面はあるかもしれん。
- 今やリポジトリがGitHubやGitLabで公開されてて、そこの
package.scm
を見ればメタデータが取れるんだから、「パッケージのidentity≡リポジトリURL」で良くね? - そしたら自前でパッケージ管理者のユーザデータベースを管理する必要もなくなる(リリースの権限とかは全部リポジトリ管理者の管轄になる)。こちらとしては単にリポジトリURLのリストを持っておくだけでメタデータ引っ張ってきてリスト作れる。
- 依存関係の部分だけ、今パッケージ名を書いてるところをURL推奨にしないと。パッケージ名→URLの対応は誰もが勝手に変えられるとまずいので、そこだけ権限を持たせた管理グループを作るか、いっそ今後は全部URLでってことにする。
- 何を以って正式リリースのトリガとみなすか、のプロトコルを決める必要があるな。タグを見るのが一番手軽か。
(元Rubyist) エンドユーザ&アマチュア開発者の目線ですが、依存関係部分も含めてパッケージ名はパッケージ名として扱われているとわかりやすいのかなと思いました。
- Rubyの場合、package.scm相当はmy_package.gemspecになり、パッケージの情報記述します。ランタイムやインストールの際に必要なパッケージの情報が記述されています。
- それ以外に、Bundler https://bundler.io/guides/gemfile.html[ ] という元々サードパーティーの仕組みもあり、プロジェクトとしてプログラムを配布する際に、そのプロジェクトを動かすのに必要なパッケージのリストをGemfileに記述、そのプロジェクトのみで有効な、バージョン指定含めたパッケージをローカルディレクトリにインストールすることができます。 なおここで言うプロジェクトは、ディレクトリの下にファイルやサブディレクトリで構成された任意の構成を指しています。
- パッケージと同じ構成であれば、プロジェクトとして開発しつつパッケージとして公開することも可能です。その場合、my-package.gemspecには、ランタイムやインストールの際に必要なパッケージ、Gemfileには開発の時必要なパッケージが記述されることになります。
# Bundlerが参照するGemfileの例 source "https://rubygems.org" gemspec # Gemfile内からランタイムで必要なパッケージの情報を取得 gem 'nokogiri' gem 'rails', '5.0.0' # 5.0.0 指定 gem 'rack', '>=1.0' # 1.0 以上 gem 'thin', '~>1.1' # 1.1 以上、2.0 未満 gem 'my_gem', '1.0', :source => 'https://gems.example.com' # rubygems.org 以外からインストール
- Bundlerのような機能は今回のパッケージの話より後の話になると思いますが、パッケージ名の指定は、エンドユーザーの目に触れる部分になるため、わかりやすい・読みやすい方がよいのかなと思い投稿しました。
Shiro(2024/01/03 20:51:51 UTC): 記述的なパッケージ名がわかりやすい、というのは同意なんですが、 ユーザアカウント作って登録してもらう形だと、長くやると連絡が取れなくなるユーザが出てきて 片手間で運用するには面倒だな、というのが一番大きな理由です。
が、リポジトリインデックスサイトにリポジトリURLを登録したら、package.scmから自動的に リポジトリ名を引っ張ってきてインデックスを作る、というのでもいけるかもしれません。 重複があったら登録時に弾く。開発が止まって、後継がforkされて開発継続した場合、 元のpackage.scmに引き継ぎ先を明記してもらえばインデックスも更新される。 これならユーザ管理せずにパッケージ名とリポジトリを安全に管理できそう。
(元Rubyist) 参考になるかわかりませんが、R言語にはパッケージを管理しているCRANというサイトがありまして、定期的に全パッケージが自動でチェックされていて、例えばC拡張のコンパイルの際にWarningがでていると自動でメールで連絡がきて、期日(3週間程度)までに解決できないと、Archiveされてしまうという仕組みがあります (そもそも初回登録の際に人のチェックが入ってWarningやドキュメント不足があると修正を求められますが、CRANの標準gccがバージョンアップした時などに登録済みパッケージに新規でWarningが発生するときがあります)。パッケージ作者と連絡が取れなくなって困るのは、必要な修正が行われない時かなと思いましたが、ある基準をつくって対応がなければArchiveするという方法もあるという話でした。参考になりましたら幸いです。
Shiro なるほど。人手が少ないのでなるべく人間による管理の手間を避けたいというのが 一番大きいんですが、自動で回して連絡取れなくなったらフラグ立てるというのは可能性としてありますね。
昔の議論
(Shiro:2016/01/05 03:41:04 UTC) パッケージ管理機能についてのメモ。
欲しいもの: 必要なライブラリを書いとくと、依存するものまで自動的に引っ張ってきてよきにはからってくれる機能
もともとの目論見としては、dpkgやrpmのような既存のパッケージマネージャが既にそういう機能を持ってるので、重複して開発するよりそっちに乗っかる方がいいかなと思ってた。のだが、
- 既存のパッケージマネージャはパッケージを作る必要がある
- コンパイルが必要なものの場合、パッケージ作成者が各種ビルド環境にアクセスできないとならない
- パッケージマネージャごとにパッケージを作らないとならない
これをライブラリ作成者にやってもらうのは難しい。
他の言語処理系を見ても、自前でやるのがトレンドっぽい。
(ポータブルなSchemeならsnowに乗っかるという手があるが、Gauche専用だと別に持つ方がよいだろう)
必要な機能:
- ストレージやネットワークは持ちたくないので、そのへんはgithubあたりに任せて、ポインタだけを管理する。
- 勝手に引っ張ってくるものだから最低限の安全性は欲しい。ライブラリ作成者がアカウント作って自分のライブラリを登録してく形
- パッケージ作成のために一手間かけるのはハードルになるので、ソースツリーのtarballそのまま引っ張ってきて手元でビルド/インストールできるのがよい。
- メタデータの統一仕様を決めとく。それをソースのトップに置いとけばあとは自動的に。
メタデータ
できればsnowのとある程度コンパチにしたいけど、引っかかりそうなところ
- パッケージ名・バージョン名の縛り: snowはパッケージ名に
#/[a-z_-][a-z0-9_-]*/
の縛りがある。- githubとつなげるならgithubのリポジトリ名と揃えられた方がいい
provide
にAPIを列挙する必要がある- メタデータとしてあった方がいいのはわかるんだけど、ライブラリ作る側としては面倒
- r7rsのライブラリ形式のようにある程度型があれば自動抽出できなくはない。が、その場合、配布物を作るのにワンステップ余分に必要になる
メタコマンド
lein
とかgo
みたいに、パッケージ管理じゃなくビルドやテスト、実行までの
面倒を見るコマンドがあると、とっつきとして導入しやすい。lein
みたいにひとつファイル
落として実行したら処理系のインストールや更新までやってくれる、というのも良い。
ただ、今はGaucheで何かするときにとりあえずgosh
と打つ、ってことになってて
この名前は結構気に入っている。goshの上に来るメタコマンドを作るとして、新たなトップレベルの
名前を導入するのが難しい。gauche-package
みたいに長い名前だと常用するのはきつい。
覚えることを減らすなら、コマンドはgosh
で統一し、gosh get
だの
gosh package
だのサブコマンドで何かする方が最近の流れには沿ってる気がする。
これはget.scm
やpackage.scm
を標準で用意しとけばいいだけなので
簡単にできるんだが、gosh
をメインコマンドにする場合、gosh
自身の
インストールとアップデートをどうやるか、というのが問題になる。
- goshを含むGauche実体のインストール、アップデートは従来どおりの方法
(untar+configure+make+make install、もしくはディストリビューションのパッケージマネージャ)で行い、パッケージ+依存性管理はgoshのサブコマンドで行う
- 現状の延長としては一番妥当。ただし、複数のGaucheバージョンの共存と切り替えをやりたい、などと言った話はgoshコマンドの外の話になってしまうので都度「上」のレイヤに来る仕組みを作る必要がある。
- goshをメタコマンドに変更し、スクリプト名が与えられなかった場合にサブコマンドとしてreplを起動する。
- leinみたいにgoshをシェルスクリプトにしておけば、「とりあえずgoshだけ落としてgosh installしてもらえばいい」ってことができるし、複数バージョンの共存と切り替えもgoshのレベルでディスパッチすれば良い
- 一段クッションを噛ませることになるので、goshでスクリプト起動している場合のオーバヘッドが嫌。
- goshに現在のrepl機能とメタディスパッチ機能を両方持たせる。最初のインストールだけは別にやってもらうが、一度goshが走ったら、新しいバージョンのインストールとか複数バージョンの切り替えはgoshで行えるようにする。
- ちょっとアクロバティックではあるけど、Gaucheの機能の本体は
libgauche.so
にあるわけで、実行時にどのバージョンのDSOを使うか選択することはできる。つまり、goshと打って起動されるのはPATH上にあるgoshコマンドでそれは多分最新のものだけど、環境変数なりオプションなりでどのバージョンのlibgauche.so
をロードするか決めてdlopenして制御を渡す。 - dlopenまわりの抽象化はlibgaucheとは独立して持たないとならないのでややごちゃごちゃするけど、gosh本体はlibgauche.soに(ld.soの意味で)依存しないので自由度は増す。
- あーでもlibgauche.soをdlopenすると、拡張モジュールはそこからさらにdlopenすることになるな。多段dlopenはOSによる差異が面倒だったような気が。
- ちょっとアクロバティックではあるけど、Gaucheの機能の本体は
ディスカッション
- skimu: .gpd に入る情報がもう少し増えたらいいなと思ってました。例えば、インストールされたファイルの一覧があればtarballがなくなってもアンインストール出来るし、オリジナルライブラリの URL もあると、そのライブラリの近況が分かって便利かも。(2016/01/05 06:15:26 UTC)
- skimu: 例えば、lalr を僕が Gauche 用にパッケージングするみたいな状況を考えてます。
- Shiro: gauche-installを加工すればインストールされたファイル一覧は自動生成できるかも。URLとかについては、各パッケージのメタデータに書いといてそれをgpdにマージするってのを考えてます。2016/01/05 18:22:32 UTC