この記事は SATySFi Advent Calendar 2019 12日目の記事です。前日は @amaoto017 さんの『SATySFi上で構文定義可能なシンタックスハイライト(の宣伝)』です。次日はしょうだいさんです。
用語
本記事では、以下の用語を使用します。
語 | 定義 |
---|---|
SATySFi パッケージ |
packages/ 以下に置かれた *.satyh ファイルや *.satyg ファイル等。 |
ライブラリ・Satyrographos ライブラリ | SATySFi パッケージやフォントファイル等を纏めた配布物。 |
OPAM パッケージ | OPAM によって管理される配布物の単位。ライブラリに相当。 |
OPAM パッケージと SATySFi パッケージは名前が紛らわしいので気を付けて下さい。
新しいライブラリを書いたら
SATySFi 用のライブラリは専ら以下の要素で構成されます1。
-
packages/
ディレクトリ以下に配置された*.satyh
ファイルや*.satyg
ファイル -
fonts/
ディレクトリ以下に配置されたフォントファイル -
md/
ディレクトリ以下に配置された*.satysfi-md
-
hash/fonts.satysfi-hash
に追加されたエントリ - ライブラリのドキュメント
名前を決めましょう!
ライブラリを書いたら(書く前でも無問題なのですが)、名前を決めましょう。
名前の付け方
Satyrographos ライブラリ名は、今のところ以下の命名を推奨しています2。 satysfi- は付けないで下さい。
種類 | 名 | 備考 |
---|---|---|
フォントライブラリ | fons-* |
フォントファイルを含むライブラリ。例:fonts-theano
|
クラスライブラリ | class-* |
document 関数を含むライブラリ。例:class-exdesign
|
他 | * |
その他。例:zrbase , base
|
ライブラリのインストール時に使われる OPAM パッケージ名は Satyrographos ライブラリ名に satysfi-
を前置したものになります3。例えば、base
という名のライブラリの OPAM パッケージ名は satysfi-base
です。
名前の使われ方
Satyrographos ライブラリを利用する際にライブラリ名/
を前置することになります4。
例えば、math-constant ライブラリとして circular.satyh
を配布する時、使用する側では math-constant/circular
を @require
します。
module Circular = struct
let pi = 3.1415926535897932384626433832975
let tau = 6.283185307179586476925286766559
end
@require: math-constant/circular
また、SATySFi フォント名には fonts-ライブラリ名:
を前置して下さい。SATySFi-fonts-theano からの例を以下に示します。
{
"fonts-theano:TheanoDidot":
<"Single":{"src-dist":"fonts-theano/TheanoDidot-Regular.otf"}>,
"fonts-theano:TheanoModern":
<"Single":{"src-dist":"fonts-theano/TheanoModern-Regular.otf"}>,
"fonts-theano:TheanoOldStyle":
<"Single":{"src-dist":"fonts-theano/TheanoOldStyle-Regular.otf"}>
}
ビルドファイルを書きましょう!
現状、ライブラリ依存関係解決やネットワークからのデータ取得には OPAM を用いているために、Satyrographos 用のビルドファイルと OPAM パッケージファイルを両方書く必要があります……(解決する方法は模索中)。
Satyrographos 用のビルドファイル(Satyristes)
Satyrographos 用ビルドファイル Satyristes
は S 式で記述します 5。
概観するとこんな感じです。
(version 0.0.2) ; Satyrographos 0.0.2 系列向け
(library ; ライブラリ宣言
(name "great-library") ; ライブラリ名
(version "1.0") ; ライブラリバージョン
(sources ; ファイル
(;; ./interesting-font.ttf を dist/fonts/interesting-font.ttf に配置
(font "interesting-font.ttf" "./interesting-font.ttf")
;; ./fonts.satysfi-hash を dist/hash/fonts.satysfi-hash に追記
(hash "fonts.satysfi-hash" "./fonts.satysfi-hash")
;; ./def.satyh を dist/packages/great-library/abc/def.satyh に配置
(package "abc/def.satyh" "./def.satyh")
;; ./ghi.satyh を dist/packages/great-library/ghi.satyh に配置
(package "ghi.satyh" "./ghi.satyh")
;; ./grc.satysfi-hyph を dist/hyph/grc.satysfi-hyph に配置
(file "hyph/grc.satysfi-hyph" "./grc.satysfi-hyph")))
(opam "satysfi-great-library.opam") ; OPAMパッケージファイル
(dependencies
(;; fonts-theano ライブラリに依存(バージョン指定無し)
(fonts-theano ())))
(compatibility ; 互換性警告
(;; パッケージ <old-name> が <new-name> に変更されたことを使用者に警告
(renamePackage "<new-name>" "<old-name>")
;; フォント <old-name> が <new-name> に変更されたことを使用者に警告
(renameFont "<new-name>" "<old-name>"))))
OPAM パッケージファイル
OPAM パッケージファイルは satyrographos-ライブラリ名.opam
という名前で作って下さい。
OPAMファイルは記法がややこしいので、作成・更新後に opam lint *.opam
を実行し、エラー・警告が出ないか確認することを奨めます。
# satysfi-great-library.opam
opam-version: "2.0"
# OPAM パッケージ名
name: "satysfi-great-library" # satysfi- + ライブラリ名
version: "1.0"
synopsis: "A Great SATySFi Library"
description: """
Brilliant description comes here.
"""
maintainer: "Your name <email@example.com>"
authors: "Your name <email@example.com>"
license: "LGPL-3.0-or-later" # お好きなライセンスを
homepage: "<product home page>"
bug-reports: "<product issue tracker>"
dev-repo: "<repo url>"
depends: [
"satysfi" {>= "0.0.5" & < "0.0.6"}
"satyrographos" {>= "0.0.2.6" & < "0.0.3"}
"satysfi-dist"
# もし他のライブラリに依存している場合には、
# OPAMパッケージ名とバージョン制約をここに記述して下さい
"satysfi-fonts-theano" {>= "2.0+satysfi0.0.3+satyrograhos0.0.2"}
]
build: [ ]
install: [
["satyrographos" "opam" "install"
"--name" "great-library" # ライブラリ名
"--prefix" "%{prefix}%"
"--script" "%{build}%/Satyristes"]
]
例:
- クラスライブラリ ExDesign
- フォントライブラリ SATySFi-fonts-theano
ドキュメント
また、libraryDoc
節を Satyristes ファイルに追加(+対応するOPAM ファイルも追加)することで、ライブラリのドキュメントをビルドすることもできます。
**実際の例を盛り込んだドキュメントを作ることを強く推奨します。**ドキュメントライブラリは SATySFi 本体や他ライブラリ更新時にビルドが壊れないか検証されるため、破壊的変更の影響を受けづらくなります。
libraryDoc
節は将来的に library
節に統合されるかもしれません。
(libraryDoc ; ライブラリドキュメント宣言
(name "great-library-doc") ; ライブラリ名 + "-doc"
(version "1.0") ; ライブラリバージョン
(workingDirectory "doc") ; ビルドコマンドを実行する為の作業ディレクトリ
(build ; ビルドコマンド
(;; make に引数 "-f" "build.make" を与えて起動
(make "-f" "build.make")
;; SATySFiで処理
(satysfi "great-library.saty" "-o" "great-library.pdf")))
(sources ; ファイル
((doc "great-library.pdf" "doc/great-library.pdf")))
(opam "satysfi-great-library-doc.opam") ; OPAMパッケージファイル
(dependencies ; 依存関係
((great-library ())
(exdesign ()))))
ビルドコマンドには (make 引数…)
と (satysfi 引数…)
が使えます。依存関係に書かれているライブラリを自動で準備してから satysfi コマンドを実行します。
対応する OPAM パッケージファイルは以下のようになります。
opam-version: "2.0"
# 対応するライブラリ名 + "-doc"
name: "satysfi-great-library-doc"
version: "1.0"
synopsis: "Document of A Great SATySFi Package"
description: """
Brilliant description comes here.
"""
maintainer: "Your name <email@example.com>"
authors: "Your name <email@example.com>"
license: "LGPL-3.0-or-later"
homepage: "<product home page>"
bug-reports: "<product issue tracker>"
dev-repo: "<repo url>"
depends: [
"satysfi" {>= "0.0.5" & < "0.0.6"}
"satyrographos" {>= "0.0.2.6" & < "0.0.3"}
# satysfi- + ライブラリ名
"satysfi-great-library" {= "%{version}%"}
# もし他のライブラリに依存している場合には、
# OPAMパッケージ名とバージョン制約をここに記述して下さい
"satysfi-exdesign"
]
build: [
["satyrographos" "opam" "build"
"--name" "great-library-doc" # ライブラリ名 + -doc
"--prefix" "%{prefix}%"
"--script" "%{build}%/Satyristes"]
]
install: [
["satyrographos" "opam" "install"
"--name" "great-library-doc" # ライブラリ名 + -doc
"--prefix" "%{prefix}%"
"--script" "%{build}%/Satyristes"]
]
ビルドしましょう!
Satyristes ファイルや OPAM ファイルを書き終えたらテストの時間です。
以下のコマンドで、現在のディレクトリをピン留め6してビルドしてみましょう。
$ opam pin add -v "file://$PWD"
Package satysfi-great-library does not exist, create as a NEW package? [Y/n] y
The following actions will be performed:
- install satysfi-great-library 1.0*
Do you want to continue? [Y/n] y
<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><>
+ /home/<user>/.opam/opam-init/hooks/sandbox.sh "install" "satyrographos" "opam" "install" "-name" "great-library" "-prefix" "/home/<user>/.opam/4.09.0" "-script" "/home/<user>/.opam/4.09.0/.opam-switch/build/satysfi-great-library.1.0/Satyristes" (CWD=/home/<user>/.opam/4.09.0/.opam-switch/build/satysfi-great-library.1.0)
-> installed satysfi-great-library.1.0
Done.
以上のようなメッセージが出たら成功です!
失敗例としては以下のようなものがあります。
$ opam pin add -v "file://$PWD"
...
#=== ERROR while installing satysfi-great-library.1.0 ================================#
# context 2.0.0 | linux/x86_64 | ocaml-base-compiler.4.09.0 | pinned(file:///home/<user>/Documents/Development/satysfi/packages/satysfi-lib)
# path ~/.opam/4.09.0/.opam-switch/build/satysfi-great-library.0.0.1
# command ~/.opam/opam-init/hooks/sandbox.sh install satyrographos opam install -name satysfi-great-library -prefix /home/<user>/.opam/4.09.0 -script /home/<user>/.opam/4.09.0/.opam-switch/build/satysfi-great-library.1.0/Satyristes
# exit-code 1
# env-file ~/.opam/log/satysfi-base-472050-05296d.env
# output-file ~/.opam/log/satysfi-base-472050-05296d.out
### output ###
# Uncaught exception:
#
# (Failure "Build file does not contains library satysfi-great-library")
#
# Raised at file "stdlib.ml", line 29, characters 17-33
# Called from file "src/command.ml", line 2817, characters 8-205
# Called from file "src/exn.ml", line 107, characters 6-10
<><> Error report <><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
+- The following actions failed
| - install satysfi-great-library 1.0
+-
+- The following changes have been performed
| - remove satysfi-great-library 1.0
+-
The former state can be restored with:
opam switch import "/home/<user>/.opam/4.09.0/.opam-switch/backup/state-20191212143911.export"
Or you can retry to install your package selection with:
opam install --restore
'opam pin add file:///home/<user>/Documents/Development/satysfi/packages/satysfi-lib --verbose' failed.
zsh: exit 31 opam pin add "file://$PWD" --verbose
この場合は、satysfi-great-library.opam
の install:
節が以下のようになっていることから、satyrographos opam install -name satysfi-great-library -prefix …… -script ……
が失敗していることが分かります。
build: [
["satyrographos" "opam" "build"
"--name" "satysfi-great-library" # <- satysfi- は要らない
"--prefix" "%{prefix}%"
"--script" "%{build}%/Satyristes"]
]
Satyrographos のエラーメッセージ等は改善していきたいので、何かありましたらご報告下さい。
リリースしましょう!
GitHub で開発していることを仮定します。GitHub そのものの使い方の解説は他に譲ります。
GitHub にてリリースを行う際には、
-
git tag -a <バージョン>
でタグ付けをして、 -
git push origin <バージョン>
で push する
ことになるかと思います。
一旦 GitHub でリリースしてしまえば、以下のコマンドでライブラリを satyrographos-repo にプルリクエストを送ることができます。
$ cd OPAMファイルのある場所
$ opam publish --repo=na4zagin3/satyrographos-repo
送ったプルリクエストが受け入れられれば公開完了です。お疲れさまでした!
Satyrographos 最後の実装予定機能
ところで
パッケージマネージャ,創らねばならないもの
— 画力・博士号・油田 (@bd_gfngfn) December 9, 2019
というわけで(?)、Satyrographos 最後の機能はネイティブなパッケージマネージャ形式への移行支援であることは決定事項です。
それまではSATySFi用パッケージマネージャーのベースラインかつ実験場として開発を頑張っていこうと思っています。