Julia - 野良パッケージをパッケージ名だけで追加できるようにする: Custom General Repository の作り方

Julia でパッケージを追加する場合、pkg mode で

(v1.0) pkg> add Example

などとすれば良いですよね、公式パッケージ*1の場合は。

野良パッケージの場合は次の例のように github の URL を打ち込まないといけません。

(v1.0) pkg> add https://github.com/goropikari/MyPackage.jl

パッケージ名だけならともかく URL を打ち込まないといけないというのは面倒です。公式パッケージ同様パッケージ名だけで追加したいと思うのは当然の願いでしょう。

この記事では Custom General Repository を作り、公式パッケージ同様 野良パッケージもパッケージ名だけで追加できるようにする方法を紹介します。

f:id:goropikarikun:20180922212714p:plain 上手くいくとこんな感じで野良パッケージがパッケージ名だけで追加することができるようになります。

目次

環境

  • OS: ArchLinux
    OS 依存する内容ではありませんが、Linux コマンドを使っているので適宜脳内変換してください。
  • Julia 1.0

Custom General Repository

Custom General Repository とは?

Custom General Repository とは何か?と普通の人なら思うでしょう。無理もありません、便宜上私がそう呼んでいるだけですから。

Julia 0.x 時代のパッケージマネージャーはパッケージの情報を METADATA から参照していましたが、Julia 1.0 からは METADATA に変わり General を参照するようになりました。

それで、これから我々がやろうとしていることを Julia 0.x 時代は Custom METADATA Repository と呼称していたので Custom General Repository としただけです。

github.com

github.com

Custom General Repository を作るメリット

現状の Julia では、パッケージ名で追加できるパッケージ公式パッケージ は同値です。

しかし、以前の記事にも書きましたが、公式パッケージにするためには README を英語で書いて、やりとりも英語でしなければならないので、非ネイティブな我々日本人にとってはハードルが高いものになっていることも事実でしょう。 おまけにレビュー付きなので「ちょっと練習がてら空のパッケージ登録をしてみよ」なんてことも出来ません。

goropikari.hatenablog.com

また、ローカルのコミュニティでしか使わないパッケージを運用したい場合や、" 田中コレクション " といった独自のパッケージ群を提供したい場合なども公式パッケージに登録することは適しているとは言えないでしょう。

そんな時に便利なのが Custom General Repository です。これを作ることによって自分たちの裁量によって野良パッケージを自分の General に登録することができ、公式パッケージ同様にパッケージ名だけでパッケージを追加することができるようになります。

Youtuber の 「チャンネル登録はこちら」ではありませんが、「私のパッケージ群を使いたい場合はこの URL を git clone♪」とするだけで他の人たちは気軽にあなたのパッケージを使えるようになります。

Custom General Repository を作る

以下の内容は私が実験しながら模索した方法であり、公式のやり方ではありません。そもそも、公式ドキュメントに独自の General を作るやり方は 2018/9/22 現在書いてありません*2

先にどんなものなのか試したい人は MyGeneral を配置する を読んでください。

まずはご自身の github にパッケージを管理するためのリポジトリを作ってください。ローカルネットワーク内のディレクトリなどでも良いのですが、わかりやすさのため今回は github で作ります。リポジトリの名前は何でもよいですが、ここでは MyGeneral としました。

以下はこの MyGeneral に私の野良パッケージ GameOfLife.jlMyPackage.jl を登録するまでの流れです。先頭が $ から始まるものは bash での操作を表します。

作ったリポジトリをクローンしてきて必要なファイルを作っておきます。

$ git clone https://github.com/goropikari/MyGeneral.git
$ cd MyGenaral
$ touch Registry.toml

$ mkdir GameOfLife
$ cd GameOfLife
$ touch Compat.toml Deps.toml Versions.toml Package.toml

Registry.toml の中身はこんな感じ。

name = "MyGeneral"
uuid = "0d136408-be1b-11e8-146b-1b5bc37d4128"
repo = "https://github.com/goropikari/MyGeneral.git"

[packages]
b53c8852-a93e-11e8-3341-5bdef8841476 = { name = "GameOfLife", path = "GameOfLife" }

name を作ったリポジトリMyGeneral にする。

uuid は適当に generate MyGeneral して出てきたものを使いました。

(v1.0) pkg> generate MyGeneral
Generating project MyGeneral:
    MyGeneral/Project.toml
    MyGeneral/src/MyGeneral.jl

shell> cat MyGeneral/Project.toml
authors = ["goropikari <goropikari56@gmail.com>"]
name = "MyGeneral"
uuid = "0d136408-be1b-11e8-146b-1b5bc37d4128"
version = "0.1.0"

[deps]

repo にはリポジトリがある URL を入れてください。

続く [packages] の項目ですが、初めの謎の文字列は GameOfLife.jlProject.toml に記載されている uuid です。path には GameOfLife.jl の情報が書かれているファイル*3がある場所を指します。今は MyGeneral の直下に置いたので ./GameOfLife となっています。

現在のディレクトリ構成

MyGeneral/
├── GameOfLife
│   ├── Compat.toml
│   ├── Deps.toml
│   ├── Package.toml
│   └── Versions.toml
└── Registry.toml

続いて Compat.toml, Deps.toml, Versions.toml, Package.toml に必要な情報を書いていきます。

Deps.toml

GameOfLife.jlProject.toml[deps] に書いてあったものをそのまま書きます。 最初の ["0.1"]GameOfLife.jl のバージョン 0.1.0 の意味です。 要するに GameOfLife.jlのバージョン x.x.x はこれらのパッケージに依存してますよ〜と書かれているのが Deps.tomlです。

["0.1"]
REPL = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb"

Versions.toml

GameOfLife.jl の tree オブジェクト の SHA-1ハッシュ を書きます。

["0.1.0"]
git-tree-sha1 = "0ea24bdd852ad9505eab96815e6f2c4dadffc018"

ハッシュ値は GameOfLife.jl パッケージ本体*4ディレクトリ上で

$ git cat-file -p HEAD
tree 0ea24bdd852ad9505eab96815e6f2c4dadffc018
parent 2f5c85c856f67d2db3152801507f30b640a83849
author goropikari <goropikari56@gmail.com> 1535299189 +0900
committer goropikari <goropikari56@gmail.com> 1535299189 +0900

とすると調べることができます。

Compat.toml

対応している Julia のバージョンなどを書きます。Pkg.jl のドキュメント に書いてある方法に従えば良いと思いますが、当面は以下のように書いておけばよいでしょう。

["0.1"]
julia = "0.7-1.1"

Package.toml

パッケージの情報を書きます。uuid は Project.toml に書いてあるものを書きます。 repo にはパッケージが置いてある github URL を書いておきます。

name = "GameOfLife"
uuid = "b53c8852-a93e-11e8-3341-5bdef8841476"
repo = "https://github.com/goropikari/GameOfLife.jl.git"

push する

MyPackage.jl の方も同様にして追加し、github に push します。

$ git add -A
$ git commit -m 'first commit'
$ git push

MyGeneral を配置する

作った MyGeneral~/.julia/registries に配置します。

$ julia -e 'using Pkg; Pkg.update()'
$ cd ~/.julia/registries
$ git clone https://github.com/goropikari/MyGeneral.git

Julia を起動し、パッケージ情報をアップデートするといつもの https://github.com/JuliaRegistries/General.git に加えて https://github.com/goropikari/MyGeneral.gitも読みにいっていることがわかります。

(v1.0) pkg> up
  Updating registry at `~/.julia/registries/General`
  Updating git-repo `https://github.com/JuliaRegistries/General.git`
  Updating registry at `~/.julia/registries/MyGeneral`
  Updating git-repo `https://github.com/goropikari/MyGeneral.git`
 Resolving package versions...

(v1.0) pkg> add GameOfLife
 Resolving package versions...
 Installed GameOfLife ─ v0.1.0
  Updating `~/.julia/environments/v1.0/Project.toml`
  [b53c8852] + GameOfLife v0.1.0
  Updating `~/.julia/environments/v1.0/Manifest.toml`
  [b53c8852] + GameOfLife v0.1.0
  [2a0f44e3] + Base64 
  [b77e0a4c] + InteractiveUtils 
  [8f399da3] + Libdl 
  [37e2e46d] + LinearAlgebra 
  [d6f4376e] + Markdown 
  [3fa0cd96] + REPL 
  [6462fe0b] + Sockets 

(v1.0) pkg> add MyPackage
 Resolving package versions...
 Installed MyPackage ─ v0.1.0
  Updating `~/.julia/environments/v1.0/Project.toml`
  [f41f8282] + MyPackage v0.1.0
  Updating `~/.julia/environments/v1.0/Manifest.toml`
  [f41f8282] + MyPackage v0.1.0
  [9a3f8284] + Random 
  [9e88b42a] + Serialization

julia> using MyPackage
[ Info: Precompiling MyPackage [f41f8282-a16f-11e8-2120-1f4619698387]

julia> MyPackage.greet()
Hello World!

無事に野良パッケージをパッケージ名だけで追加することに成功しました。 他の人の Genaral も ~/.julia/registries にクローンしてくれば同様にパッケージを追加することが出来ます。また、初回の git clone 以降はパッケージマネージャーが pull してきてくれます。

ちなみに

公式パッケージの情報が入っている ~/.julia/registries/General を消すと、パッケージマネージャーは自分のリポジトリしか見に行かなくなるので、世間から切り離された孤独感を味わうことが出来ます。

$ rm -rf ~/.julia/registries/General
$ julia -q
(v1.0) pkg> up
  Updating registry at `~/.julia/registries/MyGeneral`
  Updating git-repo `https://github.com/goropikari/MyGeneral.git`
 Resolving package versions...
  Updating `~/.julia/environments/v1.0/Project.toml`
 [no changes]
  Updating `~/.julia/environments/v1.0/Manifest.toml`
 [no changes]

おわりに

以上 Custom General Repository の作り方の紹介でした。お疲れ様でした。

この記事の内容を使えば、公式パッケージにしなくてもパッケージ名だけで追加できるようになりますが、みなさんには是非公式パッケージ作りにチャレンジしていただきたいです。

Julia 1.0 がリリースされてから、Julia を「使ってみた」といったコメントは目にするようになりましたが、「パッケージを作った」という報告は全然目にしない気がします。野良パッケージですらその状況なので公式パッケージではなおのことです。
私も他の方のパッケージ作りに興味がありますし、まだまだわからないことも多いので情報を共有していただけると嬉しく思います。

この記事で使った MyGeneral 等は以下です。必要ならばご自由にご覧ください。*5

github.com

github.com

github.com

*1:ここでは METADATAに登録されているものを公式パッケージ、されていないものを野良パッケージと呼ぶこととします。

*2:多分

*3:Compat.toml, Deps.toml, Versions.toml, Package.toml があるディレクトリ。

*4:MyPackage 中のディレクトリでない

*5:人に胸を張って見せられるようなコードではありませんが。